UNPKG

@xsai/shared-chat

Version:

extra-small AI SDK.

85 lines (79 loc) 2.57 kB
import { requestURL, requestHeaders, requestBody, clean, responseCatch } from '@xsai/shared'; const chat = async (options) => (options.fetch ?? globalThis.fetch)(requestURL("chat/completions", options.baseURL), { body: requestBody({ ...options, tools: options.tools?.map((tool) => ({ function: clean({ ...tool.function, returns: void 0 }), type: "function" })) }), headers: requestHeaders({ "Content-Type": "application/json", ...options.headers }, options.apiKey), method: "POST", signal: options.abortSignal }).then(responseCatch); const determineStepType = ({ finishReason, maxSteps, stepsLength, toolCallsLength }) => { if (stepsLength === 0) { return "initial"; } else if (stepsLength < maxSteps) { if (toolCallsLength > 0 && finishReason === "tool_calls") return "tool-result"; else if (!["error", "length"].includes(finishReason)) return "continue"; } return "done"; }; const wrapToolResult = (result) => { if (typeof result === "string") return result; if (Array.isArray(result)) { if (result.every((item) => !!(typeof item === "object" && "type" in item && ["file", "image_url", "input_audio", "text"].includes(item.type)))) { return result; } } return JSON.stringify(result); }; const executeTool = async ({ abortSignal, messages, toolCall, tools }) => { const tool = tools?.find((tool2) => tool2.function.name === toolCall.function.name); if (!tool) { const availableTools = tools?.map((tool2) => tool2.function.name); const availableToolsErrorMsg = availableTools == null || availableTools.length === 0 ? "No tools are available" : `Available tools: ${availableTools.join(", ")}`; throw new Error(`Model tried to call unavailable tool "${toolCall.function.name}", ${availableToolsErrorMsg}.`); } const toolCallId = toolCall.id; const toolName = toolCall.function.name; const parsedArgs = JSON.parse(toolCall.function.arguments); const result = wrapToolResult(await tool.execute(parsedArgs, { abortSignal, messages, toolCallId })); const completionToolCall = { args: toolCall.function.arguments, toolCallId, toolCallType: toolCall.type, toolName }; const completionToolResult = { args: parsedArgs, result, toolCallId, toolName }; const message = { content: result, role: "tool", tool_call_id: toolCallId }; return { completionToolCall, completionToolResult, message }; }; export { chat, determineStepType, executeTool };