mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
400 lines
13 KiB
TypeScript
400 lines
13 KiB
TypeScript
import { Anthropic } from "@anthropic-ai/sdk"
|
|
|
|
import type {
|
|
ClineAsk,
|
|
ToolProgressStatus,
|
|
ToolGroup,
|
|
ToolName,
|
|
BrowserActionParams,
|
|
GenerateImageParams,
|
|
FollowUpQuestion,
|
|
} from "@roo-code/types"
|
|
|
|
export type ToolResponse = string | Array<Anthropic.TextBlockParam | Anthropic.ImageBlockParam>
|
|
|
|
export type AskApproval = (
|
|
type: ClineAsk,
|
|
partialMessage?: string,
|
|
progressStatus?: ToolProgressStatus,
|
|
forceApproval?: boolean,
|
|
) => Promise<boolean>
|
|
|
|
export type HandleError = (action: string, error: Error) => Promise<void>
|
|
|
|
export type PushToolResult = (content: ToolResponse) => void
|
|
|
|
export type AskFinishSubTaskApproval = () => Promise<boolean>
|
|
|
|
export interface TextContent {
|
|
type: "text"
|
|
content: string
|
|
partial: boolean
|
|
}
|
|
|
|
export const toolParamNames = [
|
|
"command",
|
|
"path",
|
|
"content",
|
|
"regex",
|
|
"file_pattern",
|
|
"recursive",
|
|
"action",
|
|
"url",
|
|
"coordinate",
|
|
"text",
|
|
"server_name",
|
|
"tool_name",
|
|
"arguments",
|
|
"uri",
|
|
"question",
|
|
"result",
|
|
"diff",
|
|
"mode_slug",
|
|
"reason",
|
|
"line",
|
|
"mode",
|
|
"message",
|
|
"cwd",
|
|
"follow_up",
|
|
"task",
|
|
"size",
|
|
"query",
|
|
"args",
|
|
"skill", // skill tool parameter
|
|
"start_line",
|
|
"end_line",
|
|
"todos",
|
|
"prompt",
|
|
"image",
|
|
// read_file parameters (native protocol)
|
|
"operations", // search_and_replace parameter for multiple operations
|
|
"patch", // apply_patch parameter
|
|
"file_path", // search_replace and edit_file parameter
|
|
"old_string", // search_replace and edit_file parameter
|
|
"new_string", // search_replace and edit_file parameter
|
|
"expected_replacements", // edit_file parameter for multiple occurrences
|
|
"expected_replacements", // edit_file parameter for multiple occurrences
|
|
"questions", // ask_followup_question parameter for multiple questions
|
|
"artifact_id", // read_command_output parameter
|
|
"search", // read_command_output parameter for grep-like search
|
|
"offset", // read_command_output and read_file parameter
|
|
"limit", // read_command_output and read_file parameter
|
|
// read_file indentation mode parameters
|
|
"indentation",
|
|
"anchor_line",
|
|
"max_levels",
|
|
"include_siblings",
|
|
"include_header",
|
|
"max_lines",
|
|
// read_file legacy format parameter (backward compatibility)
|
|
"files",
|
|
"line_ranges",
|
|
] as const
|
|
|
|
export type ToolParamName = (typeof toolParamNames)[number]
|
|
|
|
/**
|
|
* Type map defining the native (typed) argument structure for each tool.
|
|
* Tools not listed here will fall back to `any` for backward compatibility.
|
|
*/
|
|
export type NativeToolArgs = {
|
|
access_mcp_resource: { server_name: string; uri: string }
|
|
read_file: import("@roo-code/types").ReadFileToolParams
|
|
read_command_output: { artifact_id: string; search?: string; offset?: number; limit?: number }
|
|
attempt_completion: { result: string }
|
|
execute_command: { command: string; cwd?: string }
|
|
apply_diff: { path: string; diff: string }
|
|
search_and_replace: { path: string; operations: Array<{ search: string; replace: string }> }
|
|
search_replace: { file_path: string; old_string: string; new_string: string }
|
|
edit_file: { file_path: string; old_string: string; new_string: string; expected_replacements?: number }
|
|
apply_patch: { patch: string }
|
|
list_files: { path: string; recursive?: boolean }
|
|
new_task: { mode: string; message: string; todos?: string }
|
|
ask_followup_question: {
|
|
questions: FollowUpQuestion[]
|
|
follow_up?: Array<{ text: string; mode?: string }>
|
|
}
|
|
browser_action: BrowserActionParams
|
|
codebase_search: { query: string; path?: string }
|
|
generate_image: GenerateImageParams
|
|
run_slash_command: { command: string; args?: string }
|
|
skill: { skill: string; args?: string | null }
|
|
search_files: { path: string; regex: string; file_pattern?: string | null }
|
|
switch_mode: { mode_slug: string; reason: string }
|
|
update_todo_list: { todos: string }
|
|
use_mcp_tool: { server_name: string; tool_name: string; arguments?: Record<string, unknown> }
|
|
write_to_file: { path: string; content: string }
|
|
// Add more tools as they are migrated to native protocol
|
|
}
|
|
|
|
/**
|
|
* Generic ToolUse interface that provides proper typing for both protocols.
|
|
*
|
|
* @template TName - The specific tool name, which determines the nativeArgs type
|
|
*/
|
|
export interface ToolUse<TName extends ToolName = ToolName> {
|
|
type: "tool_use"
|
|
id?: string // Optional ID to track tool calls
|
|
name: TName
|
|
/**
|
|
* The original tool name as called by the model (e.g. an alias like "edit_file"),
|
|
* if it differs from the canonical tool name used for execution.
|
|
* Used to preserve tool names in API conversation history.
|
|
*/
|
|
originalName?: string
|
|
// params is a partial record, allowing only some or none of the possible parameters to be used
|
|
params: Partial<Record<ToolParamName, string>>
|
|
partial: boolean
|
|
// nativeArgs is properly typed based on TName if it's in NativeToolArgs, otherwise never
|
|
nativeArgs?: TName extends keyof NativeToolArgs ? NativeToolArgs[TName] : never
|
|
/**
|
|
* Flag indicating whether the tool call used a legacy/deprecated format.
|
|
* Used for telemetry tracking to monitor migration from old formats.
|
|
*/
|
|
usedLegacyFormat?: boolean
|
|
}
|
|
|
|
/**
|
|
* Represents a native MCP tool call from the model.
|
|
* In native mode, MCP tools are called directly with their prefixed name (e.g., "mcp_serverName_toolName")
|
|
* rather than through the use_mcp_tool wrapper. This type preserves the original tool name
|
|
* so it appears correctly in API conversation history.
|
|
*/
|
|
export interface McpToolUse {
|
|
type: "mcp_tool_use"
|
|
id?: string // Tool call ID from the API
|
|
/** The original tool name from the API (e.g., "mcp_serverName_toolName") */
|
|
name: string
|
|
/** Extracted server name from the tool name */
|
|
serverName: string
|
|
/** Extracted tool name from the tool name */
|
|
toolName: string
|
|
/** Arguments passed to the MCP tool */
|
|
arguments: Record<string, unknown>
|
|
partial: boolean
|
|
}
|
|
|
|
export interface ExecuteCommandToolUse extends ToolUse<"execute_command"> {
|
|
name: "execute_command"
|
|
// Pick<Record<ToolParamName, string>, "command"> makes "command" required, but Partial<> makes it optional
|
|
params: Partial<Pick<Record<ToolParamName, string>, "command" | "cwd">>
|
|
}
|
|
|
|
export interface ReadFileToolUse extends ToolUse<"read_file"> {
|
|
name: "read_file"
|
|
params: Partial<
|
|
Pick<
|
|
Record<ToolParamName, string>,
|
|
| "args"
|
|
| "path"
|
|
| "start_line"
|
|
| "end_line"
|
|
| "mode"
|
|
| "offset"
|
|
| "limit"
|
|
| "indentation"
|
|
| "anchor_line"
|
|
| "max_levels"
|
|
| "include_siblings"
|
|
| "include_header"
|
|
>
|
|
>
|
|
}
|
|
|
|
export interface WriteToFileToolUse extends ToolUse<"write_to_file"> {
|
|
name: "write_to_file"
|
|
params: Partial<Pick<Record<ToolParamName, string>, "path" | "content">>
|
|
}
|
|
|
|
export interface CodebaseSearchToolUse extends ToolUse<"codebase_search"> {
|
|
name: "codebase_search"
|
|
params: Partial<Pick<Record<ToolParamName, string>, "query" | "path">>
|
|
}
|
|
|
|
export interface SearchFilesToolUse extends ToolUse<"search_files"> {
|
|
name: "search_files"
|
|
params: Partial<Pick<Record<ToolParamName, string>, "path" | "regex" | "file_pattern">>
|
|
}
|
|
|
|
export interface ListFilesToolUse extends ToolUse<"list_files"> {
|
|
name: "list_files"
|
|
params: Partial<Pick<Record<ToolParamName, string>, "path" | "recursive">>
|
|
}
|
|
|
|
export interface BrowserActionToolUse extends ToolUse<"browser_action"> {
|
|
name: "browser_action"
|
|
params: Partial<Pick<Record<ToolParamName, string>, "action" | "url" | "coordinate" | "text" | "size" | "path">>
|
|
}
|
|
|
|
export interface UseMcpToolToolUse extends ToolUse<"use_mcp_tool"> {
|
|
name: "use_mcp_tool"
|
|
params: Partial<Pick<Record<ToolParamName, string>, "server_name" | "tool_name" | "arguments">>
|
|
}
|
|
|
|
export interface AccessMcpResourceToolUse extends ToolUse<"access_mcp_resource"> {
|
|
name: "access_mcp_resource"
|
|
params: Partial<Pick<Record<ToolParamName, string>, "server_name" | "uri">>
|
|
}
|
|
|
|
export interface AskFollowupQuestionToolUse extends ToolUse<"ask_followup_question"> {
|
|
name: "ask_followup_question"
|
|
params: Partial<Pick<Record<ToolParamName, string>, "question" | "follow_up" | "questions">>
|
|
}
|
|
|
|
export interface AttemptCompletionToolUse extends ToolUse<"attempt_completion"> {
|
|
name: "attempt_completion"
|
|
params: Partial<Pick<Record<ToolParamName, string>, "result">>
|
|
}
|
|
|
|
export interface SwitchModeToolUse extends ToolUse<"switch_mode"> {
|
|
name: "switch_mode"
|
|
params: Partial<Pick<Record<ToolParamName, string>, "mode_slug" | "reason">>
|
|
}
|
|
|
|
export interface NewTaskToolUse extends ToolUse<"new_task"> {
|
|
name: "new_task"
|
|
params: Partial<Pick<Record<ToolParamName, string>, "mode" | "message" | "todos">>
|
|
}
|
|
|
|
export interface RunSlashCommandToolUse extends ToolUse<"run_slash_command"> {
|
|
name: "run_slash_command"
|
|
params: Partial<Pick<Record<ToolParamName, string>, "command" | "args">>
|
|
}
|
|
|
|
export interface SkillToolUse extends ToolUse<"skill"> {
|
|
name: "skill"
|
|
params: Partial<Pick<Record<ToolParamName, string>, "skill" | "args">>
|
|
}
|
|
|
|
export interface GenerateImageToolUse extends ToolUse<"generate_image"> {
|
|
name: "generate_image"
|
|
params: Partial<Pick<Record<ToolParamName, string>, "prompt" | "path" | "image">>
|
|
}
|
|
|
|
// Define tool group configuration
|
|
export type ToolGroupConfig = {
|
|
tools: readonly string[]
|
|
alwaysAvailable?: boolean // Whether this group is always available and shouldn't show in prompts view
|
|
customTools?: readonly string[] // Opt-in only tools - only available when explicitly included via model's includedTools
|
|
}
|
|
|
|
export const TOOL_DISPLAY_NAMES: Record<ToolName, string> = {
|
|
execute_command: "run commands",
|
|
read_file: "read files",
|
|
read_command_output: "read command output",
|
|
write_to_file: "write files",
|
|
apply_diff: "apply changes",
|
|
search_and_replace: "apply changes using search and replace",
|
|
search_replace: "apply single search and replace",
|
|
edit_file: "edit files using search and replace",
|
|
apply_patch: "apply patches using codex format",
|
|
search_files: "search files",
|
|
list_files: "list files",
|
|
browser_action: "use a browser",
|
|
use_mcp_tool: "use mcp tools",
|
|
access_mcp_resource: "access mcp resources",
|
|
ask_followup_question: "ask questions",
|
|
attempt_completion: "complete tasks",
|
|
switch_mode: "switch modes",
|
|
new_task: "create new task",
|
|
codebase_search: "codebase search",
|
|
update_todo_list: "update todo list",
|
|
run_slash_command: "run slash command",
|
|
skill: "load skill",
|
|
generate_image: "generate images",
|
|
custom_tool: "use custom tools",
|
|
} as const
|
|
|
|
// Define available tool groups.
|
|
export const TOOL_GROUPS: Record<ToolGroup, ToolGroupConfig> = {
|
|
read: {
|
|
tools: ["read_file", "search_files", "list_files", "codebase_search"],
|
|
},
|
|
edit: {
|
|
tools: ["apply_diff", "write_to_file", "generate_image"],
|
|
customTools: ["search_and_replace", "search_replace", "edit_file", "apply_patch"],
|
|
},
|
|
browser: {
|
|
tools: ["browser_action"],
|
|
},
|
|
command: {
|
|
tools: ["execute_command", "read_command_output"],
|
|
},
|
|
mcp: {
|
|
tools: ["use_mcp_tool", "access_mcp_resource"],
|
|
},
|
|
modes: {
|
|
tools: ["switch_mode", "new_task"],
|
|
alwaysAvailable: true,
|
|
},
|
|
}
|
|
|
|
// Tools that are always available to all modes.
|
|
export const ALWAYS_AVAILABLE_TOOLS: ToolName[] = [
|
|
"ask_followup_question",
|
|
"attempt_completion",
|
|
"switch_mode",
|
|
"new_task",
|
|
"update_todo_list",
|
|
"run_slash_command",
|
|
"skill",
|
|
] as const
|
|
|
|
/**
|
|
* Central registry of tool aliases.
|
|
* Maps alias name -> canonical tool name.
|
|
*
|
|
* This allows models to use alternative names for tools (e.g., "edit_file" instead of "apply_diff").
|
|
* When a model calls a tool by its alias, the system resolves it to the canonical name for execution,
|
|
* but preserves the alias in API conversation history for consistency.
|
|
*
|
|
* To add a new alias, simply add an entry here. No other files need to be modified.
|
|
*/
|
|
export const TOOL_ALIASES: Record<string, ToolName> = {
|
|
write_file: "write_to_file",
|
|
} as const
|
|
|
|
export type DiffResult =
|
|
| { success: true; content: string; failParts?: DiffResult[] }
|
|
| ({
|
|
success: false
|
|
error?: string
|
|
details?: {
|
|
similarity?: number
|
|
threshold?: number
|
|
matchedRange?: { start: number; end: number }
|
|
searchContent?: string
|
|
bestMatch?: string
|
|
}
|
|
failParts?: DiffResult[]
|
|
} & ({ error: string } | { failParts: DiffResult[] }))
|
|
|
|
export interface DiffItem {
|
|
content: string
|
|
startLine?: number
|
|
}
|
|
|
|
export interface DiffStrategy {
|
|
/**
|
|
* Get the name of this diff strategy for analytics and debugging
|
|
* @returns The name of the diff strategy
|
|
*/
|
|
getName(): string
|
|
|
|
/**
|
|
* Apply a diff to the original content
|
|
* @param originalContent The original file content
|
|
* @param diffContent The diff content in the strategy's format (string for legacy, DiffItem[] for new)
|
|
* @param startLine Optional line number where the search block starts. If not provided, searches the entire file.
|
|
* @param endLine Optional line number where the search block ends. If not provided, searches the entire file.
|
|
* @returns A DiffResult object containing either the successful result or error details
|
|
*/
|
|
applyDiff(
|
|
originalContent: string,
|
|
diffContent: string | DiffItem[],
|
|
startLine?: number,
|
|
endLine?: number,
|
|
): Promise<DiffResult>
|
|
|
|
getProgressStatus?(toolUse: ToolUse, result?: any): ToolProgressStatus
|
|
}
|