ai 2.2.1 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -22,15 +22,22 @@ var streams_exports = {};
22
22
  __export(streams_exports, {
23
23
  AIStream: () => AIStream,
24
24
  AnthropicStream: () => AnthropicStream,
25
+ COMPLEX_HEADER: () => COMPLEX_HEADER,
25
26
  CohereStream: () => CohereStream,
26
27
  HuggingFaceStream: () => HuggingFaceStream,
27
28
  LangChainStream: () => LangChainStream,
28
29
  OpenAIStream: () => OpenAIStream,
29
30
  ReplicateStream: () => ReplicateStream,
31
+ StreamStringPrefixes: () => StreamStringPrefixes,
30
32
  StreamingTextResponse: () => StreamingTextResponse,
31
33
  createCallbacksTransformer: () => createCallbacksTransformer,
32
34
  createChunkDecoder: () => createChunkDecoder,
33
35
  createEventStreamTransformer: () => createEventStreamTransformer,
36
+ createStreamDataTransformer: () => createStreamDataTransformer,
37
+ experimental_StreamData: () => experimental_StreamData,
38
+ getStreamString: () => getStreamString,
39
+ getStreamStringTypeAndValue: () => getStreamStringTypeAndValue,
40
+ isStreamStringEqualToType: () => isStreamStringEqualToType,
34
41
  nanoid: () => nanoid,
35
42
  readableFromAsyncIterable: () => readableFromAsyncIterable,
36
43
  streamToResponse: () => streamToResponse,
@@ -66,28 +73,36 @@ function createEventStreamTransformer(customParser) {
66
73
  }
67
74
  });
68
75
  }
69
- function createCallbacksTransformer(callbacks) {
76
+ function createCallbacksTransformer(cb) {
70
77
  const textEncoder = new TextEncoder();
71
78
  let aggregatedResponse = "";
72
- const { onStart, onToken, onCompletion } = callbacks || {};
79
+ const callbacks = cb || {};
73
80
  return new TransformStream({
74
81
  async start() {
75
- if (onStart)
76
- await onStart();
82
+ if (callbacks.onStart)
83
+ await callbacks.onStart();
77
84
  },
78
85
  async transform(message, controller) {
79
86
  controller.enqueue(textEncoder.encode(message));
80
- if (onToken)
81
- await onToken(message);
82
- if (onCompletion)
87
+ if (callbacks.onToken)
88
+ await callbacks.onToken(message);
89
+ if (callbacks.onCompletion)
83
90
  aggregatedResponse += message;
84
91
  },
85
92
  async flush() {
86
- if (onCompletion)
87
- await onCompletion(aggregatedResponse);
93
+ const isOpenAICallbacks = isOfTypeOpenAIStreamCallbacks(callbacks);
94
+ if (callbacks.onCompletion) {
95
+ await callbacks.onCompletion(aggregatedResponse);
96
+ }
97
+ if (callbacks.onFinal && !isOpenAICallbacks) {
98
+ await callbacks.onFinal(aggregatedResponse);
99
+ }
88
100
  }
89
101
  });
90
102
  }
103
+ function isOfTypeOpenAIStreamCallbacks(callbacks) {
104
+ return "experimental_onFunctionCall" in callbacks;
105
+ }
91
106
  function trimStartOfStreamHelper() {
92
107
  let isStreamStart = true;
93
108
  return (text) => {
@@ -147,6 +162,140 @@ function readableFromAsyncIterable(iterable) {
147
162
  });
148
163
  }
149
164
 
165
+ // shared/utils.ts
166
+ var import_non_secure = require("nanoid/non-secure");
167
+ var nanoid = (0, import_non_secure.customAlphabet)(
168
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
169
+ 7
170
+ );
171
+ function createChunkDecoder(complex) {
172
+ const decoder = new TextDecoder();
173
+ if (!complex) {
174
+ return function(chunk) {
175
+ if (!chunk)
176
+ return "";
177
+ return decoder.decode(chunk, { stream: true });
178
+ };
179
+ }
180
+ return function(chunk) {
181
+ const decoded = decoder.decode(chunk, { stream: true }).split("\n");
182
+ return decoded.map(getStreamStringTypeAndValue).filter(Boolean);
183
+ };
184
+ }
185
+ var StreamStringPrefixes = {
186
+ text: 0,
187
+ function_call: 1,
188
+ data: 2
189
+ // user_err: 3?
190
+ };
191
+ var isStreamStringEqualToType = (type, value) => value.startsWith(`${StreamStringPrefixes[type]}:`) && value.endsWith("\n");
192
+ var getStreamString = (type, value) => `${StreamStringPrefixes[type]}:${JSON.stringify(value)}
193
+ `;
194
+ var getStreamStringTypeAndValue = (line) => {
195
+ const firstSeperatorIndex = line.indexOf(":");
196
+ const prefix = line.slice(0, firstSeperatorIndex);
197
+ const type = Object.keys(StreamStringPrefixes).find(
198
+ (key) => StreamStringPrefixes[key] === Number(prefix)
199
+ );
200
+ const val = line.slice(firstSeperatorIndex + 1);
201
+ let parsedVal = val;
202
+ if (!val) {
203
+ return { type, value: "" };
204
+ }
205
+ try {
206
+ parsedVal = JSON.parse(val);
207
+ } catch (e) {
208
+ console.error("Failed to parse JSON value:", val);
209
+ }
210
+ return { type, value: parsedVal };
211
+ };
212
+ var COMPLEX_HEADER = "X-Experimental-Stream-Data";
213
+
214
+ // streams/stream-data.ts
215
+ var experimental_StreamData = class {
216
+ constructor() {
217
+ this.encoder = new TextEncoder();
218
+ this.controller = null;
219
+ // closing the stream is synchronous, but we want to return a promise
220
+ // in case we're doing async work
221
+ this.isClosedPromise = null;
222
+ this.isClosedPromiseResolver = void 0;
223
+ this.isClosed = false;
224
+ // array to store appended data
225
+ this.data = [];
226
+ this.isClosedPromise = new Promise((resolve) => {
227
+ this.isClosedPromiseResolver = resolve;
228
+ });
229
+ const self = this;
230
+ this.stream = new TransformStream({
231
+ start: async (controller) => {
232
+ self.controller = controller;
233
+ },
234
+ transform: async (chunk, controller) => {
235
+ controller.enqueue(chunk);
236
+ if (self.data.length > 0) {
237
+ const encodedData = self.encoder.encode(
238
+ getStreamString("data", JSON.stringify(self.data))
239
+ );
240
+ self.data = [];
241
+ controller.enqueue(encodedData);
242
+ }
243
+ },
244
+ async flush(controller) {
245
+ const warningTimeout = process.env.NODE_ENV === "development" ? setTimeout(() => {
246
+ console.warn(
247
+ "The data stream is hanging. Did you forget to close it with `data.close()`?"
248
+ );
249
+ }, 3e3) : null;
250
+ await self.isClosedPromise;
251
+ if (warningTimeout !== null) {
252
+ clearTimeout(warningTimeout);
253
+ }
254
+ if (self.data.length) {
255
+ const encodedData = self.encoder.encode(
256
+ getStreamString("data", JSON.stringify(self.data))
257
+ );
258
+ controller.enqueue(encodedData);
259
+ }
260
+ }
261
+ });
262
+ }
263
+ async close() {
264
+ var _a;
265
+ if (this.isClosed) {
266
+ throw new Error("Data Stream has already been closed.");
267
+ }
268
+ if (!this.controller) {
269
+ throw new Error("Stream controller is not initialized.");
270
+ }
271
+ (_a = this.isClosedPromiseResolver) == null ? void 0 : _a.call(this);
272
+ this.isClosed = true;
273
+ }
274
+ append(value) {
275
+ if (this.isClosed) {
276
+ throw new Error("Data Stream has already been closed.");
277
+ }
278
+ this.data.push(value);
279
+ }
280
+ };
281
+ function createStreamDataTransformer(experimental_streamData) {
282
+ if (!experimental_streamData) {
283
+ return new TransformStream({
284
+ transform: async (chunk, controller) => {
285
+ controller.enqueue(chunk);
286
+ }
287
+ });
288
+ }
289
+ const encoder = new TextEncoder();
290
+ const decoder = new TextDecoder();
291
+ return new TransformStream({
292
+ transform: async (chunk, controller) => {
293
+ const message = decoder.decode(chunk);
294
+ controller.enqueue(encoder.encode(getStreamString("text", message)));
295
+ }
296
+ });
297
+ }
298
+
150
299
  // streams/openai-stream.ts
151
300
  function parseOpenAIStream() {
152
301
  const extract = chunkToText();
@@ -190,27 +339,49 @@ function OpenAIStream(res, callbacks) {
190
339
  let stream;
191
340
  if (Symbol.asyncIterator in res) {
192
341
  stream = readableFromAsyncIterable(streamable(res)).pipeThrough(
193
- createCallbacksTransformer(cb)
342
+ createCallbacksTransformer(
343
+ (cb == null ? void 0 : cb.experimental_onFunctionCall) ? {
344
+ ...cb,
345
+ onFinal: void 0
346
+ } : {
347
+ ...cb
348
+ }
349
+ )
194
350
  );
195
351
  } else {
196
- stream = AIStream(res, parseOpenAIStream(), cb);
352
+ stream = AIStream(
353
+ res,
354
+ parseOpenAIStream(),
355
+ (cb == null ? void 0 : cb.experimental_onFunctionCall) ? {
356
+ ...cb,
357
+ onFinal: void 0
358
+ } : {
359
+ ...cb
360
+ }
361
+ );
197
362
  }
198
363
  if (cb && cb.experimental_onFunctionCall) {
199
364
  const functionCallTransformer = createFunctionCallTransformer(cb);
200
365
  return stream.pipeThrough(functionCallTransformer);
201
366
  } else {
202
- return stream;
367
+ return stream.pipeThrough(
368
+ createStreamDataTransformer(cb == null ? void 0 : cb.experimental_streamData)
369
+ );
203
370
  }
204
371
  }
205
372
  function createFunctionCallTransformer(callbacks) {
206
373
  const textEncoder = new TextEncoder();
207
374
  let isFirstChunk = true;
208
375
  let aggregatedResponse = "";
376
+ let aggregatedFinalCompletionResponse = "";
209
377
  let isFunctionStreamingIn = false;
210
378
  let functionCallMessages = callbacks[__internal__OpenAIFnMessagesSymbol] || [];
379
+ const isComplexMode = callbacks == null ? void 0 : callbacks.experimental_streamData;
380
+ const decode = createChunkDecoder();
211
381
  return new TransformStream({
212
382
  async transform(chunk, controller) {
213
- const message = new TextDecoder().decode(chunk);
383
+ const message = decode(chunk);
384
+ aggregatedFinalCompletionResponse += message;
214
385
  const shouldHandleAsFunction = isFirstChunk && message.startsWith('{"function_call":');
215
386
  if (shouldHandleAsFunction) {
216
387
  isFunctionStreamingIn = true;
@@ -219,64 +390,80 @@ function createFunctionCallTransformer(callbacks) {
219
390
  return;
220
391
  }
221
392
  if (!isFunctionStreamingIn) {
222
- controller.enqueue(chunk);
393
+ controller.enqueue(
394
+ isComplexMode ? textEncoder.encode(getStreamString("text", message)) : chunk
395
+ );
223
396
  return;
224
397
  } else {
225
398
  aggregatedResponse += message;
226
399
  }
227
400
  },
228
401
  async flush(controller) {
229
- const isEndOfFunction = !isFirstChunk && callbacks.experimental_onFunctionCall && isFunctionStreamingIn;
230
- if (isEndOfFunction && callbacks.experimental_onFunctionCall) {
231
- isFunctionStreamingIn = false;
232
- const payload = JSON.parse(aggregatedResponse);
233
- const argumentsPayload = JSON.parse(payload.function_call.arguments);
234
- let newFunctionCallMessages = [...functionCallMessages];
235
- const functionResponse = await callbacks.experimental_onFunctionCall(
236
- {
237
- name: payload.function_call.name,
238
- arguments: argumentsPayload
239
- },
240
- (result) => {
241
- newFunctionCallMessages = [
242
- ...functionCallMessages,
243
- {
244
- role: "assistant",
245
- content: "",
246
- function_call: payload.function_call
247
- },
248
- {
249
- role: "function",
250
- name: payload.function_call.name,
251
- content: JSON.stringify(result)
252
- }
253
- ];
254
- return newFunctionCallMessages;
402
+ try {
403
+ const isEndOfFunction = !isFirstChunk && callbacks.experimental_onFunctionCall && isFunctionStreamingIn;
404
+ if (isEndOfFunction && callbacks.experimental_onFunctionCall) {
405
+ isFunctionStreamingIn = false;
406
+ const payload = JSON.parse(aggregatedResponse);
407
+ const argumentsPayload = JSON.parse(payload.function_call.arguments);
408
+ let newFunctionCallMessages = [
409
+ ...functionCallMessages
410
+ ];
411
+ const functionResponse = await callbacks.experimental_onFunctionCall(
412
+ {
413
+ name: payload.function_call.name,
414
+ arguments: argumentsPayload
415
+ },
416
+ (result) => {
417
+ newFunctionCallMessages = [
418
+ ...functionCallMessages,
419
+ {
420
+ role: "assistant",
421
+ content: "",
422
+ function_call: payload.function_call
423
+ },
424
+ {
425
+ role: "function",
426
+ name: payload.function_call.name,
427
+ content: JSON.stringify(result)
428
+ }
429
+ ];
430
+ return newFunctionCallMessages;
431
+ }
432
+ );
433
+ if (!functionResponse) {
434
+ controller.enqueue(
435
+ textEncoder.encode(
436
+ isComplexMode ? getStreamString("function_call", aggregatedResponse) : aggregatedResponse
437
+ )
438
+ );
439
+ return;
440
+ } else if (typeof functionResponse === "string") {
441
+ controller.enqueue(
442
+ isComplexMode ? textEncoder.encode(getStreamString("text", functionResponse)) : textEncoder.encode(functionResponse)
443
+ );
444
+ return;
255
445
  }
256
- );
257
- if (!functionResponse) {
258
- controller.enqueue(textEncoder.encode(aggregatedResponse));
259
- return;
260
- } else if (typeof functionResponse === "string") {
261
- controller.enqueue(textEncoder.encode(functionResponse));
262
- return;
263
- }
264
- const filteredCallbacks = {
265
- ...callbacks,
266
- onStart: void 0,
267
- onCompletion: void 0
268
- };
269
- const openAIStream = OpenAIStream(functionResponse, {
270
- ...filteredCallbacks,
271
- [__internal__OpenAIFnMessagesSymbol]: newFunctionCallMessages
272
- });
273
- const reader = openAIStream.getReader();
274
- while (true) {
275
- const { done, value } = await reader.read();
276
- if (done) {
277
- break;
446
+ const filteredCallbacks = {
447
+ ...callbacks,
448
+ onStart: void 0
449
+ };
450
+ callbacks.onFinal = void 0;
451
+ const openAIStream = OpenAIStream(functionResponse, {
452
+ ...filteredCallbacks,
453
+ [__internal__OpenAIFnMessagesSymbol]: newFunctionCallMessages
454
+ });
455
+ const reader = openAIStream.getReader();
456
+ while (true) {
457
+ const { done, value } = await reader.read();
458
+ if (done) {
459
+ break;
460
+ }
461
+ controller.enqueue(value);
278
462
  }
279
- controller.enqueue(value);
463
+ }
464
+ } finally {
465
+ if (callbacks.onFinal && aggregatedFinalCompletionResponse) {
466
+ await callbacks.onFinal(aggregatedFinalCompletionResponse);
280
467
  }
281
468
  }
282
469
  }
@@ -285,12 +472,17 @@ function createFunctionCallTransformer(callbacks) {
285
472
 
286
473
  // streams/streaming-text-response.ts
287
474
  var StreamingTextResponse = class extends Response {
288
- constructor(res, init) {
289
- super(res, {
475
+ constructor(res, init, data) {
476
+ let processedStream = res;
477
+ if (data) {
478
+ processedStream = res.pipeThrough(data.stream);
479
+ }
480
+ super(processedStream, {
290
481
  ...init,
291
482
  status: 200,
292
483
  headers: {
293
484
  "Content-Type": "text/plain; charset=utf-8",
485
+ [COMPLEX_HEADER]: data ? "true" : "false",
294
486
  ...init == null ? void 0 : init.headers
295
487
  }
296
488
  });
@@ -342,7 +534,9 @@ function createParser2(res) {
342
534
  });
343
535
  }
344
536
  function HuggingFaceStream(res, callbacks) {
345
- return createParser2(res).pipeThrough(createCallbacksTransformer(callbacks));
537
+ return createParser2(res).pipeThrough(createCallbacksTransformer(callbacks)).pipeThrough(
538
+ createStreamDataTransformer(callbacks == null ? void 0 : callbacks.experimental_streamData)
539
+ );
346
540
  }
347
541
 
348
542
  // streams/cohere-stream.ts
@@ -389,7 +583,9 @@ function createParser3(res) {
389
583
  });
390
584
  }
391
585
  function CohereStream(reader, callbacks) {
392
- return createParser3(reader).pipeThrough(createCallbacksTransformer(callbacks));
586
+ return createParser3(reader).pipeThrough(createCallbacksTransformer(callbacks)).pipeThrough(
587
+ createStreamDataTransformer(callbacks == null ? void 0 : callbacks.experimental_streamData)
588
+ );
393
589
  }
394
590
 
395
591
  // streams/anthropic-stream.ts
@@ -421,11 +617,11 @@ async function* streamable2(stream) {
421
617
  }
422
618
  function AnthropicStream(res, cb) {
423
619
  if (Symbol.asyncIterator in res) {
424
- return readableFromAsyncIterable(streamable2(res)).pipeThrough(
425
- createCallbacksTransformer(cb)
426
- );
620
+ return readableFromAsyncIterable(streamable2(res)).pipeThrough(createCallbacksTransformer(cb)).pipeThrough(createStreamDataTransformer(cb == null ? void 0 : cb.experimental_streamData));
427
621
  } else {
428
- return AIStream(res, parseAnthropicStream(), cb);
622
+ return AIStream(res, parseAnthropicStream(), cb).pipeThrough(
623
+ createStreamDataTransformer(cb == null ? void 0 : cb.experimental_streamData)
624
+ );
429
625
  }
430
626
  }
431
627
 
@@ -450,7 +646,9 @@ function LangChainStream(callbacks) {
450
646
  }
451
647
  };
452
648
  return {
453
- stream: stream.readable.pipeThrough(createCallbacksTransformer(callbacks)),
649
+ stream: stream.readable.pipeThrough(createCallbacksTransformer(callbacks)).pipeThrough(
650
+ createStreamDataTransformer(callbacks == null ? void 0 : callbacks.experimental_streamData)
651
+ ),
454
652
  handlers: {
455
653
  handleLLMNewToken: async (token) => {
456
654
  await writer.ready;
@@ -503,36 +701,30 @@ async function ReplicateStream(res, cb) {
503
701
  Accept: "text/event-stream"
504
702
  }
505
703
  });
506
- return AIStream(eventStream, void 0, cb);
507
- }
508
-
509
- // shared/utils.ts
510
- var import_non_secure = require("nanoid/non-secure");
511
- var nanoid = (0, import_non_secure.customAlphabet)(
512
- "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
513
- 7
514
- );
515
- function createChunkDecoder() {
516
- const decoder = new TextDecoder();
517
- return function(chunk) {
518
- if (!chunk)
519
- return "";
520
- return decoder.decode(chunk, { stream: true });
521
- };
704
+ return AIStream(eventStream, void 0, cb).pipeThrough(
705
+ createStreamDataTransformer(cb == null ? void 0 : cb.experimental_streamData)
706
+ );
522
707
  }
523
708
  // Annotate the CommonJS export names for ESM import in node:
524
709
  0 && (module.exports = {
525
710
  AIStream,
526
711
  AnthropicStream,
712
+ COMPLEX_HEADER,
527
713
  CohereStream,
528
714
  HuggingFaceStream,
529
715
  LangChainStream,
530
716
  OpenAIStream,
531
717
  ReplicateStream,
718
+ StreamStringPrefixes,
532
719
  StreamingTextResponse,
533
720
  createCallbacksTransformer,
534
721
  createChunkDecoder,
535
722
  createEventStreamTransformer,
723
+ createStreamDataTransformer,
724
+ experimental_StreamData,
725
+ getStreamString,
726
+ getStreamStringTypeAndValue,
727
+ isStreamStringEqualToType,
536
728
  nanoid,
537
729
  readableFromAsyncIterable,
538
730
  streamToResponse,