From 5b41cf7af437420aada403b716a451a32f2d504e Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Wed, 25 Jun 2025 14:39:49 -0700 Subject: [PATCH] Gemini 2.5 using Claude4 system prompt (#4468) * gemini 2.5 using claude4 prompt now * changeset * more lenient claude4 family check --------- Co-authored-by: Cline Evaluation --- .changeset/eighty-timers-camp.md | 5 +++++ src/core/prompts/system.ts | 6 +++--- src/core/task/ToolExecutor.ts | 12 +++++------- src/core/task/index.ts | 10 +++++----- src/utils/model-utils.ts | 10 +++++++++- 5 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 .changeset/eighty-timers-camp.md diff --git a/.changeset/eighty-timers-camp.md b/.changeset/eighty-timers-camp.md new file mode 100644 index 0000000000..93c1a95c88 --- /dev/null +++ b/.changeset/eighty-timers-camp.md @@ -0,0 +1,5 @@ +--- +"claude-dev": minor +--- + +Optimizing cline to work for gemini 2.5 family of models diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 3477fc77ea..cd63d34025 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -12,14 +12,14 @@ export const SYSTEM_PROMPT = async ( supportsBrowserUse: boolean, mcpHub: McpHub, browserSettings: BrowserSettings, - isClaude4ModelFamily: boolean = false, + isNextGenModel: boolean = false, ) => { - if (isClaude4ModelFamily && USE_EXPERIMENTAL_CLAUDE4_FEATURES) { + if (isNextGenModel && USE_EXPERIMENTAL_CLAUDE4_FEATURES) { return SYSTEM_PROMPT_CLAUDE4_EXPERIMENTAL(cwd, supportsBrowserUse, mcpHub, browserSettings) } - if (isClaude4ModelFamily) { + if (isNextGenModel) { return SYSTEM_PROMPT_CLAUDE4(cwd, supportsBrowserUse, mcpHub, browserSettings) } diff --git a/src/core/task/ToolExecutor.ts b/src/core/task/ToolExecutor.ts index 903fe77e64..c85059f832 100644 --- a/src/core/task/ToolExecutor.ts +++ b/src/core/task/ToolExecutor.ts @@ -30,7 +30,7 @@ import { ClineAskResponse } from "@shared/WebviewMessage" import { fixModelHtmlEscaping, removeInvalidChars } from "@utils/string" import { fileExistsAtPath } from "@utils/fs" import { formatResponse } from "../prompts/responses" -import { isClaude4ModelFamily } from "@utils/model-utils" +import { isClaude4ModelFamily, isGemini2dot5ModelFamily } from "@utils/model-utils" import { ToolResponse, USE_EXPERIMENTAL_CLAUDE4_FEATURES } from "." import { serializeError } from "serialize-error" import * as path from "path" @@ -105,12 +105,12 @@ export class ToolExecutor { ) {} private pushToolResult = (content: ToolResponse, block: ToolUse) => { - const isClaude4Model = isClaude4ModelFamily(this.api) + const isNextGenModel = isClaude4ModelFamily(this.api) || isGemini2dot5ModelFamily(this.api) if (typeof content === "string") { const resultText = content || "(tool did not return anything)" - if (isClaude4Model && USE_EXPERIMENTAL_CLAUDE4_FEATURES) { + if (isNextGenModel && USE_EXPERIMENTAL_CLAUDE4_FEATURES) { // Claude 4 family: Use function_results format this.taskState.userMessageContent.push({ type: "text", @@ -472,9 +472,9 @@ export class ToolExecutor { const currentFullJson = block.params.diff // Check if we should use streaming (e.g., for specific models) - const isClaude4Model = isClaude4ModelFamily(this.api) + const isNextGenModel = isClaude4ModelFamily(this.api) || isGemini2dot5ModelFamily(this.api) // Going through claude family of models - if (isClaude4Model && USE_EXPERIMENTAL_CLAUDE4_FEATURES && currentFullJson) { + if (isNextGenModel && USE_EXPERIMENTAL_CLAUDE4_FEATURES && currentFullJson) { const streamingResult = await this.handleStreamingJsonReplacement(block, relPath, currentFullJson) if (streamingResult.error) { @@ -839,7 +839,6 @@ export class ToolExecutor { } } case "list_files": { - const isClaude4Model = isClaude4ModelFamily(this.api) const relDirPath: string | undefined = block.params.path const recursiveRaw: string | undefined = block.params.recursive const recursive = recursiveRaw?.toLowerCase() === "true" @@ -989,7 +988,6 @@ export class ToolExecutor { } } case "search_files": { - const isClaude4Model = isClaude4ModelFamily(this.api) const relDirPath: string | undefined = block.params.path const regex: string | undefined = block.params.regex const filePattern: string | undefined = block.params.file_pattern diff --git a/src/core/task/index.ts b/src/core/task/index.ts index 975f75aa61..73985ba2fe 100644 --- a/src/core/task/index.ts +++ b/src/core/task/index.ts @@ -90,7 +90,7 @@ import WorkspaceTracker from "@integrations/workspace/WorkspaceTracker" import { McpHub } from "@services/mcp/McpHub" import { isInTestMode } from "../../services/test/TestMode" import { processFilesIntoText } from "@integrations/misc/extract-text" -import { isClaude4ModelFamily } from "@utils/model-utils" +import { isClaude4ModelFamily, isGemini2dot5ModelFamily } from "@utils/model-utils" import { MessageStateHandler } from "./message-state" import { formatErrorWithStatusCode, updateApiReqMsg } from "./utils" import { TaskState } from "./TaskState" @@ -1654,8 +1654,8 @@ export class Task { const supportsBrowserUse = modelSupportsBrowserUse && !disableBrowserTool // only enable browser use if the model supports it and the user hasn't disabled it - const isClaude4Model = isClaude4ModelFamily(this.api) - let systemPrompt = await SYSTEM_PROMPT(cwd, supportsBrowserUse, this.mcpHub, this.browserSettings, isClaude4Model) + const isNextGenModel = isClaude4ModelFamily(this.api) || isGemini2dot5ModelFamily(this.api) + let systemPrompt = await SYSTEM_PROMPT(cwd, supportsBrowserUse, this.mcpHub, this.browserSettings, isNextGenModel) await this.migratePreferredLanguageToolSetting() const preferredLanguage = getLanguageKey(this.chatSettings.preferredLanguage as LanguageDisplay) @@ -2223,8 +2223,8 @@ export class Task { assistantMessage += chunk.text // parse raw assistant message into content blocks const prevLength = this.taskState.assistantMessageContent.length - const isClaude4Model = isClaude4ModelFamily(this.api) - if (isClaude4Model && USE_EXPERIMENTAL_CLAUDE4_FEATURES) { + const isNextGenModel = isClaude4ModelFamily(this.api) || isGemini2dot5ModelFamily(this.api) + if (isNextGenModel && USE_EXPERIMENTAL_CLAUDE4_FEATURES) { this.taskState.assistantMessageContent = parseAssistantMessageV3(assistantMessage) } else { this.taskState.assistantMessageContent = parseAssistantMessageV2(assistantMessage) diff --git a/src/utils/model-utils.ts b/src/utils/model-utils.ts index 2f74afa404..014a420ab1 100644 --- a/src/utils/model-utils.ts +++ b/src/utils/model-utils.ts @@ -3,5 +3,13 @@ import { ApiHandler } from "@api/index" export function isClaude4ModelFamily(api: ApiHandler): boolean { const model = api.getModel() const modelId = model.id - return modelId.includes("sonnet-4") || modelId.includes("opus-4") + return ( + modelId.includes("sonnet-4") || modelId.includes("opus-4") || modelId.includes("4-sonnet") || modelId.includes("4-opus") + ) +} + +export function isGemini2dot5ModelFamily(api: ApiHandler): boolean { + const model = api.getModel() + const modelId = model.id + return modelId.includes("gemini-2.5") }