170 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			170 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | "use strict"; | ||
|  | Object.defineProperty(exports, "__esModule", { value: true }); | ||
|  | exports.maybeParseResponse = maybeParseResponse; | ||
|  | exports.parseResponse = parseResponse; | ||
|  | exports.hasAutoParseableInput = hasAutoParseableInput; | ||
|  | exports.makeParseableResponseTool = makeParseableResponseTool; | ||
|  | exports.isAutoParsableTool = isAutoParsableTool; | ||
|  | exports.shouldParseToolCall = shouldParseToolCall; | ||
|  | exports.validateInputTools = validateInputTools; | ||
|  | exports.addOutputText = addOutputText; | ||
|  | const error_1 = require("../error.js"); | ||
|  | const parser_1 = require("../lib/parser.js"); | ||
|  | function maybeParseResponse(response, params) { | ||
|  |     if (!params || !hasAutoParseableInput(params)) { | ||
|  |         return { | ||
|  |             ...response, | ||
|  |             output_parsed: null, | ||
|  |             output: response.output.map((item) => { | ||
|  |                 if (item.type === 'function_call') { | ||
|  |                     return { | ||
|  |                         ...item, | ||
|  |                         parsed_arguments: null, | ||
|  |                     }; | ||
|  |                 } | ||
|  |                 if (item.type === 'message') { | ||
|  |                     return { | ||
|  |                         ...item, | ||
|  |                         content: item.content.map((content) => ({ | ||
|  |                             ...content, | ||
|  |                             parsed: null, | ||
|  |                         })), | ||
|  |                     }; | ||
|  |                 } | ||
|  |                 else { | ||
|  |                     return item; | ||
|  |                 } | ||
|  |             }), | ||
|  |         }; | ||
|  |     } | ||
|  |     return parseResponse(response, params); | ||
|  | } | ||
|  | function parseResponse(response, params) { | ||
|  |     const output = response.output.map((item) => { | ||
|  |         if (item.type === 'function_call') { | ||
|  |             return { | ||
|  |                 ...item, | ||
|  |                 parsed_arguments: parseToolCall(params, item), | ||
|  |             }; | ||
|  |         } | ||
|  |         if (item.type === 'message') { | ||
|  |             const content = item.content.map((content) => { | ||
|  |                 if (content.type === 'output_text') { | ||
|  |                     return { | ||
|  |                         ...content, | ||
|  |                         parsed: parseTextFormat(params, content.text), | ||
|  |                     }; | ||
|  |                 } | ||
|  |                 return content; | ||
|  |             }); | ||
|  |             return { | ||
|  |                 ...item, | ||
|  |                 content, | ||
|  |             }; | ||
|  |         } | ||
|  |         return item; | ||
|  |     }); | ||
|  |     const parsed = Object.assign({}, response, { output }); | ||
|  |     if (!Object.getOwnPropertyDescriptor(response, 'output_text')) { | ||
|  |         addOutputText(parsed); | ||
|  |     } | ||
|  |     Object.defineProperty(parsed, 'output_parsed', { | ||
|  |         enumerable: true, | ||
|  |         get() { | ||
|  |             for (const output of parsed.output) { | ||
|  |                 if (output.type !== 'message') { | ||
|  |                     continue; | ||
|  |                 } | ||
|  |                 for (const content of output.content) { | ||
|  |                     if (content.type === 'output_text' && content.parsed !== null) { | ||
|  |                         return content.parsed; | ||
|  |                     } | ||
|  |                 } | ||
|  |             } | ||
|  |             return null; | ||
|  |         }, | ||
|  |     }); | ||
|  |     return parsed; | ||
|  | } | ||
|  | function parseTextFormat(params, content) { | ||
|  |     if (params.text?.format?.type !== 'json_schema') { | ||
|  |         return null; | ||
|  |     } | ||
|  |     if ('$parseRaw' in params.text?.format) { | ||
|  |         const text_format = params.text?.format; | ||
|  |         return text_format.$parseRaw(content); | ||
|  |     } | ||
|  |     return JSON.parse(content); | ||
|  | } | ||
|  | function hasAutoParseableInput(params) { | ||
|  |     if ((0, parser_1.isAutoParsableResponseFormat)(params.text?.format)) { | ||
|  |         return true; | ||
|  |     } | ||
|  |     return false; | ||
|  | } | ||
|  | function makeParseableResponseTool(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 getInputToolByName(input_tools, name) { | ||
|  |     return input_tools.find((tool) => tool.type === 'function' && tool.name === name); | ||
|  | } | ||
|  | function parseToolCall(params, toolCall) { | ||
|  |     const inputTool = getInputToolByName(params.tools ?? [], toolCall.name); | ||
|  |     return { | ||
|  |         ...toolCall, | ||
|  |         ...toolCall, | ||
|  |         parsed_arguments: isAutoParsableTool(inputTool) ? inputTool.$parseRaw(toolCall.arguments) | ||
|  |             : inputTool?.strict ? JSON.parse(toolCall.arguments) | ||
|  |                 : null, | ||
|  |     }; | ||
|  | } | ||
|  | function shouldParseToolCall(params, toolCall) { | ||
|  |     if (!params) { | ||
|  |         return false; | ||
|  |     } | ||
|  |     const inputTool = getInputToolByName(params.tools ?? [], toolCall.name); | ||
|  |     return isAutoParsableTool(inputTool) || inputTool?.strict || false; | ||
|  | } | ||
|  | 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`); | ||
|  |         } | ||
|  |     } | ||
|  | } | ||
|  | function addOutputText(rsp) { | ||
|  |     const texts = []; | ||
|  |     for (const output of rsp.output) { | ||
|  |         if (output.type !== 'message') { | ||
|  |             continue; | ||
|  |         } | ||
|  |         for (const content of output.content) { | ||
|  |             if (content.type === 'output_text') { | ||
|  |                 texts.push(content.text); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  |     rsp.output_text = texts.join(''); | ||
|  | } | ||
|  | //# sourceMappingURL=ResponsesParser.js.map
 |