Merge PR #8795: fix(tests): stop ANTHROPIC_BASE_URL from failing the Anthropic suites (@Huang-404-Q)
This commit is contained in:
@@ -32,7 +32,7 @@ import type {
|
||||
} from "@oh-my-pi/pi-ai/types";
|
||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||
import { removeSyncWithRetries } from "@oh-my-pi/pi-utils";
|
||||
import { withEnv } from "./helpers";
|
||||
import { withEnv, withOfficialAnthropicEndpoint } from "./helpers";
|
||||
|
||||
const ANTHROPIC_MODEL_SPEC: ModelSpec<"anthropic-messages"> = {
|
||||
id: "claude-sonnet-4-5",
|
||||
@@ -152,6 +152,8 @@ function expectClaudeMetadataUserId(userId: string | undefined, expectedSessionI
|
||||
}
|
||||
}
|
||||
|
||||
withOfficialAnthropicEndpoint();
|
||||
|
||||
describe("Anthropic request fingerprint alignment", () => {
|
||||
it("maps Stainless arch values from explicit inputs", () => {
|
||||
expect(mapStainlessArch("x64")).toBe("x64");
|
||||
|
||||
@@ -3,6 +3,7 @@ import { streamSimple } from "@oh-my-pi/pi-ai";
|
||||
import type { CacheControlEphemeral, MessageCreateParams } from "@oh-my-pi/pi-ai/providers/anthropic-wire";
|
||||
import type { CacheRetention, Context, FetchImpl, Model, ProviderSessionState } from "@oh-my-pi/pi-ai/types";
|
||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||
import { withOfficialAnthropicEndpoint } from "./helpers";
|
||||
|
||||
const CACHE_REFRESH_DELAY_MS = 5 * 60_000 - 15_000;
|
||||
const CACHE_TOKENS = 1_200;
|
||||
@@ -211,6 +212,8 @@ afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
withOfficialAnthropicEndpoint();
|
||||
|
||||
describe("Anthropic prompt-cache refresh", () => {
|
||||
it("replays max_tokens=0 once per interval and stops after three refreshes", async () => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
} from "@oh-my-pi/pi-ai/providers/anthropic";
|
||||
import type { Context, Model, ProviderSessionState, ServiceTier } from "@oh-my-pi/pi-ai/types";
|
||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||
import { withOfficialAnthropicEndpoint } from "./helpers";
|
||||
|
||||
function makeAnthropicModel(id: string): Model<"anthropic-messages"> {
|
||||
return buildModel({
|
||||
@@ -52,6 +53,8 @@ function capturePayload(model: Model<"anthropic-messages">, opts: CaptureOptions
|
||||
return promise;
|
||||
}
|
||||
|
||||
withOfficialAnthropicEndpoint();
|
||||
|
||||
describe("Anthropic priority service tier → speed='fast'", () => {
|
||||
it("sets speed='fast' for Claude Opus 4.7 when serviceTier='priority'", async () => {
|
||||
const payload = (await capturePayload(makeAnthropicModel("claude-opus-4-7"), {
|
||||
|
||||
@@ -13,7 +13,7 @@ import type {
|
||||
import type { AssistantMessageEvent, Context, Model, ModelSpec, ProviderSessionState } from "@oh-my-pi/pi-ai/types";
|
||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||
import { structuredCloneJSON } from "@oh-my-pi/pi-utils";
|
||||
import { withEnv } from "./helpers";
|
||||
import { withEnv, withOfficialAnthropicEndpoint } from "./helpers";
|
||||
|
||||
const model: Model<"anthropic-messages"> = buildModel({
|
||||
id: "claude-sonnet-4-5",
|
||||
@@ -351,6 +351,8 @@ afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
withOfficialAnthropicEndpoint();
|
||||
|
||||
describe("anthropic stream envelope handling", () => {
|
||||
it("ignores duplicate message_start envelopes without resetting streamed text", async () => {
|
||||
vi.spyOn(AnthropicMessages.prototype, "create").mockImplementation(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { afterEach, beforeEach } from "bun:test";
|
||||
import * as os from "node:os";
|
||||
import * as path from "node:path";
|
||||
import type { Model } from "@oh-my-pi/pi-ai/types";
|
||||
@@ -114,3 +115,29 @@ async function readAuthGatewayE2EStatus(): Promise<AuthGatewayE2EStatus> {
|
||||
}
|
||||
return { ok: true, token };
|
||||
}
|
||||
|
||||
/**
|
||||
* Neutralize `ANTHROPIC_BASE_URL` for the calling test file.
|
||||
*
|
||||
* The variable reroutes the effective Anthropic endpoint, and every
|
||||
* "official endpoint" behavior — eager tool-input streaming, long cache
|
||||
* retention, the Cowork TLS profile, the Claude Code session header — switches
|
||||
* off once it points elsewhere. A contributor running a gateway, or running the
|
||||
* suite from inside another agent, otherwise sees these tests fail on a clean
|
||||
* checkout. Tests that exercise gateway routing set the variable explicitly
|
||||
* with `withEnv` inside the test body, which still wins over this reset.
|
||||
*/
|
||||
export function withOfficialAnthropicEndpoint(): void {
|
||||
let previous: string | undefined;
|
||||
beforeEach(() => {
|
||||
previous = Bun.env.ANTHROPIC_BASE_URL;
|
||||
delete Bun.env.ANTHROPIC_BASE_URL;
|
||||
});
|
||||
afterEach(() => {
|
||||
if (previous === undefined) {
|
||||
delete Bun.env.ANTHROPIC_BASE_URL;
|
||||
} else {
|
||||
Bun.env.ANTHROPIC_BASE_URL = previous;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import { getStreamingPartialJson, setStreamingPartialJson } from "@oh-my-pi/pi-a
|
||||
import { AssistantMessageEventStream } from "@oh-my-pi/pi-ai/utils/event-stream";
|
||||
import { wrapLeakedThinkingStream } from "@oh-my-pi/pi-ai/utils/leaked-thinking-stream";
|
||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||
import { withOfficialAnthropicEndpoint } from "./helpers";
|
||||
|
||||
/** Minimal assistant message; `content`/`stopReason` overridden per event. */
|
||||
function msg(overrides: Partial<AssistantMessage> = {}): AssistantMessage {
|
||||
@@ -92,6 +93,8 @@ async function nextToolSnapshot(iterator: AsyncIterator<AssistantMessageEvent>):
|
||||
}
|
||||
}
|
||||
|
||||
withOfficialAnthropicEndpoint();
|
||||
|
||||
describe("wrapLeakedThinkingStream", () => {
|
||||
async function runLeakedText(chunks: readonly string[]): Promise<{
|
||||
events: AssistantMessageEvent[];
|
||||
|
||||
@@ -10,6 +10,9 @@ import { AgentSession } from "@oh-my-pi/pi-coding-agent/session/agent-session";
|
||||
import { AuthStorage } from "@oh-my-pi/pi-coding-agent/session/auth-storage";
|
||||
import { SessionManager } from "@oh-my-pi/pi-coding-agent/session/session-manager";
|
||||
import { TempDir } from "@oh-my-pi/pi-utils";
|
||||
import { withOfficialAnthropicEndpoint } from "./helpers/anthropic-endpoint";
|
||||
|
||||
withOfficialAnthropicEndpoint();
|
||||
|
||||
describe("/fast targets the current model's service-tier family", () => {
|
||||
let tempDir: TempDir;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { afterEach, beforeEach } from "bun:test";
|
||||
|
||||
/**
|
||||
* Neutralize `ANTHROPIC_BASE_URL` for the calling test file.
|
||||
*
|
||||
* The variable reroutes the effective Anthropic endpoint, and every
|
||||
* "official endpoint" behavior — eager tool-input streaming, long cache
|
||||
* retention, the Cowork TLS profile, the Claude Code session header — switches
|
||||
* off once it points elsewhere. A contributor running a gateway, or running the
|
||||
* suite from inside another agent, otherwise sees these tests fail on a clean
|
||||
* checkout. Tests that exercise gateway routing set the variable explicitly
|
||||
* with `withEnv` inside the test body, which still wins over this reset.
|
||||
*/
|
||||
export function withOfficialAnthropicEndpoint(): void {
|
||||
let previous: string | undefined;
|
||||
beforeEach(() => {
|
||||
previous = Bun.env.ANTHROPIC_BASE_URL;
|
||||
delete Bun.env.ANTHROPIC_BASE_URL;
|
||||
});
|
||||
afterEach(() => {
|
||||
if (previous === undefined) {
|
||||
delete Bun.env.ANTHROPIC_BASE_URL;
|
||||
} else {
|
||||
Bun.env.ANTHROPIC_BASE_URL = previous;
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user