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.
- package/dist/index.d.ts +8 -1
- package/dist/index.js +78 -66
- package/dist/index.mjs +78 -66
- package/package.json +14 -11
- package/react/dist/index.d.ts +32 -9
- package/react/dist/index.js +150 -125
- package/react/dist/index.mjs +150 -125
- package/solid/dist/index.d.ts +9 -1
- package/solid/dist/index.js +127 -90
- package/solid/dist/index.mjs +127 -90
- package/svelte/dist/index.d.ts +9 -1
- package/svelte/dist/index.js +125 -90
- package/svelte/dist/index.mjs +125 -90
- package/vue/dist/index.d.ts +14 -1
- package/vue/dist/index.js +358 -99
- package/vue/dist/index.mjs +358 -99
package/vue/dist/index.js
CHANGED
@@ -39,9 +39,6 @@ module.exports = __toCommonJS(vue_exports);
|
|
39
39
|
var import_swrv = __toESM(require("swrv"));
|
40
40
|
var import_vue = require("vue");
|
41
41
|
|
42
|
-
// shared/utils.ts
|
43
|
-
var import_non_secure = require("nanoid/non-secure");
|
44
|
-
|
45
42
|
// shared/stream-parts.ts
|
46
43
|
var textStreamPart = {
|
47
44
|
code: "0",
|
@@ -163,7 +160,51 @@ var parseStreamPart = (line) => {
|
|
163
160
|
return streamPartsByCode[code].parse(jsonValue);
|
164
161
|
};
|
165
162
|
|
163
|
+
// shared/read-data-stream.ts
|
164
|
+
var NEWLINE = "\n".charCodeAt(0);
|
165
|
+
function concatChunks(chunks, totalLength) {
|
166
|
+
const concatenatedChunks = new Uint8Array(totalLength);
|
167
|
+
let offset = 0;
|
168
|
+
for (const chunk of chunks) {
|
169
|
+
concatenatedChunks.set(chunk, offset);
|
170
|
+
offset += chunk.length;
|
171
|
+
}
|
172
|
+
chunks.length = 0;
|
173
|
+
return concatenatedChunks;
|
174
|
+
}
|
175
|
+
async function* readDataStream(reader, {
|
176
|
+
isAborted
|
177
|
+
} = {}) {
|
178
|
+
const decoder = new TextDecoder();
|
179
|
+
const chunks = [];
|
180
|
+
let totalLength = 0;
|
181
|
+
while (true) {
|
182
|
+
const { value } = await reader.read();
|
183
|
+
if (value) {
|
184
|
+
chunks.push(value);
|
185
|
+
totalLength += value.length;
|
186
|
+
if (value[value.length - 1] !== NEWLINE) {
|
187
|
+
continue;
|
188
|
+
}
|
189
|
+
}
|
190
|
+
if (chunks.length === 0) {
|
191
|
+
break;
|
192
|
+
}
|
193
|
+
const concatenatedChunks = concatChunks(chunks, totalLength);
|
194
|
+
totalLength = 0;
|
195
|
+
const streamParts2 = decoder.decode(concatenatedChunks, { stream: true }).split("\n").filter((line) => line !== "").map(parseStreamPart);
|
196
|
+
for (const streamPart of streamParts2) {
|
197
|
+
yield streamPart;
|
198
|
+
}
|
199
|
+
if (isAborted == null ? void 0 : isAborted()) {
|
200
|
+
reader.cancel();
|
201
|
+
break;
|
202
|
+
}
|
203
|
+
}
|
204
|
+
}
|
205
|
+
|
166
206
|
// shared/utils.ts
|
207
|
+
var import_non_secure = require("nanoid/non-secure");
|
167
208
|
var nanoid = (0, import_non_secure.customAlphabet)(
|
168
209
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
169
210
|
7
|
@@ -182,6 +223,218 @@ function createChunkDecoder(complex) {
|
|
182
223
|
return decoded.map(parseStreamPart).filter(Boolean);
|
183
224
|
};
|
184
225
|
}
|
226
|
+
var COMPLEX_HEADER = "X-Experimental-Stream-Data";
|
227
|
+
|
228
|
+
// shared/parse-complex-response.ts
|
229
|
+
async function parseComplexResponse({
|
230
|
+
reader,
|
231
|
+
abortControllerRef,
|
232
|
+
update,
|
233
|
+
onFinish,
|
234
|
+
generateId = nanoid,
|
235
|
+
getCurrentDate = () => /* @__PURE__ */ new Date()
|
236
|
+
}) {
|
237
|
+
const createdAt = getCurrentDate();
|
238
|
+
const prefixMap = {
|
239
|
+
data: []
|
240
|
+
};
|
241
|
+
for await (const { type, value } of readDataStream(reader, {
|
242
|
+
isAborted: () => (abortControllerRef == null ? void 0 : abortControllerRef.current) === null
|
243
|
+
})) {
|
244
|
+
if (type === "text") {
|
245
|
+
if (prefixMap["text"]) {
|
246
|
+
prefixMap["text"] = {
|
247
|
+
...prefixMap["text"],
|
248
|
+
content: (prefixMap["text"].content || "") + value
|
249
|
+
};
|
250
|
+
} else {
|
251
|
+
prefixMap["text"] = {
|
252
|
+
id: generateId(),
|
253
|
+
role: "assistant",
|
254
|
+
content: value,
|
255
|
+
createdAt
|
256
|
+
};
|
257
|
+
}
|
258
|
+
}
|
259
|
+
let functionCallMessage = null;
|
260
|
+
if (type === "function_call") {
|
261
|
+
prefixMap["function_call"] = {
|
262
|
+
id: generateId(),
|
263
|
+
role: "assistant",
|
264
|
+
content: "",
|
265
|
+
function_call: value.function_call,
|
266
|
+
name: value.function_call.name,
|
267
|
+
createdAt
|
268
|
+
};
|
269
|
+
functionCallMessage = prefixMap["function_call"];
|
270
|
+
}
|
271
|
+
if (type === "data") {
|
272
|
+
prefixMap["data"].push(...value);
|
273
|
+
}
|
274
|
+
const responseMessage = prefixMap["text"];
|
275
|
+
const merged = [functionCallMessage, responseMessage].filter(
|
276
|
+
Boolean
|
277
|
+
);
|
278
|
+
update(merged, [...prefixMap["data"]]);
|
279
|
+
}
|
280
|
+
onFinish == null ? void 0 : onFinish(prefixMap);
|
281
|
+
return {
|
282
|
+
messages: [prefixMap.text, prefixMap.function_call].filter(
|
283
|
+
Boolean
|
284
|
+
),
|
285
|
+
data: prefixMap.data
|
286
|
+
};
|
287
|
+
}
|
288
|
+
|
289
|
+
// shared/call-api.ts
|
290
|
+
async function callApi({
|
291
|
+
api,
|
292
|
+
messages,
|
293
|
+
body,
|
294
|
+
credentials,
|
295
|
+
headers,
|
296
|
+
abortController,
|
297
|
+
appendMessage,
|
298
|
+
restoreMessagesOnFailure,
|
299
|
+
onResponse,
|
300
|
+
onUpdate,
|
301
|
+
onFinish,
|
302
|
+
generateId
|
303
|
+
}) {
|
304
|
+
var _a;
|
305
|
+
const response = await fetch(api, {
|
306
|
+
method: "POST",
|
307
|
+
body: JSON.stringify({
|
308
|
+
messages,
|
309
|
+
...body
|
310
|
+
}),
|
311
|
+
headers: {
|
312
|
+
"Content-Type": "application/json",
|
313
|
+
...headers
|
314
|
+
},
|
315
|
+
signal: (_a = abortController == null ? void 0 : abortController()) == null ? void 0 : _a.signal,
|
316
|
+
credentials
|
317
|
+
}).catch((err) => {
|
318
|
+
restoreMessagesOnFailure();
|
319
|
+
throw err;
|
320
|
+
});
|
321
|
+
if (onResponse) {
|
322
|
+
try {
|
323
|
+
await onResponse(response);
|
324
|
+
} catch (err) {
|
325
|
+
throw err;
|
326
|
+
}
|
327
|
+
}
|
328
|
+
if (!response.ok) {
|
329
|
+
restoreMessagesOnFailure();
|
330
|
+
throw new Error(
|
331
|
+
await response.text() || "Failed to fetch the chat response."
|
332
|
+
);
|
333
|
+
}
|
334
|
+
if (!response.body) {
|
335
|
+
throw new Error("The response body is empty.");
|
336
|
+
}
|
337
|
+
const reader = response.body.getReader();
|
338
|
+
const isComplexMode = response.headers.get(COMPLEX_HEADER) === "true";
|
339
|
+
if (isComplexMode) {
|
340
|
+
return await parseComplexResponse({
|
341
|
+
reader,
|
342
|
+
abortControllerRef: abortController != null ? { current: abortController() } : void 0,
|
343
|
+
update: onUpdate,
|
344
|
+
onFinish(prefixMap) {
|
345
|
+
if (onFinish && prefixMap.text != null) {
|
346
|
+
onFinish(prefixMap.text);
|
347
|
+
}
|
348
|
+
},
|
349
|
+
generateId
|
350
|
+
});
|
351
|
+
} else {
|
352
|
+
const createdAt = /* @__PURE__ */ new Date();
|
353
|
+
const decode = createChunkDecoder(false);
|
354
|
+
let streamedResponse = "";
|
355
|
+
const replyId = generateId();
|
356
|
+
let responseMessage = {
|
357
|
+
id: replyId,
|
358
|
+
createdAt,
|
359
|
+
content: "",
|
360
|
+
role: "assistant"
|
361
|
+
};
|
362
|
+
while (true) {
|
363
|
+
const { done, value } = await reader.read();
|
364
|
+
if (done) {
|
365
|
+
break;
|
366
|
+
}
|
367
|
+
streamedResponse += decode(value);
|
368
|
+
if (streamedResponse.startsWith('{"function_call":')) {
|
369
|
+
responseMessage["function_call"] = streamedResponse;
|
370
|
+
} else {
|
371
|
+
responseMessage["content"] = streamedResponse;
|
372
|
+
}
|
373
|
+
appendMessage({ ...responseMessage });
|
374
|
+
if ((abortController == null ? void 0 : abortController()) === null) {
|
375
|
+
reader.cancel();
|
376
|
+
break;
|
377
|
+
}
|
378
|
+
}
|
379
|
+
if (streamedResponse.startsWith('{"function_call":')) {
|
380
|
+
const parsedFunctionCall = JSON.parse(streamedResponse).function_call;
|
381
|
+
responseMessage["function_call"] = parsedFunctionCall;
|
382
|
+
appendMessage({ ...responseMessage });
|
383
|
+
}
|
384
|
+
if (onFinish) {
|
385
|
+
onFinish(responseMessage);
|
386
|
+
}
|
387
|
+
return responseMessage;
|
388
|
+
}
|
389
|
+
}
|
390
|
+
|
391
|
+
// shared/process-chat-stream.ts
|
392
|
+
async function processChatStream({
|
393
|
+
getStreamedResponse,
|
394
|
+
experimental_onFunctionCall,
|
395
|
+
updateChatRequest,
|
396
|
+
getCurrentMessages
|
397
|
+
}) {
|
398
|
+
while (true) {
|
399
|
+
const messagesAndDataOrJustMessage = await getStreamedResponse();
|
400
|
+
if ("messages" in messagesAndDataOrJustMessage) {
|
401
|
+
let hasFollowingResponse = false;
|
402
|
+
for (const message of messagesAndDataOrJustMessage.messages) {
|
403
|
+
if (message.function_call === void 0 || typeof message.function_call === "string") {
|
404
|
+
continue;
|
405
|
+
}
|
406
|
+
hasFollowingResponse = true;
|
407
|
+
if (experimental_onFunctionCall) {
|
408
|
+
const functionCall = message.function_call;
|
409
|
+
const functionCallResponse = await experimental_onFunctionCall(
|
410
|
+
getCurrentMessages(),
|
411
|
+
functionCall
|
412
|
+
);
|
413
|
+
if (functionCallResponse === void 0) {
|
414
|
+
hasFollowingResponse = false;
|
415
|
+
break;
|
416
|
+
}
|
417
|
+
updateChatRequest(functionCallResponse);
|
418
|
+
}
|
419
|
+
}
|
420
|
+
if (!hasFollowingResponse) {
|
421
|
+
break;
|
422
|
+
}
|
423
|
+
} else {
|
424
|
+
const streamedResponseMessage = messagesAndDataOrJustMessage;
|
425
|
+
if (streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") {
|
426
|
+
break;
|
427
|
+
}
|
428
|
+
if (experimental_onFunctionCall) {
|
429
|
+
const functionCall = streamedResponseMessage.function_call;
|
430
|
+
const functionCallResponse = await experimental_onFunctionCall(getCurrentMessages(), functionCall);
|
431
|
+
if (functionCallResponse === void 0)
|
432
|
+
break;
|
433
|
+
updateChatRequest(functionCallResponse);
|
434
|
+
}
|
435
|
+
}
|
436
|
+
}
|
437
|
+
}
|
185
438
|
|
186
439
|
// vue/use-chat.ts
|
187
440
|
var uniqueId = 0;
|
@@ -193,17 +446,19 @@ function useChat({
|
|
193
446
|
initialMessages = [],
|
194
447
|
initialInput = "",
|
195
448
|
sendExtraMessageFields,
|
449
|
+
experimental_onFunctionCall,
|
196
450
|
onResponse,
|
197
451
|
onFinish,
|
198
452
|
onError,
|
199
453
|
credentials,
|
200
454
|
headers,
|
201
|
-
body
|
455
|
+
body,
|
456
|
+
generateId = nanoid
|
202
457
|
} = {}) {
|
203
|
-
var _a;
|
458
|
+
var _a, _b;
|
204
459
|
const chatId = id || `chat-${uniqueId++}`;
|
205
460
|
const key = `${api}|${chatId}`;
|
206
|
-
const { data, mutate: originalMutate } = useSWRV(
|
461
|
+
const { data: messagesData, mutate: originalMutate } = useSWRV(
|
207
462
|
key,
|
208
463
|
() => store[key] || initialMessages
|
209
464
|
);
|
@@ -212,99 +467,78 @@ function useChat({
|
|
212
467
|
null
|
213
468
|
);
|
214
469
|
(_a = isLoading.value) != null ? _a : isLoading.value = false;
|
215
|
-
|
216
|
-
const mutate = (
|
217
|
-
store[key] =
|
470
|
+
(_b = messagesData.value) != null ? _b : messagesData.value = initialMessages;
|
471
|
+
const mutate = (data) => {
|
472
|
+
store[key] = data;
|
218
473
|
return originalMutate();
|
219
474
|
};
|
220
|
-
const messages =
|
475
|
+
const messages = messagesData;
|
221
476
|
const error = (0, import_vue.ref)(void 0);
|
477
|
+
const streamData = (0, import_vue.ref)(void 0);
|
222
478
|
let abortController = null;
|
223
479
|
async function triggerRequest(messagesSnapshot, options) {
|
224
480
|
try {
|
225
481
|
error.value = void 0;
|
226
482
|
mutateLoading(() => true);
|
227
483
|
abortController = new AbortController();
|
228
|
-
const previousMessages =
|
484
|
+
const previousMessages = messagesData.value;
|
229
485
|
mutate(messagesSnapshot);
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
486
|
+
let chatRequest = {
|
487
|
+
messages: messagesSnapshot,
|
488
|
+
options
|
489
|
+
};
|
490
|
+
await processChatStream({
|
491
|
+
getStreamedResponse: async () => {
|
492
|
+
var _a2;
|
493
|
+
const existingData = (_a2 = streamData.value) != null ? _a2 : [];
|
494
|
+
return await callApi({
|
495
|
+
api,
|
496
|
+
messages: sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(
|
497
|
+
({ role, content, name, function_call }) => ({
|
498
|
+
role,
|
499
|
+
content,
|
500
|
+
...name !== void 0 && { name },
|
501
|
+
...function_call !== void 0 && {
|
502
|
+
function_call
|
503
|
+
}
|
504
|
+
})
|
505
|
+
),
|
506
|
+
body: {
|
507
|
+
...(0, import_vue.unref)(body),
|
508
|
+
// Use unref to unwrap the ref value
|
509
|
+
...options == null ? void 0 : options.body
|
510
|
+
},
|
511
|
+
headers: {
|
512
|
+
...headers,
|
513
|
+
...options == null ? void 0 : options.headers
|
514
|
+
},
|
515
|
+
abortController: () => abortController,
|
516
|
+
credentials,
|
517
|
+
onResponse,
|
518
|
+
onUpdate(merged, data) {
|
519
|
+
mutate([...chatRequest.messages, ...merged]);
|
520
|
+
streamData.value = [...existingData, ...data != null ? data : []];
|
521
|
+
},
|
522
|
+
onFinish(message) {
|
523
|
+
mutate([...chatRequest.messages, message]);
|
524
|
+
onFinish == null ? void 0 : onFinish(message);
|
525
|
+
},
|
526
|
+
appendMessage(message) {
|
527
|
+
mutate([...chatRequest.messages, message]);
|
528
|
+
},
|
529
|
+
restoreMessagesOnFailure() {
|
530
|
+
mutate(previousMessages);
|
531
|
+
},
|
532
|
+
generateId
|
533
|
+
});
|
250
534
|
},
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
535
|
+
experimental_onFunctionCall,
|
536
|
+
updateChatRequest(newChatRequest) {
|
537
|
+
chatRequest = newChatRequest;
|
538
|
+
},
|
539
|
+
getCurrentMessages: () => messages.value
|
256
540
|
});
|
257
|
-
if (onResponse) {
|
258
|
-
try {
|
259
|
-
await onResponse(res);
|
260
|
-
} catch (err) {
|
261
|
-
throw err;
|
262
|
-
}
|
263
|
-
}
|
264
|
-
if (!res.ok) {
|
265
|
-
mutate(previousMessages);
|
266
|
-
throw new Error(
|
267
|
-
await res.text() || "Failed to fetch the chat response."
|
268
|
-
);
|
269
|
-
}
|
270
|
-
if (!res.body) {
|
271
|
-
throw new Error("The response body is empty.");
|
272
|
-
}
|
273
|
-
let result = "";
|
274
|
-
const createdAt = /* @__PURE__ */ new Date();
|
275
|
-
const replyId = nanoid();
|
276
|
-
const reader = res.body.getReader();
|
277
|
-
const decoder = createChunkDecoder();
|
278
|
-
while (true) {
|
279
|
-
const { done, value } = await reader.read();
|
280
|
-
if (done) {
|
281
|
-
break;
|
282
|
-
}
|
283
|
-
result += decoder(value);
|
284
|
-
mutate([
|
285
|
-
...messagesSnapshot,
|
286
|
-
{
|
287
|
-
id: replyId,
|
288
|
-
createdAt,
|
289
|
-
content: result,
|
290
|
-
role: "assistant"
|
291
|
-
}
|
292
|
-
]);
|
293
|
-
if (abortController === null) {
|
294
|
-
reader.cancel();
|
295
|
-
break;
|
296
|
-
}
|
297
|
-
}
|
298
|
-
if (onFinish) {
|
299
|
-
onFinish({
|
300
|
-
id: replyId,
|
301
|
-
createdAt,
|
302
|
-
content: result,
|
303
|
-
role: "assistant"
|
304
|
-
});
|
305
|
-
}
|
306
541
|
abortController = null;
|
307
|
-
return result;
|
308
542
|
} catch (err) {
|
309
543
|
if (err.name === "AbortError") {
|
310
544
|
abortController = null;
|
@@ -320,7 +554,7 @@ function useChat({
|
|
320
554
|
}
|
321
555
|
const append = async (message, options) => {
|
322
556
|
if (!message.id) {
|
323
|
-
message.id =
|
557
|
+
message.id = generateId();
|
324
558
|
}
|
325
559
|
return triggerRequest(messages.value.concat(message), options);
|
326
560
|
};
|
@@ -364,7 +598,8 @@ function useChat({
|
|
364
598
|
setMessages,
|
365
599
|
input,
|
366
600
|
handleSubmit,
|
367
|
-
isLoading
|
601
|
+
isLoading,
|
602
|
+
data: streamData
|
368
603
|
};
|
369
604
|
}
|
370
605
|
|
@@ -398,6 +633,7 @@ function useCompletion({
|
|
398
633
|
null
|
399
634
|
);
|
400
635
|
(_a = isLoading.value) != null ? _a : isLoading.value = false;
|
636
|
+
const { data: streamData, mutate: mutateStreamData } = useSWRV2(`${completionId}-data`, null);
|
401
637
|
data.value || (data.value = initialCompletion);
|
402
638
|
const mutate = (data2) => {
|
403
639
|
store2[key] = data2;
|
@@ -407,6 +643,7 @@ function useCompletion({
|
|
407
643
|
const error = (0, import_vue2.ref)(void 0);
|
408
644
|
let abortController = null;
|
409
645
|
async function triggerRequest(prompt, options) {
|
646
|
+
var _a2;
|
410
647
|
try {
|
411
648
|
error.value = void 0;
|
412
649
|
mutateLoading(() => true);
|
@@ -420,6 +657,7 @@ function useCompletion({
|
|
420
657
|
...options == null ? void 0 : options.body
|
421
658
|
}),
|
422
659
|
headers: {
|
660
|
+
"Content-Type": "application/json",
|
423
661
|
...headers,
|
424
662
|
...options == null ? void 0 : options.headers
|
425
663
|
},
|
@@ -445,17 +683,37 @@ function useCompletion({
|
|
445
683
|
}
|
446
684
|
let result = "";
|
447
685
|
const reader = res.body.getReader();
|
448
|
-
const
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
686
|
+
const existingData = (_a2 = streamData.value) != null ? _a2 : [];
|
687
|
+
const isComplexMode = res.headers.get(COMPLEX_HEADER) === "true";
|
688
|
+
if (isComplexMode) {
|
689
|
+
for await (const { type, value } of readDataStream(reader, {
|
690
|
+
isAborted: () => abortController === null
|
691
|
+
})) {
|
692
|
+
switch (type) {
|
693
|
+
case "text": {
|
694
|
+
result += value;
|
695
|
+
mutate(result);
|
696
|
+
break;
|
697
|
+
}
|
698
|
+
case "data": {
|
699
|
+
streamData.value = [...existingData, ...value != null ? value : []];
|
700
|
+
break;
|
701
|
+
}
|
702
|
+
}
|
453
703
|
}
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
reader.
|
458
|
-
|
704
|
+
} else {
|
705
|
+
const decoder = createChunkDecoder();
|
706
|
+
while (true) {
|
707
|
+
const { done, value } = await reader.read();
|
708
|
+
if (done) {
|
709
|
+
break;
|
710
|
+
}
|
711
|
+
result += decoder(value);
|
712
|
+
mutate(result);
|
713
|
+
if (abortController === null) {
|
714
|
+
reader.cancel();
|
715
|
+
break;
|
716
|
+
}
|
459
717
|
}
|
460
718
|
}
|
461
719
|
if (onFinish) {
|
@@ -504,7 +762,8 @@ function useCompletion({
|
|
504
762
|
setCompletion,
|
505
763
|
input,
|
506
764
|
handleSubmit,
|
507
|
-
isLoading
|
765
|
+
isLoading,
|
766
|
+
data: streamData
|
508
767
|
};
|
509
768
|
}
|
510
769
|
// Annotate the CommonJS export names for ESM import in node:
|