Update tools to use specific directive types for enhanced type safety

This commit is contained in:
Steven T. Cramer 2025-06-16 12:24:22 +07:00
parent 4090116081
commit 2202273cc1
23 changed files with 182 additions and 66 deletions

View file

@ -1,7 +1,26 @@
export type { Directive } from "./Directive"
export type { TextDirective } from "./TextDirective"
export type { ToolDirective } from "./ToolDirective"
export type { ToolParamName, ToolResponse } from "./tool-directives"
export type {
ToolParamName,
ToolResponse,
ExecuteCommandToolDirective,
ReadFileToolDirective,
WriteToFileToolDirective,
InsertCodeBlockToolDirective,
CodebaseSearchToolDirective,
SearchFilesToolDirective,
ListFilesToolDirective,
ListCodeDefinitionNamesToolDirective,
BrowserActionToolDirective,
UseMcpToolToolDirective,
AccessMcpResourceToolDirective,
AskFollowupQuestionToolDirective,
AttemptCompletionToolDirective,
SwitchModeToolDirective,
NewTaskToolDirective,
SearchAndReplaceToolDirective,
} from "./tool-directives"
export { type LogDirective, logLevels } from "./LogDirective"
export { toolParamNames } from "./tool-directives"

View file

@ -2,7 +2,7 @@ export type { ToolResponse } from "./ToolResponse"
export type { ToolParamName } from "./ToolParamName"
export type { ExecuteCommandToolDirective } from "./ExecuteCommandToolDirective"
export type { ReadFileToolDirective } from "./ReadFileToolDirective"
export type { FetchInstructionsToolDirective } from "./FetchInstructionsToolDirective"
// export type { FetchInstructionsToolDirective } from "./FetchInstructionsToolDirective"
export type { WriteToFileToolDirective } from "./WriteToFileToolDirective"
export type { InsertCodeBlockToolDirective } from "./InsertCodeBlockToolDirective"
export type { CodebaseSearchToolDirective } from "./CodebaseSearchToolDirective"

View file

@ -4,7 +4,26 @@ import { serializeError } from "serialize-error"
import type { ToolName, ClineAsk, ToolProgressStatus } from "@roo-code/types"
import { TelemetryService } from "@roo-code/telemetry"
import type { LogDirective, ToolParamName, ToolResponse } from "./directives"
import type {
LogDirective,
ToolParamName,
ToolResponse,
ExecuteCommandToolDirective,
ListFilesToolDirective,
ReadFileToolDirective,
WriteToFileToolDirective,
InsertCodeBlockToolDirective,
SearchAndReplaceToolDirective,
SearchFilesToolDirective,
ListCodeDefinitionNamesToolDirective,
UseMcpToolToolDirective,
AccessMcpResourceToolDirective,
AskFollowupQuestionToolDirective,
SwitchModeToolDirective,
NewTaskToolDirective,
AttemptCompletionToolDirective,
BrowserActionToolDirective,
} from "./directives"
import { defaultModeSlug, getModeBySlug } from "../../shared/modes"
@ -410,7 +429,14 @@ export async function presentAssistantMessage(cline: Task) {
switch (block.name) {
case "write_to_file":
await writeToFileTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
await writeToFileTool(
cline,
block as WriteToFileToolDirective,
askApproval,
handleError,
pushToolResult,
removeClosingTag,
)
break
case "apply_diff": {
// Get the provider and state to check experiment settings
@ -440,20 +466,48 @@ export async function presentAssistantMessage(cline: Task) {
break
}
case "insert_content":
await insertContentTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
await insertContentTool(
cline,
block as InsertCodeBlockToolDirective,
askApproval,
handleError,
pushToolResult,
removeClosingTag,
)
break
case "search_and_replace":
await searchAndReplaceTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
await searchAndReplaceTool(
cline,
block as SearchAndReplaceToolDirective,
askApproval,
handleError,
pushToolResult,
removeClosingTag,
)
break
case "read_file":
await readFileTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
await readFileTool(
cline,
block as ReadFileToolDirective,
askApproval,
handleError,
pushToolResult,
removeClosingTag,
)
break
case "fetch_instructions":
await fetchInstructionsTool(cline, block, askApproval, handleError, pushToolResult)
break
case "list_files":
await listFilesTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
await listFilesTool(
cline,
block as ListFilesToolDirective,
askApproval,
handleError,
pushToolResult,
removeClosingTag,
)
break
case "codebase_search":
await codebaseSearchTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
@ -461,7 +515,7 @@ export async function presentAssistantMessage(cline: Task) {
case "list_code_definition_names":
await listCodeDefinitionNamesTool(
cline,
block,
block as ListCodeDefinitionNamesToolDirective,
askApproval,
handleError,
pushToolResult,
@ -469,21 +523,49 @@ export async function presentAssistantMessage(cline: Task) {
)
break
case "search_files":
await searchFilesTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
await searchFilesTool(
cline,
block as SearchFilesToolDirective,
askApproval,
handleError,
pushToolResult,
removeClosingTag,
)
break
case "browser_action":
await browserActionTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
await browserActionTool(
cline,
block as BrowserActionToolDirective,
askApproval,
handleError,
pushToolResult,
removeClosingTag,
)
break
case "execute_command":
await executeCommandTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
await executeCommandTool(
cline,
block as ExecuteCommandToolDirective,
askApproval,
handleError,
pushToolResult,
removeClosingTag,
)
break
case "use_mcp_tool":
await useMcpToolTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
await useMcpToolTool(
cline,
block as UseMcpToolToolDirective,
askApproval,
handleError,
pushToolResult,
removeClosingTag,
)
break
case "access_mcp_resource":
await accessMcpResourceTool(
cline,
block,
block as AccessMcpResourceToolDirective,
askApproval,
handleError,
pushToolResult,
@ -493,7 +575,7 @@ export async function presentAssistantMessage(cline: Task) {
case "ask_followup_question":
await askFollowupQuestionTool(
cline,
block,
block as AskFollowupQuestionToolDirective,
askApproval,
handleError,
pushToolResult,
@ -501,15 +583,29 @@ export async function presentAssistantMessage(cline: Task) {
)
break
case "switch_mode":
await switchModeTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
await switchModeTool(
cline,
block as SwitchModeToolDirective,
askApproval,
handleError,
pushToolResult,
removeClosingTag,
)
break
case "new_task":
await newTaskTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
await newTaskTool(
cline,
block as NewTaskToolDirective,
askApproval,
handleError,
pushToolResult,
removeClosingTag,
)
break
case "attempt_completion":
await attemptCompletionTool(
cline,
block,
block as AttemptCompletionToolDirective,
askApproval,
handleError,
pushToolResult,

View file

@ -87,7 +87,7 @@ import { maybeRemoveImageBlocks } from "../../api/transform/image-cleaning"
import { LogManager } from "../logging"
import { Directive, DirectiveStreamingParser } from "../message-parsing"
export type ClineEvents = {
type ClineEvents = {
message: [{ action: "created" | "updated"; message: ClineMessage }]
taskStarted: []
taskModeSwitched: [taskId: string, mode: string]

View file

@ -27,7 +27,7 @@ vitest.mock("../executeCommandTool")
// Import after mocking
import { executeCommandTool } from "../executeCommandTool"
import { ToolDirective } from "../../message-parsing/directives"
import { ExecuteCommandToolDirective, ToolDirective } from "../../message-parsing/directives"
// Now manually restore and mock the functions
beforeEach(() => {
@ -80,7 +80,7 @@ describe("executeCommandTool", () => {
let mockHandleError: any
let mockPushToolResult: any
let mockRemoveClosingTag: any
let mockToolDirective: ToolDirective
let mockToolDirective: ExecuteCommandToolDirective
beforeEach(() => {
// Reset mocks

View file

@ -52,7 +52,7 @@ jest.mock("../../prompts/responses", () => ({
// Import the function to test AFTER mocks are set up
import { newTaskTool } from "../newTaskTool"
import { ToolDirective } from "../../message-parsing/directives"
import { ToolDirective, NewTaskToolDirective } from "../../message-parsing/directives"
describe("newTaskTool", () => {
beforeEach(() => {
@ -77,7 +77,7 @@ describe("newTaskTool", () => {
await newTaskTool(
mockCline as any, // Use 'as any' for simplicity in mocking complex type
block,
block as NewTaskToolDirective,
mockAskApproval, // Now correctly typed
mockHandleError,
mockPushToolResult,
@ -114,7 +114,7 @@ describe("newTaskTool", () => {
await newTaskTool(
mockCline as any,
block,
block as NewTaskToolDirective,
mockAskApproval, // Now correctly typed
mockHandleError,
mockPushToolResult,
@ -141,7 +141,7 @@ describe("newTaskTool", () => {
await newTaskTool(
mockCline as any,
block,
block as NewTaskToolDirective,
mockAskApproval, // Now correctly typed
mockHandleError,
mockPushToolResult,
@ -168,7 +168,7 @@ describe("newTaskTool", () => {
await newTaskTool(
mockCline as any,
block,
block as NewTaskToolDirective,
mockAskApproval, // Now correctly typed
mockHandleError,
mockPushToolResult,

View file

@ -1,7 +1,7 @@
import { useMcpToolTool } from "../useMcpToolTool"
import { Task } from "../../task/Task"
import { formatResponse } from "../../prompts/responses"
import { ToolDirective } from "../../message-parsing/directives"
import { ToolDirective, UseMcpToolToolDirective } from "../../message-parsing/directives"
// Mock dependencies
jest.mock("../../prompts/responses", () => ({
@ -71,7 +71,7 @@ describe("useMcpToolTool", () => {
await useMcpToolTool(
mockTask as Task,
block,
block as UseMcpToolToolDirective,
mockAskApproval,
mockHandleError,
mockPushToolResult,
@ -99,7 +99,7 @@ describe("useMcpToolTool", () => {
await useMcpToolTool(
mockTask as Task,
block,
block as UseMcpToolToolDirective,
mockAskApproval,
mockHandleError,
mockPushToolResult,
@ -126,7 +126,7 @@ describe("useMcpToolTool", () => {
await useMcpToolTool(
mockTask as Task,
block,
block as UseMcpToolToolDirective,
mockAskApproval,
mockHandleError,
mockPushToolResult,
@ -157,7 +157,7 @@ describe("useMcpToolTool", () => {
await useMcpToolTool(
mockTask as Task,
block,
block as UseMcpToolToolDirective,
mockAskApproval,
mockHandleError,
mockPushToolResult,
@ -197,7 +197,7 @@ describe("useMcpToolTool", () => {
await useMcpToolTool(
mockTask as Task,
block,
block as UseMcpToolToolDirective,
mockAskApproval,
mockHandleError,
mockPushToolResult,
@ -227,7 +227,7 @@ describe("useMcpToolTool", () => {
await useMcpToolTool(
mockTask as Task,
block,
block as UseMcpToolToolDirective,
mockAskApproval,
mockHandleError,
mockPushToolResult,
@ -256,7 +256,7 @@ describe("useMcpToolTool", () => {
await useMcpToolTool(
mockTask as Task,
block,
block as UseMcpToolToolDirective,
mockAskApproval,
mockHandleError,
mockPushToolResult,

View file

@ -7,7 +7,7 @@ import { getReadablePath } from "../../../utils/path"
import { unescapeHtmlEntities } from "../../../utils/text-normalization"
import { everyLineHasLineNumbers, stripLineNumbers } from "../../../integrations/misc/extract-text"
import { writeToFileTool } from "../writeToFileTool"
import { ToolDirective, ToolResponse } from "../../message-parsing/directives"
import { ToolDirective, ToolResponse, WriteToFileToolDirective } from "../../message-parsing/directives"
jest.mock("path", () => {
const originalPath = jest.requireActual("path")
@ -213,7 +213,7 @@ describe("writeToFileTool", () => {
await writeToFileTool(
mockCline,
ToolDirective,
ToolDirective as WriteToFileToolDirective,
mockAskApproval,
mockHandleError,
(result: ToolResponse) => {

View file

@ -2,11 +2,11 @@ import { ClineAskUseMcpServer } from "../../shared/ExtensionMessage"
import { RemoveClosingTag, AskApproval, HandleError, PushToolResult } from "../../shared/tools"
import { Task } from "../task/Task"
import { formatResponse } from "../prompts/responses"
import { ToolDirective } from "../message-parsing/directives"
import { AccessMcpResourceToolDirective } from "../message-parsing/directives"
export async function accessMcpResourceTool(
cline: Task,
block: ToolDirective,
block: AccessMcpResourceToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,

View file

@ -2,11 +2,11 @@ import { Task } from "../task/Task"
import { AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "../../shared/tools"
import { formatResponse } from "../prompts/responses"
import { parseXml } from "../../utils/xml"
import { ToolDirective } from "../message-parsing/directives"
import { AskFollowupQuestionToolDirective } from "../message-parsing/directives"
export async function askFollowupQuestionTool(
cline: Task,
block: ToolDirective,
block: AskFollowupQuestionToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,

View file

@ -14,11 +14,11 @@ import {
import { formatResponse } from "../prompts/responses"
import { type ExecuteCommandOptions, executeCommand } from "./executeCommandTool"
import { EXPERIMENT_IDS, experiments, experimentDefault } from "../../shared/experiments"
import { ToolDirective, ToolResponse } from "../message-parsing/directives"
import { ToolDirective, ToolResponse, AttemptCompletionToolDirective } from "../message-parsing/directives"
export async function attemptCompletionTool(
cline: Task,
block: ToolDirective,
block: AttemptCompletionToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,

View file

@ -7,11 +7,11 @@ import {
ClineSayBrowserAction,
} from "../../shared/ExtensionMessage"
import { formatResponse } from "../prompts/responses"
import { ToolDirective } from "../message-parsing/directives"
import { ToolDirective, BrowserActionToolDirective } from "../message-parsing/directives"
export async function browserActionTool(
cline: Task,
block: ToolDirective,
block: BrowserActionToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,

View file

@ -14,13 +14,14 @@ import { unescapeHtmlEntities } from "../../utils/text-normalization"
import { ExitCodeDetails, RooTerminalCallbacks, RooTerminalProcess } from "../../integrations/terminal/types"
import { TerminalRegistry } from "../../integrations/terminal/TerminalRegistry"
import { Terminal } from "../../integrations/terminal/Terminal"
import { ToolDirective, ToolResponse } from "../message-parsing/directives"
import { ExecuteCommandToolDirective } from "../message-parsing/directives/tool-directives/ExecuteCommandToolDirective"
import { ToolResponse } from "../message-parsing/directives"
class ShellIntegrationError extends Error {}
export async function executeCommandTool(
cline: Task,
block: ToolDirective,
block: ExecuteCommandToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,

View file

@ -10,11 +10,11 @@ import { ClineSayTool } from "../../shared/ExtensionMessage"
import { RecordSource } from "../context-tracking/FileContextTrackerTypes"
import { fileExistsAtPath } from "../../utils/fs"
import { insertGroups } from "../diff/insert-groups"
import { ToolDirective } from "../message-parsing/directives"
import { InsertCodeBlockToolDirective } from "../message-parsing/directives"
export async function insertContentTool(
cline: Task,
block: ToolDirective,
block: InsertCodeBlockToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,

View file

@ -7,11 +7,11 @@ import { ClineSayTool } from "../../shared/ExtensionMessage"
import { getReadablePath } from "../../utils/path"
import { parseSourceCodeForDefinitionsTopLevel, parseSourceCodeDefinitionsForFile } from "../../services/tree-sitter"
import { RecordSource } from "../context-tracking/FileContextTrackerTypes"
import { ToolDirective } from "../message-parsing/directives"
import { ListCodeDefinitionNamesToolDirective } from "../message-parsing/directives"
export async function listCodeDefinitionNamesTool(
cline: Task,
block: ToolDirective,
block: ListCodeDefinitionNamesToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,

View file

@ -6,7 +6,7 @@ import { formatResponse } from "../prompts/responses"
import { listFiles } from "../../services/glob/list-files"
import { getReadablePath } from "../../utils/path"
import { AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "../../shared/tools"
import { ToolDirective } from "../message-parsing/directives"
import { ListFilesToolDirective } from "../message-parsing/directives"
/**
* Implements the list_files tool.
@ -25,7 +25,7 @@ import { ToolDirective } from "../message-parsing/directives"
export async function listFilesTool(
cline: Task,
block: ToolDirective,
block: ListFilesToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,

View file

@ -4,11 +4,11 @@ import { AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "../.
import { Task } from "../task/Task"
import { defaultModeSlug, getModeBySlug } from "../../shared/modes"
import { formatResponse } from "../prompts/responses"
import { ToolDirective } from "../message-parsing/directives"
import { NewTaskToolDirective } from "../message-parsing/directives"
export async function newTaskTool(
cline: Task,
block: ToolDirective,
block: NewTaskToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,

View file

@ -14,7 +14,7 @@ import { readLines } from "../../integrations/misc/read-lines"
import { extractTextFromFile, addLineNumbers, getSupportedBinaryFormats } from "../../integrations/misc/extract-text"
import { parseSourceCodeDefinitionsForFile } from "../../services/tree-sitter"
import { parseXml } from "../../utils/xml"
import { ToolDirective } from "../message-parsing/directives"
import { ReadFileToolDirective } from "../message-parsing/directives"
export function getReadFileToolDescription(blockName: string, blockParams: any): string {
// Handle both single path and multiple files via args
@ -73,7 +73,7 @@ interface FileResult {
export async function readFileTool(
cline: Task,
block: ToolDirective,
block: ReadFileToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,

View file

@ -11,7 +11,7 @@ import { ClineSayTool } from "../../shared/ExtensionMessage"
import { getReadablePath } from "../../utils/path"
import { fileExistsAtPath } from "../../utils/fs"
import { RecordSource } from "../context-tracking/FileContextTrackerTypes"
import { ToolDirective } from "../message-parsing/directives"
import { SearchAndReplaceToolDirective } from "../message-parsing/directives"
/**
* Tool for performing search and replace operations on files
@ -63,7 +63,7 @@ async function validateParams(
*/
export async function searchAndReplaceTool(
cline: Task,
block: ToolDirective,
block: SearchAndReplaceToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,

View file

@ -5,11 +5,11 @@ import { AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "../.
import { ClineSayTool } from "../../shared/ExtensionMessage"
import { getReadablePath } from "../../utils/path"
import { regexSearchFiles } from "../../services/ripgrep"
import { ToolDirective } from "../message-parsing/directives"
import { SearchFilesToolDirective } from "../message-parsing/directives"
export async function searchFilesTool(
cline: Task,
block: ToolDirective,
block: SearchFilesToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,

View file

@ -4,11 +4,11 @@ import { Task } from "../task/Task"
import { AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "../../shared/tools"
import { formatResponse } from "../prompts/responses"
import { defaultModeSlug, getModeBySlug } from "../../shared/modes"
import { ToolDirective } from "../message-parsing/directives"
import { SwitchModeToolDirective } from "../message-parsing/directives"
export async function switchModeTool(
cline: Task,
block: ToolDirective,
block: SwitchModeToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,

View file

@ -4,7 +4,7 @@ import { formatResponse } from "../prompts/responses"
import { ClineAskUseMcpServer } from "../../shared/ExtensionMessage"
import { McpExecutionStatus } from "@roo-code/types"
import { t } from "../../i18n"
import { ToolDirective } from "../message-parsing/directives"
import { UseMcpToolToolDirective } from "../message-parsing/directives"
interface McpToolParams {
server_name?: string
@ -167,7 +167,7 @@ async function executeToolAndProcessResult(
export async function useMcpToolTool(
cline: Task,
block: ToolDirective,
block: UseMcpToolToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,

View file

@ -13,11 +13,11 @@ import { getReadablePath } from "../../utils/path"
import { isPathOutsideWorkspace } from "../../utils/pathUtils"
import { detectCodeOmission } from "../../integrations/editor/detect-omission"
import { unescapeHtmlEntities } from "../../utils/text-normalization"
import { ToolDirective } from "../message-parsing/directives"
import { WriteToFileToolDirective } from "../message-parsing/directives"
export async function writeToFileTool(
cline: Task,
block: ToolDirective,
block: WriteToFileToolDirective,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,