fix: preserve native Vertex endpoint defaults (#1104)

## Summary
- keep `ANTHROPIC_VERTEX_BASE_URL` unset when `providers/set` selects
Vertex's native default endpoint
- retain explicit `ANTHROPIC_VERTEX_BASE_URL` only for custom Vertex
gateways/endpoints
- add a regression test for the default Vertex endpoint env mapping

Closes #1087

## Test Plan
- `npm run test:run -- src/tests/providers.test.ts` — passed (21 tests)
- `npm run check` — passed (`eslint src --ext .ts` + `prettier --check
.`)
- `npm run build` — passed (`tsc`)
- `git diff --check origin/main..HEAD` — passed

Note: `claude -p` delegation was attempted for candidate discovery but
this cron shell's Claude Code auth is not logged in (`Not logged in ·
Please run /login`), so the implementation/validation above was done
directly with local tests.

Signed-off-by: Emre K <110906681+kocaemre@users.noreply.github.com>
This commit is contained in:
Emre K.
2026-09-23 12:40:40 +03:00
committed by GitHub
parent 6e97e071c5
commit 29a4e98477
2 changed files with 35 additions and 2 deletions

View File

@@ -1300,6 +1300,7 @@ const AUTH_REQUIRED_CODE = RequestError.authRequired().code;
const SUPPORTED_PROTOCOLS: LlmProtocol[] = ["anthropic", "bedrock", "vertex"];
const PROVIDER_ID = "main";
const DEFAULT_ANTHROPIC_BASE_URL = "https://api.anthropic.com";
const DEFAULT_VERTEX_BASE_URL = "https://aiplatform.googleapis.com";
/**
* Vertex needs project + region that the standard `providers/set` payload
@@ -2691,7 +2692,7 @@ export class ClaudeAcpAgent {
if (process.env.CLAUDE_CODE_USE_VERTEX) {
return {
apiType: "vertex",
baseUrl: process.env.ANTHROPIC_VERTEX_BASE_URL ?? "https://aiplatform.googleapis.com",
baseUrl: process.env.ANTHROPIC_VERTEX_BASE_URL ?? DEFAULT_VERTEX_BASE_URL,
headers: {},
};
}
@@ -9133,10 +9134,16 @@ function createEnvForProvider(config: ProviderConfig | null): Record<string, str
if (config.apiType === "vertex") {
// `config.vertex` is guaranteed present for vertex by `unstable_setProvider`
// validation; fall back to empty strings defensively.
// Leaving ANTHROPIC_VERTEX_BASE_URL empty for the default endpoint lets
// Claude Code use its native Vertex endpoint/model resolution. Supplying
// even the default host marks the session as a custom Vertex deployment and
// can hide otherwise-valid models.
return {
...resetRouting,
CLAUDE_CODE_USE_VERTEX: "1",
ANTHROPIC_VERTEX_BASE_URL: config.baseUrl,
...(config.baseUrl !== DEFAULT_VERTEX_BASE_URL
? { ANTHROPIC_VERTEX_BASE_URL: config.baseUrl }
: {}),
ANTHROPIC_VERTEX_PROJECT_ID: config.vertex?.projectId ?? "",
CLOUD_ML_REGION: config.vertex?.region ?? "",
ANTHROPIC_CUSTOM_HEADERS: customHeaders,

View File

@@ -429,6 +429,32 @@ describe("providers", () => {
);
});
it("leaves the native Vertex base URL unset for the default endpoint", async () => {
const [agent, mockQuery] = await createAgentMock();
await agent.initialize({ protocolVersion: 1, clientCapabilities: {} });
await agent.unstable_setProvider({
providerId: "main",
apiType: "vertex",
baseUrl: "https://aiplatform.googleapis.com",
_meta: { claudeCode: { vertex: { projectId: "my-project", region: "global" } } },
});
await agent.newSession({ cwd: process.cwd(), mcpServers: [] });
expect(mockQuery).toHaveBeenCalledWith(
expect.objectContaining({
options: expect.objectContaining({
env: expect.objectContaining({
CLAUDE_CODE_USE_VERTEX: "1",
ANTHROPIC_VERTEX_BASE_URL: "",
ANTHROPIC_VERTEX_PROJECT_ID: "my-project",
CLOUD_ML_REGION: "global",
}),
}),
}),
);
});
it("rejects vertex set without _meta project/region", async () => {
const [agent] = await createAgentMock();
await expect(