ai 2.2.25 → 2.2.27

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.
@@ -2,9 +2,6 @@
2
2
  import swrv from "swrv";
3
3
  import { ref, unref } from "vue";
4
4
 
5
- // shared/utils.ts
6
- import { customAlphabet } from "nanoid/non-secure";
7
-
8
5
  // shared/stream-parts.ts
9
6
  var textStreamPart = {
10
7
  code: "0",
@@ -126,7 +123,51 @@ var parseStreamPart = (line) => {
126
123
  return streamPartsByCode[code].parse(jsonValue);
127
124
  };
128
125
 
126
+ // shared/read-data-stream.ts
127
+ var NEWLINE = "\n".charCodeAt(0);
128
+ function concatChunks(chunks, totalLength) {
129
+ const concatenatedChunks = new Uint8Array(totalLength);
130
+ let offset = 0;
131
+ for (const chunk of chunks) {
132
+ concatenatedChunks.set(chunk, offset);
133
+ offset += chunk.length;
134
+ }
135
+ chunks.length = 0;
136
+ return concatenatedChunks;
137
+ }
138
+ async function* readDataStream(reader, {
139
+ isAborted
140
+ } = {}) {
141
+ const decoder = new TextDecoder();
142
+ const chunks = [];
143
+ let totalLength = 0;
144
+ while (true) {
145
+ const { value } = await reader.read();
146
+ if (value) {
147
+ chunks.push(value);
148
+ totalLength += value.length;
149
+ if (value[value.length - 1] !== NEWLINE) {
150
+ continue;
151
+ }
152
+ }
153
+ if (chunks.length === 0) {
154
+ break;
155
+ }
156
+ const concatenatedChunks = concatChunks(chunks, totalLength);
157
+ totalLength = 0;
158
+ const streamParts2 = decoder.decode(concatenatedChunks, { stream: true }).split("\n").filter((line) => line !== "").map(parseStreamPart);
159
+ for (const streamPart of streamParts2) {
160
+ yield streamPart;
161
+ }
162
+ if (isAborted == null ? void 0 : isAborted()) {
163
+ reader.cancel();
164
+ break;
165
+ }
166
+ }
167
+ }
168
+
129
169
  // shared/utils.ts
170
+ import { customAlphabet } from "nanoid/non-secure";
130
171
  var nanoid = customAlphabet(
131
172
  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
132
173
  7
@@ -145,6 +186,218 @@ function createChunkDecoder(complex) {
145
186
  return decoded.map(parseStreamPart).filter(Boolean);
146
187
  };
147
188
  }
189
+ var COMPLEX_HEADER = "X-Experimental-Stream-Data";
190
+
191
+ // shared/parse-complex-response.ts
192
+ async function parseComplexResponse({
193
+ reader,
194
+ abortControllerRef,
195
+ update,
196
+ onFinish,
197
+ generateId = nanoid,
198
+ getCurrentDate = () => /* @__PURE__ */ new Date()
199
+ }) {
200
+ const createdAt = getCurrentDate();
201
+ const prefixMap = {
202
+ data: []
203
+ };
204
+ for await (const { type, value } of readDataStream(reader, {
205
+ isAborted: () => (abortControllerRef == null ? void 0 : abortControllerRef.current) === null
206
+ })) {
207
+ if (type === "text") {
208
+ if (prefixMap["text"]) {
209
+ prefixMap["text"] = {
210
+ ...prefixMap["text"],
211
+ content: (prefixMap["text"].content || "") + value
212
+ };
213
+ } else {
214
+ prefixMap["text"] = {
215
+ id: generateId(),
216
+ role: "assistant",
217
+ content: value,
218
+ createdAt
219
+ };
220
+ }
221
+ }
222
+ let functionCallMessage = null;
223
+ if (type === "function_call") {
224
+ prefixMap["function_call"] = {
225
+ id: generateId(),
226
+ role: "assistant",
227
+ content: "",
228
+ function_call: value.function_call,
229
+ name: value.function_call.name,
230
+ createdAt
231
+ };
232
+ functionCallMessage = prefixMap["function_call"];
233
+ }
234
+ if (type === "data") {
235
+ prefixMap["data"].push(...value);
236
+ }
237
+ const responseMessage = prefixMap["text"];
238
+ const merged = [functionCallMessage, responseMessage].filter(
239
+ Boolean
240
+ );
241
+ update(merged, [...prefixMap["data"]]);
242
+ }
243
+ onFinish == null ? void 0 : onFinish(prefixMap);
244
+ return {
245
+ messages: [prefixMap.text, prefixMap.function_call].filter(
246
+ Boolean
247
+ ),
248
+ data: prefixMap.data
249
+ };
250
+ }
251
+
252
+ // shared/call-api.ts
253
+ async function callApi({
254
+ api,
255
+ messages,
256
+ body,
257
+ credentials,
258
+ headers,
259
+ abortController,
260
+ appendMessage,
261
+ restoreMessagesOnFailure,
262
+ onResponse,
263
+ onUpdate,
264
+ onFinish,
265
+ generateId
266
+ }) {
267
+ var _a;
268
+ const response = await fetch(api, {
269
+ method: "POST",
270
+ body: JSON.stringify({
271
+ messages,
272
+ ...body
273
+ }),
274
+ headers: {
275
+ "Content-Type": "application/json",
276
+ ...headers
277
+ },
278
+ signal: (_a = abortController == null ? void 0 : abortController()) == null ? void 0 : _a.signal,
279
+ credentials
280
+ }).catch((err) => {
281
+ restoreMessagesOnFailure();
282
+ throw err;
283
+ });
284
+ if (onResponse) {
285
+ try {
286
+ await onResponse(response);
287
+ } catch (err) {
288
+ throw err;
289
+ }
290
+ }
291
+ if (!response.ok) {
292
+ restoreMessagesOnFailure();
293
+ throw new Error(
294
+ await response.text() || "Failed to fetch the chat response."
295
+ );
296
+ }
297
+ if (!response.body) {
298
+ throw new Error("The response body is empty.");
299
+ }
300
+ const reader = response.body.getReader();
301
+ const isComplexMode = response.headers.get(COMPLEX_HEADER) === "true";
302
+ if (isComplexMode) {
303
+ return await parseComplexResponse({
304
+ reader,
305
+ abortControllerRef: abortController != null ? { current: abortController() } : void 0,
306
+ update: onUpdate,
307
+ onFinish(prefixMap) {
308
+ if (onFinish && prefixMap.text != null) {
309
+ onFinish(prefixMap.text);
310
+ }
311
+ },
312
+ generateId
313
+ });
314
+ } else {
315
+ const createdAt = /* @__PURE__ */ new Date();
316
+ const decode = createChunkDecoder(false);
317
+ let streamedResponse = "";
318
+ const replyId = generateId();
319
+ let responseMessage = {
320
+ id: replyId,
321
+ createdAt,
322
+ content: "",
323
+ role: "assistant"
324
+ };
325
+ while (true) {
326
+ const { done, value } = await reader.read();
327
+ if (done) {
328
+ break;
329
+ }
330
+ streamedResponse += decode(value);
331
+ if (streamedResponse.startsWith('{"function_call":')) {
332
+ responseMessage["function_call"] = streamedResponse;
333
+ } else {
334
+ responseMessage["content"] = streamedResponse;
335
+ }
336
+ appendMessage({ ...responseMessage });
337
+ if ((abortController == null ? void 0 : abortController()) === null) {
338
+ reader.cancel();
339
+ break;
340
+ }
341
+ }
342
+ if (streamedResponse.startsWith('{"function_call":')) {
343
+ const parsedFunctionCall = JSON.parse(streamedResponse).function_call;
344
+ responseMessage["function_call"] = parsedFunctionCall;
345
+ appendMessage({ ...responseMessage });
346
+ }
347
+ if (onFinish) {
348
+ onFinish(responseMessage);
349
+ }
350
+ return responseMessage;
351
+ }
352
+ }
353
+
354
+ // shared/process-chat-stream.ts
355
+ async function processChatStream({
356
+ getStreamedResponse,
357
+ experimental_onFunctionCall,
358
+ updateChatRequest,
359
+ getCurrentMessages
360
+ }) {
361
+ while (true) {
362
+ const messagesAndDataOrJustMessage = await getStreamedResponse();
363
+ if ("messages" in messagesAndDataOrJustMessage) {
364
+ let hasFollowingResponse = false;
365
+ for (const message of messagesAndDataOrJustMessage.messages) {
366
+ if (message.function_call === void 0 || typeof message.function_call === "string") {
367
+ continue;
368
+ }
369
+ hasFollowingResponse = true;
370
+ if (experimental_onFunctionCall) {
371
+ const functionCall = message.function_call;
372
+ const functionCallResponse = await experimental_onFunctionCall(
373
+ getCurrentMessages(),
374
+ functionCall
375
+ );
376
+ if (functionCallResponse === void 0) {
377
+ hasFollowingResponse = false;
378
+ break;
379
+ }
380
+ updateChatRequest(functionCallResponse);
381
+ }
382
+ }
383
+ if (!hasFollowingResponse) {
384
+ break;
385
+ }
386
+ } else {
387
+ const streamedResponseMessage = messagesAndDataOrJustMessage;
388
+ if (streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") {
389
+ break;
390
+ }
391
+ if (experimental_onFunctionCall) {
392
+ const functionCall = streamedResponseMessage.function_call;
393
+ const functionCallResponse = await experimental_onFunctionCall(getCurrentMessages(), functionCall);
394
+ if (functionCallResponse === void 0)
395
+ break;
396
+ updateChatRequest(functionCallResponse);
397
+ }
398
+ }
399
+ }
400
+ }
148
401
 
149
402
  // vue/use-chat.ts
150
403
  var uniqueId = 0;
@@ -156,17 +409,19 @@ function useChat({
156
409
  initialMessages = [],
157
410
  initialInput = "",
158
411
  sendExtraMessageFields,
412
+ experimental_onFunctionCall,
159
413
  onResponse,
160
414
  onFinish,
161
415
  onError,
162
416
  credentials,
163
417
  headers,
164
- body
418
+ body,
419
+ generateId = nanoid
165
420
  } = {}) {
166
- var _a;
421
+ var _a, _b;
167
422
  const chatId = id || `chat-${uniqueId++}`;
168
423
  const key = `${api}|${chatId}`;
169
- const { data, mutate: originalMutate } = useSWRV(
424
+ const { data: messagesData, mutate: originalMutate } = useSWRV(
170
425
  key,
171
426
  () => store[key] || initialMessages
172
427
  );
@@ -175,99 +430,78 @@ function useChat({
175
430
  null
176
431
  );
177
432
  (_a = isLoading.value) != null ? _a : isLoading.value = false;
178
- data.value || (data.value = initialMessages);
179
- const mutate = (data2) => {
180
- store[key] = data2;
433
+ (_b = messagesData.value) != null ? _b : messagesData.value = initialMessages;
434
+ const mutate = (data) => {
435
+ store[key] = data;
181
436
  return originalMutate();
182
437
  };
183
- const messages = data;
438
+ const messages = messagesData;
184
439
  const error = ref(void 0);
440
+ const streamData = ref(void 0);
185
441
  let abortController = null;
186
442
  async function triggerRequest(messagesSnapshot, options) {
187
443
  try {
188
444
  error.value = void 0;
189
445
  mutateLoading(() => true);
190
446
  abortController = new AbortController();
191
- const previousMessages = messages.value;
447
+ const previousMessages = messagesData.value;
192
448
  mutate(messagesSnapshot);
193
- const res = await fetch(api, {
194
- method: "POST",
195
- body: JSON.stringify({
196
- messages: sendExtraMessageFields ? messagesSnapshot : messagesSnapshot.map(
197
- ({ role, content, name, function_call }) => ({
198
- role,
199
- content,
200
- ...name !== void 0 && { name },
201
- ...function_call !== void 0 && {
202
- function_call
203
- }
204
- })
205
- ),
206
- ...unref(body),
207
- // Use unref to unwrap the ref value
208
- ...options == null ? void 0 : options.body
209
- }),
210
- headers: {
211
- ...headers,
212
- ...options == null ? void 0 : options.headers
449
+ let chatRequest = {
450
+ messages: messagesSnapshot,
451
+ options
452
+ };
453
+ await processChatStream({
454
+ getStreamedResponse: async () => {
455
+ var _a2;
456
+ const existingData = (_a2 = streamData.value) != null ? _a2 : [];
457
+ return await callApi({
458
+ api,
459
+ messages: sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(
460
+ ({ role, content, name, function_call }) => ({
461
+ role,
462
+ content,
463
+ ...name !== void 0 && { name },
464
+ ...function_call !== void 0 && {
465
+ function_call
466
+ }
467
+ })
468
+ ),
469
+ body: {
470
+ ...unref(body),
471
+ // Use unref to unwrap the ref value
472
+ ...options == null ? void 0 : options.body
473
+ },
474
+ headers: {
475
+ ...headers,
476
+ ...options == null ? void 0 : options.headers
477
+ },
478
+ abortController: () => abortController,
479
+ credentials,
480
+ onResponse,
481
+ onUpdate(merged, data) {
482
+ mutate([...chatRequest.messages, ...merged]);
483
+ streamData.value = [...existingData, ...data != null ? data : []];
484
+ },
485
+ onFinish(message) {
486
+ mutate([...chatRequest.messages, message]);
487
+ onFinish == null ? void 0 : onFinish(message);
488
+ },
489
+ appendMessage(message) {
490
+ mutate([...chatRequest.messages, message]);
491
+ },
492
+ restoreMessagesOnFailure() {
493
+ mutate(previousMessages);
494
+ },
495
+ generateId
496
+ });
213
497
  },
214
- signal: abortController.signal,
215
- credentials
216
- }).catch((err) => {
217
- mutate(previousMessages);
218
- throw err;
498
+ experimental_onFunctionCall,
499
+ updateChatRequest(newChatRequest) {
500
+ chatRequest = newChatRequest;
501
+ },
502
+ getCurrentMessages: () => messages.value
219
503
  });
220
- if (onResponse) {
221
- try {
222
- await onResponse(res);
223
- } catch (err) {
224
- throw err;
225
- }
226
- }
227
- if (!res.ok) {
228
- mutate(previousMessages);
229
- throw new Error(
230
- await res.text() || "Failed to fetch the chat response."
231
- );
232
- }
233
- if (!res.body) {
234
- throw new Error("The response body is empty.");
235
- }
236
- let result = "";
237
- const createdAt = /* @__PURE__ */ new Date();
238
- const replyId = nanoid();
239
- const reader = res.body.getReader();
240
- const decoder = createChunkDecoder();
241
- while (true) {
242
- const { done, value } = await reader.read();
243
- if (done) {
244
- break;
245
- }
246
- result += decoder(value);
247
- mutate([
248
- ...messagesSnapshot,
249
- {
250
- id: replyId,
251
- createdAt,
252
- content: result,
253
- role: "assistant"
254
- }
255
- ]);
256
- if (abortController === null) {
257
- reader.cancel();
258
- break;
259
- }
260
- }
261
- if (onFinish) {
262
- onFinish({
263
- id: replyId,
264
- createdAt,
265
- content: result,
266
- role: "assistant"
267
- });
268
- }
269
504
  abortController = null;
270
- return result;
271
505
  } catch (err) {
272
506
  if (err.name === "AbortError") {
273
507
  abortController = null;
@@ -283,7 +517,7 @@ function useChat({
283
517
  }
284
518
  const append = async (message, options) => {
285
519
  if (!message.id) {
286
- message.id = nanoid();
520
+ message.id = generateId();
287
521
  }
288
522
  return triggerRequest(messages.value.concat(message), options);
289
523
  };
@@ -327,7 +561,8 @@ function useChat({
327
561
  setMessages,
328
562
  input,
329
563
  handleSubmit,
330
- isLoading
564
+ isLoading,
565
+ data: streamData
331
566
  };
332
567
  }
333
568
 
@@ -361,6 +596,7 @@ function useCompletion({
361
596
  null
362
597
  );
363
598
  (_a = isLoading.value) != null ? _a : isLoading.value = false;
599
+ const { data: streamData, mutate: mutateStreamData } = useSWRV2(`${completionId}-data`, null);
364
600
  data.value || (data.value = initialCompletion);
365
601
  const mutate = (data2) => {
366
602
  store2[key] = data2;
@@ -370,6 +606,7 @@ function useCompletion({
370
606
  const error = ref2(void 0);
371
607
  let abortController = null;
372
608
  async function triggerRequest(prompt, options) {
609
+ var _a2;
373
610
  try {
374
611
  error.value = void 0;
375
612
  mutateLoading(() => true);
@@ -383,6 +620,7 @@ function useCompletion({
383
620
  ...options == null ? void 0 : options.body
384
621
  }),
385
622
  headers: {
623
+ "Content-Type": "application/json",
386
624
  ...headers,
387
625
  ...options == null ? void 0 : options.headers
388
626
  },
@@ -408,17 +646,37 @@ function useCompletion({
408
646
  }
409
647
  let result = "";
410
648
  const reader = res.body.getReader();
411
- const decoder = createChunkDecoder();
412
- while (true) {
413
- const { done, value } = await reader.read();
414
- if (done) {
415
- break;
649
+ const existingData = (_a2 = streamData.value) != null ? _a2 : [];
650
+ const isComplexMode = res.headers.get(COMPLEX_HEADER) === "true";
651
+ if (isComplexMode) {
652
+ for await (const { type, value } of readDataStream(reader, {
653
+ isAborted: () => abortController === null
654
+ })) {
655
+ switch (type) {
656
+ case "text": {
657
+ result += value;
658
+ mutate(result);
659
+ break;
660
+ }
661
+ case "data": {
662
+ streamData.value = [...existingData, ...value != null ? value : []];
663
+ break;
664
+ }
665
+ }
416
666
  }
417
- result += decoder(value);
418
- mutate(result);
419
- if (abortController === null) {
420
- reader.cancel();
421
- break;
667
+ } else {
668
+ const decoder = createChunkDecoder();
669
+ while (true) {
670
+ const { done, value } = await reader.read();
671
+ if (done) {
672
+ break;
673
+ }
674
+ result += decoder(value);
675
+ mutate(result);
676
+ if (abortController === null) {
677
+ reader.cancel();
678
+ break;
679
+ }
422
680
  }
423
681
  }
424
682
  if (onFinish) {
@@ -467,7 +725,8 @@ function useCompletion({
467
725
  setCompletion,
468
726
  input,
469
727
  handleSubmit,
470
- isLoading
728
+ isLoading,
729
+ data: streamData
471
730
  };
472
731
  }
473
732
  export {