Compare commits

...

2 Commits

Author SHA1 Message Date
Cline Evaluation 4ba2e353eb moved system prompt after tool defs 2025-05-28 15:48:31 -07:00
Cline Evaluation 7bb0cb04c8 exact antml 2025-05-28 15:29:18 -07:00
3 changed files with 121 additions and 70 deletions
+1
View File
@@ -5,3 +5,4 @@ webview-ui/build/
package-lock.json
src/core/prompts/system.ts
src/core/prompts/model_prompts/claude4.ts
src/core/prompts/model_prompts/jsonToolToXml.ts
+9 -5
View File
@@ -8,17 +8,18 @@ import { createAntmlToolPrompt, createSimpleXmlToolPrompt, toolDefinitionToSimpl
import { bashToolDefinition } from "@core/tools/bashTool"
import { readToolDefinition } from "@core/tools/readTool"
import { writeToolDefinition } from "@core/tools/writeTool"
import { read } from "fs"
export const SYSTEM_PROMPT_CLAUDE4 = async (
cwd: string,
supportsBrowserUse: boolean,
mcpHub: McpHub,
browserSettings: BrowserSettings,
) => `
${/* createAntmlToolPrompt([bashToolDefinition, readToolDefinition, writeToolDefinition], true) */''}
You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.
) => {
const systemPrompt = `You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.
====
@@ -636,3 +637,6 @@ You accomplish a given task iteratively, breaking it down into clear steps and w
3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. Before calling a tool, do some analysis within <thinking></thinking> tags. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the ask_followup_question tool. DO NOT ask for more information on optional parameters if it is not provided.
4. Once you've completed the user's task, you must use the attempt_completion tool to present the result of the task to the user. You may also provide a CLI command to showcase the result of your task; this can be particularly useful for web development tasks, where you can run e.g. \`open index.html\` to show the website you've built.
5. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance.`
return createAntmlToolPrompt([bashToolDefinition, readToolDefinition, writeToolDefinition], true, systemPrompt);
}
+111 -65
View File
@@ -18,6 +18,11 @@
* </antml:function_calls>
*/
function escapeXml(text: string): string {
// Anything that could be interpreted as markup has to be entity-encoded
return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
}
export interface ToolDefinition {
name: string
description?: string
@@ -42,8 +47,16 @@ export function toolDefinitionToAntmlDefinition(toolDef: ToolDefinition): string
description: toolDef.descriptionForAgent || toolDef.description || "",
parameters: toolDef.inputSchema,
}
const jsonString = JSON.stringify(functionDef)
return `<function>${jsonString}</function>`
// 1. Build JSON
const rawJson = JSON.stringify(functionDef)
// 2. Escape <, > and & so the JSON can sit INSIDE the XML tag safely.
// (Quotes dont need escaping - theyre not markup.)
const safeJson = escapeXml(rawJson)
// 3. Return wrapped in <function> tags
return `<function>${safeJson}</function>`
}
/**
@@ -52,14 +65,18 @@ export function toolDefinitionToAntmlDefinition(toolDef: ToolDefinition): string
* @param toolDefs Array of tool definition objects
* @returns Complete <functions> block with all tool definitions
*/
export function toolDefinitionsToAntmlDefinitions(toolDefs: ToolDefinition[]): string {
const functionTags = toolDefs.map((toolDef) => toolDefinitionToAntmlDefinition(toolDef))
export function toolDefinitionsToAntmlDefinitions(
toolDefs: ToolDefinition[],
): string {
const functionTags = toolDefs.map(toolDefinitionToAntmlDefinition);
return `Here are the functions available in JSONSchema format:
<functions>
${functionTags.join("\n ")}
</functions>`
${functionTags.join('\n')}
</functions>`;
}
/**
* Creates an example of an ANTML tool call for a given tool definition.
* This is for *calling* a tool.
@@ -67,26 +84,33 @@ export function toolDefinitionsToAntmlDefinitions(toolDefs: ToolDefinition[]): s
* @param exampleValues Optional example values for parameters
* @returns Example ANTML function call string
*/
export function toolDefinitionToAntmlCallExample(toolDef: ToolDefinition, exampleValues: Record<string, any> = {}): string {
const properties = toolDef.inputSchema.properties || {}
let parametersXml = ""
if (Object.keys(properties).length > 0) {
parametersXml = Object.entries(properties)
.map(([paramName]) => {
const exampleValue = exampleValues[paramName] || `$${paramName.toUpperCase()}` // Use placeholder like $PARAMETER_NAME
return ` <antml:parameter name="${paramName}">${exampleValue}</antml:parameter>`
})
.join("\n")
} else {
// Handle tools with no parameters
parametersXml = " <!-- This tool takes no parameters -->"
}
export function toolDefinitionToAntmlCallExample(
toolDef: ToolDefinition,
exampleValues: Record<string, any> = {},
): string {
const props = toolDef.inputSchema.properties ?? {};
return `<antml:function_calls>
<antml:invoke name="${toolDef.name}">
${parametersXml}
</antml:invoke>
</antml:function_calls>`
const paramLines = Object.keys(props).length
? Object.entries(props)
.map(([name]) => {
const value = exampleValues[name] ?? `$${name.toUpperCase()}`; // placeholder
// Don't escape XML here - the example should show raw format
return `<parameter name="${name}">${value}</parameter>`;
})
.join('\n')
: '';
// Include the dots to show multiple invokes can be used
return [
'<function_calls>',
`<invoke name="${toolDef.name}">`,
paramLines,
'</invoke>',
'<invoke name="$FUNCTION_NAME2">',
'...',
'</invoke>',
'</function_calls>'
].filter(Boolean).join('\n');
}
/**
@@ -96,50 +120,72 @@ ${parametersXml}
* @param includeInstructions Whether to include the standard tool calling instructions
* @returns Complete system prompt section for ANTML tools
*/
export function createAntmlToolPrompt(toolDefs: ToolDefinition[], includeInstructions: boolean = true): string {
if (toolDefs.length === 0 && includeInstructions) {
// If no tools but instructions are requested, still provide basic instruction.
return `In this environment you have access to a set of tools you can use to answer the user's question.
You can invoke functions by writing a "<antml:function_calls>" block as part of your reply.
However, no tools are currently available.`
}
if (toolDefs.length === 0) {
return ""
}
export function createAntmlToolPrompt(
toolDefs: ToolDefinition[],
includeInstructions = true,
systemPrompt = '',
): string {
if (toolDefs.length === 0) {
if (!includeInstructions) return '';
const noToolsMessage = [
'In this environment you have access to a set of tools you can use to answer the user\'s question.',
'You can invoke functions by writing a "<function_calls>" block like the following as part of your reply to the user:',
'<function_calls>',
'<invoke name="$FUNCTION_NAME">',
'<parameter name="$PARAMETER_NAME">$PARAMETER_VALUE</parameter>',
'...',
'</invoke>',
'<invoke name="$FUNCTION_NAME2">',
'...',
'</invoke>',
'</function_calls>',
'',
'String and scalar parameters should be specified as is, while lists and objects should use JSON format.',
'',
'However, no tools are currently available.'
].join('\n');
return noToolsMessage;
}
let prompt = ""
let prompt = '';
if (includeInstructions) {
// Generate a generic example or use the first tool for a more concrete example
const exampleToolCall =
toolDefs.length > 0
? toolDefinitionToAntmlCallExample(toolDefs[0])
: `<antml:function_calls>
<antml:invoke name="$FUNCTION_NAME">
<antml:parameter name="$PARAMETER_NAME">$VALUE</antml:parameter>
</antml:invoke>
</antml:function_calls>`
if (includeInstructions) {
const instructionLines = [
'In this environment you have access to a set of tools you can use to answer the user\'s question.',
'You can invoke functions by writing a "<function_calls>" block like the following as part of your reply to the user:',
'<function_calls>',
'<invoke name="$FUNCTION_NAME">',
'<parameter name="$PARAMETER_NAME">$PARAMETER_VALUE</parameter>',
'...',
'</invoke>',
'<invoke name="$FUNCTION_NAME2">',
'...',
'</invoke>',
'</function_calls>',
'',
'String and scalar parameters should be specified as is, while lists and objects should use JSON format.',
''
];
prompt += instructionLines.join('\n');
}
prompt += `In this environment you have access to a set of tools you can use to answer the user's question.
prompt += toolDefinitionsToAntmlDefinitions(toolDefs);
You can invoke functions by writing a "<antml:function_calls>" block as part of your reply. For example:
${exampleToolCall}
if (includeInstructions) {
const closingInstructions = [
'',
'',
systemPrompt,
'',
'',
'Answer the user\'s request using the relevant tool(s), if they are available. Check that all the required parameters for each tool call are provided or can reasonably be 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. If the user provides a specific value for a parameter (for example provided in quotes), make sure to use that value EXACTLY. DO NOT make up values for or ask about optional parameters. Carefully analyze descriptive terms in the request as they may indicate required parameter values that should be included even if not explicitly quoted.'
];
prompt += closingInstructions.join('\n');
}
String and scalar parameters should be specified as is, while lists and objects should use JSON format.
The output is not expected to be valid XML and is parsed with regular expressions.
DO NOT use antml unless you intend to invoke a tool.
`
}
prompt += toolDefinitionsToAntmlDefinitions(toolDefs)
if (includeInstructions) {
prompt += `
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.`
}
return prompt
return prompt; // Don't trim - preserve exact formatting
}
// --- SimpleXML Functions (Cline's internal format) ---
@@ -243,5 +289,5 @@ Always adhere to this format for the tool use to ensure proper parsing and execu
4. After each tool use, the user will respond with the result of that tool use.
5. ALWAYS wait for user confirmation after each tool use before proceeding.`
}
return prompt
return prompt.trimEnd();
}