@xsai/shared-chat
Version:
extra-small AI SDK.
85 lines (79 loc) • 2.57 kB
JavaScript
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 };