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