From 1a0a6fec65271625813bd4e83f65e957bdb375fa Mon Sep 17 00:00:00 2001 From: daniel-lxs Date: Fri, 7 Nov 2025 14:55:10 -0500 Subject: [PATCH 1/4] PR1: Gate XML out of prompts when native tool protocol is enabled; make tool protocol code-only; omit Tools catalog in native mode; update tests --- packages/types/src/tool.ts | 5 + .../prompts/__tests__/system-prompt.spec.ts | 178 +++++++++++++++++- .../__tests__/toolProtocolResolver.spec.ts | 39 ++++ src/core/prompts/responses.ts | 49 +++-- .../prompts/sections/custom-instructions.ts | 11 +- src/core/prompts/sections/rules.ts | 8 +- .../prompts/sections/tool-use-guidelines.ts | 16 +- src/core/prompts/sections/tool-use.ts | 12 +- src/core/prompts/system.ts | 46 +++-- src/core/prompts/toolProtocolResolver.ts | 35 ++++ src/core/prompts/tools/index.ts | 7 +- src/core/prompts/types.ts | 3 + src/core/task/Task.ts | 2 + src/core/webview/generateSystemPrompt.ts | 2 + 14 files changed, 374 insertions(+), 39 deletions(-) create mode 100644 src/core/prompts/__tests__/toolProtocolResolver.spec.ts create mode 100644 src/core/prompts/toolProtocolResolver.ts diff --git a/packages/types/src/tool.ts b/packages/types/src/tool.ts index 8c12a2dc049..2e4c1a1ed77 100644 --- a/packages/types/src/tool.ts +++ b/packages/types/src/tool.ts @@ -54,3 +54,8 @@ export const toolUsageSchema = z.record( ) export type ToolUsage = z.infer + +/** + * Tool protocol type for system prompt generation + */ +export type ToolProtocol = "xml" | "native" diff --git a/src/core/prompts/__tests__/system-prompt.spec.ts b/src/core/prompts/__tests__/system-prompt.spec.ts index 477a68261d2..1caa42c3204 100644 --- a/src/core/prompts/__tests__/system-prompt.spec.ts +++ b/src/core/prompts/__tests__/system-prompt.spec.ts @@ -112,8 +112,11 @@ __setMockImplementation( } const joinedSections = sections.join("\n\n") + const effectiveProtocol = options?.settings?.toolProtocol || "xml" + const skipXmlReferences = effectiveProtocol === "native" + const toolUseRef = skipXmlReferences ? "." : " without interfering with the TOOL USE guidelines." return joinedSections - ? `\n====\n\nUSER'S CUSTOM INSTRUCTIONS\n\nThe following additional instructions are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines.\n\n${joinedSections}` + ? `\n====\n\nUSER'S CUSTOM INSTRUCTIONS\n\nThe following additional instructions are provided by the user, and should be followed to the best of your ability${toolUseRef}\n\n${joinedSections}` : "" }, ) @@ -581,6 +584,7 @@ describe("SYSTEM_PROMPT", () => { todoListEnabled: false, useAgentRules: true, newTaskRequireTodos: false, + toolProtocol: "xml" as const, } const prompt = await SYSTEM_PROMPT( @@ -614,6 +618,7 @@ describe("SYSTEM_PROMPT", () => { todoListEnabled: true, useAgentRules: true, newTaskRequireTodos: false, + toolProtocol: "xml" as const, } const prompt = await SYSTEM_PROMPT( @@ -646,6 +651,7 @@ describe("SYSTEM_PROMPT", () => { todoListEnabled: true, useAgentRules: true, newTaskRequireTodos: false, + toolProtocol: "xml" as const, } const prompt = await SYSTEM_PROMPT( @@ -672,6 +678,176 @@ describe("SYSTEM_PROMPT", () => { expect(prompt).toContain("## update_todo_list") }) + it("should include XML tool instructions when disableXmlToolInstructions is false (default)", async () => { + const settings = { + maxConcurrentFileReads: 5, + todoListEnabled: true, + useAgentRules: true, + newTaskRequireTodos: false, + toolProtocol: "xml" as const, // explicitly xml + } + + const prompt = await SYSTEM_PROMPT( + mockContext, + "/test/path", + false, + undefined, // mcpHub + undefined, // diffStrategy + undefined, // browserViewportSize + defaultModeSlug, // mode + undefined, // customModePrompts + undefined, // customModes + undefined, // globalCustomInstructions + undefined, // diffEnabled + experiments, + true, // enableMcpServerCreation + undefined, // language + undefined, // rooIgnoreInstructions + undefined, // partialReadsEnabled + settings, // settings + ) + + // Should contain XML guidance sections + expect(prompt).toContain("TOOL USE") + expect(prompt).toContain("XML-style tags") + expect(prompt).toContain("") + expect(prompt).toContain("") + expect(prompt).toContain("Tool Use Guidelines") + expect(prompt).toContain("# Tools") + + // Should contain tool descriptions with XML examples + expect(prompt).toContain("## read_file") + expect(prompt).toContain("") + expect(prompt).toContain("") + + // Should be byte-for-byte compatible with default behavior + const defaultPrompt = await SYSTEM_PROMPT( + mockContext, + "/test/path", + false, + undefined, + undefined, + undefined, + defaultModeSlug, + undefined, + undefined, + undefined, + undefined, + experiments, + true, + undefined, + undefined, + undefined, + { + maxConcurrentFileReads: 5, + todoListEnabled: true, + useAgentRules: true, + newTaskRequireTodos: false, + toolProtocol: "xml" as const, + }, + ) + + expect(prompt).toBe(defaultPrompt) + }) + + it("should include native tool instructions when toolProtocol is native", async () => { + const settings = { + maxConcurrentFileReads: 5, + todoListEnabled: true, + useAgentRules: true, + newTaskRequireTodos: false, + toolProtocol: "native" as const, // native protocol + } + + const prompt = await SYSTEM_PROMPT( + mockContext, + "/test/path", + false, + undefined, // mcpHub + undefined, // diffStrategy + undefined, // browserViewportSize + defaultModeSlug, // mode + undefined, // customModePrompts + undefined, // customModes + undefined, // globalCustomInstructions + undefined, // diffEnabled + experiments, + true, // enableMcpServerCreation + undefined, // language + undefined, // rooIgnoreInstructions + undefined, // partialReadsEnabled + settings, // settings + ) + + // Should contain TOOL USE section with native note + expect(prompt).toContain("TOOL USE") + expect(prompt).toContain("provider-native tool-calling mechanism") + expect(prompt).toContain("Do not include XML markup or examples") + + // Should NOT contain XML-style tags or examples + expect(prompt).not.toContain("XML-style tags") + expect(prompt).not.toContain("") + expect(prompt).not.toContain("") + + // Should contain Tool Use Guidelines section with native wording + expect(prompt).toContain("Tool Use Guidelines") + expect(prompt).toContain("provider's native tool-calling mechanism") + expect(prompt).not.toContain("XML format specified for each tool") + + // Should NOT contain # Tools catalog at all in native mode + expect(prompt).not.toContain("# Tools") + expect(prompt).not.toContain("## read_file") + expect(prompt).not.toContain("## execute_command") + expect(prompt).not.toContain("") + expect(prompt).not.toContain("") + expect(prompt).not.toContain("Usage:") + expect(prompt).not.toContain("Examples:") + + // Should still contain role definition and other non-XML sections + expect(prompt).toContain(modes[0].roleDefinition) + expect(prompt).toContain("CAPABILITIES") + expect(prompt).toContain("RULES") + expect(prompt).toContain("SYSTEM INFORMATION") + expect(prompt).toContain("OBJECTIVE") + }) + + it("should default to XML tool instructions when toolProtocol is undefined", async () => { + const settings = { + maxConcurrentFileReads: 5, + todoListEnabled: true, + useAgentRules: true, + newTaskRequireTodos: false, + toolProtocol: "xml" as const, + } + + const prompt = await SYSTEM_PROMPT( + mockContext, + "/test/path", + false, + undefined, // mcpHub + undefined, // diffStrategy + undefined, // browserViewportSize + defaultModeSlug, // mode + undefined, // customModePrompts + undefined, // customModes + undefined, // globalCustomInstructions + undefined, // diffEnabled + experiments, + true, // enableMcpServerCreation + undefined, // language + undefined, // rooIgnoreInstructions + undefined, // partialReadsEnabled + settings, // settings + ) + + // Should contain XML guidance (default behavior) + expect(prompt).toContain("TOOL USE") + expect(prompt).toContain("XML-style tags") + expect(prompt).toContain("") + expect(prompt).toContain("Tool Use Guidelines") + expect(prompt).toContain("# Tools") + }) + afterAll(() => { vi.restoreAllMocks() }) diff --git a/src/core/prompts/__tests__/toolProtocolResolver.spec.ts b/src/core/prompts/__tests__/toolProtocolResolver.spec.ts new file mode 100644 index 00000000000..a64c4676ace --- /dev/null +++ b/src/core/prompts/__tests__/toolProtocolResolver.spec.ts @@ -0,0 +1,39 @@ +// npx vitest core/prompts/__tests__/toolProtocolResolver.spec.ts + +import { describe, it, expect, beforeEach } from "vitest" +import { setToolProtocol, getToolProtocol, resolveToolProtocol } from "../toolProtocolResolver" + +describe("toolProtocolResolver", () => { + beforeEach(() => { + // Reset to default before each test + setToolProtocol("xml") + }) + + it("should default to xml protocol", () => { + expect(resolveToolProtocol()).toBe("xml") + expect(getToolProtocol()).toBe("xml") + }) + + it("should allow setting protocol to native", () => { + setToolProtocol("native") + expect(resolveToolProtocol()).toBe("native") + expect(getToolProtocol()).toBe("native") + }) + + it("should allow setting protocol back to xml", () => { + setToolProtocol("native") + expect(getToolProtocol()).toBe("native") + + setToolProtocol("xml") + expect(getToolProtocol()).toBe("xml") + }) + + it("should maintain state across multiple calls", () => { + setToolProtocol("native") + + expect(resolveToolProtocol()).toBe("native") + expect(getToolProtocol()).toBe("native") + expect(resolveToolProtocol()).toBe("native") + expect(getToolProtocol()).toBe("native") + }) +}) diff --git a/src/core/prompts/responses.ts b/src/core/prompts/responses.ts index 21703684b8b..3d013120873 100644 --- a/src/core/prompts/responses.ts +++ b/src/core/prompts/responses.ts @@ -3,6 +3,8 @@ import * as path from "path" import * as diff from "diff" import { RooIgnoreController, LOCK_TEXT_SYMBOL } from "../ignore/RooIgnoreController" import { RooProtectedController } from "../protect/RooProtectedController" +import { resolveToolProtocol } from "./toolProtocolResolver" +import { ToolProtocol } from "@roo-code/types" export const formatResponse = { toolDenied: () => `The user denied this operation.`, @@ -18,25 +20,40 @@ export const formatResponse = { rooIgnoreError: (path: string) => `Access to ${path} is blocked by the .rooignore file settings. You must try to continue in the task without using this file, or ask the user to update the .rooignore file.`, - noToolsUsed: () => - `[ERROR] You did not use a tool in your previous response! Please retry with a tool use. + noToolsUsed: (protocol?: ToolProtocol) => { + const effectiveProtocol = protocol ?? resolveToolProtocol() + const instructions = + effectiveProtocol === "native" ? toolUseInstructionsReminderNative : toolUseInstructionsReminder -${toolUseInstructionsReminder} + return `[ERROR] You did not use a tool in your previous response! Please retry with a tool use. + +${instructions} # Next Steps -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, if you have not completed the task and do not need additional information, then proceed with the next step of the task. -(This is an automated message, so do not respond to it conversationally.)`, +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, if you have not completed the task and do not need additional information, then proceed with the next step of the task. +(This is an automated message, so do not respond to it conversationally.)` + }, tooManyMistakes: (feedback?: string) => `You seem to be having trouble proceeding. The user has provided the following feedback to help guide you:\n\n${feedback}\n`, - missingToolParameterError: (paramName: string) => - `Missing value for required parameter '${paramName}'. Please retry with complete response.\n\n${toolUseInstructionsReminder}`, + missingToolParameterError: (paramName: string, protocol?: ToolProtocol) => { + const effectiveProtocol = protocol ?? resolveToolProtocol() + const instructions = + effectiveProtocol === "native" ? toolUseInstructionsReminderNative : toolUseInstructionsReminder + + return `Missing value for required parameter '${paramName}'. Please retry with complete response.\n\n${instructions}` + }, - lineCountTruncationError: (actualLineCount: number, isNewFile: boolean, diffStrategyEnabled: boolean = false) => { + lineCountTruncationError: ( + actualLineCount: number, + isNewFile: boolean, + diffStrategyEnabled: boolean = false, + protocol?: ToolProtocol, + ) => { const truncationMessage = `Note: Your response may have been truncated because it exceeded your output limit. You wrote ${actualLineCount} lines of content, but the line_count parameter was either missing or not included in your response.` const newFileGuidance = @@ -65,7 +82,11 @@ Otherwise, if you have not completed the task and do not need additional informa `RECOMMENDED APPROACH:\n` + `${existingFileApproaches.join("\n")}\n` - return `${isNewFile ? newFileGuidance : existingFileGuidance}\n${toolUseInstructionsReminder}` + const effectiveProtocol = protocol ?? resolveToolProtocol() + const instructions = + effectiveProtocol === "native" ? toolUseInstructionsReminderNative : toolUseInstructionsReminder + + return `${isNewFile ? newFileGuidance : existingFileGuidance}\n${instructions}` }, invalidMcpToolArgumentError: (serverName: string, toolName: string) => @@ -220,3 +241,9 @@ I have completed the task... Always use the actual tool name as the XML tag name for proper parsing and execution.` + +const toolUseInstructionsReminderNative = `# Reminder: Instructions for Tool Use + +Tools are invoked using the platform's native tool calling mechanism. Each tool requires specific parameters as defined in the tool descriptions. Refer to the tool definitions provided in your system instructions for the correct parameter structure and usage examples. + +Always ensure you provide all required parameters for the tool you wish to use.` diff --git a/src/core/prompts/sections/custom-instructions.ts b/src/core/prompts/sections/custom-instructions.ts index 2d70e454191..6e2da39a35e 100644 --- a/src/core/prompts/sections/custom-instructions.ts +++ b/src/core/prompts/sections/custom-instructions.ts @@ -368,15 +368,22 @@ export async function addCustomInstructions( const joinedSections = sections.join("\n\n") + const effectiveProtocol = options.settings?.toolProtocol || "xml" + + const skipXmlReferences = effectiveProtocol === "native" + return joinedSections ? ` ==== USER'S CUSTOM INSTRUCTIONS -The following additional instructions are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines. +The following additional instructions are provided by the user, and should be followed to the best of your ability${ + skipXmlReferences ? "." : " without interfering with the TOOL USE guidelines." + } -${joinedSections}` +${joinedSections} +` : "" } diff --git a/src/core/prompts/sections/rules.ts b/src/core/prompts/sections/rules.ts index e8c7534b18a..5a1100fb621 100644 --- a/src/core/prompts/sections/rules.ts +++ b/src/core/prompts/sections/rules.ts @@ -1,5 +1,6 @@ import { DiffStrategy } from "../../../shared/tools" import { CodeIndexManager } from "../../../services/code-index/manager" +import type { SystemPromptSettings } from "../types" function getEditingInstructions(diffStrategy?: DiffStrategy): string { const instructions: string[] = [] @@ -45,6 +46,7 @@ export function getRulesSection( supportsComputerUse: boolean, diffStrategy?: DiffStrategy, codeIndexManager?: CodeIndexManager, + settings?: SystemPromptSettings, ): string { const isCodebaseSearchAvailable = codeIndexManager && @@ -56,12 +58,16 @@ export function getRulesSection( ? "- **CRITICAL: For ANY exploration of code you haven't examined yet in this conversation, you MUST use the `codebase_search` tool FIRST before using search_files or other file exploration tools.** This requirement applies throughout the entire conversation, not just when starting a task. The codebase_search tool uses semantic search to find relevant code based on meaning, not just keywords, making it much more effective for understanding how features are implemented. Even if you've already explored some parts of the codebase, any new area or functionality you need to understand requires using codebase_search first.\n" : "" + // Determine whether to use XML tool references based on protocol + const effectiveProtocol = settings?.toolProtocol || "xml" + const skipXmlReferences = effectiveProtocol === "native" + return `==== RULES - The project base directory is: ${cwd.toPosix()} -- All file paths must be relative to this directory. However, commands may change directories in terminals, so respect working directory specified by the response to . +- All file paths must be relative to this directory. However, commands may change directories in terminals, so respect working directory specified by the response to ${skipXmlReferences ? "execute_command" : ""}. - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '${cwd.toPosix()}', so be sure to pass in the correct 'path' parameter when using tools that require a path. - Do not use the ~ character or $HOME to refer to the home directory. - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '${cwd.toPosix()}', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '${cwd.toPosix()}'). For example, if you needed to run \`npm install\` in a project outside of '${cwd.toPosix()}', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`. diff --git a/src/core/prompts/sections/tool-use-guidelines.ts b/src/core/prompts/sections/tool-use-guidelines.ts index f6843cf8423..ccdabc29b16 100644 --- a/src/core/prompts/sections/tool-use-guidelines.ts +++ b/src/core/prompts/sections/tool-use-guidelines.ts @@ -1,6 +1,10 @@ +import { ToolProtocol } from "@roo-code/types" import { CodeIndexManager } from "../../../services/code-index/manager" -export function getToolUseGuidelinesSection(codeIndexManager?: CodeIndexManager): string { +export function getToolUseGuidelinesSection( + codeIndexManager?: CodeIndexManager, + protocol: ToolProtocol = "xml", +): string { const isCodebaseSearchAvailable = codeIndexManager && codeIndexManager.isFeatureEnabled && @@ -34,7 +38,15 @@ export function getToolUseGuidelinesSection(codeIndexManager?: CodeIndexManager) guidelinesList.push( `${itemNumber++}. If multiple actions are needed, use one tool at a time per message to accomplish the task iteratively, with each tool use being informed by the result of the previous tool use. Do not assume the outcome of any tool use. Each step must be informed by the previous step's result.`, ) - guidelinesList.push(`${itemNumber++}. Formulate your tool use using the XML format specified for each tool.`) + + // Protocol-specific guideline + if (protocol === "native") { + guidelinesList.push( + `${itemNumber++}. Formulate your tool call using the provider's native tool-calling mechanism.`, + ) + } else { + guidelinesList.push(`${itemNumber++}. Formulate your tool use using the XML format specified for each tool.`) + } guidelinesList.push(`${itemNumber++}. After each tool use, the user will respond with the result of that tool use. This result will provide you with the necessary information to continue your task or make further decisions. This response may include: - Information about whether the tool succeeded or failed, along with any reasons for failure. - Linter errors that may have arisen due to the changes you made, which you'll need to address. diff --git a/src/core/prompts/sections/tool-use.ts b/src/core/prompts/sections/tool-use.ts index 28d47d09858..0ca3a336667 100644 --- a/src/core/prompts/sections/tool-use.ts +++ b/src/core/prompts/sections/tool-use.ts @@ -1,4 +1,14 @@ -export function getSharedToolUseSection(): string { +import { ToolProtocol } from "@roo-code/types" + +export function getSharedToolUseSection(protocol: ToolProtocol = "xml"): string { + if (protocol === "native") { + return `==== + +TOOL USE + +You have access to a set of tools that are executed upon the user's approval. Use the provider-native tool-calling mechanism. Do not include XML markup or examples.` + } + return `==== TOOL USE diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 3cc327c8151..a13793c8e57 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -88,29 +88,37 @@ async function generatePrompt( const codeIndexManager = CodeIndexManager.getInstance(context, cwd) + // Determine the effective protocol (defaults to 'xml') + const effectiveProtocol = settings?.toolProtocol || "xml" + + // Build tools catalog section only for XML protocol + const toolsCatalog = + effectiveProtocol === "xml" + ? `\n\n${getToolDescriptionsForMode( + mode, + cwd, + supportsComputerUse, + codeIndexManager, + effectiveDiffStrategy, + browserViewportSize, + shouldIncludeMcp ? mcpHub : undefined, + customModeConfigs, + experiments, + partialReadsEnabled, + settings, + enableMcpServerCreation, + modelId, + effectiveProtocol, + )}` + : "" + const basePrompt = `${roleDefinition} ${markdownFormattingSection()} -${getSharedToolUseSection()} - -${getToolDescriptionsForMode( - mode, - cwd, - supportsComputerUse, - codeIndexManager, - effectiveDiffStrategy, - browserViewportSize, - shouldIncludeMcp ? mcpHub : undefined, - customModeConfigs, - experiments, - partialReadsEnabled, - settings, - enableMcpServerCreation, - modelId, -)} +${getSharedToolUseSection(effectiveProtocol)}${toolsCatalog} -${getToolUseGuidelinesSection(codeIndexManager)} +${getToolUseGuidelinesSection(codeIndexManager, effectiveProtocol)} ${mcpServersSection} @@ -118,7 +126,7 @@ ${getCapabilitiesSection(cwd, supportsComputerUse, shouldIncludeMcp ? mcpHub : u ${modesSection} -${getRulesSection(cwd, supportsComputerUse, effectiveDiffStrategy, codeIndexManager)} +${getRulesSection(cwd, supportsComputerUse, effectiveDiffStrategy, codeIndexManager, settings)} ${getSystemInfoSection(cwd)} diff --git a/src/core/prompts/toolProtocolResolver.ts b/src/core/prompts/toolProtocolResolver.ts new file mode 100644 index 00000000000..c0c2931419a --- /dev/null +++ b/src/core/prompts/toolProtocolResolver.ts @@ -0,0 +1,35 @@ +import { ToolProtocol } from "@roo-code/types" + +/** + * Internal tool protocol state management. + * This is code-only and not exposed through VS Code settings. + */ +let currentProtocol: ToolProtocol = "xml" + +/** + * Sets the current tool protocol. + * This is an internal API and should not be called by external code. + * + * @param protocol - The tool protocol to set ('xml' or 'native') + */ +export function setToolProtocol(protocol: ToolProtocol): void { + currentProtocol = protocol +} + +/** + * Gets the current tool protocol. + * + * @returns The current tool protocol + */ +export function getToolProtocol(): ToolProtocol { + return currentProtocol +} + +/** + * Resolves the effective tool protocol. + * + * @returns The effective tool protocol (defaults to "xml") + */ +export function resolveToolProtocol(): ToolProtocol { + return currentProtocol +} diff --git a/src/core/prompts/tools/index.ts b/src/core/prompts/tools/index.ts index 22588d55d12..67cdfe69df3 100644 --- a/src/core/prompts/tools/index.ts +++ b/src/core/prompts/tools/index.ts @@ -1,4 +1,4 @@ -import type { ToolName, ModeConfig } from "@roo-code/types" +import type { ToolName, ModeConfig, ToolProtocol } from "@roo-code/types" import { TOOL_GROUPS, ALWAYS_AVAILABLE_TOOLS, DiffStrategy } from "../../../shared/tools" import { McpHub } from "../../../services/mcp/McpHub" @@ -74,6 +74,7 @@ export function getToolDescriptionsForMode( settings?: Record, enableMcpServerCreation?: boolean, modelId?: string, + protocol: ToolProtocol = "xml", ): string { const config = getModeConfig(mode, customModes) const args: ToolArgs = { @@ -148,10 +149,12 @@ export function getToolDescriptionsForMode( return undefined } - return descriptionFn({ + const description = descriptionFn({ ...args, toolOptions: undefined, // No tool options in group-based approach }) + + return description }) return `# Tools\n\n${descriptions.filter(Boolean).join("\n\n")}` diff --git a/src/core/prompts/types.ts b/src/core/prompts/types.ts index d90b1b821ab..99642ebf359 100644 --- a/src/core/prompts/types.ts +++ b/src/core/prompts/types.ts @@ -1,3 +1,5 @@ +import { ToolProtocol } from "@roo-code/types" + /** * Settings passed to system prompt generation functions */ @@ -6,4 +8,5 @@ export interface SystemPromptSettings { todoListEnabled: boolean useAgentRules: boolean newTaskRequireTodos: boolean + toolProtocol?: ToolProtocol } diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 7ed317da108..82b28c17060 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -80,6 +80,7 @@ import { getWorkspacePath } from "../../utils/path" // prompts import { formatResponse } from "../prompts/responses" import { SYSTEM_PROMPT } from "../prompts/system" +import { resolveToolProtocol } from "../prompts/toolProtocolResolver" // core modules import { ToolRepetitionDetector } from "../tools/ToolRepetitionDetector" @@ -2595,6 +2596,7 @@ export class Task extends EventEmitter implements TaskLike { newTaskRequireTodos: vscode.workspace .getConfiguration("roo-cline") .get("newTaskRequireTodos", false), + toolProtocol: resolveToolProtocol(), }, undefined, // todoList this.api.getModel().id, diff --git a/src/core/webview/generateSystemPrompt.ts b/src/core/webview/generateSystemPrompt.ts index 0920a616482..65f908edad4 100644 --- a/src/core/webview/generateSystemPrompt.ts +++ b/src/core/webview/generateSystemPrompt.ts @@ -7,6 +7,7 @@ import { experiments as experimentsModule, EXPERIMENT_IDS } from "../../shared/e import { SYSTEM_PROMPT } from "../prompts/system" import { MultiSearchReplaceDiffStrategy } from "../diff/strategies/multi-search-replace" import { MultiFileSearchReplaceDiffStrategy } from "../diff/strategies/multi-file-search-replace" +import { resolveToolProtocol } from "../prompts/toolProtocolResolver" import { ClineProvider } from "./ClineProvider" @@ -91,6 +92,7 @@ export const generateSystemPrompt = async (provider: ClineProvider, message: Web newTaskRequireTodos: vscode.workspace .getConfiguration("roo-cline") .get("newTaskRequireTodos", false), + toolProtocol: resolveToolProtocol(), }, ) From f16629cb2b69dde7682afee890964aa5fec5a014 Mon Sep 17 00:00:00 2001 From: daniel-lxs Date: Fri, 7 Nov 2025 17:23:24 -0500 Subject: [PATCH 2/4] =?UTF-8?q?PR1:=20address=20review=20comments=20?= =?UTF-8?q?=E2=80=94=20gate=20Tools=20catalog=20in=20system.ts=20for=20XML?= =?UTF-8?q?=20only;=20remove=20unused=20protocol=20param=20from=20getToolD?= =?UTF-8?q?escriptionsForMode;=20protocol=20selection=20via=20non-exported?= =?UTF-8?q?=20code=20constant;=20tests=20pass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__tests__/toolProtocolResolver.spec.ts | 33 ++----------------- src/core/prompts/system.ts | 1 - src/core/prompts/toolProtocolResolver.ts | 26 +++------------ src/core/prompts/tools/index.ts | 3 +- 4 files changed, 7 insertions(+), 56 deletions(-) diff --git a/src/core/prompts/__tests__/toolProtocolResolver.spec.ts b/src/core/prompts/__tests__/toolProtocolResolver.spec.ts index a64c4676ace..0fe1522663b 100644 --- a/src/core/prompts/__tests__/toolProtocolResolver.spec.ts +++ b/src/core/prompts/__tests__/toolProtocolResolver.spec.ts @@ -1,39 +1,10 @@ // npx vitest core/prompts/__tests__/toolProtocolResolver.spec.ts -import { describe, it, expect, beforeEach } from "vitest" -import { setToolProtocol, getToolProtocol, resolveToolProtocol } from "../toolProtocolResolver" +import { describe, it, expect } from "vitest" +import { resolveToolProtocol } from "../toolProtocolResolver" describe("toolProtocolResolver", () => { - beforeEach(() => { - // Reset to default before each test - setToolProtocol("xml") - }) - it("should default to xml protocol", () => { expect(resolveToolProtocol()).toBe("xml") - expect(getToolProtocol()).toBe("xml") - }) - - it("should allow setting protocol to native", () => { - setToolProtocol("native") - expect(resolveToolProtocol()).toBe("native") - expect(getToolProtocol()).toBe("native") - }) - - it("should allow setting protocol back to xml", () => { - setToolProtocol("native") - expect(getToolProtocol()).toBe("native") - - setToolProtocol("xml") - expect(getToolProtocol()).toBe("xml") - }) - - it("should maintain state across multiple calls", () => { - setToolProtocol("native") - - expect(resolveToolProtocol()).toBe("native") - expect(getToolProtocol()).toBe("native") - expect(resolveToolProtocol()).toBe("native") - expect(getToolProtocol()).toBe("native") }) }) diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index a13793c8e57..3bd1c956dc1 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -108,7 +108,6 @@ async function generatePrompt( settings, enableMcpServerCreation, modelId, - effectiveProtocol, )}` : "" diff --git a/src/core/prompts/toolProtocolResolver.ts b/src/core/prompts/toolProtocolResolver.ts index c0c2931419a..c68412b4581 100644 --- a/src/core/prompts/toolProtocolResolver.ts +++ b/src/core/prompts/toolProtocolResolver.ts @@ -1,29 +1,11 @@ import { ToolProtocol } from "@roo-code/types" /** - * Internal tool protocol state management. + * Current tool protocol setting. * This is code-only and not exposed through VS Code settings. + * To switch protocols, edit this constant directly in the source code. */ -let currentProtocol: ToolProtocol = "xml" - -/** - * Sets the current tool protocol. - * This is an internal API and should not be called by external code. - * - * @param protocol - The tool protocol to set ('xml' or 'native') - */ -export function setToolProtocol(protocol: ToolProtocol): void { - currentProtocol = protocol -} - -/** - * Gets the current tool protocol. - * - * @returns The current tool protocol - */ -export function getToolProtocol(): ToolProtocol { - return currentProtocol -} +const CURRENT_TOOL_PROTOCOL: ToolProtocol = "xml" // change to 'native' to enable native protocol /** * Resolves the effective tool protocol. @@ -31,5 +13,5 @@ export function getToolProtocol(): ToolProtocol { * @returns The effective tool protocol (defaults to "xml") */ export function resolveToolProtocol(): ToolProtocol { - return currentProtocol + return CURRENT_TOOL_PROTOCOL } diff --git a/src/core/prompts/tools/index.ts b/src/core/prompts/tools/index.ts index 67cdfe69df3..2486cd0c297 100644 --- a/src/core/prompts/tools/index.ts +++ b/src/core/prompts/tools/index.ts @@ -1,4 +1,4 @@ -import type { ToolName, ModeConfig, ToolProtocol } from "@roo-code/types" +import type { ToolName, ModeConfig } from "@roo-code/types" import { TOOL_GROUPS, ALWAYS_AVAILABLE_TOOLS, DiffStrategy } from "../../../shared/tools" import { McpHub } from "../../../services/mcp/McpHub" @@ -74,7 +74,6 @@ export function getToolDescriptionsForMode( settings?: Record, enableMcpServerCreation?: boolean, modelId?: string, - protocol: ToolProtocol = "xml", ): string { const config = getModeConfig(mode, customModes) const args: ToolArgs = { From 45b9ab7c354a4f04747f1bdb2a3b6b9fd3486374 Mon Sep 17 00:00:00 2001 From: daniel-lxs Date: Mon, 10 Nov 2025 14:25:21 -0500 Subject: [PATCH 3/4] refactor: improve tool protocol code organization and reduce duplication - Add type-safe TOOL_PROTOCOL constants with derived ToolProtocol type - Extract getEffectiveProtocol() and isNativeProtocol() utility functions - Add getToolInstructionsReminder() helper to eliminate duplication - Remove repetitive protocol resolution patterns across 7 files - Remove unnecessary skipXmlReferences intermediate variables - All 142 prompt tests passing --- packages/types/src/tool.ts | 11 +++++- src/core/prompts/responses.ts | 25 +++++++----- .../prompts/sections/custom-instructions.ts | 7 ++-- src/core/prompts/sections/rules.ts | 6 +-- .../prompts/sections/tool-use-guidelines.ts | 7 ++-- src/core/prompts/sections/tool-use.ts | 7 ++-- src/core/prompts/system.ts | 39 ++++++++++--------- src/core/prompts/toolProtocolResolver.ts | 25 +++++++++++- 8 files changed, 82 insertions(+), 45 deletions(-) diff --git a/packages/types/src/tool.ts b/packages/types/src/tool.ts index 2e4c1a1ed77..9d4269b9fa6 100644 --- a/packages/types/src/tool.ts +++ b/packages/types/src/tool.ts @@ -55,7 +55,16 @@ export const toolUsageSchema = z.record( export type ToolUsage = z.infer +/** + * Tool protocol constants + */ +export const TOOL_PROTOCOL = { + XML: "xml", + NATIVE: "native", +} as const + /** * Tool protocol type for system prompt generation + * Derived from TOOL_PROTOCOL constants to ensure type safety */ -export type ToolProtocol = "xml" | "native" +export type ToolProtocol = (typeof TOOL_PROTOCOL)[keyof typeof TOOL_PROTOCOL] diff --git a/src/core/prompts/responses.ts b/src/core/prompts/responses.ts index 3d013120873..1c1212e70f1 100644 --- a/src/core/prompts/responses.ts +++ b/src/core/prompts/responses.ts @@ -3,7 +3,7 @@ import * as path from "path" import * as diff from "diff" import { RooIgnoreController, LOCK_TEXT_SYMBOL } from "../ignore/RooIgnoreController" import { RooProtectedController } from "../protect/RooProtectedController" -import { resolveToolProtocol } from "./toolProtocolResolver" +import { resolveToolProtocol, isNativeProtocol } from "./toolProtocolResolver" import { ToolProtocol } from "@roo-code/types" export const formatResponse = { @@ -21,9 +21,7 @@ export const formatResponse = { `Access to ${path} is blocked by the .rooignore file settings. You must try to continue in the task without using this file, or ask the user to update the .rooignore file.`, noToolsUsed: (protocol?: ToolProtocol) => { - const effectiveProtocol = protocol ?? resolveToolProtocol() - const instructions = - effectiveProtocol === "native" ? toolUseInstructionsReminderNative : toolUseInstructionsReminder + const instructions = getToolInstructionsReminder(protocol) return `[ERROR] You did not use a tool in your previous response! Please retry with a tool use. @@ -41,9 +39,7 @@ Otherwise, if you have not completed the task and do not need additional informa `You seem to be having trouble proceeding. The user has provided the following feedback to help guide you:\n\n${feedback}\n`, missingToolParameterError: (paramName: string, protocol?: ToolProtocol) => { - const effectiveProtocol = protocol ?? resolveToolProtocol() - const instructions = - effectiveProtocol === "native" ? toolUseInstructionsReminderNative : toolUseInstructionsReminder + const instructions = getToolInstructionsReminder(protocol) return `Missing value for required parameter '${paramName}'. Please retry with complete response.\n\n${instructions}` }, @@ -82,9 +78,7 @@ Otherwise, if you have not completed the task and do not need additional informa `RECOMMENDED APPROACH:\n` + `${existingFileApproaches.join("\n")}\n` - const effectiveProtocol = protocol ?? resolveToolProtocol() - const instructions = - effectiveProtocol === "native" ? toolUseInstructionsReminderNative : toolUseInstructionsReminder + const instructions = getToolInstructionsReminder(protocol) return `${isNewFile ? newFileGuidance : existingFileGuidance}\n${instructions}` }, @@ -247,3 +241,14 @@ const toolUseInstructionsReminderNative = `# Reminder: Instructions for Tool Use Tools are invoked using the platform's native tool calling mechanism. Each tool requires specific parameters as defined in the tool descriptions. Refer to the tool definitions provided in your system instructions for the correct parameter structure and usage examples. Always ensure you provide all required parameters for the tool you wish to use.` + +/** + * Gets the appropriate tool use instructions reminder based on the protocol. + * + * @param protocol - Optional tool protocol, falls back to default if not provided + * @returns The tool use instructions reminder text + */ +function getToolInstructionsReminder(protocol?: ToolProtocol): string { + const effectiveProtocol = protocol ?? resolveToolProtocol() + return isNativeProtocol(effectiveProtocol) ? toolUseInstructionsReminderNative : toolUseInstructionsReminder +} diff --git a/src/core/prompts/sections/custom-instructions.ts b/src/core/prompts/sections/custom-instructions.ts index 6e2da39a35e..4e5e5d19ac3 100644 --- a/src/core/prompts/sections/custom-instructions.ts +++ b/src/core/prompts/sections/custom-instructions.ts @@ -6,6 +6,7 @@ import { Dirent } from "fs" import { isLanguage } from "@roo-code/types" import type { SystemPromptSettings } from "../types" +import { getEffectiveProtocol, isNativeProtocol } from "../toolProtocolResolver" import { LANGUAGES } from "../../../shared/language" import { getRooDirectoriesForCwd, getGlobalRooDirectory } from "../../../services/roo-config" @@ -368,9 +369,7 @@ export async function addCustomInstructions( const joinedSections = sections.join("\n\n") - const effectiveProtocol = options.settings?.toolProtocol || "xml" - - const skipXmlReferences = effectiveProtocol === "native" + const effectiveProtocol = getEffectiveProtocol(options.settings) return joinedSections ? ` @@ -379,7 +378,7 @@ export async function addCustomInstructions( USER'S CUSTOM INSTRUCTIONS The following additional instructions are provided by the user, and should be followed to the best of your ability${ - skipXmlReferences ? "." : " without interfering with the TOOL USE guidelines." + isNativeProtocol(effectiveProtocol) ? "." : " without interfering with the TOOL USE guidelines." } ${joinedSections} diff --git a/src/core/prompts/sections/rules.ts b/src/core/prompts/sections/rules.ts index 5a1100fb621..0eceb2dc98d 100644 --- a/src/core/prompts/sections/rules.ts +++ b/src/core/prompts/sections/rules.ts @@ -1,6 +1,7 @@ import { DiffStrategy } from "../../../shared/tools" import { CodeIndexManager } from "../../../services/code-index/manager" import type { SystemPromptSettings } from "../types" +import { getEffectiveProtocol, isNativeProtocol } from "../toolProtocolResolver" function getEditingInstructions(diffStrategy?: DiffStrategy): string { const instructions: string[] = [] @@ -59,15 +60,14 @@ export function getRulesSection( : "" // Determine whether to use XML tool references based on protocol - const effectiveProtocol = settings?.toolProtocol || "xml" - const skipXmlReferences = effectiveProtocol === "native" + const effectiveProtocol = getEffectiveProtocol(settings) return `==== RULES - The project base directory is: ${cwd.toPosix()} -- All file paths must be relative to this directory. However, commands may change directories in terminals, so respect working directory specified by the response to ${skipXmlReferences ? "execute_command" : ""}. +- All file paths must be relative to this directory. However, commands may change directories in terminals, so respect working directory specified by the response to ${isNativeProtocol(effectiveProtocol) ? "execute_command" : ""}. - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '${cwd.toPosix()}', so be sure to pass in the correct 'path' parameter when using tools that require a path. - Do not use the ~ character or $HOME to refer to the home directory. - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '${cwd.toPosix()}', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '${cwd.toPosix()}'). For example, if you needed to run \`npm install\` in a project outside of '${cwd.toPosix()}', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`. diff --git a/src/core/prompts/sections/tool-use-guidelines.ts b/src/core/prompts/sections/tool-use-guidelines.ts index ccdabc29b16..586faa371c1 100644 --- a/src/core/prompts/sections/tool-use-guidelines.ts +++ b/src/core/prompts/sections/tool-use-guidelines.ts @@ -1,9 +1,10 @@ -import { ToolProtocol } from "@roo-code/types" +import { ToolProtocol, TOOL_PROTOCOL } from "@roo-code/types" import { CodeIndexManager } from "../../../services/code-index/manager" +import { isNativeProtocol } from "../toolProtocolResolver" export function getToolUseGuidelinesSection( codeIndexManager?: CodeIndexManager, - protocol: ToolProtocol = "xml", + protocol: ToolProtocol = TOOL_PROTOCOL.XML, ): string { const isCodebaseSearchAvailable = codeIndexManager && @@ -40,7 +41,7 @@ export function getToolUseGuidelinesSection( ) // Protocol-specific guideline - if (protocol === "native") { + if (isNativeProtocol(protocol)) { guidelinesList.push( `${itemNumber++}. Formulate your tool call using the provider's native tool-calling mechanism.`, ) diff --git a/src/core/prompts/sections/tool-use.ts b/src/core/prompts/sections/tool-use.ts index 0ca3a336667..e3f54a7d185 100644 --- a/src/core/prompts/sections/tool-use.ts +++ b/src/core/prompts/sections/tool-use.ts @@ -1,7 +1,8 @@ -import { ToolProtocol } from "@roo-code/types" +import { ToolProtocol, TOOL_PROTOCOL } from "@roo-code/types" +import { isNativeProtocol } from "../toolProtocolResolver" -export function getSharedToolUseSection(protocol: ToolProtocol = "xml"): string { - if (protocol === "native") { +export function getSharedToolUseSection(protocol: ToolProtocol = TOOL_PROTOCOL.XML): string { + if (isNativeProtocol(protocol)) { return `==== TOOL USE diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 3bd1c956dc1..3d45f7fcf0d 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -16,6 +16,7 @@ import { CodeIndexManager } from "../../services/code-index/manager" import { PromptVariables, loadSystemPromptFile } from "./sections/custom-system-prompt" import { getToolDescriptionsForMode } from "./tools" +import { getEffectiveProtocol, isNativeProtocol } from "./toolProtocolResolver" import { getRulesSection, getSystemInfoSection, @@ -28,6 +29,7 @@ import { addCustomInstructions, markdownFormattingSection, } from "./sections" +import { TOOL_PROTOCOL } from "@roo-code/types" // Helper function to get prompt component, filtering out empty objects export function getPromptComponent( @@ -89,27 +91,26 @@ async function generatePrompt( const codeIndexManager = CodeIndexManager.getInstance(context, cwd) // Determine the effective protocol (defaults to 'xml') - const effectiveProtocol = settings?.toolProtocol || "xml" + const effectiveProtocol = getEffectiveProtocol(settings) // Build tools catalog section only for XML protocol - const toolsCatalog = - effectiveProtocol === "xml" - ? `\n\n${getToolDescriptionsForMode( - mode, - cwd, - supportsComputerUse, - codeIndexManager, - effectiveDiffStrategy, - browserViewportSize, - shouldIncludeMcp ? mcpHub : undefined, - customModeConfigs, - experiments, - partialReadsEnabled, - settings, - enableMcpServerCreation, - modelId, - )}` - : "" + const toolsCatalog = isNativeProtocol(effectiveProtocol) + ? "" + : `\n\n${getToolDescriptionsForMode( + mode, + cwd, + supportsComputerUse, + codeIndexManager, + effectiveDiffStrategy, + browserViewportSize, + shouldIncludeMcp ? mcpHub : undefined, + customModeConfigs, + experiments, + partialReadsEnabled, + settings, + enableMcpServerCreation, + modelId, + )}` const basePrompt = `${roleDefinition} diff --git a/src/core/prompts/toolProtocolResolver.ts b/src/core/prompts/toolProtocolResolver.ts index c68412b4581..1cd87f7251e 100644 --- a/src/core/prompts/toolProtocolResolver.ts +++ b/src/core/prompts/toolProtocolResolver.ts @@ -1,11 +1,12 @@ -import { ToolProtocol } from "@roo-code/types" +import { ToolProtocol, TOOL_PROTOCOL } from "@roo-code/types" +import type { SystemPromptSettings } from "./types" /** * Current tool protocol setting. * This is code-only and not exposed through VS Code settings. * To switch protocols, edit this constant directly in the source code. */ -const CURRENT_TOOL_PROTOCOL: ToolProtocol = "xml" // change to 'native' to enable native protocol +const CURRENT_TOOL_PROTOCOL: ToolProtocol = TOOL_PROTOCOL.XML // change to TOOL_PROTOCOL.NATIVE to enable native protocol /** * Resolves the effective tool protocol. @@ -15,3 +16,23 @@ const CURRENT_TOOL_PROTOCOL: ToolProtocol = "xml" // change to 'native' to enabl export function resolveToolProtocol(): ToolProtocol { return CURRENT_TOOL_PROTOCOL } + +/** + * Gets the effective protocol from settings or falls back to the default. + * + * @param settings - Optional system prompt settings + * @returns The effective tool protocol + */ +export function getEffectiveProtocol(settings?: SystemPromptSettings): ToolProtocol { + return settings?.toolProtocol || resolveToolProtocol() +} + +/** + * Checks if the protocol is native (non-XML). + * + * @param protocol - The tool protocol to check + * @returns True if protocol is native + */ +export function isNativeProtocol(protocol: ToolProtocol): boolean { + return protocol === TOOL_PROTOCOL.NATIVE +} From 4b8d69f74dbaec9dfa428e72ee0c43142608b2e0 Mon Sep 17 00:00:00 2001 From: daniel-lxs Date: Mon, 10 Nov 2025 14:30:55 -0500 Subject: [PATCH 4/4] refactor: remove protocol-specific formatting guideline in native mode When native tool calling is enabled, the guideline about formulating tool calls is no longer needed since the provider handles the formatting automatically. Only XML mode needs the explicit formatting instruction. --- src/core/prompts/__tests__/system-prompt.spec.ts | 5 +++-- src/core/prompts/sections/tool-use-guidelines.ts | 8 ++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/core/prompts/__tests__/system-prompt.spec.ts b/src/core/prompts/__tests__/system-prompt.spec.ts index 1caa42c3204..247078b76d2 100644 --- a/src/core/prompts/__tests__/system-prompt.spec.ts +++ b/src/core/prompts/__tests__/system-prompt.spec.ts @@ -789,9 +789,10 @@ describe("SYSTEM_PROMPT", () => { expect(prompt).not.toContain("") expect(prompt).not.toContain("") - // Should contain Tool Use Guidelines section with native wording + // Should contain Tool Use Guidelines section without format-specific guidance expect(prompt).toContain("Tool Use Guidelines") - expect(prompt).toContain("provider's native tool-calling mechanism") + // Should NOT contain any protocol-specific formatting instructions + expect(prompt).not.toContain("provider's native tool-calling mechanism") expect(prompt).not.toContain("XML format specified for each tool") // Should NOT contain # Tools catalog at all in native mode diff --git a/src/core/prompts/sections/tool-use-guidelines.ts b/src/core/prompts/sections/tool-use-guidelines.ts index 586faa371c1..6258a1f13ac 100644 --- a/src/core/prompts/sections/tool-use-guidelines.ts +++ b/src/core/prompts/sections/tool-use-guidelines.ts @@ -40,12 +40,8 @@ export function getToolUseGuidelinesSection( `${itemNumber++}. If multiple actions are needed, use one tool at a time per message to accomplish the task iteratively, with each tool use being informed by the result of the previous tool use. Do not assume the outcome of any tool use. Each step must be informed by the previous step's result.`, ) - // Protocol-specific guideline - if (isNativeProtocol(protocol)) { - guidelinesList.push( - `${itemNumber++}. Formulate your tool call using the provider's native tool-calling mechanism.`, - ) - } else { + // Protocol-specific guideline - only add for XML protocol + if (!isNativeProtocol(protocol)) { guidelinesList.push(`${itemNumber++}. Formulate your tool use using the XML format specified for each tool.`) } guidelinesList.push(`${itemNumber++}. After each tool use, the user will respond with the result of that tool use. This result will provide you with the necessary information to continue your task or make further decisions. This response may include: