Skip to content

Commit 6001743

Browse files
pashpashpashCline Evaluationellipsis-dev[bot]
authored
created framework for idiomatic tool calling in claude 4 models (RooCodeInc#3872)
* created framework for idiomatic tool calling in claude 4 models * aligning * Update src/core/tools/bashTool.ts Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> * Fix Diff edit prompt * commented out for now --------- Co-authored-by: Cline Evaluation <[email protected]> Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
1 parent 9818d97 commit 6001743

File tree

4 files changed

+501
-33
lines changed

4 files changed

+501
-33
lines changed

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ webview-ui/build/
44
*.md
55
package-lock.json
66
src/core/prompts/system.ts
7+
src/core/prompts/model_prompts/claude4.ts

src/core/prompts/model_prompts/claude4.ts

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,19 @@ import osName from "os-name"
44
import { McpHub } from "@services/mcp/McpHub"
55
import { BrowserSettings } from "@shared/BrowserSettings"
66

7+
import { createAntmlToolPrompt, createSimpleXmlToolPrompt } from "@core/prompts/model_prompts/jsonToolToXml"
8+
import {bashToolDefinition} from "@core/tools/bashTool"
9+
710
export const SYSTEM_PROMPT_CLAUDE4 = async (
811
cwd: string,
912
supportsBrowserUse: boolean,
1013
mcpHub: McpHub,
1114
browserSettings: BrowserSettings,
12-
) => `You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.
15+
) => `
16+
17+
${/* createAntmlToolPrompt([bashToolDefinition], true) */''}
18+
19+
You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.
1320
1421
====
1522
@@ -354,38 +361,6 @@ Usage:
354361
</diff>
355362
</replace_in_file>
356363
357-
<path>src/components/App.tsx</path>
358-
<diff>
359-
<<<<<<< SEARCH
360-
import React from 'react';
361-
=======
362-
import React, { useState } from 'react';
363-
>>>>>>> REPLACE
364-
365-
<<<<<<< SEARCH
366-
function handleSubmit() {
367-
saveData();
368-
setLoading(false);
369-
}
370-
371-
=======
372-
>>>>>>> REPLACE
373-
374-
<<<<<<< SEARCH
375-
return (
376-
<div>
377-
=======
378-
function handleSubmit() {
379-
saveData();
380-
setLoading(false);
381-
}
382-
383-
return (
384-
<div>
385-
>>>>>>> REPLACE
386-
</diff>
387-
</replace_in_file>
388-
389364
390365
## Example 5: Requesting to use an MCP tool
391366
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
/**
2+
* Converts a tool definition to ANTML (Anthropic Markup Language) format
3+
* as used internally by Claude for tool calling.
4+
*
5+
* Based on the Claude 4 System Card: https://www-cdn.anthropic.com/6be99a52cb68eb70eb9572b4cafad13df32ed995.pdf
6+
*
7+
* Tool definitions are provided in JSON schema within <functions> tags:
8+
* <functions>
9+
* <function>{"description": "...", "name": "...", "parameters": {...}}</function>
10+
* ... (other functions) ...
11+
* </functions>
12+
*
13+
* Tool calls are made using <antml:function_calls> blocks:
14+
* <antml:function_calls>
15+
* <antml:invoke name="tool_name">
16+
* <antml:parameter name="param_name">value</antml:parameter>
17+
* </antml:invoke>
18+
* </antml:function_calls>
19+
*/
20+
21+
export interface ToolDefinition {
22+
name: string
23+
description?: string
24+
descriptionForAgent?: string
25+
inputSchema: {
26+
type: string
27+
properties: Record<string, any>
28+
required?: string[]
29+
[key: string]: any
30+
}
31+
}
32+
33+
/**
34+
* Converts a single tool definition (JSON schema) to the <function> tag format.
35+
* This is for *defining* the tool, not calling it.
36+
* @param toolDef The tool definition object
37+
* @returns The tool definition as a JSON string wrapped in <function> tags
38+
*/
39+
export function toolDefinitionToAntmlDefinition(toolDef: ToolDefinition): string {
40+
const functionDef = {
41+
name: toolDef.name,
42+
description: toolDef.descriptionForAgent || toolDef.description || "",
43+
parameters: toolDef.inputSchema,
44+
}
45+
const jsonString = JSON.stringify(functionDef)
46+
return `<function>${jsonString}</function>`
47+
}
48+
49+
/**
50+
* Converts multiple tool definitions to the complete <functions> block.
51+
* This is for *defining* the tools.
52+
* @param toolDefs Array of tool definition objects
53+
* @returns Complete <functions> block with all tool definitions
54+
*/
55+
export function toolDefinitionsToAntmlDefinitions(toolDefs: ToolDefinition[]): string {
56+
const functionTags = toolDefs.map((toolDef) => toolDefinitionToAntmlDefinition(toolDef))
57+
return `Here are the functions available in JSONSchema format:
58+
<functions>
59+
${functionTags.join("\n ")}
60+
</functions>`
61+
}
62+
63+
/**
64+
* Creates an example of an ANTML tool call for a given tool definition.
65+
* This is for *calling* a tool.
66+
* @param toolDef The tool definition object
67+
* @param exampleValues Optional example values for parameters
68+
* @returns Example ANTML function call string
69+
*/
70+
export function toolDefinitionToAntmlCallExample(toolDef: ToolDefinition, exampleValues: Record<string, any> = {}): string {
71+
const properties = toolDef.inputSchema.properties || {}
72+
let parametersXml = ""
73+
if (Object.keys(properties).length > 0) {
74+
parametersXml = Object.entries(properties)
75+
.map(([paramName]) => {
76+
const exampleValue = exampleValues[paramName] || `$${paramName.toUpperCase()}` // Use placeholder like $PARAMETER_NAME
77+
return ` <antml:parameter name="${paramName}">${exampleValue}</antml:parameter>`
78+
})
79+
.join("\n")
80+
} else {
81+
// Handle tools with no parameters
82+
parametersXml = " <!-- This tool takes no parameters -->"
83+
}
84+
85+
return `<antml:function_calls>
86+
<antml:invoke name="${toolDef.name}">
87+
${parametersXml}
88+
</antml:invoke>
89+
</antml:function_calls>`
90+
}
91+
92+
/**
93+
* Creates a complete system prompt section for tools in ANTML format,
94+
* including instructions and tool definitions.
95+
* @param toolDefs Array of tool definition objects
96+
* @param includeInstructions Whether to include the standard tool calling instructions
97+
* @returns Complete system prompt section for ANTML tools
98+
*/
99+
export function createAntmlToolPrompt(toolDefs: ToolDefinition[], includeInstructions: boolean = true): string {
100+
if (toolDefs.length === 0 && includeInstructions) {
101+
// If no tools but instructions are requested, still provide basic instruction.
102+
return `In this environment you have access to a set of tools you can use to answer the user's question.
103+
You can invoke functions by writing a "<antml:function_calls>" block as part of your reply.
104+
However, no tools are currently available.`
105+
}
106+
if (toolDefs.length === 0) {
107+
return ""
108+
}
109+
110+
let prompt = ""
111+
112+
if (includeInstructions) {
113+
// Generate a generic example or use the first tool for a more concrete example
114+
const exampleToolCall =
115+
toolDefs.length > 0
116+
? toolDefinitionToAntmlCallExample(toolDefs[0])
117+
: `<antml:function_calls>
118+
<antml:invoke name="$FUNCTION_NAME">
119+
<antml:parameter name="$PARAMETER_NAME">$VALUE</antml:parameter>
120+
</antml:invoke>
121+
</antml:function_calls>`
122+
123+
prompt += `In this environment you have access to a set of tools you can use to answer the user's question.
124+
125+
You can invoke functions by writing a "<antml:function_calls>" block as part of your reply. For example:
126+
${exampleToolCall}
127+
128+
String and scalar parameters should be specified as is, while lists and objects should use JSON format.
129+
The output is not expected to be valid XML and is parsed with regular expressions.
130+
DO NOT use antml unless you intend to invoke a tool.
131+
`
132+
}
133+
134+
prompt += toolDefinitionsToAntmlDefinitions(toolDefs)
135+
136+
if (includeInstructions) {
137+
prompt += `
138+
139+
Answer the user's request using the relevant tool(s), if they are available. Check that all required parameters for each tool call are provided or can be reasonably inferred from context. If there are no relevant tools or there are missing values for required parameters, ask the user to supply these values; otherwise proceed with the tool calls.`
140+
}
141+
142+
return prompt
143+
}
144+
145+
// --- SimpleXML Functions (Cline's internal format) ---
146+
147+
/**
148+
* Converts a single tool definition to the SimpleXML format
149+
* as used by Cline's current system prompts for non-ANTML models.
150+
* @param toolDef The tool definition object
151+
* @returns The tool definition formatted for SimpleXML usage
152+
*/
153+
export function toolDefinitionToSimpleXml(toolDef: ToolDefinition): string {
154+
const description = toolDef.descriptionForAgent || toolDef.description || ""
155+
const properties = toolDef.inputSchema.properties || {}
156+
const required = toolDef.inputSchema.required || []
157+
158+
let parameterDocs = ""
159+
if (Object.keys(properties).length > 0) {
160+
parameterDocs = "Parameters:\n"
161+
for (const [paramName, paramDef] of Object.entries(properties)) {
162+
const isRequired = required.includes(paramName)
163+
const requiredText = isRequired ? "(required)" : "(optional)"
164+
const paramDescription = (paramDef as any).description || "No description."
165+
parameterDocs += `- ${paramName}: ${requiredText} ${paramDescription}\n`
166+
}
167+
}
168+
169+
const exampleParams = Object.keys(properties)
170+
.map((paramName) => `<${paramName}>${paramName} value here</${paramName}>`)
171+
.join("\n")
172+
173+
const usageExample = `Usage:
174+
<${toolDef.name}>
175+
${exampleParams.length > 0 ? exampleParams + "\n" : ""}</${toolDef.name}>`
176+
177+
return `## ${toolDef.name}
178+
Description: ${description}
179+
${parameterDocs.trim()}
180+
${usageExample}`
181+
}
182+
183+
/**
184+
* Converts multiple tool definitions to the complete SimpleXML format.
185+
* @param toolDefs Array of tool definition objects
186+
* @returns Complete tools documentation in SimpleXML format
187+
*/
188+
export function toolDefinitionsToSimpleXml(toolDefs: ToolDefinition[]): string {
189+
const toolDocs = toolDefs.map((toolDef) => toolDefinitionToSimpleXml(toolDef))
190+
return `# Tools
191+
192+
${toolDocs.join("\n\n")}`
193+
}
194+
195+
/**
196+
* Creates a complete system prompt section for tools in SimpleXML format.
197+
* @param toolDefs Array of tool definition objects
198+
* @param includeInstructions Whether to include the standard tool calling instructions
199+
* @returns Complete system prompt section for SimpleXML tools
200+
*/
201+
export function createSimpleXmlToolPrompt(toolDefs: ToolDefinition[], includeInstructions: boolean = true): string {
202+
if (toolDefs.length === 0) {
203+
return ""
204+
}
205+
206+
let prompt = ""
207+
208+
if (includeInstructions) {
209+
prompt += `TOOL USE
210+
211+
You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
212+
213+
# Tool Use Formatting
214+
215+
Tool use is formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. Here's the structure:
216+
217+
<tool_name>
218+
<parameter1_name>value1</parameter1_name>
219+
<parameter2_name>value2</parameter2_name>
220+
...
221+
</tool_name>
222+
223+
For example:
224+
225+
<read_file>
226+
<path>src/main.js</path>
227+
</read_file>
228+
229+
Always adhere to this format for the tool use to ensure proper parsing and execution.
230+
`
231+
}
232+
233+
prompt += toolDefinitionsToSimpleXml(toolDefs)
234+
235+
if (includeInstructions) {
236+
prompt += `
237+
238+
# Tool Use Guidelines
239+
240+
1. Choose the most appropriate tool based on the task and the tool descriptions provided.
241+
2. If multiple actions are needed, use one tool at a time per message to accomplish the task iteratively.
242+
3. Formulate your tool use using the XML format specified for each tool.
243+
4. After each tool use, the user will respond with the result of that tool use.
244+
5. ALWAYS wait for user confirmation after each tool use before proceeding.`
245+
}
246+
return prompt
247+
}

0 commit comments

Comments
 (0)