Browse Source

Refactor tool call to tool use

Saoud Rizwan 1 year ago
parent
commit
204116c6d3
2 changed files with 43 additions and 43 deletions
  1. 28 23
      src/core/ClaudeDev.ts
  2. 15 20
      src/core/prompts/AssistantMessage.ts

+ 28 - 23
src/core/ClaudeDev.ts

@@ -31,11 +31,11 @@ import { arePathsEqual, getReadablePath } from "../utils/path"
 import {
 	AssistantMessageContent,
 	TextContent,
-	ToolCall,
-	ToolCallName,
-	toolCallNames,
 	ToolParamName,
 	toolParamNames,
+	ToolUse,
+	ToolUseName,
+	toolUseNames,
 } from "./prompts/AssistantMessage"
 import { parseMentions } from "./mentions"
 import { formatResponse } from "./prompts/responses"
@@ -1140,7 +1140,7 @@ export class ClaudeDev {
 			case "text":
 				await this.say("text", block.content, undefined, block.partial)
 				break
-			case "tool_call":
+			case "tool_use":
 				const toolDescription = () => {
 					switch (block.name) {
 						case "execute_command":
@@ -2058,9 +2058,9 @@ export class ClaudeDev {
 			content: "",
 			partial: true,
 		}
-		let toolCalls: ToolCall[] = []
+		let toolUses: ToolUse[] = []
 
-		let currentToolCall: ToolCall | undefined = undefined
+		let currentToolUse: ToolUse | undefined = undefined
 		let currentParamName: ToolParamName | undefined = undefined
 		let currentParamValueLines: string[] = []
 		let textContentLines: string[] = []
@@ -2090,42 +2090,47 @@ export class ClaudeDev {
 		for (const line of rawLines) {
 			const trimmed = line.trim()
 			// 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
-				currentToolCall.params[currentParamName] = currentParamValueLines.join("\n")
+				currentToolUse.params[currentParamName] = currentParamValueLines.join("\n")
 				currentParamName = undefined
 				currentParamValueLines = []
 				// currentParamValue = undefined
 				continue
-			} else if (currentToolCall && !currentParamName && trimmed === `</${currentToolCall.name}>`) {
+			} else if (currentToolUse && !currentParamName && trimmed === `</${currentToolUse.name}>`) {
 				// End of a tool call
-				currentToolCall.partial = false
-				toolCalls.push(currentToolCall)
-				currentToolCall = undefined
+				currentToolUse.partial = false
+				toolUses.push(currentToolUse)
+				currentToolUse = undefined
 				continue
 			}
 			if (!currentParamName && trimmed.startsWith("<") && trimmed.endsWith(">")) {
 				const tag = trimmed.slice(1, -1)
-				if (toolCallNames.includes(tag as ToolCallName)) {
+				if (toolUseNames.includes(tag as ToolUseName)) {
 					// 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
 					textContent.partial = false
 					continue
-				} else if (currentToolCall && toolParamNames.includes(tag as ToolParamName)) {
+				} else if (currentToolUse && toolParamNames.includes(tag as ToolParamName)) {
 					// Start of a parameter
 					currentParamName = tag as ToolParamName
-					// currentToolCall.params[currentParamName] = ""
+					// currentToolUse.params[currentParamName] = ""
 					continue
 				}
 			}
 
-			if (currentToolCall && !currentParamName) {
+			if (currentToolUse && !currentParamName) {
 				// current tool doesn't have a param match yet, it's likely partial so ignore
 				continue
 			}
 
-			if (currentToolCall && currentParamName) {
+			if (currentToolUse && currentParamName) {
 				// add line to current param value
 				currentParamValueLines.push(line)
 				continue
@@ -2137,18 +2142,18 @@ export class ClaudeDev {
 			}
 		}
 
-		if (currentToolCall) {
+		if (currentToolUse) {
 			// stream did not complete tool call, add it as partial
 			if (currentParamName) {
 				// 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")
 		const prevLength = this.assistantMessageContent.length
-		this.assistantMessageContent = [textContent, ...toolCalls]
+		this.assistantMessageContent = [textContent, ...toolUses]
 		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
 		}
@@ -2321,7 +2326,7 @@ export class ClaudeDev {
 				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
-				const didToolUse = this.assistantMessageContent.some((block) => block.type === "tool_call")
+				const didToolUse = this.assistantMessageContent.some((block) => block.type === "tool_use")
 				if (!didToolUse) {
 					this.userMessageContent.push({
 						type: "text",

+ 15 - 20
src/core/prompts/AssistantMessage.ts

@@ -1,9 +1,4 @@
-// export interface AssistantMessage {
-// 	textContent: TextContent
-// 	toolCalls: ToolCall[]
-// }
-
-export type AssistantMessageContent = TextContent | ToolCall
+export type AssistantMessageContent = TextContent | ToolUse
 
 export interface TextContent {
 	type: "text"
@@ -11,7 +6,7 @@ export interface TextContent {
 	partial: boolean
 }
 
-export const toolCallNames = [
+export const toolUseNames = [
 	"execute_command",
 	"read_file",
 	"write_to_file",
@@ -24,7 +19,7 @@ export const toolCallNames = [
 ] as const
 
 // 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 = [
 	"command",
@@ -40,56 +35,56 @@ export const toolParamNames = [
 
 export type ToolParamName = (typeof toolParamNames)[number]
 
-export interface ToolCall {
-	type: "tool_call"
-	name: ToolCallName
+export interface ToolUse {
+	type: "tool_use"
+	name: ToolUseName
 	// params is a partial record, allowing only some or none of the possible parameters to be used
 	params: Partial<Record<ToolParamName, string>>
 	partial: boolean
 }
 
-interface ExecuteCommandToolCall extends ToolCall {
+export interface ExecuteCommandToolUse extends ToolUse {
 	name: "execute_command"
 	// Pick<Record<ToolParamName, string>, "command"> makes "command" required, but Partial<> makes it optional
 	params: Partial<Pick<Record<ToolParamName, string>, "command">>
 }
 
-interface ReadFileToolCall extends ToolCall {
+export interface ReadFileToolUse extends ToolUse {
 	name: "read_file"
 	params: Partial<Pick<Record<ToolParamName, string>, "path">>
 }
 
-interface WriteToFileToolCall extends ToolCall {
+export interface WriteToFileToolUse extends ToolUse {
 	name: "write_to_file"
 	params: Partial<Pick<Record<ToolParamName, string>, "path" | "content">>
 }
 
-interface SearchFilesToolCall extends ToolCall {
+export interface SearchFilesToolUse extends ToolUse {
 	name: "search_files"
 	params: Partial<Pick<Record<ToolParamName, string>, "path" | "regex" | "file_pattern">>
 }
 
-interface ListFilesToolCall extends ToolCall {
+export interface ListFilesToolUse extends ToolUse {
 	name: "list_files"
 	params: Partial<Pick<Record<ToolParamName, string>, "path" | "recursive">>
 }
 
-interface ListCodeDefinitionNamesToolCall extends ToolCall {
+export interface ListCodeDefinitionNamesToolUse extends ToolUse {
 	name: "list_code_definition_names"
 	params: Partial<Pick<Record<ToolParamName, string>, "path">>
 }
 
-interface InspectSiteToolCall extends ToolCall {
+export interface InspectSiteToolUse extends ToolUse {
 	name: "inspect_site"
 	params: Partial<Pick<Record<ToolParamName, string>, "url">>
 }
 
-interface AskFollowupQuestionToolCall extends ToolCall {
+export interface AskFollowupQuestionToolUse extends ToolUse {
 	name: "ask_followup_question"
 	params: Partial<Pick<Record<ToolParamName, string>, "question">>
 }
 
-interface AttemptCompletionToolCall extends ToolCall {
+export interface AttemptCompletionToolUse extends ToolUse {
 	name: "attempt_completion"
 	params: Partial<Pick<Record<ToolParamName, string>, "result" | "command">>
 }