ai 2.2.24 → 2.2.26
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 +20 -1
- package/dist/index.js +79 -27
- package/dist/index.mjs +75 -27
- package/package.json +5 -1
- package/prompts/dist/index.d.ts +8 -1
- package/prompts/dist/index.js +17 -0
- package/prompts/dist/index.mjs +16 -0
- package/react/dist/index.d.ts +27 -9
- package/react/dist/index.js +75 -55
- package/react/dist/index.mjs +75 -55
- package/solid/dist/index.d.ts +7 -1
- package/solid/dist/index.js +14 -10
- package/solid/dist/index.mjs +14 -10
- package/svelte/dist/index.d.ts +12 -1
- package/svelte/dist/index.js +291 -94
- package/svelte/dist/index.mjs +291 -94
- package/vue/dist/index.d.ts +12 -1
- package/vue/dist/index.js +312 -85
- package/vue/dist/index.mjs +312 -85
package/vue/dist/index.js
CHANGED
@@ -182,6 +182,251 @@ function createChunkDecoder(complex) {
|
|
182
182
|
return decoded.map(parseStreamPart).filter(Boolean);
|
183
183
|
};
|
184
184
|
}
|
185
|
+
var COMPLEX_HEADER = "X-Experimental-Stream-Data";
|
186
|
+
|
187
|
+
// shared/parse-complex-response.ts
|
188
|
+
async function parseComplexResponse({
|
189
|
+
reader,
|
190
|
+
abortControllerRef,
|
191
|
+
update,
|
192
|
+
onFinish,
|
193
|
+
generateId = nanoid,
|
194
|
+
getCurrentDate = () => /* @__PURE__ */ new Date()
|
195
|
+
}) {
|
196
|
+
const createdAt = getCurrentDate();
|
197
|
+
const decode = createChunkDecoder(true);
|
198
|
+
const prefixMap = {
|
199
|
+
data: []
|
200
|
+
};
|
201
|
+
const NEWLINE = "\n".charCodeAt(0);
|
202
|
+
const chunks = [];
|
203
|
+
let totalLength = 0;
|
204
|
+
while (true) {
|
205
|
+
const { value } = await reader.read();
|
206
|
+
if (value) {
|
207
|
+
chunks.push(value);
|
208
|
+
totalLength += value.length;
|
209
|
+
if (value[value.length - 1] !== NEWLINE) {
|
210
|
+
continue;
|
211
|
+
}
|
212
|
+
}
|
213
|
+
if (chunks.length === 0) {
|
214
|
+
break;
|
215
|
+
}
|
216
|
+
let concatenatedChunks = new Uint8Array(totalLength);
|
217
|
+
let offset = 0;
|
218
|
+
for (const chunk of chunks) {
|
219
|
+
concatenatedChunks.set(chunk, offset);
|
220
|
+
offset += chunk.length;
|
221
|
+
}
|
222
|
+
chunks.length = 0;
|
223
|
+
totalLength = 0;
|
224
|
+
const lines = decode(concatenatedChunks);
|
225
|
+
if (typeof lines === "string") {
|
226
|
+
throw new Error(
|
227
|
+
"Invalid response format. Complex mode was set but the response is a string. This should never happen."
|
228
|
+
);
|
229
|
+
}
|
230
|
+
for (const { type, value: value2 } of lines) {
|
231
|
+
if (type === "text") {
|
232
|
+
if (prefixMap["text"]) {
|
233
|
+
prefixMap["text"] = {
|
234
|
+
...prefixMap["text"],
|
235
|
+
content: (prefixMap["text"].content || "") + value2
|
236
|
+
};
|
237
|
+
} else {
|
238
|
+
prefixMap["text"] = {
|
239
|
+
id: generateId(),
|
240
|
+
role: "assistant",
|
241
|
+
content: value2,
|
242
|
+
createdAt
|
243
|
+
};
|
244
|
+
}
|
245
|
+
}
|
246
|
+
let functionCallMessage = null;
|
247
|
+
if (type === "function_call") {
|
248
|
+
prefixMap["function_call"] = {
|
249
|
+
id: generateId(),
|
250
|
+
role: "assistant",
|
251
|
+
content: "",
|
252
|
+
function_call: value2.function_call,
|
253
|
+
name: value2.function_call.name,
|
254
|
+
createdAt
|
255
|
+
};
|
256
|
+
functionCallMessage = prefixMap["function_call"];
|
257
|
+
}
|
258
|
+
if (type === "data") {
|
259
|
+
prefixMap["data"].push(...value2);
|
260
|
+
}
|
261
|
+
const responseMessage = prefixMap["text"];
|
262
|
+
const merged = [functionCallMessage, responseMessage].filter(
|
263
|
+
Boolean
|
264
|
+
);
|
265
|
+
update(merged, [...prefixMap["data"]]);
|
266
|
+
if ((abortControllerRef == null ? void 0 : abortControllerRef.current) === null) {
|
267
|
+
reader.cancel();
|
268
|
+
break;
|
269
|
+
}
|
270
|
+
}
|
271
|
+
}
|
272
|
+
onFinish == null ? void 0 : onFinish(prefixMap);
|
273
|
+
return {
|
274
|
+
messages: [prefixMap.text, prefixMap.function_call].filter(
|
275
|
+
Boolean
|
276
|
+
),
|
277
|
+
data: prefixMap.data
|
278
|
+
};
|
279
|
+
}
|
280
|
+
|
281
|
+
// shared/call-api.ts
|
282
|
+
async function callApi({
|
283
|
+
api,
|
284
|
+
messages,
|
285
|
+
body,
|
286
|
+
credentials,
|
287
|
+
headers,
|
288
|
+
abortController,
|
289
|
+
appendMessage,
|
290
|
+
restoreMessagesOnFailure,
|
291
|
+
onResponse,
|
292
|
+
onUpdate,
|
293
|
+
onFinish,
|
294
|
+
generateId
|
295
|
+
}) {
|
296
|
+
var _a;
|
297
|
+
const response = await fetch(api, {
|
298
|
+
method: "POST",
|
299
|
+
body: JSON.stringify({
|
300
|
+
messages,
|
301
|
+
...body
|
302
|
+
}),
|
303
|
+
headers: {
|
304
|
+
"Content-Type": "application/json",
|
305
|
+
...headers
|
306
|
+
},
|
307
|
+
signal: (_a = abortController == null ? void 0 : abortController()) == null ? void 0 : _a.signal,
|
308
|
+
credentials
|
309
|
+
}).catch((err) => {
|
310
|
+
restoreMessagesOnFailure();
|
311
|
+
throw err;
|
312
|
+
});
|
313
|
+
if (onResponse) {
|
314
|
+
try {
|
315
|
+
await onResponse(response);
|
316
|
+
} catch (err) {
|
317
|
+
throw err;
|
318
|
+
}
|
319
|
+
}
|
320
|
+
if (!response.ok) {
|
321
|
+
restoreMessagesOnFailure();
|
322
|
+
throw new Error(
|
323
|
+
await response.text() || "Failed to fetch the chat response."
|
324
|
+
);
|
325
|
+
}
|
326
|
+
if (!response.body) {
|
327
|
+
throw new Error("The response body is empty.");
|
328
|
+
}
|
329
|
+
const reader = response.body.getReader();
|
330
|
+
const isComplexMode = response.headers.get(COMPLEX_HEADER) === "true";
|
331
|
+
if (isComplexMode) {
|
332
|
+
return await parseComplexResponse({
|
333
|
+
reader,
|
334
|
+
abortControllerRef: abortController != null ? { current: abortController() } : void 0,
|
335
|
+
update: onUpdate,
|
336
|
+
onFinish(prefixMap) {
|
337
|
+
if (onFinish && prefixMap.text != null) {
|
338
|
+
onFinish(prefixMap.text);
|
339
|
+
}
|
340
|
+
},
|
341
|
+
generateId
|
342
|
+
});
|
343
|
+
} else {
|
344
|
+
const createdAt = /* @__PURE__ */ new Date();
|
345
|
+
const decode = createChunkDecoder(false);
|
346
|
+
let streamedResponse = "";
|
347
|
+
const replyId = generateId();
|
348
|
+
let responseMessage = {
|
349
|
+
id: replyId,
|
350
|
+
createdAt,
|
351
|
+
content: "",
|
352
|
+
role: "assistant"
|
353
|
+
};
|
354
|
+
while (true) {
|
355
|
+
const { done, value } = await reader.read();
|
356
|
+
if (done) {
|
357
|
+
break;
|
358
|
+
}
|
359
|
+
streamedResponse += decode(value);
|
360
|
+
if (streamedResponse.startsWith('{"function_call":')) {
|
361
|
+
responseMessage["function_call"] = streamedResponse;
|
362
|
+
} else {
|
363
|
+
responseMessage["content"] = streamedResponse;
|
364
|
+
}
|
365
|
+
appendMessage({ ...responseMessage });
|
366
|
+
if ((abortController == null ? void 0 : abortController()) === null) {
|
367
|
+
reader.cancel();
|
368
|
+
break;
|
369
|
+
}
|
370
|
+
}
|
371
|
+
if (streamedResponse.startsWith('{"function_call":')) {
|
372
|
+
const parsedFunctionCall = JSON.parse(streamedResponse).function_call;
|
373
|
+
responseMessage["function_call"] = parsedFunctionCall;
|
374
|
+
appendMessage({ ...responseMessage });
|
375
|
+
}
|
376
|
+
if (onFinish) {
|
377
|
+
onFinish(responseMessage);
|
378
|
+
}
|
379
|
+
return responseMessage;
|
380
|
+
}
|
381
|
+
}
|
382
|
+
|
383
|
+
// shared/process-chat-stream.ts
|
384
|
+
async function processChatStream({
|
385
|
+
getStreamedResponse,
|
386
|
+
experimental_onFunctionCall,
|
387
|
+
updateChatRequest,
|
388
|
+
getCurrentMessages
|
389
|
+
}) {
|
390
|
+
while (true) {
|
391
|
+
const messagesAndDataOrJustMessage = await getStreamedResponse();
|
392
|
+
if ("messages" in messagesAndDataOrJustMessage) {
|
393
|
+
let hasFollowingResponse = false;
|
394
|
+
for (const message of messagesAndDataOrJustMessage.messages) {
|
395
|
+
if (message.function_call === void 0 || typeof message.function_call === "string") {
|
396
|
+
continue;
|
397
|
+
}
|
398
|
+
hasFollowingResponse = true;
|
399
|
+
if (experimental_onFunctionCall) {
|
400
|
+
const functionCall = message.function_call;
|
401
|
+
const functionCallResponse = await experimental_onFunctionCall(
|
402
|
+
getCurrentMessages(),
|
403
|
+
functionCall
|
404
|
+
);
|
405
|
+
if (functionCallResponse === void 0) {
|
406
|
+
hasFollowingResponse = false;
|
407
|
+
break;
|
408
|
+
}
|
409
|
+
updateChatRequest(functionCallResponse);
|
410
|
+
}
|
411
|
+
}
|
412
|
+
if (!hasFollowingResponse) {
|
413
|
+
break;
|
414
|
+
}
|
415
|
+
} else {
|
416
|
+
const streamedResponseMessage = messagesAndDataOrJustMessage;
|
417
|
+
if (streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") {
|
418
|
+
break;
|
419
|
+
}
|
420
|
+
if (experimental_onFunctionCall) {
|
421
|
+
const functionCall = streamedResponseMessage.function_call;
|
422
|
+
const functionCallResponse = await experimental_onFunctionCall(getCurrentMessages(), functionCall);
|
423
|
+
if (functionCallResponse === void 0)
|
424
|
+
break;
|
425
|
+
updateChatRequest(functionCallResponse);
|
426
|
+
}
|
427
|
+
}
|
428
|
+
}
|
429
|
+
}
|
185
430
|
|
186
431
|
// vue/use-chat.ts
|
187
432
|
var uniqueId = 0;
|
@@ -193,17 +438,19 @@ function useChat({
|
|
193
438
|
initialMessages = [],
|
194
439
|
initialInput = "",
|
195
440
|
sendExtraMessageFields,
|
441
|
+
experimental_onFunctionCall,
|
196
442
|
onResponse,
|
197
443
|
onFinish,
|
198
444
|
onError,
|
199
445
|
credentials,
|
200
446
|
headers,
|
201
|
-
body
|
447
|
+
body,
|
448
|
+
generateId = nanoid
|
202
449
|
} = {}) {
|
203
|
-
var _a;
|
450
|
+
var _a, _b;
|
204
451
|
const chatId = id || `chat-${uniqueId++}`;
|
205
452
|
const key = `${api}|${chatId}`;
|
206
|
-
const { data, mutate: originalMutate } = useSWRV(
|
453
|
+
const { data: messagesData, mutate: originalMutate } = useSWRV(
|
207
454
|
key,
|
208
455
|
() => store[key] || initialMessages
|
209
456
|
);
|
@@ -212,99 +459,78 @@ function useChat({
|
|
212
459
|
null
|
213
460
|
);
|
214
461
|
(_a = isLoading.value) != null ? _a : isLoading.value = false;
|
215
|
-
|
216
|
-
const mutate = (
|
217
|
-
store[key] =
|
462
|
+
(_b = messagesData.value) != null ? _b : messagesData.value = initialMessages;
|
463
|
+
const mutate = (data) => {
|
464
|
+
store[key] = data;
|
218
465
|
return originalMutate();
|
219
466
|
};
|
220
|
-
const messages =
|
467
|
+
const messages = messagesData;
|
221
468
|
const error = (0, import_vue.ref)(void 0);
|
469
|
+
const streamData = (0, import_vue.ref)(void 0);
|
222
470
|
let abortController = null;
|
223
471
|
async function triggerRequest(messagesSnapshot, options) {
|
224
472
|
try {
|
225
473
|
error.value = void 0;
|
226
474
|
mutateLoading(() => true);
|
227
475
|
abortController = new AbortController();
|
228
|
-
const previousMessages =
|
476
|
+
const previousMessages = messagesData.value;
|
229
477
|
mutate(messagesSnapshot);
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
478
|
+
let chatRequest = {
|
479
|
+
messages: messagesSnapshot,
|
480
|
+
options
|
481
|
+
};
|
482
|
+
await processChatStream({
|
483
|
+
getStreamedResponse: async () => {
|
484
|
+
var _a2;
|
485
|
+
const existingData = (_a2 = streamData.value) != null ? _a2 : [];
|
486
|
+
return await callApi({
|
487
|
+
api,
|
488
|
+
messages: sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(
|
489
|
+
({ role, content, name, function_call }) => ({
|
490
|
+
role,
|
491
|
+
content,
|
492
|
+
...name !== void 0 && { name },
|
493
|
+
...function_call !== void 0 && {
|
494
|
+
function_call
|
495
|
+
}
|
496
|
+
})
|
497
|
+
),
|
498
|
+
body: {
|
499
|
+
...(0, import_vue.unref)(body),
|
500
|
+
// Use unref to unwrap the ref value
|
501
|
+
...options == null ? void 0 : options.body
|
502
|
+
},
|
503
|
+
headers: {
|
504
|
+
...headers,
|
505
|
+
...options == null ? void 0 : options.headers
|
506
|
+
},
|
507
|
+
abortController: () => abortController,
|
508
|
+
credentials,
|
509
|
+
onResponse,
|
510
|
+
onUpdate(merged, data) {
|
511
|
+
mutate([...chatRequest.messages, ...merged]);
|
512
|
+
streamData.value = [...existingData, ...data != null ? data : []];
|
513
|
+
},
|
514
|
+
onFinish(message) {
|
515
|
+
mutate([...chatRequest.messages, message]);
|
516
|
+
onFinish == null ? void 0 : onFinish(message);
|
517
|
+
},
|
518
|
+
appendMessage(message) {
|
519
|
+
mutate([...chatRequest.messages, message]);
|
520
|
+
},
|
521
|
+
restoreMessagesOnFailure() {
|
522
|
+
mutate(previousMessages);
|
523
|
+
},
|
524
|
+
generateId
|
525
|
+
});
|
250
526
|
},
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
527
|
+
experimental_onFunctionCall,
|
528
|
+
updateChatRequest(newChatRequest) {
|
529
|
+
chatRequest = newChatRequest;
|
530
|
+
},
|
531
|
+
getCurrentMessages: () => messages.value
|
256
532
|
});
|
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
533
|
abortController = null;
|
307
|
-
return result;
|
308
534
|
} catch (err) {
|
309
535
|
if (err.name === "AbortError") {
|
310
536
|
abortController = null;
|
@@ -320,7 +546,7 @@ function useChat({
|
|
320
546
|
}
|
321
547
|
const append = async (message, options) => {
|
322
548
|
if (!message.id) {
|
323
|
-
message.id =
|
549
|
+
message.id = generateId();
|
324
550
|
}
|
325
551
|
return triggerRequest(messages.value.concat(message), options);
|
326
552
|
};
|
@@ -364,7 +590,8 @@ function useChat({
|
|
364
590
|
setMessages,
|
365
591
|
input,
|
366
592
|
handleSubmit,
|
367
|
-
isLoading
|
593
|
+
isLoading,
|
594
|
+
data: streamData
|
368
595
|
};
|
369
596
|
}
|
370
597
|
|