diff --git a/src/core/assistant-message/presentAssistantMessage.ts b/src/core/assistant-message/presentAssistantMessage.ts index 7f5862be154..7ce938ccef2 100644 --- a/src/core/assistant-message/presentAssistantMessage.ts +++ b/src/core/assistant-message/presentAssistantMessage.ts @@ -300,22 +300,27 @@ export async function presentAssistantMessage(cline: Task) { // A tool_use block without an id is invalid and cannot be executed. const toolCallId = (block as any).id as string | undefined if (!toolCallId) { - const errorMessage = - "Invalid tool call: missing tool_use.id. XML tool calls are no longer supported. Remove any XML tool markup (e.g. ...) and use native tool calling instead." + const userFacingError = + "XML tool calls are no longer supported. Remove any XML tool markup (e.g. ...) and use native tool calling instead." // Record a tool error for visibility/telemetry. Use the reported tool name if present. try { if ( typeof (cline as any).recordToolError === "function" && typeof (block as any).name === "string" ) { - ;(cline as any).recordToolError((block as any).name as ToolName, errorMessage) + ;(cline as any).recordToolError((block as any).name as ToolName, userFacingError) } } catch { // Best-effort only } cline.consecutiveMistakeCount++ - await cline.say("error", errorMessage) - cline.userMessageContent.push({ type: "text", text: errorMessage }) + await cline.say("error", userFacingError) + // Push comprehensive error with tool-use instructions so the model + // can self-correct on the next turn (see #11106). + cline.userMessageContent.push({ + type: "text", + text: formatResponse.xmlToolCallError(), + }) cline.didAlreadyUseTool = true break } diff --git a/src/core/prompts/__tests__/responses-xml-tool-call-error.spec.ts b/src/core/prompts/__tests__/responses-xml-tool-call-error.spec.ts new file mode 100644 index 00000000000..ae632d32e90 --- /dev/null +++ b/src/core/prompts/__tests__/responses-xml-tool-call-error.spec.ts @@ -0,0 +1,38 @@ +// npx vitest core/prompts/__tests__/responses-xml-tool-call-error.spec.ts + +import { formatResponse } from "../responses" + +describe("formatResponse.xmlToolCallError", () => { + it("should return a string containing the XML error explanation", () => { + const result = formatResponse.xmlToolCallError() + expect(result).toContain("XML tool calls are no longer supported") + }) + + it("should include instruction to not embed XML tags in text", () => { + const result = formatResponse.xmlToolCallError() + expect(result).toContain("Do NOT embed tool invocations as XML tags") + }) + + it("should include tool use instructions reminder", () => { + const result = formatResponse.xmlToolCallError() + expect(result).toContain("Reminder: Instructions for Tool Use") + expect(result).toContain("native tool calling mechanism") + }) + + it("should include next steps guidance", () => { + const result = formatResponse.xmlToolCallError() + expect(result).toContain("Next Steps") + expect(result).toContain("attempt_completion") + expect(result).toContain("ask_followup_question") + }) + + it("should include the [ERROR] prefix", () => { + const result = formatResponse.xmlToolCallError() + expect(result).toMatch(/^\[ERROR\]/) + }) + + it("should include automated message notice", () => { + const result = formatResponse.xmlToolCallError() + expect(result).toContain("This is an automated message") + }) +}) diff --git a/src/core/prompts/responses.ts b/src/core/prompts/responses.ts index 60b5b4123ac..96bfa37bd99 100644 --- a/src/core/prompts/responses.ts +++ b/src/core/prompts/responses.ts @@ -54,6 +54,24 @@ Otherwise, if you have not completed the task and do not need additional informa (This is an automated message, so do not respond to it conversationally.)` }, + xmlToolCallError: () => { + const instructions = getToolInstructionsReminder() + + return `[ERROR] XML tool calls are no longer supported. The model produced XML-style tool markup (e.g. ...) instead of using the API's native tool calling mechanism. + +Do NOT embed tool invocations as XML tags in your text response. Instead, use the platform's built-in function/tool calling feature to invoke tools. + +${instructions} + +# Next Steps + +Please retry your previous action using proper native tool calls. +If you have completed the user's task, use the attempt_completion tool. +If you require additional information from the user, use the ask_followup_question tool. +Otherwise, proceed with the next step of the task using native tool calls. +(This is an automated message, so do not respond to it conversationally.)` + }, + tooManyMistakes: (feedback?: string) => JSON.stringify({ status: "guidance", diff --git a/src/core/tools/BaseTool.ts b/src/core/tools/BaseTool.ts index 7d574068a97..1a27d4f7bea 100644 --- a/src/core/tools/BaseTool.ts +++ b/src/core/tools/BaseTool.ts @@ -142,10 +142,15 @@ export abstract class BaseTool { })() if (paramsText.includes("<") && paramsText.includes(">")) { throw new Error( - "XML tool calls are no longer supported. Use native tool calling (nativeArgs) instead.", + "XML tool calls are no longer supported. " + + "Do not embed tool invocations as XML tags in your text response. " + + "Use the platform's native tool calling mechanism (nativeArgs) instead.", ) } - throw new Error("Tool call is missing native arguments (nativeArgs).") + throw new Error( + "Tool call is missing native arguments (nativeArgs). " + + "Use the platform's native tool calling mechanism to invoke tools.", + ) } } catch (error) { console.error(`Error parsing parameters:`, error)