493 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			493 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| var _ChatCompletionStream_instances, _ChatCompletionStream_params, _ChatCompletionStream_choiceEventStates, _ChatCompletionStream_currentChatCompletionSnapshot, _ChatCompletionStream_beginRequest, _ChatCompletionStream_getChoiceEventState, _ChatCompletionStream_addChunk, _ChatCompletionStream_emitToolCallDoneEvent, _ChatCompletionStream_emitContentDoneEvents, _ChatCompletionStream_endRequest, _ChatCompletionStream_getAutoParseableResponseFormat, _ChatCompletionStream_accumulateChatCompletion;
 | |
| Object.defineProperty(exports, "__esModule", { value: true });
 | |
| exports.ChatCompletionStream = void 0;
 | |
| const tslib_1 = require("../internal/tslib.js");
 | |
| const parser_1 = require("../_vendor/partial-json-parser/parser.js");
 | |
| const error_1 = require("../error.js");
 | |
| const parser_2 = require("../lib/parser.js");
 | |
| const streaming_1 = require("../streaming.js");
 | |
| const AbstractChatCompletionRunner_1 = require("./AbstractChatCompletionRunner.js");
 | |
| class ChatCompletionStream extends AbstractChatCompletionRunner_1.AbstractChatCompletionRunner {
 | |
|     constructor(params) {
 | |
|         super();
 | |
|         _ChatCompletionStream_instances.add(this);
 | |
|         _ChatCompletionStream_params.set(this, void 0);
 | |
|         _ChatCompletionStream_choiceEventStates.set(this, void 0);
 | |
|         _ChatCompletionStream_currentChatCompletionSnapshot.set(this, void 0);
 | |
|         tslib_1.__classPrivateFieldSet(this, _ChatCompletionStream_params, params, "f");
 | |
|         tslib_1.__classPrivateFieldSet(this, _ChatCompletionStream_choiceEventStates, [], "f");
 | |
|     }
 | |
|     get currentChatCompletionSnapshot() {
 | |
|         return tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
 | |
|     }
 | |
|     /**
 | |
|      * Intended for use on the frontend, consuming a stream produced with
 | |
|      * `.toReadableStream()` on the backend.
 | |
|      *
 | |
|      * Note that messages sent to the model do not appear in `.on('message')`
 | |
|      * in this context.
 | |
|      */
 | |
|     static fromReadableStream(stream) {
 | |
|         const runner = new ChatCompletionStream(null);
 | |
|         runner._run(() => runner._fromReadableStream(stream));
 | |
|         return runner;
 | |
|     }
 | |
|     static createChatCompletion(client, params, options) {
 | |
|         const runner = new ChatCompletionStream(params);
 | |
|         runner._run(() => runner._runChatCompletion(client, { ...params, stream: true }, { ...options, headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' } }));
 | |
|         return runner;
 | |
|     }
 | |
|     async _createChatCompletion(client, params, options) {
 | |
|         super._createChatCompletion;
 | |
|         const signal = options?.signal;
 | |
|         if (signal) {
 | |
|             if (signal.aborted)
 | |
|                 this.controller.abort();
 | |
|             signal.addEventListener('abort', () => this.controller.abort());
 | |
|         }
 | |
|         tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this);
 | |
|         const stream = await client.chat.completions.create({ ...params, stream: true }, { ...options, signal: this.controller.signal });
 | |
|         this._connected();
 | |
|         for await (const chunk of stream) {
 | |
|             tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk);
 | |
|         }
 | |
|         if (stream.controller.signal?.aborted) {
 | |
|             throw new error_1.APIUserAbortError();
 | |
|         }
 | |
|         return this._addChatCompletion(tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this));
 | |
|     }
 | |
|     async _fromReadableStream(readableStream, options) {
 | |
|         const signal = options?.signal;
 | |
|         if (signal) {
 | |
|             if (signal.aborted)
 | |
|                 this.controller.abort();
 | |
|             signal.addEventListener('abort', () => this.controller.abort());
 | |
|         }
 | |
|         tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this);
 | |
|         this._connected();
 | |
|         const stream = streaming_1.Stream.fromReadableStream(readableStream, this.controller);
 | |
|         let chatId;
 | |
|         for await (const chunk of stream) {
 | |
|             if (chatId && chatId !== chunk.id) {
 | |
|                 // A new request has been made.
 | |
|                 this._addChatCompletion(tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this));
 | |
|             }
 | |
|             tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk);
 | |
|             chatId = chunk.id;
 | |
|         }
 | |
|         if (stream.controller.signal?.aborted) {
 | |
|             throw new error_1.APIUserAbortError();
 | |
|         }
 | |
|         return this._addChatCompletion(tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this));
 | |
|     }
 | |
|     [(_ChatCompletionStream_params = new WeakMap(), _ChatCompletionStream_choiceEventStates = new WeakMap(), _ChatCompletionStream_currentChatCompletionSnapshot = new WeakMap(), _ChatCompletionStream_instances = new WeakSet(), _ChatCompletionStream_beginRequest = function _ChatCompletionStream_beginRequest() {
 | |
|         if (this.ended)
 | |
|             return;
 | |
|         tslib_1.__classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, undefined, "f");
 | |
|     }, _ChatCompletionStream_getChoiceEventState = function _ChatCompletionStream_getChoiceEventState(choice) {
 | |
|         let state = tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_choiceEventStates, "f")[choice.index];
 | |
|         if (state) {
 | |
|             return state;
 | |
|         }
 | |
|         state = {
 | |
|             content_done: false,
 | |
|             refusal_done: false,
 | |
|             logprobs_content_done: false,
 | |
|             logprobs_refusal_done: false,
 | |
|             done_tool_calls: new Set(),
 | |
|             current_tool_call_index: null,
 | |
|         };
 | |
|         tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_choiceEventStates, "f")[choice.index] = state;
 | |
|         return state;
 | |
|     }, _ChatCompletionStream_addChunk = function _ChatCompletionStream_addChunk(chunk) {
 | |
|         if (this.ended)
 | |
|             return;
 | |
|         const completion = tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_accumulateChatCompletion).call(this, chunk);
 | |
|         this._emit('chunk', chunk, completion);
 | |
|         for (const choice of chunk.choices) {
 | |
|             const choiceSnapshot = completion.choices[choice.index];
 | |
|             if (choice.delta.content != null &&
 | |
|                 choiceSnapshot.message?.role === 'assistant' &&
 | |
|                 choiceSnapshot.message?.content) {
 | |
|                 this._emit('content', choice.delta.content, choiceSnapshot.message.content);
 | |
|                 this._emit('content.delta', {
 | |
|                     delta: choice.delta.content,
 | |
|                     snapshot: choiceSnapshot.message.content,
 | |
|                     parsed: choiceSnapshot.message.parsed,
 | |
|                 });
 | |
|             }
 | |
|             if (choice.delta.refusal != null &&
 | |
|                 choiceSnapshot.message?.role === 'assistant' &&
 | |
|                 choiceSnapshot.message?.refusal) {
 | |
|                 this._emit('refusal.delta', {
 | |
|                     delta: choice.delta.refusal,
 | |
|                     snapshot: choiceSnapshot.message.refusal,
 | |
|                 });
 | |
|             }
 | |
|             if (choice.logprobs?.content != null && choiceSnapshot.message?.role === 'assistant') {
 | |
|                 this._emit('logprobs.content.delta', {
 | |
|                     content: choice.logprobs?.content,
 | |
|                     snapshot: choiceSnapshot.logprobs?.content ?? [],
 | |
|                 });
 | |
|             }
 | |
|             if (choice.logprobs?.refusal != null && choiceSnapshot.message?.role === 'assistant') {
 | |
|                 this._emit('logprobs.refusal.delta', {
 | |
|                     refusal: choice.logprobs?.refusal,
 | |
|                     snapshot: choiceSnapshot.logprobs?.refusal ?? [],
 | |
|                 });
 | |
|             }
 | |
|             const state = tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot);
 | |
|             if (choiceSnapshot.finish_reason) {
 | |
|                 tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitContentDoneEvents).call(this, choiceSnapshot);
 | |
|                 if (state.current_tool_call_index != null) {
 | |
|                     tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitToolCallDoneEvent).call(this, choiceSnapshot, state.current_tool_call_index);
 | |
|                 }
 | |
|             }
 | |
|             for (const toolCall of choice.delta.tool_calls ?? []) {
 | |
|                 if (state.current_tool_call_index !== toolCall.index) {
 | |
|                     tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitContentDoneEvents).call(this, choiceSnapshot);
 | |
|                     // new tool call started, the previous one is done
 | |
|                     if (state.current_tool_call_index != null) {
 | |
|                         tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitToolCallDoneEvent).call(this, choiceSnapshot, state.current_tool_call_index);
 | |
|                     }
 | |
|                 }
 | |
|                 state.current_tool_call_index = toolCall.index;
 | |
|             }
 | |
|             for (const toolCallDelta of choice.delta.tool_calls ?? []) {
 | |
|                 const toolCallSnapshot = choiceSnapshot.message.tool_calls?.[toolCallDelta.index];
 | |
|                 if (!toolCallSnapshot?.type) {
 | |
|                     continue;
 | |
|                 }
 | |
|                 if (toolCallSnapshot?.type === 'function') {
 | |
|                     this._emit('tool_calls.function.arguments.delta', {
 | |
|                         name: toolCallSnapshot.function?.name,
 | |
|                         index: toolCallDelta.index,
 | |
|                         arguments: toolCallSnapshot.function.arguments,
 | |
|                         parsed_arguments: toolCallSnapshot.function.parsed_arguments,
 | |
|                         arguments_delta: toolCallDelta.function?.arguments ?? '',
 | |
|                     });
 | |
|                 }
 | |
|                 else {
 | |
|                     assertNever(toolCallSnapshot?.type);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }, _ChatCompletionStream_emitToolCallDoneEvent = function _ChatCompletionStream_emitToolCallDoneEvent(choiceSnapshot, toolCallIndex) {
 | |
|         const state = tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot);
 | |
|         if (state.done_tool_calls.has(toolCallIndex)) {
 | |
|             // we've already fired the done event
 | |
|             return;
 | |
|         }
 | |
|         const toolCallSnapshot = choiceSnapshot.message.tool_calls?.[toolCallIndex];
 | |
|         if (!toolCallSnapshot) {
 | |
|             throw new Error('no tool call snapshot');
 | |
|         }
 | |
|         if (!toolCallSnapshot.type) {
 | |
|             throw new Error('tool call snapshot missing `type`');
 | |
|         }
 | |
|         if (toolCallSnapshot.type === 'function') {
 | |
|             const inputTool = tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.tools?.find((tool) => (0, parser_2.isChatCompletionFunctionTool)(tool) && tool.function.name === toolCallSnapshot.function.name); // TS doesn't narrow based on isChatCompletionTool
 | |
|             this._emit('tool_calls.function.arguments.done', {
 | |
|                 name: toolCallSnapshot.function.name,
 | |
|                 index: toolCallIndex,
 | |
|                 arguments: toolCallSnapshot.function.arguments,
 | |
|                 parsed_arguments: (0, parser_2.isAutoParsableTool)(inputTool) ? inputTool.$parseRaw(toolCallSnapshot.function.arguments)
 | |
|                     : inputTool?.function.strict ? JSON.parse(toolCallSnapshot.function.arguments)
 | |
|                         : null,
 | |
|             });
 | |
|         }
 | |
|         else {
 | |
|             assertNever(toolCallSnapshot.type);
 | |
|         }
 | |
|     }, _ChatCompletionStream_emitContentDoneEvents = function _ChatCompletionStream_emitContentDoneEvents(choiceSnapshot) {
 | |
|         const state = tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot);
 | |
|         if (choiceSnapshot.message.content && !state.content_done) {
 | |
|             state.content_done = true;
 | |
|             const responseFormat = tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getAutoParseableResponseFormat).call(this);
 | |
|             this._emit('content.done', {
 | |
|                 content: choiceSnapshot.message.content,
 | |
|                 parsed: responseFormat ? responseFormat.$parseRaw(choiceSnapshot.message.content) : null,
 | |
|             });
 | |
|         }
 | |
|         if (choiceSnapshot.message.refusal && !state.refusal_done) {
 | |
|             state.refusal_done = true;
 | |
|             this._emit('refusal.done', { refusal: choiceSnapshot.message.refusal });
 | |
|         }
 | |
|         if (choiceSnapshot.logprobs?.content && !state.logprobs_content_done) {
 | |
|             state.logprobs_content_done = true;
 | |
|             this._emit('logprobs.content.done', { content: choiceSnapshot.logprobs.content });
 | |
|         }
 | |
|         if (choiceSnapshot.logprobs?.refusal && !state.logprobs_refusal_done) {
 | |
|             state.logprobs_refusal_done = true;
 | |
|             this._emit('logprobs.refusal.done', { refusal: choiceSnapshot.logprobs.refusal });
 | |
|         }
 | |
|     }, _ChatCompletionStream_endRequest = function _ChatCompletionStream_endRequest() {
 | |
|         if (this.ended) {
 | |
|             throw new error_1.OpenAIError(`stream has ended, this shouldn't happen`);
 | |
|         }
 | |
|         const snapshot = tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
 | |
|         if (!snapshot) {
 | |
|             throw new error_1.OpenAIError(`request ended without sending any chunks`);
 | |
|         }
 | |
|         tslib_1.__classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, undefined, "f");
 | |
|         tslib_1.__classPrivateFieldSet(this, _ChatCompletionStream_choiceEventStates, [], "f");
 | |
|         return finalizeChatCompletion(snapshot, tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_params, "f"));
 | |
|     }, _ChatCompletionStream_getAutoParseableResponseFormat = function _ChatCompletionStream_getAutoParseableResponseFormat() {
 | |
|         const responseFormat = tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.response_format;
 | |
|         if ((0, parser_2.isAutoParsableResponseFormat)(responseFormat)) {
 | |
|             return responseFormat;
 | |
|         }
 | |
|         return null;
 | |
|     }, _ChatCompletionStream_accumulateChatCompletion = function _ChatCompletionStream_accumulateChatCompletion(chunk) {
 | |
|         var _a, _b, _c, _d;
 | |
|         let snapshot = tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
 | |
|         const { choices, ...rest } = chunk;
 | |
|         if (!snapshot) {
 | |
|             snapshot = tslib_1.__classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, {
 | |
|                 ...rest,
 | |
|                 choices: [],
 | |
|             }, "f");
 | |
|         }
 | |
|         else {
 | |
|             Object.assign(snapshot, rest);
 | |
|         }
 | |
|         for (const { delta, finish_reason, index, logprobs = null, ...other } of chunk.choices) {
 | |
|             let choice = snapshot.choices[index];
 | |
|             if (!choice) {
 | |
|                 choice = snapshot.choices[index] = { finish_reason, index, message: {}, logprobs, ...other };
 | |
|             }
 | |
|             if (logprobs) {
 | |
|                 if (!choice.logprobs) {
 | |
|                     choice.logprobs = Object.assign({}, logprobs);
 | |
|                 }
 | |
|                 else {
 | |
|                     const { content, refusal, ...rest } = logprobs;
 | |
|                     assertIsEmpty(rest);
 | |
|                     Object.assign(choice.logprobs, rest);
 | |
|                     if (content) {
 | |
|                         (_a = choice.logprobs).content ?? (_a.content = []);
 | |
|                         choice.logprobs.content.push(...content);
 | |
|                     }
 | |
|                     if (refusal) {
 | |
|                         (_b = choice.logprobs).refusal ?? (_b.refusal = []);
 | |
|                         choice.logprobs.refusal.push(...refusal);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             if (finish_reason) {
 | |
|                 choice.finish_reason = finish_reason;
 | |
|                 if (tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_params, "f") && (0, parser_2.hasAutoParseableInput)(tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_params, "f"))) {
 | |
|                     if (finish_reason === 'length') {
 | |
|                         throw new error_1.LengthFinishReasonError();
 | |
|                     }
 | |
|                     if (finish_reason === 'content_filter') {
 | |
|                         throw new error_1.ContentFilterFinishReasonError();
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             Object.assign(choice, other);
 | |
|             if (!delta)
 | |
|                 continue; // Shouldn't happen; just in case.
 | |
|             const { content, refusal, function_call, role, tool_calls, ...rest } = delta;
 | |
|             assertIsEmpty(rest);
 | |
|             Object.assign(choice.message, rest);
 | |
|             if (refusal) {
 | |
|                 choice.message.refusal = (choice.message.refusal || '') + refusal;
 | |
|             }
 | |
|             if (role)
 | |
|                 choice.message.role = role;
 | |
|             if (function_call) {
 | |
|                 if (!choice.message.function_call) {
 | |
|                     choice.message.function_call = function_call;
 | |
|                 }
 | |
|                 else {
 | |
|                     if (function_call.name)
 | |
|                         choice.message.function_call.name = function_call.name;
 | |
|                     if (function_call.arguments) {
 | |
|                         (_c = choice.message.function_call).arguments ?? (_c.arguments = '');
 | |
|                         choice.message.function_call.arguments += function_call.arguments;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             if (content) {
 | |
|                 choice.message.content = (choice.message.content || '') + content;
 | |
|                 if (!choice.message.refusal && tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getAutoParseableResponseFormat).call(this)) {
 | |
|                     choice.message.parsed = (0, parser_1.partialParse)(choice.message.content);
 | |
|                 }
 | |
|             }
 | |
|             if (tool_calls) {
 | |
|                 if (!choice.message.tool_calls)
 | |
|                     choice.message.tool_calls = [];
 | |
|                 for (const { index, id, type, function: fn, ...rest } of tool_calls) {
 | |
|                     const tool_call = ((_d = choice.message.tool_calls)[index] ?? (_d[index] = {}));
 | |
|                     Object.assign(tool_call, rest);
 | |
|                     if (id)
 | |
|                         tool_call.id = id;
 | |
|                     if (type)
 | |
|                         tool_call.type = type;
 | |
|                     if (fn)
 | |
|                         tool_call.function ?? (tool_call.function = { name: fn.name ?? '', arguments: '' });
 | |
|                     if (fn?.name)
 | |
|                         tool_call.function.name = fn.name;
 | |
|                     if (fn?.arguments) {
 | |
|                         tool_call.function.arguments += fn.arguments;
 | |
|                         if ((0, parser_2.shouldParseToolCall)(tslib_1.__classPrivateFieldGet(this, _ChatCompletionStream_params, "f"), tool_call)) {
 | |
|                             tool_call.function.parsed_arguments = (0, parser_1.partialParse)(tool_call.function.arguments);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         return snapshot;
 | |
|     }, Symbol.asyncIterator)]() {
 | |
|         const pushQueue = [];
 | |
|         const readQueue = [];
 | |
|         let done = false;
 | |
|         this.on('chunk', (chunk) => {
 | |
|             const reader = readQueue.shift();
 | |
|             if (reader) {
 | |
|                 reader.resolve(chunk);
 | |
|             }
 | |
|             else {
 | |
|                 pushQueue.push(chunk);
 | |
|             }
 | |
|         });
 | |
|         this.on('end', () => {
 | |
|             done = true;
 | |
|             for (const reader of readQueue) {
 | |
|                 reader.resolve(undefined);
 | |
|             }
 | |
|             readQueue.length = 0;
 | |
|         });
 | |
|         this.on('abort', (err) => {
 | |
|             done = true;
 | |
|             for (const reader of readQueue) {
 | |
|                 reader.reject(err);
 | |
|             }
 | |
|             readQueue.length = 0;
 | |
|         });
 | |
|         this.on('error', (err) => {
 | |
|             done = true;
 | |
|             for (const reader of readQueue) {
 | |
|                 reader.reject(err);
 | |
|             }
 | |
|             readQueue.length = 0;
 | |
|         });
 | |
|         return {
 | |
|             next: async () => {
 | |
|                 if (!pushQueue.length) {
 | |
|                     if (done) {
 | |
|                         return { value: undefined, done: true };
 | |
|                     }
 | |
|                     return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((chunk) => (chunk ? { value: chunk, done: false } : { value: undefined, done: true }));
 | |
|                 }
 | |
|                 const chunk = pushQueue.shift();
 | |
|                 return { value: chunk, done: false };
 | |
|             },
 | |
|             return: async () => {
 | |
|                 this.abort();
 | |
|                 return { value: undefined, done: true };
 | |
|             },
 | |
|         };
 | |
|     }
 | |
|     toReadableStream() {
 | |
|         const stream = new streaming_1.Stream(this[Symbol.asyncIterator].bind(this), this.controller);
 | |
|         return stream.toReadableStream();
 | |
|     }
 | |
| }
 | |
| exports.ChatCompletionStream = ChatCompletionStream;
 | |
| function finalizeChatCompletion(snapshot, params) {
 | |
|     const { id, choices, created, model, system_fingerprint, ...rest } = snapshot;
 | |
|     const completion = {
 | |
|         ...rest,
 | |
|         id,
 | |
|         choices: choices.map(({ message, finish_reason, index, logprobs, ...choiceRest }) => {
 | |
|             if (!finish_reason) {
 | |
|                 throw new error_1.OpenAIError(`missing finish_reason for choice ${index}`);
 | |
|             }
 | |
|             const { content = null, function_call, tool_calls, ...messageRest } = message;
 | |
|             const role = message.role; // this is what we expect; in theory it could be different which would make our types a slight lie but would be fine.
 | |
|             if (!role) {
 | |
|                 throw new error_1.OpenAIError(`missing role for choice ${index}`);
 | |
|             }
 | |
|             if (function_call) {
 | |
|                 const { arguments: args, name } = function_call;
 | |
|                 if (args == null) {
 | |
|                     throw new error_1.OpenAIError(`missing function_call.arguments for choice ${index}`);
 | |
|                 }
 | |
|                 if (!name) {
 | |
|                     throw new error_1.OpenAIError(`missing function_call.name for choice ${index}`);
 | |
|                 }
 | |
|                 return {
 | |
|                     ...choiceRest,
 | |
|                     message: {
 | |
|                         content,
 | |
|                         function_call: { arguments: args, name },
 | |
|                         role,
 | |
|                         refusal: message.refusal ?? null,
 | |
|                     },
 | |
|                     finish_reason,
 | |
|                     index,
 | |
|                     logprobs,
 | |
|                 };
 | |
|             }
 | |
|             if (tool_calls) {
 | |
|                 return {
 | |
|                     ...choiceRest,
 | |
|                     index,
 | |
|                     finish_reason,
 | |
|                     logprobs,
 | |
|                     message: {
 | |
|                         ...messageRest,
 | |
|                         role,
 | |
|                         content,
 | |
|                         refusal: message.refusal ?? null,
 | |
|                         tool_calls: tool_calls.map((tool_call, i) => {
 | |
|                             const { function: fn, type, id, ...toolRest } = tool_call;
 | |
|                             const { arguments: args, name, ...fnRest } = fn || {};
 | |
|                             if (id == null) {
 | |
|                                 throw new error_1.OpenAIError(`missing choices[${index}].tool_calls[${i}].id\n${str(snapshot)}`);
 | |
|                             }
 | |
|                             if (type == null) {
 | |
|                                 throw new error_1.OpenAIError(`missing choices[${index}].tool_calls[${i}].type\n${str(snapshot)}`);
 | |
|                             }
 | |
|                             if (name == null) {
 | |
|                                 throw new error_1.OpenAIError(`missing choices[${index}].tool_calls[${i}].function.name\n${str(snapshot)}`);
 | |
|                             }
 | |
|                             if (args == null) {
 | |
|                                 throw new error_1.OpenAIError(`missing choices[${index}].tool_calls[${i}].function.arguments\n${str(snapshot)}`);
 | |
|                             }
 | |
|                             return { ...toolRest, id, type, function: { ...fnRest, name, arguments: args } };
 | |
|                         }),
 | |
|                     },
 | |
|                 };
 | |
|             }
 | |
|             return {
 | |
|                 ...choiceRest,
 | |
|                 message: { ...messageRest, content, role, refusal: message.refusal ?? null },
 | |
|                 finish_reason,
 | |
|                 index,
 | |
|                 logprobs,
 | |
|             };
 | |
|         }),
 | |
|         created,
 | |
|         model,
 | |
|         object: 'chat.completion',
 | |
|         ...(system_fingerprint ? { system_fingerprint } : {}),
 | |
|     };
 | |
|     return (0, parser_2.maybeParseChatCompletion)(completion, params);
 | |
| }
 | |
| function str(x) {
 | |
|     return JSON.stringify(x);
 | |
| }
 | |
| /**
 | |
|  * Ensures the given argument is an empty object, useful for
 | |
|  * asserting that all known properties on an object have been
 | |
|  * destructured.
 | |
|  */
 | |
| function assertIsEmpty(obj) {
 | |
|     return;
 | |
| }
 | |
| function assertNever(_x) { }
 | |
| //# sourceMappingURL=ChatCompletionStream.js.map
 |