Move list_code_definition_names to a tool file (#2097)

This commit is contained in:
Matt Rubens 2025-03-30 01:21:01 -04:00 committed by GitHub
parent bdb668b68b
commit da2af71106
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 80 additions and 60 deletions

View file

@ -89,6 +89,7 @@ import { writeToFileTool } from "./tools/writeToFileTool"
import { applyDiffTool } from "./tools/applyDiffTool"
import { insertContentTool } from "./tools/insertContentTool"
import { searchAndReplaceTool } from "./tools/searchAndReplaceTool"
import { listCodeDefinitionNamesTool } from "./tools/listCodeDefinitionNamesTool"
export type ToolResponse = string | Array<Anthropic.TextBlockParam | Anthropic.ImageBlockParam>
type UserContent = Array<Anthropic.Messages.ContentBlockParam>
@ -1596,66 +1597,16 @@ export class Cline extends EventEmitter<ClineEvents> {
case "list_files":
await listFilesTool(this, block, askApproval, handleError, pushToolResult, removeClosingTag)
break
case "list_code_definition_names": {
const relPath: string | undefined = block.params.path
const sharedMessageProps: ClineSayTool = {
tool: "listCodeDefinitionNames",
path: getReadablePath(this.cwd, removeClosingTag("path", relPath)),
}
try {
if (block.partial) {
const partialMessage = JSON.stringify({
...sharedMessageProps,
content: "",
} satisfies ClineSayTool)
await this.ask("tool", partialMessage, block.partial).catch(() => {})
break
} else {
if (!relPath) {
this.consecutiveMistakeCount++
pushToolResult(
await this.sayAndCreateMissingParamError("list_code_definition_names", "path"),
)
break
}
this.consecutiveMistakeCount = 0
const absolutePath = path.resolve(this.cwd, relPath)
let result: string
try {
const stats = await fs.stat(absolutePath)
if (stats.isFile()) {
const fileResult = await parseSourceCodeDefinitionsForFile(
absolutePath,
this.rooIgnoreController,
)
result = fileResult ?? "No source code definitions found in this file."
} else if (stats.isDirectory()) {
result = await parseSourceCodeForDefinitionsTopLevel(
absolutePath,
this.rooIgnoreController,
)
} else {
result = "The specified path is neither a file nor a directory."
}
} catch {
result = `${absolutePath}: does not exist or cannot be accessed.`
}
const completeMessage = JSON.stringify({
...sharedMessageProps,
content: result,
} satisfies ClineSayTool)
const didApprove = await askApproval("tool", completeMessage)
if (!didApprove) {
break
}
pushToolResult(result)
break
}
} catch (error) {
await handleError("parsing source code definitions", error)
break
}
}
case "list_code_definition_names":
await listCodeDefinitionNamesTool(
this,
block,
askApproval,
handleError,
pushToolResult,
removeClosingTag,
)
break
case "search_files": {
const relDirPath: string | undefined = block.params.path
const regex: string | undefined = block.params.regex

View file

@ -0,0 +1,69 @@
import { ToolUse } from "../assistant-message"
import { HandleError, PushToolResult, RemoveClosingTag } from "./types"
import { Cline } from "../Cline"
import { AskApproval } from "./types"
import { ClineSayTool } from "../../shared/ExtensionMessage"
import { getReadablePath } from "../../utils/path"
import path from "path"
import fs from "fs/promises"
import { parseSourceCodeForDefinitionsTopLevel, parseSourceCodeDefinitionsForFile } from "../../services/tree-sitter"
export async function listCodeDefinitionNamesTool(
cline: Cline,
block: ToolUse,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,
removeClosingTag: RemoveClosingTag,
) {
const relPath: string | undefined = block.params.path
const sharedMessageProps: ClineSayTool = {
tool: "listCodeDefinitionNames",
path: getReadablePath(cline.cwd, removeClosingTag("path", relPath)),
}
try {
if (block.partial) {
const partialMessage = JSON.stringify({
...sharedMessageProps,
content: "",
} satisfies ClineSayTool)
await cline.ask("tool", partialMessage, block.partial).catch(() => {})
return
} else {
if (!relPath) {
cline.consecutiveMistakeCount++
pushToolResult(await cline.sayAndCreateMissingParamError("list_code_definition_names", "path"))
return
}
cline.consecutiveMistakeCount = 0
const absolutePath = path.resolve(cline.cwd, relPath)
let result: string
try {
const stats = await fs.stat(absolutePath)
if (stats.isFile()) {
const fileResult = await parseSourceCodeDefinitionsForFile(absolutePath, cline.rooIgnoreController)
result = fileResult ?? "No source code definitions found in cline file."
} else if (stats.isDirectory()) {
result = await parseSourceCodeForDefinitionsTopLevel(absolutePath, cline.rooIgnoreController)
} else {
result = "The specified path is neither a file nor a directory."
}
} catch {
result = `${absolutePath}: does not exist or cannot be accessed.`
}
const completeMessage = JSON.stringify({
...sharedMessageProps,
content: result,
} satisfies ClineSayTool)
const didApprove = await askApproval("tool", completeMessage)
if (!didApprove) {
return
}
pushToolResult(result)
return
}
} catch (error) {
await handleError("parsing source code definitions", error)
return
}
}