mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-02 09:11:34 +00:00
fix(anthropic-vertex): correct multi-region endpoints (#116757)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
This commit is contained in:
committed by
GitHub
parent
c75e435e30
commit
754fddbc79
@@ -102,6 +102,19 @@ describe("anthropic-vertex provider plugin", () => {
|
||||
expect(result.provider.models[4]?.thinkingLevelMap).toEqual({ xhigh: null, max: "max" });
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ region: "global", baseUrl: "https://aiplatform.googleapis.com" },
|
||||
{ region: "us", baseUrl: "https://aiplatform.us.rep.googleapis.com" },
|
||||
{ region: "eu", baseUrl: "https://aiplatform.eu.rep.googleapis.com" },
|
||||
{ region: "us-east5", baseUrl: "https://us-east5-aiplatform.googleapis.com" },
|
||||
])("publishes the SDK endpoint for the $region location", ({ region, baseUrl }) => {
|
||||
expect(
|
||||
buildAnthropicVertexProvider({
|
||||
env: { GOOGLE_CLOUD_LOCATION: region },
|
||||
}).baseUrl,
|
||||
).toBe(baseUrl);
|
||||
});
|
||||
|
||||
it.each(["global", "us", "eu"])("publishes Opus 5 for the %s endpoint", (region) => {
|
||||
const provider = buildAnthropicVertexProvider({
|
||||
env: { GOOGLE_CLOUD_LOCATION: region },
|
||||
@@ -194,7 +207,7 @@ describe("anthropic-vertex provider plugin", () => {
|
||||
name: "Claude Sonnet 5",
|
||||
api: "anthropic-messages",
|
||||
provider: "anthropic-vertex",
|
||||
baseUrl: "https://us-aiplatform.googleapis.com",
|
||||
baseUrl: "https://aiplatform.us.rep.googleapis.com",
|
||||
reasoning: true,
|
||||
input: ["text", "image"],
|
||||
contextWindow: 1_000_000,
|
||||
@@ -235,7 +248,7 @@ describe("anthropic-vertex provider plugin", () => {
|
||||
name: "Claude Opus 5",
|
||||
api: "anthropic-messages",
|
||||
provider: "anthropic-vertex",
|
||||
baseUrl: "https://us-aiplatform.googleapis.com",
|
||||
baseUrl: "https://aiplatform.us.rep.googleapis.com",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
|
||||
|
||||
@@ -238,7 +238,9 @@ export function buildAnthropicVertexProvider(params?: {
|
||||
const baseUrl =
|
||||
normalizeLowercaseStringOrEmpty(region) === "global"
|
||||
? "https://aiplatform.googleapis.com"
|
||||
: `https://${region}-aiplatform.googleapis.com`;
|
||||
: region === "us" || region === "eu"
|
||||
? `https://aiplatform.${region}.rep.googleapis.com`
|
||||
: `https://${region}-aiplatform.googleapis.com`;
|
||||
|
||||
return {
|
||||
baseUrl,
|
||||
|
||||
@@ -25,6 +25,12 @@ describe("anthropic vertex region helpers", () => {
|
||||
).toBe("europe-west4");
|
||||
});
|
||||
|
||||
it.each(["us", "eu"])("parses the %s multi-region Vertex endpoint", (region) => {
|
||||
expect(
|
||||
resolveAnthropicVertexRegionFromBaseUrl(`https://aiplatform.${region}.rep.googleapis.com`),
|
||||
).toBe(region);
|
||||
});
|
||||
|
||||
it("treats the global Vertex endpoint as global", () => {
|
||||
expect(resolveAnthropicVertexRegionFromBaseUrl("https://aiplatform.googleapis.com")).toBe(
|
||||
"global",
|
||||
|
||||
@@ -589,6 +589,24 @@ describe("createAnthropicVertexStreamFn", () => {
|
||||
});
|
||||
|
||||
describe("createAnthropicVertexStreamFnForModel", () => {
|
||||
it.each(["us", "eu"])("preserves the %s multi-region SDK endpoint", (region) => {
|
||||
const { deps, anthropicVertexCtorMock, googleAuthClient } = createStreamDeps();
|
||||
const streamFn = createAnthropicVertexStreamFnForModel(
|
||||
{ baseUrl: `https://aiplatform.${region}.rep.googleapis.com` },
|
||||
{ GOOGLE_CLOUD_PROJECT_ID: "vertex-project" } as NodeJS.ProcessEnv,
|
||||
deps,
|
||||
);
|
||||
|
||||
void streamFn(makeModel({ id: "claude-sonnet-5", maxTokens: 128_000 }), { messages: [] }, {});
|
||||
|
||||
expect(anthropicVertexCtorMock).toHaveBeenCalledWith({
|
||||
googleAuth: googleAuthClient,
|
||||
projectId: "vertex-project",
|
||||
region,
|
||||
baseURL: `https://aiplatform.${region}.rep.googleapis.com/v1`,
|
||||
});
|
||||
});
|
||||
|
||||
it("derives project and region from the model and env", () => {
|
||||
const { deps, anthropicVertexCtorMock, googleAuthClient } = createStreamDeps();
|
||||
const streamFn = createAnthropicVertexStreamFnForModel(
|
||||
|
||||
36
packages/ai/src/transports/anthropic-payload-policy.test.ts
Normal file
36
packages/ai/src/transports/anthropic-payload-policy.test.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { resolveAnthropicEphemeralCacheControl } from "./anthropic-payload-policy.js";
|
||||
|
||||
describe("resolveAnthropicEphemeralCacheControl", () => {
|
||||
afterEach(() => {
|
||||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
it.each([
|
||||
"https://aiplatform.googleapis.com",
|
||||
"https://us-east5-aiplatform.googleapis.com",
|
||||
"https://aiplatform.us.rep.googleapis.com",
|
||||
"https://aiplatform.eu.rep.googleapis.com",
|
||||
])("preserves env-configured long retention for the official %s endpoint", (baseUrl) => {
|
||||
vi.stubEnv("OPENCLAW_CACHE_RETENTION", "long");
|
||||
|
||||
expect(resolveAnthropicEphemeralCacheControl(baseUrl, undefined)).toEqual({
|
||||
type: "ephemeral",
|
||||
ttl: "1h",
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps env-configured long retention restricted for custom proxy endpoints", () => {
|
||||
vi.stubEnv("OPENCLAW_CACHE_RETENTION", "long");
|
||||
|
||||
expect(
|
||||
resolveAnthropicEphemeralCacheControl("https://proxy.example.test/vertex", undefined),
|
||||
).toEqual({ type: "ephemeral" });
|
||||
});
|
||||
|
||||
it("preserves explicitly configured long retention for custom proxy endpoints", () => {
|
||||
expect(
|
||||
resolveAnthropicEphemeralCacheControl("https://proxy.example.test/vertex", "long"),
|
||||
).toEqual({ type: "ephemeral", ttl: "1h" });
|
||||
});
|
||||
});
|
||||
@@ -56,6 +56,8 @@ function isLongTtlEligibleEndpoint(baseUrl: string | undefined): boolean {
|
||||
return (
|
||||
hostname === "api.anthropic.com" ||
|
||||
hostname === "aiplatform.googleapis.com" ||
|
||||
hostname === "aiplatform.us.rep.googleapis.com" ||
|
||||
hostname === "aiplatform.eu.rep.googleapis.com" ||
|
||||
hostname.endsWith("-aiplatform.googleapis.com")
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user