mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-21 04:41:16 -05:00
Refactor tool call to tool use
This commit is contained in:
@@ -31,11 +31,11 @@ import { arePathsEqual, getReadablePath } from "../utils/path"
|
|||||||
import {
|
import {
|
||||||
AssistantMessageContent,
|
AssistantMessageContent,
|
||||||
TextContent,
|
TextContent,
|
||||||
ToolCall,
|
|
||||||
ToolCallName,
|
|
||||||
toolCallNames,
|
|
||||||
ToolParamName,
|
ToolParamName,
|
||||||
toolParamNames,
|
toolParamNames,
|
||||||
|
ToolUse,
|
||||||
|
ToolUseName,
|
||||||
|
toolUseNames,
|
||||||
} from "./prompts/AssistantMessage"
|
} from "./prompts/AssistantMessage"
|
||||||
import { parseMentions } from "./mentions"
|
import { parseMentions } from "./mentions"
|
||||||
import { formatResponse } from "./prompts/responses"
|
import { formatResponse } from "./prompts/responses"
|
||||||
@@ -1140,7 +1140,7 @@ export class ClaudeDev {
|
|||||||
case "text":
|
case "text":
|
||||||
await this.say("text", block.content, undefined, block.partial)
|
await this.say("text", block.content, undefined, block.partial)
|
||||||
break
|
break
|
||||||
case "tool_call":
|
case "tool_use":
|
||||||
const toolDescription = () => {
|
const toolDescription = () => {
|
||||||
switch (block.name) {
|
switch (block.name) {
|
||||||
case "execute_command":
|
case "execute_command":
|
||||||
@@ -2058,9 +2058,9 @@ export class ClaudeDev {
|
|||||||
content: "",
|
content: "",
|
||||||
partial: true,
|
partial: true,
|
||||||
}
|
}
|
||||||
let toolCalls: ToolCall[] = []
|
let toolUses: ToolUse[] = []
|
||||||
|
|
||||||
let currentToolCall: ToolCall | undefined = undefined
|
let currentToolUse: ToolUse | undefined = undefined
|
||||||
let currentParamName: ToolParamName | undefined = undefined
|
let currentParamName: ToolParamName | undefined = undefined
|
||||||
let currentParamValueLines: string[] = []
|
let currentParamValueLines: string[] = []
|
||||||
let textContentLines: string[] = []
|
let textContentLines: string[] = []
|
||||||
@@ -2090,42 +2090,47 @@ export class ClaudeDev {
|
|||||||
for (const line of rawLines) {
|
for (const line of rawLines) {
|
||||||
const trimmed = line.trim()
|
const trimmed = line.trim()
|
||||||
// if currenttoolcall or currentparamname look for closing tag, more efficient and safe
|
// if currenttoolcall or currentparamname look for closing tag, more efficient and safe
|
||||||
if (currentToolCall && currentParamName && trimmed === `</${currentParamName}>`) {
|
if (currentToolUse && currentParamName && trimmed === `</${currentParamName}>`) {
|
||||||
// End of a tool parameter
|
// End of a tool parameter
|
||||||
currentToolCall.params[currentParamName] = currentParamValueLines.join("\n")
|
currentToolUse.params[currentParamName] = currentParamValueLines.join("\n")
|
||||||
currentParamName = undefined
|
currentParamName = undefined
|
||||||
currentParamValueLines = []
|
currentParamValueLines = []
|
||||||
// currentParamValue = undefined
|
// currentParamValue = undefined
|
||||||
continue
|
continue
|
||||||
} else if (currentToolCall && !currentParamName && trimmed === `</${currentToolCall.name}>`) {
|
} else if (currentToolUse && !currentParamName && trimmed === `</${currentToolUse.name}>`) {
|
||||||
// End of a tool call
|
// End of a tool call
|
||||||
currentToolCall.partial = false
|
currentToolUse.partial = false
|
||||||
toolCalls.push(currentToolCall)
|
toolUses.push(currentToolUse)
|
||||||
currentToolCall = undefined
|
currentToolUse = undefined
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (!currentParamName && trimmed.startsWith("<") && trimmed.endsWith(">")) {
|
if (!currentParamName && trimmed.startsWith("<") && trimmed.endsWith(">")) {
|
||||||
const tag = trimmed.slice(1, -1)
|
const tag = trimmed.slice(1, -1)
|
||||||
if (toolCallNames.includes(tag as ToolCallName)) {
|
if (toolUseNames.includes(tag as ToolUseName)) {
|
||||||
// Start of a new tool call
|
// Start of a new tool call
|
||||||
currentToolCall = { type: "tool_call", name: tag as ToolCallName, params: {}, partial: true }
|
currentToolUse = {
|
||||||
|
type: "tool_use",
|
||||||
|
name: tag as ToolUseName,
|
||||||
|
params: {},
|
||||||
|
partial: true,
|
||||||
|
} satisfies ToolUse
|
||||||
// This also indicates the end of the text content
|
// This also indicates the end of the text content
|
||||||
textContent.partial = false
|
textContent.partial = false
|
||||||
continue
|
continue
|
||||||
} else if (currentToolCall && toolParamNames.includes(tag as ToolParamName)) {
|
} else if (currentToolUse && toolParamNames.includes(tag as ToolParamName)) {
|
||||||
// Start of a parameter
|
// Start of a parameter
|
||||||
currentParamName = tag as ToolParamName
|
currentParamName = tag as ToolParamName
|
||||||
// currentToolCall.params[currentParamName] = ""
|
// currentToolUse.params[currentParamName] = ""
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentToolCall && !currentParamName) {
|
if (currentToolUse && !currentParamName) {
|
||||||
// current tool doesn't have a param match yet, it's likely partial so ignore
|
// current tool doesn't have a param match yet, it's likely partial so ignore
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentToolCall && currentParamName) {
|
if (currentToolUse && currentParamName) {
|
||||||
// add line to current param value
|
// add line to current param value
|
||||||
currentParamValueLines.push(line)
|
currentParamValueLines.push(line)
|
||||||
continue
|
continue
|
||||||
@@ -2137,18 +2142,18 @@ export class ClaudeDev {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentToolCall) {
|
if (currentToolUse) {
|
||||||
// stream did not complete tool call, add it as partial
|
// stream did not complete tool call, add it as partial
|
||||||
if (currentParamName) {
|
if (currentParamName) {
|
||||||
// tool call has a parameter that was not completed
|
// tool call has a parameter that was not completed
|
||||||
currentToolCall.params[currentParamName] = currentParamValueLines.join("\n")
|
currentToolUse.params[currentParamName] = currentParamValueLines.join("\n")
|
||||||
}
|
}
|
||||||
toolCalls.push(currentToolCall)
|
toolUses.push(currentToolUse)
|
||||||
}
|
}
|
||||||
|
|
||||||
textContent.content = textContentLines.join("\n")
|
textContent.content = textContentLines.join("\n")
|
||||||
const prevLength = this.assistantMessageContent.length
|
const prevLength = this.assistantMessageContent.length
|
||||||
this.assistantMessageContent = [textContent, ...toolCalls]
|
this.assistantMessageContent = [textContent, ...toolUses]
|
||||||
if (this.assistantMessageContent.length > prevLength) {
|
if (this.assistantMessageContent.length > prevLength) {
|
||||||
this.userMessageContentReady = false // new content we need to present, reset to false in case previous content set this to true
|
this.userMessageContentReady = false // new content we need to present, reset to false in case previous content set this to true
|
||||||
}
|
}
|
||||||
@@ -2321,7 +2326,7 @@ export class ClaudeDev {
|
|||||||
await pWaitFor(() => this.userMessageContentReady)
|
await pWaitFor(() => this.userMessageContentReady)
|
||||||
|
|
||||||
// if the model did not tool use, then we need to tell it to either use a tool or attempt_completion
|
// if the model did not tool use, then we need to tell it to either use a tool or attempt_completion
|
||||||
const didToolUse = this.assistantMessageContent.some((block) => block.type === "tool_call")
|
const didToolUse = this.assistantMessageContent.some((block) => block.type === "tool_use")
|
||||||
if (!didToolUse) {
|
if (!didToolUse) {
|
||||||
this.userMessageContent.push({
|
this.userMessageContent.push({
|
||||||
type: "text",
|
type: "text",
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
// export interface AssistantMessage {
|
export type AssistantMessageContent = TextContent | ToolUse
|
||||||
// textContent: TextContent
|
|
||||||
// toolCalls: ToolCall[]
|
|
||||||
// }
|
|
||||||
|
|
||||||
export type AssistantMessageContent = TextContent | ToolCall
|
|
||||||
|
|
||||||
export interface TextContent {
|
export interface TextContent {
|
||||||
type: "text"
|
type: "text"
|
||||||
@@ -11,7 +6,7 @@ export interface TextContent {
|
|||||||
partial: boolean
|
partial: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export const toolCallNames = [
|
export const toolUseNames = [
|
||||||
"execute_command",
|
"execute_command",
|
||||||
"read_file",
|
"read_file",
|
||||||
"write_to_file",
|
"write_to_file",
|
||||||
@@ -24,7 +19,7 @@ export const toolCallNames = [
|
|||||||
] as const
|
] as const
|
||||||
|
|
||||||
// Converts array of tool call names into a union type ("execute_command" | "read_file" | ...)
|
// Converts array of tool call names into a union type ("execute_command" | "read_file" | ...)
|
||||||
export type ToolCallName = (typeof toolCallNames)[number]
|
export type ToolUseName = (typeof toolUseNames)[number]
|
||||||
|
|
||||||
export const toolParamNames = [
|
export const toolParamNames = [
|
||||||
"command",
|
"command",
|
||||||
@@ -40,56 +35,56 @@ export const toolParamNames = [
|
|||||||
|
|
||||||
export type ToolParamName = (typeof toolParamNames)[number]
|
export type ToolParamName = (typeof toolParamNames)[number]
|
||||||
|
|
||||||
export interface ToolCall {
|
export interface ToolUse {
|
||||||
type: "tool_call"
|
type: "tool_use"
|
||||||
name: ToolCallName
|
name: ToolUseName
|
||||||
// params is a partial record, allowing only some or none of the possible parameters to be used
|
// params is a partial record, allowing only some or none of the possible parameters to be used
|
||||||
params: Partial<Record<ToolParamName, string>>
|
params: Partial<Record<ToolParamName, string>>
|
||||||
partial: boolean
|
partial: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ExecuteCommandToolCall extends ToolCall {
|
export interface ExecuteCommandToolUse extends ToolUse {
|
||||||
name: "execute_command"
|
name: "execute_command"
|
||||||
// Pick<Record<ToolParamName, string>, "command"> makes "command" required, but Partial<> makes it optional
|
// Pick<Record<ToolParamName, string>, "command"> makes "command" required, but Partial<> makes it optional
|
||||||
params: Partial<Pick<Record<ToolParamName, string>, "command">>
|
params: Partial<Pick<Record<ToolParamName, string>, "command">>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ReadFileToolCall extends ToolCall {
|
export interface ReadFileToolUse extends ToolUse {
|
||||||
name: "read_file"
|
name: "read_file"
|
||||||
params: Partial<Pick<Record<ToolParamName, string>, "path">>
|
params: Partial<Pick<Record<ToolParamName, string>, "path">>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface WriteToFileToolCall extends ToolCall {
|
export interface WriteToFileToolUse extends ToolUse {
|
||||||
name: "write_to_file"
|
name: "write_to_file"
|
||||||
params: Partial<Pick<Record<ToolParamName, string>, "path" | "content">>
|
params: Partial<Pick<Record<ToolParamName, string>, "path" | "content">>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SearchFilesToolCall extends ToolCall {
|
export interface SearchFilesToolUse extends ToolUse {
|
||||||
name: "search_files"
|
name: "search_files"
|
||||||
params: Partial<Pick<Record<ToolParamName, string>, "path" | "regex" | "file_pattern">>
|
params: Partial<Pick<Record<ToolParamName, string>, "path" | "regex" | "file_pattern">>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ListFilesToolCall extends ToolCall {
|
export interface ListFilesToolUse extends ToolUse {
|
||||||
name: "list_files"
|
name: "list_files"
|
||||||
params: Partial<Pick<Record<ToolParamName, string>, "path" | "recursive">>
|
params: Partial<Pick<Record<ToolParamName, string>, "path" | "recursive">>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ListCodeDefinitionNamesToolCall extends ToolCall {
|
export interface ListCodeDefinitionNamesToolUse extends ToolUse {
|
||||||
name: "list_code_definition_names"
|
name: "list_code_definition_names"
|
||||||
params: Partial<Pick<Record<ToolParamName, string>, "path">>
|
params: Partial<Pick<Record<ToolParamName, string>, "path">>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface InspectSiteToolCall extends ToolCall {
|
export interface InspectSiteToolUse extends ToolUse {
|
||||||
name: "inspect_site"
|
name: "inspect_site"
|
||||||
params: Partial<Pick<Record<ToolParamName, string>, "url">>
|
params: Partial<Pick<Record<ToolParamName, string>, "url">>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AskFollowupQuestionToolCall extends ToolCall {
|
export interface AskFollowupQuestionToolUse extends ToolUse {
|
||||||
name: "ask_followup_question"
|
name: "ask_followup_question"
|
||||||
params: Partial<Pick<Record<ToolParamName, string>, "question">>
|
params: Partial<Pick<Record<ToolParamName, string>, "question">>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AttemptCompletionToolCall extends ToolCall {
|
export interface AttemptCompletionToolUse extends ToolUse {
|
||||||
name: "attempt_completion"
|
name: "attempt_completion"
|
||||||
params: Partial<Pick<Record<ToolParamName, string>, "result" | "command">>
|
params: Partial<Pick<Record<ToolParamName, string>, "result" | "command">>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user