This repository was archived by the owner on May 15, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Expand file tree
/
Copy pathtools.ts
More file actions
359 lines (321 loc) · 11.6 KB
/
Copy pathtools.ts
File metadata and controls
359 lines (321 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
import { Anthropic } from "@anthropic-ai/sdk"
import type {
ClineAsk,
ToolProgressStatus,
ToolGroup,
ToolName,
FileEntry,
BrowserActionParams,
GenerateImageParams,
} 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",
"start_line",
"end_line",
"todos",
"prompt",
"image",
"files", // Native protocol parameter for read_file
"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
] 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: { files: FileEntry[] }
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: {
question: string
follow_up: Array<{ text: string; mode?: string }>
}
browser_action: BrowserActionParams
codebase_search: { query: string; path?: string }
fetch_instructions: { task: string }
generate_image: GenerateImageParams
run_slash_command: { command: string; args?: string }
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
}
/**
* 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" | "files">>
}
export interface FetchInstructionsToolUse extends ToolUse<"fetch_instructions"> {
name: "fetch_instructions"
params: Partial<Pick<Record<ToolParamName, string>, "task">>
}
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">>
}
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 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",
fetch_instructions: "fetch instructions",
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",
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", "fetch_instructions", "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"],
},
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",
] 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
}