diff --git a/src/api/providers/__tests__/gemini.spec.ts b/src/api/providers/__tests__/gemini.spec.ts index 8c2ee87a78..47ee79dd0d 100644 --- a/src/api/providers/__tests__/gemini.spec.ts +++ b/src/api/providers/__tests__/gemini.spec.ts @@ -173,6 +173,20 @@ describe("GeminiHandler", () => { const modelInfo = invalidHandler.getModel() expect(modelInfo.id).toBe(geminiDefaultModelId) // Default model }) + + it("should exclude apply_diff and include edit in tool preferences", () => { + const modelInfo = handler.getModel() + expect(modelInfo.info.excludedTools).toContain("apply_diff") + expect(modelInfo.info.includedTools).toContain("edit") + }) + + it("should not duplicate tool entries if already present", () => { + const modelInfo = handler.getModel() + const excludedCount = modelInfo.info.excludedTools!.filter((t: string) => t === "apply_diff").length + const includedCount = modelInfo.info.includedTools!.filter((t: string) => t === "edit").length + expect(excludedCount).toBe(1) + expect(includedCount).toBe(1) + }) }) describe("calculateCost", () => { diff --git a/src/api/providers/__tests__/vertex.spec.ts b/src/api/providers/__tests__/vertex.spec.ts index 1420b05c7a..3361176f1f 100644 --- a/src/api/providers/__tests__/vertex.spec.ts +++ b/src/api/providers/__tests__/vertex.spec.ts @@ -137,5 +137,31 @@ describe("VertexHandler", () => { expect(modelInfo.info.maxTokens).toBe(8192) expect(modelInfo.info.contextWindow).toBe(1048576) }) + + it("should exclude apply_diff and include edit in tool preferences", () => { + const testHandler = new VertexHandler({ + apiModelId: "gemini-2.0-flash-001", + vertexProjectId: "test-project", + vertexRegion: "us-central1", + }) + + const modelInfo = testHandler.getModel() + expect(modelInfo.info.excludedTools).toContain("apply_diff") + expect(modelInfo.info.includedTools).toContain("edit") + }) + + it("should not duplicate tool entries if already present", () => { + const testHandler = new VertexHandler({ + apiModelId: "gemini-2.0-flash-001", + vertexProjectId: "test-project", + vertexRegion: "us-central1", + }) + + const modelInfo = testHandler.getModel() + const excludedCount = modelInfo.info.excludedTools!.filter((t: string) => t === "apply_diff").length + const includedCount = modelInfo.info.includedTools!.filter((t: string) => t === "edit").length + expect(excludedCount).toBe(1) + expect(includedCount).toBe(1) + }) }) }) diff --git a/src/api/providers/gemini.ts b/src/api/providers/gemini.ts index db8041b980..a49073ea33 100644 --- a/src/api/providers/gemini.ts +++ b/src/api/providers/gemini.ts @@ -359,6 +359,13 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl defaultTemperature: info.defaultTemperature ?? 1, }) + // Gemini models perform better with the edit tool instead of apply_diff. + info = { + ...info, + excludedTools: [...new Set([...(info.excludedTools || []), "apply_diff"])], + includedTools: [...new Set([...(info.includedTools || []), "edit"])], + } + // The `:thinking` suffix indicates that the model is a "Hybrid" // reasoning model and that reasoning is required to be enabled. // The actual model ID honored by Gemini's API does not have this diff --git a/src/api/providers/vertex.ts b/src/api/providers/vertex.ts index f470b88e9b..fd318d9b19 100644 --- a/src/api/providers/vertex.ts +++ b/src/api/providers/vertex.ts @@ -15,7 +15,7 @@ export class VertexHandler extends GeminiHandler implements SingleCompletionHand override getModel() { const modelId = this.options.apiModelId let id = modelId && modelId in vertexModels ? (modelId as VertexModelId) : vertexDefaultModelId - const info: ModelInfo = vertexModels[id] + let info: ModelInfo = vertexModels[id] const params = getModelParams({ format: "gemini", modelId: id, @@ -24,6 +24,13 @@ export class VertexHandler extends GeminiHandler implements SingleCompletionHand defaultTemperature: info.defaultTemperature ?? 1, }) + // Vertex Gemini models perform better with the edit tool instead of apply_diff. + info = { + ...info, + excludedTools: [...new Set([...(info.excludedTools || []), "apply_diff"])], + includedTools: [...new Set([...(info.includedTools || []), "edit"])], + } + // The `:thinking` suffix indicates that the model is a "Hybrid" // reasoning model and that reasoning is required to be enabled. // The actual model ID honored by Gemini's API does not have this