diff --git a/packages/types/src/providers/vertex.ts b/packages/types/src/providers/vertex.ts index 858b28048ed..251e7cb9ad6 100644 --- a/packages/types/src/providers/vertex.ts +++ b/packages/types/src/providers/vertex.ts @@ -35,6 +35,17 @@ export const vertexModels = { }, ], }, + "gemini-3.1-flash-lite-preview": { + maxTokens: 65_536, + contextWindow: 1_048_576, + supportsImages: true, + supportsPromptCache: true, + + supportsTemperature: true, + defaultTemperature: 1, + inputPrice: 0.0, + outputPrice: 0.0, + }, "gemini-3.1-pro-preview-customtools": { maxTokens: 65_536, contextWindow: 1_048_576, diff --git a/src/api/providers/__tests__/anthropic-vertex.spec.ts b/src/api/providers/__tests__/anthropic-vertex.spec.ts index 9ed0e51ad92..0c3f1fecda2 100644 --- a/src/api/providers/__tests__/anthropic-vertex.spec.ts +++ b/src/api/providers/__tests__/anthropic-vertex.spec.ts @@ -869,6 +869,34 @@ describe("VertexHandler", () => { expect(result.temperature).toBe(0) }) + it("should pass through custom/unknown model IDs with sensible defaults", () => { + const handler = new AnthropicVertexHandler({ + apiModelId: "claude-5-opus@20260101", + vertexProjectId: "test-project", + vertexRegion: "us-central1", + }) + + const modelInfo = handler.getModel() + expect(modelInfo.id).toBe("claude-5-opus@20260101") + expect(modelInfo.info).toBeDefined() + expect(modelInfo.info.maxTokens).toBe(8192) + expect(modelInfo.info.contextWindow).toBe(200_000) + expect(modelInfo.info.supportsImages).toBe(true) + expect(modelInfo.info.supportsPromptCache).toBe(false) + }) + + it("should fall back to default model when no model ID is provided", () => { + const handler = new AnthropicVertexHandler({ + vertexProjectId: "test-project", + vertexRegion: "us-central1", + }) + + const modelInfo = handler.getModel() + expect(modelInfo.id).toBeDefined() + expect(modelInfo.info).toBeDefined() + expect(modelInfo.info.maxTokens).toBeGreaterThan(0) + }) + it("should enable 1M context for Claude Sonnet 4 when beta flag is set", () => { const handler = new AnthropicVertexHandler({ apiModelId: VERTEX_1M_CONTEXT_MODEL_IDS[0], diff --git a/src/api/providers/__tests__/vertex.spec.ts b/src/api/providers/__tests__/vertex.spec.ts index 3361176f1fa..6faba3cab9d 100644 --- a/src/api/providers/__tests__/vertex.spec.ts +++ b/src/api/providers/__tests__/vertex.spec.ts @@ -163,5 +163,35 @@ describe("VertexHandler", () => { expect(excludedCount).toBe(1) expect(includedCount).toBe(1) }) + + it("should pass through custom/unknown model IDs with sensible defaults", () => { + const testHandler = new VertexHandler({ + apiModelId: "gemini-4.0-ultra-preview", + vertexProjectId: "test-project", + vertexRegion: "us-central1", + }) + + const modelInfo = testHandler.getModel() + expect(modelInfo.id).toBe("gemini-4.0-ultra-preview") + expect(modelInfo.info).toBeDefined() + expect(modelInfo.info.maxTokens).toBe(8192) + expect(modelInfo.info.contextWindow).toBe(1_048_576) + expect(modelInfo.info.supportsImages).toBe(true) + expect(modelInfo.info.supportsPromptCache).toBe(false) + expect(modelInfo.info.excludedTools).toContain("apply_diff") + expect(modelInfo.info.includedTools).toContain("edit") + }) + + it("should fall back to default model when no model ID is provided", () => { + const testHandler = new VertexHandler({ + vertexProjectId: "test-project", + vertexRegion: "us-central1", + }) + + const modelInfo = testHandler.getModel() + expect(modelInfo.id).toBeDefined() + expect(modelInfo.info).toBeDefined() + expect(modelInfo.info.maxTokens).toBeGreaterThan(0) + }) }) }) diff --git a/src/api/providers/anthropic-vertex.ts b/src/api/providers/anthropic-vertex.ts index 3ed5dd45cce..17264281ce6 100644 --- a/src/api/providers/anthropic-vertex.ts +++ b/src/api/providers/anthropic-vertex.ts @@ -207,8 +207,27 @@ export class AnthropicVertexHandler extends BaseProvider implements SingleComple getModel() { const modelId = this.options.apiModelId - let id = modelId && modelId in vertexModels ? (modelId as VertexModelId) : vertexDefaultModelId - let info: ModelInfo = vertexModels[id] + let id: string + let info: ModelInfo + + if (modelId && modelId in vertexModels) { + id = modelId as VertexModelId + info = vertexModels[id as VertexModelId] + } else if (modelId) { + // Pass through custom/unknown model IDs with sensible defaults + id = modelId + info = { + maxTokens: 8192, + contextWindow: 200_000, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + } + } else { + id = vertexDefaultModelId + info = vertexModels[vertexDefaultModelId] + } // Check if 1M context beta should be enabled for supported models const supports1MContext = VERTEX_1M_CONTEXT_MODEL_IDS.includes( diff --git a/src/api/providers/vertex.ts b/src/api/providers/vertex.ts index fd318d9b19a..675701dd007 100644 --- a/src/api/providers/vertex.ts +++ b/src/api/providers/vertex.ts @@ -14,8 +14,27 @@ export class VertexHandler extends GeminiHandler implements SingleCompletionHand override getModel() { const modelId = this.options.apiModelId - let id = modelId && modelId in vertexModels ? (modelId as VertexModelId) : vertexDefaultModelId - let info: ModelInfo = vertexModels[id] + let id: string + let info: ModelInfo + + if (modelId && modelId in vertexModels) { + id = modelId as VertexModelId + info = vertexModels[id as VertexModelId] + } else if (modelId) { + // Pass through custom/unknown model IDs with sensible defaults + id = modelId + info = { + maxTokens: 8192, + contextWindow: 1_048_576, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0, + outputPrice: 0, + } + } else { + id = vertexDefaultModelId + info = vertexModels[vertexDefaultModelId] + } const params = getModelParams({ format: "gemini", modelId: id,