176 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			176 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | "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
 |