ChatCompletionStream.mjs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
  2. if (kind === "m") throw new TypeError("Private method is not writable");
  3. if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
  4. 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");
  5. return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
  6. };
  7. var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
  8. if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
  9. 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");
  10. return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
  11. };
  12. 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;
  13. import { OpenAIError, APIUserAbortError, LengthFinishReasonError, ContentFilterFinishReasonError, } from "../error.mjs";
  14. import { AbstractChatCompletionRunner, } from "./AbstractChatCompletionRunner.mjs";
  15. import { Stream } from "../streaming.mjs";
  16. import { hasAutoParseableInput, isAutoParsableResponseFormat, isAutoParsableTool, maybeParseChatCompletion, shouldParseToolCall, } from "../lib/parser.mjs";
  17. import { partialParse } from "../_vendor/partial-json-parser/parser.mjs";
  18. export class ChatCompletionStream extends AbstractChatCompletionRunner {
  19. constructor(params) {
  20. super();
  21. _ChatCompletionStream_instances.add(this);
  22. _ChatCompletionStream_params.set(this, void 0);
  23. _ChatCompletionStream_choiceEventStates.set(this, void 0);
  24. _ChatCompletionStream_currentChatCompletionSnapshot.set(this, void 0);
  25. __classPrivateFieldSet(this, _ChatCompletionStream_params, params, "f");
  26. __classPrivateFieldSet(this, _ChatCompletionStream_choiceEventStates, [], "f");
  27. }
  28. get currentChatCompletionSnapshot() {
  29. return __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
  30. }
  31. /**
  32. * Intended for use on the frontend, consuming a stream produced with
  33. * `.toReadableStream()` on the backend.
  34. *
  35. * Note that messages sent to the model do not appear in `.on('message')`
  36. * in this context.
  37. */
  38. static fromReadableStream(stream) {
  39. const runner = new ChatCompletionStream(null);
  40. runner._run(() => runner._fromReadableStream(stream));
  41. return runner;
  42. }
  43. static createChatCompletion(client, params, options) {
  44. const runner = new ChatCompletionStream(params);
  45. runner._run(() => runner._runChatCompletion(client, { ...params, stream: true }, { ...options, headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' } }));
  46. return runner;
  47. }
  48. async _createChatCompletion(client, params, options) {
  49. super._createChatCompletion;
  50. const signal = options?.signal;
  51. if (signal) {
  52. if (signal.aborted)
  53. this.controller.abort();
  54. signal.addEventListener('abort', () => this.controller.abort());
  55. }
  56. __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this);
  57. const stream = await client.chat.completions.create({ ...params, stream: true }, { ...options, signal: this.controller.signal });
  58. this._connected();
  59. for await (const chunk of stream) {
  60. __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk);
  61. }
  62. if (stream.controller.signal?.aborted) {
  63. throw new APIUserAbortError();
  64. }
  65. return this._addChatCompletion(__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this));
  66. }
  67. async _fromReadableStream(readableStream, options) {
  68. const signal = options?.signal;
  69. if (signal) {
  70. if (signal.aborted)
  71. this.controller.abort();
  72. signal.addEventListener('abort', () => this.controller.abort());
  73. }
  74. __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this);
  75. this._connected();
  76. const stream = Stream.fromReadableStream(readableStream, this.controller);
  77. let chatId;
  78. for await (const chunk of stream) {
  79. if (chatId && chatId !== chunk.id) {
  80. // A new request has been made.
  81. this._addChatCompletion(__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this));
  82. }
  83. __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk);
  84. chatId = chunk.id;
  85. }
  86. if (stream.controller.signal?.aborted) {
  87. throw new APIUserAbortError();
  88. }
  89. return this._addChatCompletion(__classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this));
  90. }
  91. [(_ChatCompletionStream_params = new WeakMap(), _ChatCompletionStream_choiceEventStates = new WeakMap(), _ChatCompletionStream_currentChatCompletionSnapshot = new WeakMap(), _ChatCompletionStream_instances = new WeakSet(), _ChatCompletionStream_beginRequest = function _ChatCompletionStream_beginRequest() {
  92. if (this.ended)
  93. return;
  94. __classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, undefined, "f");
  95. }, _ChatCompletionStream_getChoiceEventState = function _ChatCompletionStream_getChoiceEventState(choice) {
  96. let state = __classPrivateFieldGet(this, _ChatCompletionStream_choiceEventStates, "f")[choice.index];
  97. if (state) {
  98. return state;
  99. }
  100. state = {
  101. content_done: false,
  102. refusal_done: false,
  103. logprobs_content_done: false,
  104. logprobs_refusal_done: false,
  105. done_tool_calls: new Set(),
  106. current_tool_call_index: null,
  107. };
  108. __classPrivateFieldGet(this, _ChatCompletionStream_choiceEventStates, "f")[choice.index] = state;
  109. return state;
  110. }, _ChatCompletionStream_addChunk = function _ChatCompletionStream_addChunk(chunk) {
  111. if (this.ended)
  112. return;
  113. const completion = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_accumulateChatCompletion).call(this, chunk);
  114. this._emit('chunk', chunk, completion);
  115. for (const choice of chunk.choices) {
  116. const choiceSnapshot = completion.choices[choice.index];
  117. if (choice.delta.content != null &&
  118. choiceSnapshot.message?.role === 'assistant' &&
  119. choiceSnapshot.message?.content) {
  120. this._emit('content', choice.delta.content, choiceSnapshot.message.content);
  121. this._emit('content.delta', {
  122. delta: choice.delta.content,
  123. snapshot: choiceSnapshot.message.content,
  124. parsed: choiceSnapshot.message.parsed,
  125. });
  126. }
  127. if (choice.delta.refusal != null &&
  128. choiceSnapshot.message?.role === 'assistant' &&
  129. choiceSnapshot.message?.refusal) {
  130. this._emit('refusal.delta', {
  131. delta: choice.delta.refusal,
  132. snapshot: choiceSnapshot.message.refusal,
  133. });
  134. }
  135. if (choice.logprobs?.content != null && choiceSnapshot.message?.role === 'assistant') {
  136. this._emit('logprobs.content.delta', {
  137. content: choice.logprobs?.content,
  138. snapshot: choiceSnapshot.logprobs?.content ?? [],
  139. });
  140. }
  141. if (choice.logprobs?.refusal != null && choiceSnapshot.message?.role === 'assistant') {
  142. this._emit('logprobs.refusal.delta', {
  143. refusal: choice.logprobs?.refusal,
  144. snapshot: choiceSnapshot.logprobs?.refusal ?? [],
  145. });
  146. }
  147. const state = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot);
  148. if (choiceSnapshot.finish_reason) {
  149. __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitContentDoneEvents).call(this, choiceSnapshot);
  150. if (state.current_tool_call_index != null) {
  151. __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitToolCallDoneEvent).call(this, choiceSnapshot, state.current_tool_call_index);
  152. }
  153. }
  154. for (const toolCall of choice.delta.tool_calls ?? []) {
  155. if (state.current_tool_call_index !== toolCall.index) {
  156. __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitContentDoneEvents).call(this, choiceSnapshot);
  157. // new tool call started, the previous one is done
  158. if (state.current_tool_call_index != null) {
  159. __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitToolCallDoneEvent).call(this, choiceSnapshot, state.current_tool_call_index);
  160. }
  161. }
  162. state.current_tool_call_index = toolCall.index;
  163. }
  164. for (const toolCallDelta of choice.delta.tool_calls ?? []) {
  165. const toolCallSnapshot = choiceSnapshot.message.tool_calls?.[toolCallDelta.index];
  166. if (!toolCallSnapshot?.type) {
  167. continue;
  168. }
  169. if (toolCallSnapshot?.type === 'function') {
  170. this._emit('tool_calls.function.arguments.delta', {
  171. name: toolCallSnapshot.function?.name,
  172. index: toolCallDelta.index,
  173. arguments: toolCallSnapshot.function.arguments,
  174. parsed_arguments: toolCallSnapshot.function.parsed_arguments,
  175. arguments_delta: toolCallDelta.function?.arguments ?? '',
  176. });
  177. }
  178. else {
  179. assertNever(toolCallSnapshot?.type);
  180. }
  181. }
  182. }
  183. }, _ChatCompletionStream_emitToolCallDoneEvent = function _ChatCompletionStream_emitToolCallDoneEvent(choiceSnapshot, toolCallIndex) {
  184. const state = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot);
  185. if (state.done_tool_calls.has(toolCallIndex)) {
  186. // we've already fired the done event
  187. return;
  188. }
  189. const toolCallSnapshot = choiceSnapshot.message.tool_calls?.[toolCallIndex];
  190. if (!toolCallSnapshot) {
  191. throw new Error('no tool call snapshot');
  192. }
  193. if (!toolCallSnapshot.type) {
  194. throw new Error('tool call snapshot missing `type`');
  195. }
  196. if (toolCallSnapshot.type === 'function') {
  197. const inputTool = __classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.tools?.find((tool) => tool.type === 'function' && tool.function.name === toolCallSnapshot.function.name);
  198. this._emit('tool_calls.function.arguments.done', {
  199. name: toolCallSnapshot.function.name,
  200. index: toolCallIndex,
  201. arguments: toolCallSnapshot.function.arguments,
  202. parsed_arguments: isAutoParsableTool(inputTool) ? inputTool.$parseRaw(toolCallSnapshot.function.arguments)
  203. : inputTool?.function.strict ? JSON.parse(toolCallSnapshot.function.arguments)
  204. : null,
  205. });
  206. }
  207. else {
  208. assertNever(toolCallSnapshot.type);
  209. }
  210. }, _ChatCompletionStream_emitContentDoneEvents = function _ChatCompletionStream_emitContentDoneEvents(choiceSnapshot) {
  211. const state = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot);
  212. if (choiceSnapshot.message.content && !state.content_done) {
  213. state.content_done = true;
  214. const responseFormat = __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getAutoParseableResponseFormat).call(this);
  215. this._emit('content.done', {
  216. content: choiceSnapshot.message.content,
  217. parsed: responseFormat ? responseFormat.$parseRaw(choiceSnapshot.message.content) : null,
  218. });
  219. }
  220. if (choiceSnapshot.message.refusal && !state.refusal_done) {
  221. state.refusal_done = true;
  222. this._emit('refusal.done', { refusal: choiceSnapshot.message.refusal });
  223. }
  224. if (choiceSnapshot.logprobs?.content && !state.logprobs_content_done) {
  225. state.logprobs_content_done = true;
  226. this._emit('logprobs.content.done', { content: choiceSnapshot.logprobs.content });
  227. }
  228. if (choiceSnapshot.logprobs?.refusal && !state.logprobs_refusal_done) {
  229. state.logprobs_refusal_done = true;
  230. this._emit('logprobs.refusal.done', { refusal: choiceSnapshot.logprobs.refusal });
  231. }
  232. }, _ChatCompletionStream_endRequest = function _ChatCompletionStream_endRequest() {
  233. if (this.ended) {
  234. throw new OpenAIError(`stream has ended, this shouldn't happen`);
  235. }
  236. const snapshot = __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
  237. if (!snapshot) {
  238. throw new OpenAIError(`request ended without sending any chunks`);
  239. }
  240. __classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, undefined, "f");
  241. __classPrivateFieldSet(this, _ChatCompletionStream_choiceEventStates, [], "f");
  242. return finalizeChatCompletion(snapshot, __classPrivateFieldGet(this, _ChatCompletionStream_params, "f"));
  243. }, _ChatCompletionStream_getAutoParseableResponseFormat = function _ChatCompletionStream_getAutoParseableResponseFormat() {
  244. const responseFormat = __classPrivateFieldGet(this, _ChatCompletionStream_params, "f")?.response_format;
  245. if (isAutoParsableResponseFormat(responseFormat)) {
  246. return responseFormat;
  247. }
  248. return null;
  249. }, _ChatCompletionStream_accumulateChatCompletion = function _ChatCompletionStream_accumulateChatCompletion(chunk) {
  250. var _a, _b, _c, _d;
  251. let snapshot = __classPrivateFieldGet(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
  252. const { choices, ...rest } = chunk;
  253. if (!snapshot) {
  254. snapshot = __classPrivateFieldSet(this, _ChatCompletionStream_currentChatCompletionSnapshot, {
  255. ...rest,
  256. choices: [],
  257. }, "f");
  258. }
  259. else {
  260. Object.assign(snapshot, rest);
  261. }
  262. for (const { delta, finish_reason, index, logprobs = null, ...other } of chunk.choices) {
  263. let choice = snapshot.choices[index];
  264. if (!choice) {
  265. choice = snapshot.choices[index] = { finish_reason, index, message: {}, logprobs, ...other };
  266. }
  267. if (logprobs) {
  268. if (!choice.logprobs) {
  269. choice.logprobs = Object.assign({}, logprobs);
  270. }
  271. else {
  272. const { content, refusal, ...rest } = logprobs;
  273. assertIsEmpty(rest);
  274. Object.assign(choice.logprobs, rest);
  275. if (content) {
  276. (_a = choice.logprobs).content ?? (_a.content = []);
  277. choice.logprobs.content.push(...content);
  278. }
  279. if (refusal) {
  280. (_b = choice.logprobs).refusal ?? (_b.refusal = []);
  281. choice.logprobs.refusal.push(...refusal);
  282. }
  283. }
  284. }
  285. if (finish_reason) {
  286. choice.finish_reason = finish_reason;
  287. if (__classPrivateFieldGet(this, _ChatCompletionStream_params, "f") && hasAutoParseableInput(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f"))) {
  288. if (finish_reason === 'length') {
  289. throw new LengthFinishReasonError();
  290. }
  291. if (finish_reason === 'content_filter') {
  292. throw new ContentFilterFinishReasonError();
  293. }
  294. }
  295. }
  296. Object.assign(choice, other);
  297. if (!delta)
  298. continue; // Shouldn't happen; just in case.
  299. const { content, refusal, function_call, role, tool_calls, ...rest } = delta;
  300. assertIsEmpty(rest);
  301. Object.assign(choice.message, rest);
  302. if (refusal) {
  303. choice.message.refusal = (choice.message.refusal || '') + refusal;
  304. }
  305. if (role)
  306. choice.message.role = role;
  307. if (function_call) {
  308. if (!choice.message.function_call) {
  309. choice.message.function_call = function_call;
  310. }
  311. else {
  312. if (function_call.name)
  313. choice.message.function_call.name = function_call.name;
  314. if (function_call.arguments) {
  315. (_c = choice.message.function_call).arguments ?? (_c.arguments = '');
  316. choice.message.function_call.arguments += function_call.arguments;
  317. }
  318. }
  319. }
  320. if (content) {
  321. choice.message.content = (choice.message.content || '') + content;
  322. if (!choice.message.refusal && __classPrivateFieldGet(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getAutoParseableResponseFormat).call(this)) {
  323. choice.message.parsed = partialParse(choice.message.content);
  324. }
  325. }
  326. if (tool_calls) {
  327. if (!choice.message.tool_calls)
  328. choice.message.tool_calls = [];
  329. for (const { index, id, type, function: fn, ...rest } of tool_calls) {
  330. const tool_call = ((_d = choice.message.tool_calls)[index] ?? (_d[index] = {}));
  331. Object.assign(tool_call, rest);
  332. if (id)
  333. tool_call.id = id;
  334. if (type)
  335. tool_call.type = type;
  336. if (fn)
  337. tool_call.function ?? (tool_call.function = { name: fn.name ?? '', arguments: '' });
  338. if (fn?.name)
  339. tool_call.function.name = fn.name;
  340. if (fn?.arguments) {
  341. tool_call.function.arguments += fn.arguments;
  342. if (shouldParseToolCall(__classPrivateFieldGet(this, _ChatCompletionStream_params, "f"), tool_call)) {
  343. tool_call.function.parsed_arguments = partialParse(tool_call.function.arguments);
  344. }
  345. }
  346. }
  347. }
  348. }
  349. return snapshot;
  350. }, Symbol.asyncIterator)]() {
  351. const pushQueue = [];
  352. const readQueue = [];
  353. let done = false;
  354. this.on('chunk', (chunk) => {
  355. const reader = readQueue.shift();
  356. if (reader) {
  357. reader.resolve(chunk);
  358. }
  359. else {
  360. pushQueue.push(chunk);
  361. }
  362. });
  363. this.on('end', () => {
  364. done = true;
  365. for (const reader of readQueue) {
  366. reader.resolve(undefined);
  367. }
  368. readQueue.length = 0;
  369. });
  370. this.on('abort', (err) => {
  371. done = true;
  372. for (const reader of readQueue) {
  373. reader.reject(err);
  374. }
  375. readQueue.length = 0;
  376. });
  377. this.on('error', (err) => {
  378. done = true;
  379. for (const reader of readQueue) {
  380. reader.reject(err);
  381. }
  382. readQueue.length = 0;
  383. });
  384. return {
  385. next: async () => {
  386. if (!pushQueue.length) {
  387. if (done) {
  388. return { value: undefined, done: true };
  389. }
  390. return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((chunk) => (chunk ? { value: chunk, done: false } : { value: undefined, done: true }));
  391. }
  392. const chunk = pushQueue.shift();
  393. return { value: chunk, done: false };
  394. },
  395. return: async () => {
  396. this.abort();
  397. return { value: undefined, done: true };
  398. },
  399. };
  400. }
  401. toReadableStream() {
  402. const stream = new Stream(this[Symbol.asyncIterator].bind(this), this.controller);
  403. return stream.toReadableStream();
  404. }
  405. }
  406. function finalizeChatCompletion(snapshot, params) {
  407. const { id, choices, created, model, system_fingerprint, ...rest } = snapshot;
  408. const completion = {
  409. ...rest,
  410. id,
  411. choices: choices.map(({ message, finish_reason, index, logprobs, ...choiceRest }) => {
  412. if (!finish_reason) {
  413. throw new OpenAIError(`missing finish_reason for choice ${index}`);
  414. }
  415. const { content = null, function_call, tool_calls, ...messageRest } = message;
  416. 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.
  417. if (!role) {
  418. throw new OpenAIError(`missing role for choice ${index}`);
  419. }
  420. if (function_call) {
  421. const { arguments: args, name } = function_call;
  422. if (args == null) {
  423. throw new OpenAIError(`missing function_call.arguments for choice ${index}`);
  424. }
  425. if (!name) {
  426. throw new OpenAIError(`missing function_call.name for choice ${index}`);
  427. }
  428. return {
  429. ...choiceRest,
  430. message: {
  431. content,
  432. function_call: { arguments: args, name },
  433. role,
  434. refusal: message.refusal ?? null,
  435. },
  436. finish_reason,
  437. index,
  438. logprobs,
  439. };
  440. }
  441. if (tool_calls) {
  442. return {
  443. ...choiceRest,
  444. index,
  445. finish_reason,
  446. logprobs,
  447. message: {
  448. ...messageRest,
  449. role,
  450. content,
  451. refusal: message.refusal ?? null,
  452. tool_calls: tool_calls.map((tool_call, i) => {
  453. const { function: fn, type, id, ...toolRest } = tool_call;
  454. const { arguments: args, name, ...fnRest } = fn || {};
  455. if (id == null) {
  456. throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].id\n${str(snapshot)}`);
  457. }
  458. if (type == null) {
  459. throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].type\n${str(snapshot)}`);
  460. }
  461. if (name == null) {
  462. throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.name\n${str(snapshot)}`);
  463. }
  464. if (args == null) {
  465. throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.arguments\n${str(snapshot)}`);
  466. }
  467. return { ...toolRest, id, type, function: { ...fnRest, name, arguments: args } };
  468. }),
  469. },
  470. };
  471. }
  472. return {
  473. ...choiceRest,
  474. message: { ...messageRest, content, role, refusal: message.refusal ?? null },
  475. finish_reason,
  476. index,
  477. logprobs,
  478. };
  479. }),
  480. created,
  481. model,
  482. object: 'chat.completion',
  483. ...(system_fingerprint ? { system_fingerprint } : {}),
  484. };
  485. return maybeParseChatCompletion(completion, params);
  486. }
  487. function str(x) {
  488. return JSON.stringify(x);
  489. }
  490. /**
  491. * Ensures the given argument is an empty object, useful for
  492. * asserting that all known properties on an object have been
  493. * destructured.
  494. */
  495. function assertIsEmpty(obj) {
  496. return;
  497. }
  498. function assertNever(_x) { }
  499. //# sourceMappingURL=ChatCompletionStream.mjs.map