Roo-Code/src/core/tools/SearchFilesTool.ts
Hannes Rudolph 8de9337e63
chore: remove XML tool calling support (#10841)
Co-authored-by: daniel-lxs <ricciodaniel98@gmail.com>
Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com>
2026-01-20 20:25:08 -05:00

95 lines
2.9 KiB
TypeScript

import path from "path"
import { type ClineSayTool } from "@roo-code/types"
import { Task } from "../task/Task"
import { getReadablePath } from "../../utils/path"
import { isPathOutsideWorkspace } from "../../utils/pathUtils"
import { regexSearchFiles } from "../../services/ripgrep"
import type { ToolUse } from "../../shared/tools"
import { BaseTool, ToolCallbacks } from "./BaseTool"
interface SearchFilesParams {
path: string
regex: string
file_pattern?: string | null
}
export class SearchFilesTool extends BaseTool<"search_files"> {
readonly name = "search_files" as const
async execute(params: SearchFilesParams, task: Task, callbacks: ToolCallbacks): Promise<void> {
const { askApproval, handleError, pushToolResult } = callbacks
const relDirPath = params.path
const regex = params.regex
const filePattern = params.file_pattern || undefined
if (!relDirPath) {
task.consecutiveMistakeCount++
task.recordToolError("search_files")
task.didToolFailInCurrentTurn = true
pushToolResult(await task.sayAndCreateMissingParamError("search_files", "path"))
return
}
if (!regex) {
task.consecutiveMistakeCount++
task.recordToolError("search_files")
task.didToolFailInCurrentTurn = true
pushToolResult(await task.sayAndCreateMissingParamError("search_files", "regex"))
return
}
task.consecutiveMistakeCount = 0
const absolutePath = path.resolve(task.cwd, relDirPath)
const isOutsideWorkspace = isPathOutsideWorkspace(absolutePath)
const sharedMessageProps: ClineSayTool = {
tool: "searchFiles",
path: getReadablePath(task.cwd, relDirPath),
regex: regex,
filePattern: filePattern,
isOutsideWorkspace,
}
try {
const results = await regexSearchFiles(task.cwd, absolutePath, regex, filePattern, task.rooIgnoreController)
const completeMessage = JSON.stringify({ ...sharedMessageProps, content: results } satisfies ClineSayTool)
const didApprove = await askApproval("tool", completeMessage)
if (!didApprove) {
return
}
pushToolResult(results)
} catch (error) {
await handleError("searching files", error as Error)
}
}
override async handlePartial(task: Task, block: ToolUse<"search_files">): Promise<void> {
const relDirPath = block.params.path
const regex = block.params.regex
const filePattern = block.params.file_pattern
const absolutePath = relDirPath ? path.resolve(task.cwd, relDirPath) : task.cwd
const isOutsideWorkspace = isPathOutsideWorkspace(absolutePath)
const sharedMessageProps: ClineSayTool = {
tool: "searchFiles",
path: getReadablePath(task.cwd, relDirPath ?? ""),
regex: regex ?? "",
filePattern: filePattern ?? "",
isOutsideWorkspace,
}
const partialMessage = JSON.stringify({ ...sharedMessageProps, content: "" } satisfies ClineSayTool)
await task.ask("tool", partialMessage, block.partial).catch(() => {})
}
}
export const searchFilesTool = new SearchFilesTool()