You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
4.0 KiB
TypeScript
116 lines
4.0 KiB
TypeScript
import { formatDataStreamPart, Message } from "ai";
|
|
import tools from "./tools.js";
|
|
import { DelegateParams } from "./tools.js";
|
|
|
|
export function singleSpace(str: string) {
|
|
return str.replace(/\s+/g, " ");
|
|
}
|
|
|
|
export async function processPendingToolCalls(
|
|
messages: Message[],
|
|
dataStreamWriter: any
|
|
) {
|
|
const lastMessage = messages[messages.length - 1];
|
|
if (!lastMessage) {
|
|
return;
|
|
}
|
|
if (!lastMessage.parts) {
|
|
return;
|
|
}
|
|
|
|
console.log("Processing pending tool calls in message:", lastMessage.id);
|
|
|
|
/** Execute all the pending tool calls: */
|
|
lastMessage.parts = await Promise.all(
|
|
lastMessage.parts?.map(async (part: any) => {
|
|
// Check if this part has a tool invocation
|
|
if (part.type === "tool-invocation" && part.toolInvocation) {
|
|
const toolInvocation = part.toolInvocation as any;
|
|
console.log("Found tool invocation:", toolInvocation);
|
|
|
|
if (toolInvocation.state === "result") {
|
|
// Check if user approved the tool call
|
|
if (toolInvocation.result === "yes") {
|
|
try {
|
|
// Get the tool function
|
|
const toolName = toolInvocation.toolName || toolInvocation.name;
|
|
console.log(`Executing tool: ${toolName}`);
|
|
|
|
const toolFunction = tools[toolName as keyof typeof tools];
|
|
|
|
if (toolFunction) {
|
|
// Extract parameters from the tool invocation
|
|
let parameters = {};
|
|
try {
|
|
if (toolInvocation.parameters) {
|
|
parameters = JSON.parse(toolInvocation.parameters);
|
|
} else if (toolInvocation.args) {
|
|
parameters = toolInvocation.args;
|
|
}
|
|
console.log(`Tool parameters:`, parameters);
|
|
} catch (e) {
|
|
console.error("Error parsing tool parameters:", e);
|
|
}
|
|
|
|
// Call the tool function with the parameters
|
|
console.log(
|
|
`Calling tool function with parameters:`,
|
|
parameters
|
|
);
|
|
const result = await toolFunction(parameters as DelegateParams);
|
|
console.log(`Tool result:`, result);
|
|
|
|
// forward updated tool result to the client:
|
|
dataStreamWriter.write(
|
|
formatDataStreamPart("tool_result", {
|
|
toolCallId: toolInvocation.toolCallId,
|
|
result,
|
|
})
|
|
);
|
|
|
|
// update the message part:
|
|
return {
|
|
...part,
|
|
toolInvocation: { ...toolInvocation, result },
|
|
};
|
|
|
|
// // Set the result
|
|
// toolInvocation.result = result;
|
|
|
|
// // Add a new message with the tool result
|
|
// if (result) {
|
|
// messages.push({
|
|
// id: `tool-result-${Date.now()}`,
|
|
// role: "assistant",
|
|
// content: `Tool Result: ${result}`,
|
|
// parts: [
|
|
// {
|
|
// type: "text",
|
|
// text: `Tool Result: ${result}`,
|
|
// },
|
|
// ],
|
|
// });
|
|
// }
|
|
} else {
|
|
const errorMsg = `Error: Tool '${toolName}' not found`;
|
|
console.error(errorMsg);
|
|
toolInvocation.result = errorMsg;
|
|
}
|
|
} catch (error: unknown) {
|
|
const errorMessage =
|
|
error instanceof Error ? error.message : "Unknown error";
|
|
console.error("Error executing tool:", error);
|
|
toolInvocation.result = `Error executing tool: ${errorMessage}`;
|
|
}
|
|
} else if (toolInvocation.result === "no") {
|
|
toolInvocation.result = "Error: User denied tool call.";
|
|
}
|
|
}
|
|
}
|
|
return part;
|
|
}) ?? []
|
|
);
|
|
|
|
console.log("Finished processing tool calls. Updated messages:", messages);
|
|
}
|