Skip to content

Commit 4d97f77

Browse files
committed
feat: add ToolAdapter for backward compatibility
- Created ToolAdapter to bridge existing code with new RooTool system - Allows gradual migration of tools without breaking existing functionality - Provides fallback to legacy implementations for unmigrated tools
1 parent 6b08c26 commit 4d97f77

File tree

1 file changed

+231
-0
lines changed

1 file changed

+231
-0
lines changed

src/core/tools/ToolAdapter.ts

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
import { toolRegistry } from "./ToolRegistry"
2+
import { ToolName } from "@roo-code/types"
3+
import { Task } from "../task/Task"
4+
import { ToolUse, AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "../../shared/tools"
5+
6+
/**
7+
* ToolAdapter - Provides backward compatibility with existing tool invocation code
8+
* This adapter allows the existing codebase to work with the new RooTool classes
9+
* without requiring immediate changes to all tool invocations.
10+
*
11+
* This is a transitional component that can be removed once all code
12+
* has been updated to use the ToolRegistry directly.
13+
*/
14+
export class ToolAdapter {
15+
/**
16+
* Execute a tool by name using the new RooTool system
17+
* This method provides the same interface as the old tool functions
18+
* but delegates to the new RooTool implementations
19+
*/
20+
static async executeTool(
21+
toolName: ToolName,
22+
cline: Task,
23+
block: ToolUse,
24+
askApproval: AskApproval,
25+
handleError: HandleError,
26+
pushToolResult: PushToolResult,
27+
removeClosingTag: RemoveClosingTag,
28+
): Promise<void> {
29+
const tool = toolRegistry.getTool(toolName)
30+
31+
if (!tool) {
32+
// Fall back to legacy implementation if tool hasn't been migrated yet
33+
return ToolAdapter.executeLegacyTool(
34+
toolName,
35+
cline,
36+
block,
37+
askApproval,
38+
handleError,
39+
pushToolResult,
40+
removeClosingTag,
41+
)
42+
}
43+
44+
// Execute using the new RooTool implementation
45+
return tool.execute(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
46+
}
47+
48+
/**
49+
* Execute a legacy tool that hasn't been migrated yet
50+
* This allows for gradual migration of tools
51+
*/
52+
private static async executeLegacyTool(
53+
toolName: ToolName,
54+
cline: Task,
55+
block: ToolUse,
56+
askApproval: AskApproval,
57+
handleError: HandleError,
58+
pushToolResult: PushToolResult,
59+
removeClosingTag: RemoveClosingTag,
60+
): Promise<void> {
61+
// Import and execute legacy tool implementations
62+
// These imports will be removed as tools are migrated
63+
switch (toolName) {
64+
case "write_to_file": {
65+
// This is already migrated, but keeping as example
66+
const { writeToFileTool } = await import("../tools/writeToFileTool")
67+
return writeToFileTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
68+
}
69+
case "read_file": {
70+
const { readFileTool } = await import("../tools/readFileTool")
71+
return readFileTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
72+
}
73+
case "execute_command": {
74+
const { executeCommandTool } = await import("../tools/executeCommandTool")
75+
return executeCommandTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
76+
}
77+
case "apply_diff": {
78+
// Use the legacy apply diff for now
79+
const { applyDiffToolLegacy } = await import("../tools/applyDiffTool")
80+
return applyDiffToolLegacy(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
81+
}
82+
case "search_files": {
83+
const { searchFilesTool } = await import("../tools/searchFilesTool")
84+
return searchFilesTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
85+
}
86+
case "list_files": {
87+
const { listFilesTool } = await import("../tools/listFilesTool")
88+
return listFilesTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
89+
}
90+
case "list_code_definition_names": {
91+
const { listCodeDefinitionNamesTool } = await import("../tools/listCodeDefinitionNamesTool")
92+
return listCodeDefinitionNamesTool(
93+
cline,
94+
block,
95+
askApproval,
96+
handleError,
97+
pushToolResult,
98+
removeClosingTag,
99+
)
100+
}
101+
case "browser_action": {
102+
const { browserActionTool } = await import("../tools/browserActionTool")
103+
return browserActionTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
104+
}
105+
case "use_mcp_tool": {
106+
const { useMcpToolTool } = await import("../tools/useMcpToolTool")
107+
return useMcpToolTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
108+
}
109+
case "access_mcp_resource": {
110+
const { accessMcpResourceTool } = await import("../tools/accessMcpResourceTool")
111+
return accessMcpResourceTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
112+
}
113+
case "ask_followup_question": {
114+
const { askFollowupQuestionTool } = await import("../tools/askFollowupQuestionTool")
115+
return askFollowupQuestionTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
116+
}
117+
case "attempt_completion": {
118+
const { attemptCompletionTool } = await import("../tools/attemptCompletionTool")
119+
// attemptCompletionTool requires additional parameters
120+
const toolDescription = () => `[${block.name}]`
121+
const askFinishSubTaskApproval = async () => {
122+
const toolMessage = JSON.stringify({ tool: "finishTask" })
123+
return await askApproval("tool", toolMessage)
124+
}
125+
return attemptCompletionTool(
126+
cline,
127+
block,
128+
askApproval,
129+
handleError,
130+
pushToolResult,
131+
removeClosingTag,
132+
toolDescription,
133+
askFinishSubTaskApproval,
134+
)
135+
}
136+
case "switch_mode": {
137+
const { switchModeTool } = await import("../tools/switchModeTool")
138+
return switchModeTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
139+
}
140+
case "new_task": {
141+
const { newTaskTool } = await import("../tools/newTaskTool")
142+
return newTaskTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
143+
}
144+
case "insert_content": {
145+
const { insertContentTool } = await import("../tools/insertContentTool")
146+
return insertContentTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
147+
}
148+
case "search_and_replace": {
149+
const { searchAndReplaceTool } = await import("../tools/searchAndReplaceTool")
150+
return searchAndReplaceTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
151+
}
152+
case "codebase_search": {
153+
const { codebaseSearchTool } = await import("../tools/codebaseSearchTool")
154+
return codebaseSearchTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
155+
}
156+
case "update_todo_list": {
157+
const { updateTodoListTool } = await import("../tools/updateTodoListTool")
158+
return updateTodoListTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
159+
}
160+
case "run_slash_command": {
161+
const { runSlashCommandTool } = await import("../tools/runSlashCommandTool")
162+
return runSlashCommandTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
163+
}
164+
case "generate_image": {
165+
const { generateImageTool } = await import("../tools/generateImageTool")
166+
return generateImageTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
167+
}
168+
case "fetch_instructions": {
169+
const { fetchInstructionsTool } = await import("../tools/fetchInstructionsTool")
170+
return fetchInstructionsTool(cline, block, askApproval, handleError, pushToolResult)
171+
}
172+
default:
173+
throw new Error(`Unknown tool: ${toolName}`)
174+
}
175+
}
176+
177+
/**
178+
* Get tool usage description using the new system
179+
* Falls back to legacy implementation if needed
180+
*/
181+
static getToolUsageDescription(block: ToolUse): string {
182+
const tool = toolRegistry.getTool(block.name as ToolName)
183+
184+
if (tool) {
185+
return tool.getToolUsageDescription(block)
186+
}
187+
188+
// Fall back to legacy description logic
189+
// This is copied from presentAssistantMessage.ts and can be removed
190+
// once all tools are migrated
191+
switch (block.name) {
192+
case "execute_command":
193+
return `[${block.name} for '${block.params.command}']`
194+
case "write_to_file":
195+
return `[${block.name} to '${block.params.path}']`
196+
case "read_file":
197+
// This would use the getReadFileToolDescription function
198+
return `[${block.name} for '${block.params.path || block.params.args}']`
199+
case "list_files":
200+
return `[${block.name} for '${block.params.path}']`
201+
case "list_code_definition_names":
202+
return `[${block.name} for '${block.params.path}']`
203+
case "search_files":
204+
return `[${block.name} for '${block.params.regex}' in '${block.params.path}']`
205+
case "browser_action":
206+
return `[${block.name} for '${block.params.action}']`
207+
case "use_mcp_tool":
208+
return `[${block.name} for '${block.params.server_name}']`
209+
case "access_mcp_resource":
210+
return `[${block.name} for '${block.params.server_name}']`
211+
case "ask_followup_question":
212+
return `[${block.name} for '${block.params.question}']`
213+
case "attempt_completion":
214+
return `[${block.name}]`
215+
case "switch_mode":
216+
return `[${block.name} to '${block.params.mode_slug}'${block.params.reason ? ` because: ${block.params.reason}` : ""}]`
217+
case "codebase_search":
218+
return `[${block.name} for '${block.params.query}']`
219+
case "update_todo_list":
220+
return `[${block.name}]`
221+
case "new_task":
222+
return `[${block.name} in ${block.params.mode} mode: '${block.params.message}']`
223+
case "run_slash_command":
224+
return `[${block.name} for '${block.params.command}'${block.params.args ? ` with args: ${block.params.args}` : ""}]`
225+
case "generate_image":
226+
return `[${block.name} for '${block.params.path}']`
227+
default:
228+
return `[${block.name}]`
229+
}
230+
}
231+
}

0 commit comments

Comments
 (0)