import { Anthropic } from "@anthropic-ai/sdk" import { ClineAsk, ToolProgressStatus, ToolGroup, ToolName } from "../schemas" export type ToolResponse = string | Array export type AskApproval = ( type: ClineAsk, partialMessage?: string, progressStatus?: ToolProgressStatus, ) => Promise export type HandleError = (action: string, error: Error) => Promise export type PushToolResult = (content: ToolResponse) => void export type RemoveClosingTag = (tag: ToolParamName, content?: string) => string export type AskFinishSubTaskApproval = () => Promise export type ToolDescription = () => string export interface TextContent { type: "text" content: string partial: boolean } export const toolParamNames = [ "command", "path", "content", "line_count", "regex", "file_pattern", "recursive", "action", "url", "coordinate", "text", "server_name", "tool_name", "arguments", "uri", "question", "result", "diff", "start_line", "end_line", "mode_slug", "reason", "operations", "mode", "message", "cwd", "follow_up", "task", "size", "search", "replace", "use_regex", "ignore_case", "start_line", "end_line", ] as const export type ToolParamName = (typeof toolParamNames)[number] export interface ToolUse { type: "tool_use" name: ToolName // params is a partial record, allowing only some or none of the possible parameters to be used params: Partial> partial: boolean } export interface ExecuteCommandToolUse extends ToolUse { name: "execute_command" // Pick, "command"> makes "command" required, but Partial<> makes it optional params: Partial, "command" | "cwd">> } export interface ReadFileToolUse extends ToolUse { name: "read_file" params: Partial, "path" | "start_line" | "end_line">> } export interface FetchInstructionsToolUse extends ToolUse { name: "fetch_instructions" params: Partial, "task">> } export interface WriteToFileToolUse extends ToolUse { name: "write_to_file" params: Partial, "path" | "content" | "line_count">> } export interface InsertCodeBlockToolUse extends ToolUse { name: "insert_content" params: Partial, "path" | "operations">> } export interface SearchFilesToolUse extends ToolUse { name: "search_files" params: Partial, "path" | "regex" | "file_pattern">> } export interface ListFilesToolUse extends ToolUse { name: "list_files" params: Partial, "path" | "recursive">> } export interface ListCodeDefinitionNamesToolUse extends ToolUse { name: "list_code_definition_names" params: Partial, "path">> } export interface BrowserActionToolUse extends ToolUse { name: "browser_action" params: Partial, "action" | "url" | "coordinate" | "text" | "size">> } export interface UseMcpToolToolUse extends ToolUse { name: "use_mcp_tool" params: Partial, "server_name" | "tool_name" | "arguments">> } export interface AccessMcpResourceToolUse extends ToolUse { name: "access_mcp_resource" params: Partial, "server_name" | "uri">> } export interface AskFollowupQuestionToolUse extends ToolUse { name: "ask_followup_question" params: Partial, "question" | "follow_up">> } export interface AttemptCompletionToolUse extends ToolUse { name: "attempt_completion" params: Partial, "result" | "command">> } export interface SwitchModeToolUse extends ToolUse { name: "switch_mode" params: Partial, "mode_slug" | "reason">> } export interface NewTaskToolUse extends ToolUse { name: "new_task" params: Partial, "mode" | "message">> } export interface SearchAndReplaceToolUse extends ToolUse { name: "search_and_replace" params: Required, "path" | "search" | "replace">> & Partial, "use_regex" | "ignore_case" | "start_line" | "end_line">> } // 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 } export const TOOL_DISPLAY_NAMES: Record = { execute_command: "run commands", read_file: "read files", fetch_instructions: "fetch instructions", write_to_file: "write files", append_to_file: "append to files", apply_diff: "apply changes", search_files: "search files", list_files: "list files", list_code_definition_names: "list definitions", 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", insert_content: "insert content", search_and_replace: "search and replace", } as const export type { ToolGroup } // Define available tool groups. export const TOOL_GROUPS: Record = { read: { tools: ["read_file", "fetch_instructions", "search_files", "list_files", "list_code_definition_names"], }, edit: { tools: ["apply_diff", "write_to_file", "append_to_file", "insert_content", "search_and_replace"], }, browser: { tools: ["browser_action"], }, command: { tools: ["execute_command"], }, 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", ] 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 DiffStrategy { /** * Get the name of this diff strategy for analytics and debugging * @returns The name of the diff strategy */ getName(): string /** * Get the tool description for this diff strategy * @param args The tool arguments including cwd and toolOptions * @returns The complete tool description including format requirements and examples */ getToolDescription(args: { cwd: string; toolOptions?: { [key: string]: string } }): string /** * Apply a diff to the original content * @param originalContent The original file content * @param diffContent The diff content in the strategy's format * @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, startLine?: number, endLine?: number): Promise getProgressStatus?(toolUse: ToolUse, result?: any): ToolProgressStatus }