Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/api/providers/__tests__/anthropic-vertex.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,58 @@ describe("VertexHandler", () => {
expect(AnthropicVertex).toHaveBeenCalledWith({
projectId: "test-project",
region: "us-central1",
baseURL: undefined,
})
})

it("should use custom baseURL for global region", () => {
handler = new AnthropicVertexHandler({
apiModelId: "claude-3-5-sonnet-v2@20241022",
vertexProjectId: "test-project",
vertexRegion: "global",
})

expect(AnthropicVertex).toHaveBeenCalledWith({
projectId: "test-project",
region: "global",
baseURL: "https://aiplatform.googleapis.com/v1",
})
})

it("should use custom baseURL for global region with JSON credentials", () => {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] Consider complementary tests for non-global regions with JSON credentials and with key files to assert baseURL remains undefined. This guards against regressions in the credential branches.

const mockCredentials = JSON.stringify({ type: "service_account", project_id: "test" })
handler = new AnthropicVertexHandler({
apiModelId: "claude-3-5-sonnet-v2@20241022",
vertexProjectId: "test-project",
vertexRegion: "global",
vertexJsonCredentials: mockCredentials,
})

expect(AnthropicVertex).toHaveBeenCalledWith(
expect.objectContaining({
projectId: "test-project",
region: "global",
baseURL: "https://aiplatform.googleapis.com/v1",
}),
)
})

it("should use custom baseURL for global region with key file", () => {
handler = new AnthropicVertexHandler({
apiModelId: "claude-3-5-sonnet-v2@20241022",
vertexProjectId: "test-project",
vertexRegion: "global",
vertexKeyFile: "/path/to/keyfile.json",
})

expect(AnthropicVertex).toHaveBeenCalledWith(
expect.objectContaining({
projectId: "test-project",
region: "global",
baseURL: "https://aiplatform.googleapis.com/v1",
}),
)
})
})

describe("createMessage", () => {
Expand Down
9 changes: 8 additions & 1 deletion src/api/providers/anthropic-vertex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,16 @@ export class AnthropicVertexHandler extends BaseProvider implements SingleComple
const projectId = this.options.vertexProjectId ?? "not-provided"
const region = this.options.vertexRegion ?? "us-east5"

// For the "global" region, we need to use a custom base URL
// The default would be "global-aiplatform.googleapis.com" which is incorrect
// The correct endpoint for global is "aiplatform.googleapis.com"
const baseURL = region === "global" ? `https://aiplatform.googleapis.com/v1` : undefined // Let the SDK use its default for other regions
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Region comparison is exact-match; a user-provided value like "Global" or trailing whitespace would miss this branch. Consider normalizing before compare.

Suggested change
const baseURL = region === "global" ? `https://aiplatform.googleapis.com/v1` : undefined // Let the SDK use its default for other regions
const baseURL = region.trim().toLowerCase() === "global" ? `https://aiplatform.googleapis.com/v1` : undefined // Let the SDK use its default for other regions

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Verify SDK behavior regarding baseURL path: if the Vertex SDK appends "/v1" internally, this string may yield a double "/v1/v1". If so, prefer host-only.

Suggested change
const baseURL = region === "global" ? `https://aiplatform.googleapis.com/v1` : undefined // Let the SDK use its default for other regions
const baseURL = region.trim().toLowerCase() === "global" ? `https://aiplatform.googleapis.com` : undefined // Let the SDK use its default for other regions


if (this.options.vertexJsonCredentials) {
this.client = new AnthropicVertex({
projectId,
region,
baseURL,
googleAuth: new GoogleAuth({
scopes: ["https://www.googleapis.com/auth/cloud-platform"],
credentials: safeJsonParse<JWTInput>(this.options.vertexJsonCredentials, undefined),
Expand All @@ -47,13 +53,14 @@ export class AnthropicVertexHandler extends BaseProvider implements SingleComple
this.client = new AnthropicVertex({
projectId,
region,
baseURL,
googleAuth: new GoogleAuth({
scopes: ["https://www.googleapis.com/auth/cloud-platform"],
keyFile: this.options.vertexKeyFile,
}),
})
} else {
this.client = new AnthropicVertex({ projectId, region })
this.client = new AnthropicVertex({ projectId, region, baseURL })
}
}

Expand Down