| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503 |
- "use strict";
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
- if (kind === "m") throw new TypeError("Private method is not writable");
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
- };
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
- };
- 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 error_1 = require("../error.js");
- const AbstractChatCompletionRunner_1 = require("./AbstractChatCompletionRunner.js");
- const streaming_1 = require("../streaming.js");
- const parser_1 = require("../lib/parser.js");
- const parser_2 = require("../_vendor/partial-json-parser/parser.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);
- __classPrivateFieldSet(this, _ChatCompletionStream_params, params, "f");
- __classPrivateFieldSet(this, _ChatCompletionStream_choiceEventStates, [], "f");
- }
- get currentChatCompletionSnapshot() {
- return __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());
- }
- __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) {
- __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk);
- }
- if (stream.controller.signal?.aborted) {
- throw new error_1.APIUserAbortError();
- }
- return this._addChatCompletion(__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());
- }
- __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(__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this));
- }
- __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(__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;
- __classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, undefined, "f");
- }, _ChatCompletionStream_getChoiceEventState = function _ChatCompletionStream_getChoiceEventState(choice) {
- let state = __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,
- };
- __classPrivateFieldGet(this, _ChatCompletionStream_choiceEventStates, "f")[choice.index] = state;
- return state;
- }, _ChatCompletionStream_addChunk = function _ChatCompletionStream_addChunk(chunk) {
- if (this.ended)
- return;
- const completion = __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 = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot);
- if (choiceSnapshot.finish_reason) {
- __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitContentDoneEvents).call(this, choiceSnapshot);
- if (state.current_tool_call_index != null) {
- __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) {
- __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) {
- __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 = __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 = __classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.tools?.find((tool) => tool.type === 'function' && tool.function.name === toolCallSnapshot.function.name);
- this._emit('tool_calls.function.arguments.done', {
- name: toolCallSnapshot.function.name,
- index: toolCallIndex,
- arguments: toolCallSnapshot.function.arguments,
- parsed_arguments: (0, parser_1.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 = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot);
- if (choiceSnapshot.message.content && !state.content_done) {
- state.content_done = true;
- const responseFormat = __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 = __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
- if (!snapshot) {
- throw new error_1.OpenAIError(`request ended without sending any chunks`);
- }
- __classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, undefined, "f");
- __classPrivateFieldSet(this, _ChatCompletionStream_choiceEventStates, [], "f");
- return finalizeChatCompletion(snapshot, __classPrivateFieldGet(this, _ChatCompletionStream_params, "f"));
- }, _ChatCompletionStream_getAutoParseableResponseFormat = function _ChatCompletionStream_getAutoParseableResponseFormat() {
- const responseFormat = __classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.response_format;
- if ((0, parser_1.isAutoParsableResponseFormat)(responseFormat)) {
- return responseFormat;
- }
- return null;
- }, _ChatCompletionStream_accumulateChatCompletion = function _ChatCompletionStream_accumulateChatCompletion(chunk) {
- var _a, _b, _c, _d;
- let snapshot = __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
- const { choices, ...rest } = chunk;
- if (!snapshot) {
- snapshot = __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 (__classPrivateFieldGet(this, _ChatCompletionStream_params, "f") && (0, parser_1.hasAutoParseableInput)(__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 && __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getAutoParseableResponseFormat).call(this)) {
- choice.message.parsed = (0, parser_2.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_1.shouldParseToolCall)(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f"), tool_call)) {
- tool_call.function.parsed_arguments = (0, parser_2.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_1.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
|