"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isChatCompletionFunctionTool = isChatCompletionFunctionTool; exports.makeParseableResponseFormat = makeParseableResponseFormat; exports.makeParseableTextFormat = makeParseableTextFormat; exports.isAutoParsableResponseFormat = isAutoParsableResponseFormat; exports.makeParseableTool = makeParseableTool; exports.isAutoParsableTool = isAutoParsableTool; exports.maybeParseChatCompletion = maybeParseChatCompletion; exports.parseChatCompletion = parseChatCompletion; exports.shouldParseToolCall = shouldParseToolCall; exports.hasAutoParseableInput = hasAutoParseableInput; exports.assertToolCallsAreChatCompletionFunctionToolCalls = assertToolCallsAreChatCompletionFunctionToolCalls; exports.validateInputTools = validateInputTools; const error_1 = require("../error.js"); function isChatCompletionFunctionTool(tool) { return tool !== undefined && 'function' in tool && tool.function !== undefined; } function makeParseableResponseFormat(response_format, parser) { const obj = { ...response_format }; Object.defineProperties(obj, { $brand: { value: 'auto-parseable-response-format', enumerable: false, }, $parseRaw: { value: parser, enumerable: false, }, }); return obj; } function makeParseableTextFormat(response_format, parser) { const obj = { ...response_format }; Object.defineProperties(obj, { $brand: { value: 'auto-parseable-response-format', enumerable: false, }, $parseRaw: { value: parser, enumerable: false, }, }); return obj; } function isAutoParsableResponseFormat(response_format) { return response_format?.['$brand'] === 'auto-parseable-response-format'; } function makeParseableTool(tool, { parser, callback, }) { const obj = { ...tool }; Object.defineProperties(obj, { $brand: { value: 'auto-parseable-tool', enumerable: false, }, $parseRaw: { value: parser, enumerable: false, }, $callback: { value: callback, enumerable: false, }, }); return obj; } function isAutoParsableTool(tool) { return tool?.['$brand'] === 'auto-parseable-tool'; } function maybeParseChatCompletion(completion, params) { if (!params || !hasAutoParseableInput(params)) { return { ...completion, choices: completion.choices.map((choice) => { assertToolCallsAreChatCompletionFunctionToolCalls(choice.message.tool_calls); return { ...choice, message: { ...choice.message, parsed: null, ...(choice.message.tool_calls ? { tool_calls: choice.message.tool_calls, } : undefined), }, }; }), }; } return parseChatCompletion(completion, params); } function parseChatCompletion(completion, params) { const choices = completion.choices.map((choice) => { if (choice.finish_reason === 'length') { throw new error_1.LengthFinishReasonError(); } if (choice.finish_reason === 'content_filter') { throw new error_1.ContentFilterFinishReasonError(); } assertToolCallsAreChatCompletionFunctionToolCalls(choice.message.tool_calls); return { ...choice, message: { ...choice.message, ...(choice.message.tool_calls ? { tool_calls: choice.message.tool_calls?.map((toolCall) => parseToolCall(params, toolCall)) ?? undefined, } : undefined), parsed: choice.message.content && !choice.message.refusal ? parseResponseFormat(params, choice.message.content) : null, }, }; }); return { ...completion, choices }; } function parseResponseFormat(params, content) { if (params.response_format?.type !== 'json_schema') { return null; } if (params.response_format?.type === 'json_schema') { if ('$parseRaw' in params.response_format) { const response_format = params.response_format; return response_format.$parseRaw(content); } return JSON.parse(content); } return null; } function parseToolCall(params, toolCall) { const inputTool = params.tools?.find((inputTool) => isChatCompletionFunctionTool(inputTool) && inputTool.function?.name === toolCall.function.name); // TS doesn't narrow based on isChatCompletionTool return { ...toolCall, function: { ...toolCall.function, parsed_arguments: isAutoParsableTool(inputTool) ? inputTool.$parseRaw(toolCall.function.arguments) : inputTool?.function.strict ? JSON.parse(toolCall.function.arguments) : null, }, }; } function shouldParseToolCall(params, toolCall) { if (!params || !('tools' in params) || !params.tools) { return false; } const inputTool = params.tools?.find((inputTool) => isChatCompletionFunctionTool(inputTool) && inputTool.function?.name === toolCall.function.name); return (isChatCompletionFunctionTool(inputTool) && (isAutoParsableTool(inputTool) || inputTool?.function.strict || false)); } function hasAutoParseableInput(params) { if (isAutoParsableResponseFormat(params.response_format)) { return true; } return (params.tools?.some((t) => isAutoParsableTool(t) || (t.type === 'function' && t.function.strict === true)) ?? false); } function assertToolCallsAreChatCompletionFunctionToolCalls(toolCalls) { for (const toolCall of toolCalls || []) { if (toolCall.type !== 'function') { throw new error_1.OpenAIError(`Currently only \`function\` tool calls are supported; Received \`${toolCall.type}\``); } } } function validateInputTools(tools) { for (const tool of tools ?? []) { if (tool.type !== 'function') { throw new error_1.OpenAIError(`Currently only \`function\` tool types support auto-parsing; Received \`${tool.type}\``); } if (tool.function.strict !== true) { throw new error_1.OpenAIError(`The \`${tool.function.name}\` tool is not marked with \`strict: true\`. Only strict function tools can be auto-parsed`); } } } //# sourceMappingURL=parser.js.map