ai 2.2.22 → 2.2.24
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 +59 -25
- package/dist/index.js +318 -39
- package/dist/index.mjs +317 -36
- package/package.json +10 -6
- package/react/dist/index.d.ts +40 -2
- package/react/dist/index.js +445 -195
- package/react/dist/index.mjs +444 -195
- package/solid/dist/index.d.ts +7 -1
- package/solid/dist/index.js +426 -107
- package/solid/dist/index.mjs +426 -107
- package/svelte/dist/index.d.ts +2 -0
- package/svelte/dist/index.js +124 -25
- package/svelte/dist/index.mjs +124 -25
- package/vue/dist/index.d.ts +1 -0
- package/vue/dist/index.js +124 -25
- package/vue/dist/index.mjs +124 -25
package/solid/dist/index.d.ts
CHANGED
@@ -64,6 +64,7 @@ type ChatRequest = {
|
|
64
64
|
options?: RequestOptions;
|
65
65
|
functions?: Array<Function>;
|
66
66
|
function_call?: FunctionCall;
|
67
|
+
data?: Record<string, string>;
|
67
68
|
};
|
68
69
|
type FunctionCallHandler = (chatMessages: Message[], functionCall: FunctionCall) => Promise<ChatRequest | void>;
|
69
70
|
type RequestOptions = {
|
@@ -194,6 +195,9 @@ type UseCompletionOptions = {
|
|
194
195
|
*/
|
195
196
|
body?: object;
|
196
197
|
};
|
198
|
+
type JSONValue = null | string | number | boolean | {
|
199
|
+
[x: string]: JSONValue;
|
200
|
+
} | Array<JSONValue>;
|
197
201
|
|
198
202
|
type UseChatHelpers = {
|
199
203
|
/** Current messages in the chat */
|
@@ -231,8 +235,10 @@ type UseChatHelpers = {
|
|
231
235
|
handleSubmit: (e: any) => void;
|
232
236
|
/** Whether the API request is in progress */
|
233
237
|
isLoading: Accessor<boolean>;
|
238
|
+
/** Additional data added on the server via StreamData */
|
239
|
+
data: Accessor<JSONValue[] | undefined>;
|
234
240
|
};
|
235
|
-
declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, onResponse, onFinish, onError, credentials, headers, body, }?: UseChatOptions): UseChatHelpers;
|
241
|
+
declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, experimental_onFunctionCall, onResponse, onFinish, onError, credentials, headers, body, }?: UseChatOptions): UseChatHelpers;
|
236
242
|
|
237
243
|
type UseCompletionHelpers = {
|
238
244
|
/** The current completion result */
|
package/solid/dist/index.js
CHANGED
@@ -30,8 +30,134 @@ var import_solid_js = require("solid-js");
|
|
30
30
|
var import_solid_swr_store = require("solid-swr-store");
|
31
31
|
var import_swr_store = require("swr-store");
|
32
32
|
|
33
|
+
// shared/call-api.ts
|
34
|
+
var import_nanoid = require("nanoid");
|
35
|
+
|
33
36
|
// shared/utils.ts
|
34
37
|
var import_non_secure = require("nanoid/non-secure");
|
38
|
+
|
39
|
+
// shared/stream-parts.ts
|
40
|
+
var textStreamPart = {
|
41
|
+
code: "0",
|
42
|
+
name: "text",
|
43
|
+
parse: (value) => {
|
44
|
+
if (typeof value !== "string") {
|
45
|
+
throw new Error('"text" parts expect a string value.');
|
46
|
+
}
|
47
|
+
return { type: "text", value };
|
48
|
+
}
|
49
|
+
};
|
50
|
+
var functionCallStreamPart = {
|
51
|
+
code: "1",
|
52
|
+
name: "function_call",
|
53
|
+
parse: (value) => {
|
54
|
+
if (value == null || typeof value !== "object" || !("function_call" in value) || typeof value.function_call !== "object" || value.function_call == null || !("name" in value.function_call) || !("arguments" in value.function_call) || typeof value.function_call.name !== "string" || typeof value.function_call.arguments !== "string") {
|
55
|
+
throw new Error(
|
56
|
+
'"function_call" parts expect an object with a "function_call" property.'
|
57
|
+
);
|
58
|
+
}
|
59
|
+
return {
|
60
|
+
type: "function_call",
|
61
|
+
value
|
62
|
+
};
|
63
|
+
}
|
64
|
+
};
|
65
|
+
var dataStreamPart = {
|
66
|
+
code: "2",
|
67
|
+
name: "data",
|
68
|
+
parse: (value) => {
|
69
|
+
if (!Array.isArray(value)) {
|
70
|
+
throw new Error('"data" parts expect an array value.');
|
71
|
+
}
|
72
|
+
return { type: "data", value };
|
73
|
+
}
|
74
|
+
};
|
75
|
+
var errorStreamPart = {
|
76
|
+
code: "3",
|
77
|
+
name: "error",
|
78
|
+
parse: (value) => {
|
79
|
+
if (typeof value !== "string") {
|
80
|
+
throw new Error('"error" parts expect a string value.');
|
81
|
+
}
|
82
|
+
return { type: "error", value };
|
83
|
+
}
|
84
|
+
};
|
85
|
+
var assistantMessage = {
|
86
|
+
code: "4",
|
87
|
+
name: "assistant_message",
|
88
|
+
parse: (value) => {
|
89
|
+
if (value == null || typeof value !== "object" || !("id" in value) || !("role" in value) || !("content" in value) || typeof value.id !== "string" || typeof value.role !== "string" || value.role !== "assistant" || !Array.isArray(value.content) || !value.content.every(
|
90
|
+
(item) => item != null && typeof item === "object" && "type" in item && item.type === "text" && "text" in item && item.text != null && typeof item.text === "object" && "value" in item.text && typeof item.text.value === "string"
|
91
|
+
)) {
|
92
|
+
throw new Error(
|
93
|
+
'"assistant_message" parts expect an object with an "id", "role", and "content" property.'
|
94
|
+
);
|
95
|
+
}
|
96
|
+
return {
|
97
|
+
type: "assistant_message",
|
98
|
+
value
|
99
|
+
};
|
100
|
+
}
|
101
|
+
};
|
102
|
+
var assistantControlData = {
|
103
|
+
code: "5",
|
104
|
+
name: "assistant_control_data",
|
105
|
+
parse: (value) => {
|
106
|
+
if (value == null || typeof value !== "object" || !("threadId" in value) || !("messageId" in value) || typeof value.threadId !== "string" || typeof value.messageId !== "string") {
|
107
|
+
throw new Error(
|
108
|
+
'"assistant_control_data" parts expect an object with a "threadId" and "messageId" property.'
|
109
|
+
);
|
110
|
+
}
|
111
|
+
return {
|
112
|
+
type: "assistant_control_data",
|
113
|
+
value: {
|
114
|
+
threadId: value.threadId,
|
115
|
+
messageId: value.messageId
|
116
|
+
}
|
117
|
+
};
|
118
|
+
}
|
119
|
+
};
|
120
|
+
var streamParts = [
|
121
|
+
textStreamPart,
|
122
|
+
functionCallStreamPart,
|
123
|
+
dataStreamPart,
|
124
|
+
errorStreamPart,
|
125
|
+
assistantMessage,
|
126
|
+
assistantControlData
|
127
|
+
];
|
128
|
+
var streamPartsByCode = {
|
129
|
+
[textStreamPart.code]: textStreamPart,
|
130
|
+
[functionCallStreamPart.code]: functionCallStreamPart,
|
131
|
+
[dataStreamPart.code]: dataStreamPart,
|
132
|
+
[errorStreamPart.code]: errorStreamPart,
|
133
|
+
[assistantMessage.code]: assistantMessage,
|
134
|
+
[assistantControlData.code]: assistantControlData
|
135
|
+
};
|
136
|
+
var StreamStringPrefixes = {
|
137
|
+
[textStreamPart.name]: textStreamPart.code,
|
138
|
+
[functionCallStreamPart.name]: functionCallStreamPart.code,
|
139
|
+
[dataStreamPart.name]: dataStreamPart.code,
|
140
|
+
[errorStreamPart.name]: errorStreamPart.code,
|
141
|
+
[assistantMessage.name]: assistantMessage.code,
|
142
|
+
[assistantControlData.name]: assistantControlData.code
|
143
|
+
};
|
144
|
+
var validCodes = streamParts.map((part) => part.code);
|
145
|
+
var parseStreamPart = (line) => {
|
146
|
+
const firstSeparatorIndex = line.indexOf(":");
|
147
|
+
if (firstSeparatorIndex === -1) {
|
148
|
+
throw new Error("Failed to parse stream string. No separator found.");
|
149
|
+
}
|
150
|
+
const prefix = line.slice(0, firstSeparatorIndex);
|
151
|
+
if (!validCodes.includes(prefix)) {
|
152
|
+
throw new Error(`Failed to parse stream string. Invalid code ${prefix}.`);
|
153
|
+
}
|
154
|
+
const code = prefix;
|
155
|
+
const textValue = line.slice(firstSeparatorIndex + 1);
|
156
|
+
const jsonValue = JSON.parse(textValue);
|
157
|
+
return streamPartsByCode[code].parse(jsonValue);
|
158
|
+
};
|
159
|
+
|
160
|
+
// shared/utils.ts
|
35
161
|
var nanoid = (0, import_non_secure.customAlphabet)(
|
36
162
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
37
163
|
7
|
@@ -47,33 +173,249 @@ function createChunkDecoder(complex) {
|
|
47
173
|
}
|
48
174
|
return function(chunk) {
|
49
175
|
const decoded = decoder.decode(chunk, { stream: true }).split("\n").filter((line) => line !== "");
|
50
|
-
return decoded.map(
|
176
|
+
return decoded.map(parseStreamPart).filter(Boolean);
|
51
177
|
};
|
52
178
|
}
|
53
|
-
var
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
);
|
65
|
-
const
|
66
|
-
|
67
|
-
|
68
|
-
|
179
|
+
var COMPLEX_HEADER = "X-Experimental-Stream-Data";
|
180
|
+
|
181
|
+
// shared/parse-complex-response.ts
|
182
|
+
async function parseComplexResponse({
|
183
|
+
reader,
|
184
|
+
abortControllerRef,
|
185
|
+
update,
|
186
|
+
onFinish,
|
187
|
+
generateId = nanoid,
|
188
|
+
getCurrentDate = () => /* @__PURE__ */ new Date()
|
189
|
+
}) {
|
190
|
+
const createdAt = getCurrentDate();
|
191
|
+
const decode = createChunkDecoder(true);
|
192
|
+
const prefixMap = {
|
193
|
+
data: []
|
194
|
+
};
|
195
|
+
const NEWLINE = "\n".charCodeAt(0);
|
196
|
+
const chunks = [];
|
197
|
+
let totalLength = 0;
|
198
|
+
while (true) {
|
199
|
+
const { value } = await reader.read();
|
200
|
+
if (value) {
|
201
|
+
chunks.push(value);
|
202
|
+
totalLength += value.length;
|
203
|
+
if (value[value.length - 1] !== NEWLINE) {
|
204
|
+
continue;
|
205
|
+
}
|
206
|
+
}
|
207
|
+
if (chunks.length === 0) {
|
208
|
+
break;
|
209
|
+
}
|
210
|
+
let concatenatedChunks = new Uint8Array(totalLength);
|
211
|
+
let offset = 0;
|
212
|
+
for (const chunk of chunks) {
|
213
|
+
concatenatedChunks.set(chunk, offset);
|
214
|
+
offset += chunk.length;
|
215
|
+
}
|
216
|
+
chunks.length = 0;
|
217
|
+
totalLength = 0;
|
218
|
+
const lines = decode(concatenatedChunks);
|
219
|
+
if (typeof lines === "string") {
|
220
|
+
throw new Error(
|
221
|
+
"Invalid response format. Complex mode was set but the response is a string. This should never happen."
|
222
|
+
);
|
223
|
+
}
|
224
|
+
for (const { type, value: value2 } of lines) {
|
225
|
+
if (type === "text") {
|
226
|
+
if (prefixMap["text"]) {
|
227
|
+
prefixMap["text"] = {
|
228
|
+
...prefixMap["text"],
|
229
|
+
content: (prefixMap["text"].content || "") + value2
|
230
|
+
};
|
231
|
+
} else {
|
232
|
+
prefixMap["text"] = {
|
233
|
+
id: generateId(),
|
234
|
+
role: "assistant",
|
235
|
+
content: value2,
|
236
|
+
createdAt
|
237
|
+
};
|
238
|
+
}
|
239
|
+
}
|
240
|
+
let functionCallMessage = null;
|
241
|
+
if (type === "function_call") {
|
242
|
+
prefixMap["function_call"] = {
|
243
|
+
id: generateId(),
|
244
|
+
role: "assistant",
|
245
|
+
content: "",
|
246
|
+
function_call: value2.function_call,
|
247
|
+
name: value2.function_call.name,
|
248
|
+
createdAt
|
249
|
+
};
|
250
|
+
functionCallMessage = prefixMap["function_call"];
|
251
|
+
}
|
252
|
+
if (type === "data") {
|
253
|
+
prefixMap["data"].push(...value2);
|
254
|
+
}
|
255
|
+
const responseMessage = prefixMap["text"];
|
256
|
+
const merged = [functionCallMessage, responseMessage].filter(
|
257
|
+
Boolean
|
258
|
+
);
|
259
|
+
update(merged, [...prefixMap["data"]]);
|
260
|
+
if ((abortControllerRef == null ? void 0 : abortControllerRef.current) === null) {
|
261
|
+
reader.cancel();
|
262
|
+
break;
|
263
|
+
}
|
264
|
+
}
|
69
265
|
}
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
266
|
+
onFinish == null ? void 0 : onFinish(prefixMap);
|
267
|
+
return {
|
268
|
+
messages: [prefixMap.text, prefixMap.function_call].filter(
|
269
|
+
Boolean
|
270
|
+
),
|
271
|
+
data: prefixMap.data
|
272
|
+
};
|
273
|
+
}
|
274
|
+
|
275
|
+
// shared/call-api.ts
|
276
|
+
async function callApi({
|
277
|
+
api,
|
278
|
+
messages,
|
279
|
+
body,
|
280
|
+
credentials,
|
281
|
+
headers,
|
282
|
+
abortController,
|
283
|
+
appendMessage,
|
284
|
+
restoreMessagesOnFailure,
|
285
|
+
onResponse,
|
286
|
+
onUpdate,
|
287
|
+
onFinish
|
288
|
+
}) {
|
289
|
+
var _a;
|
290
|
+
const response = await fetch(api, {
|
291
|
+
method: "POST",
|
292
|
+
body: JSON.stringify({
|
293
|
+
messages,
|
294
|
+
...body
|
295
|
+
}),
|
296
|
+
headers,
|
297
|
+
signal: (_a = abortController == null ? void 0 : abortController()) == null ? void 0 : _a.signal,
|
298
|
+
credentials
|
299
|
+
}).catch((err) => {
|
300
|
+
restoreMessagesOnFailure();
|
301
|
+
throw err;
|
302
|
+
});
|
303
|
+
if (onResponse) {
|
304
|
+
try {
|
305
|
+
await onResponse(response);
|
306
|
+
} catch (err) {
|
307
|
+
throw err;
|
308
|
+
}
|
74
309
|
}
|
75
|
-
|
76
|
-
|
310
|
+
if (!response.ok) {
|
311
|
+
restoreMessagesOnFailure();
|
312
|
+
throw new Error(
|
313
|
+
await response.text() || "Failed to fetch the chat response."
|
314
|
+
);
|
315
|
+
}
|
316
|
+
if (!response.body) {
|
317
|
+
throw new Error("The response body is empty.");
|
318
|
+
}
|
319
|
+
const reader = response.body.getReader();
|
320
|
+
const isComplexMode = response.headers.get(COMPLEX_HEADER) === "true";
|
321
|
+
if (isComplexMode) {
|
322
|
+
return await parseComplexResponse({
|
323
|
+
reader,
|
324
|
+
abortControllerRef: abortController != null ? { current: abortController() } : void 0,
|
325
|
+
update: onUpdate,
|
326
|
+
onFinish(prefixMap) {
|
327
|
+
if (onFinish && prefixMap.text != null) {
|
328
|
+
onFinish(prefixMap.text);
|
329
|
+
}
|
330
|
+
}
|
331
|
+
});
|
332
|
+
} else {
|
333
|
+
const createdAt = /* @__PURE__ */ new Date();
|
334
|
+
const decode = createChunkDecoder(false);
|
335
|
+
let streamedResponse = "";
|
336
|
+
const replyId = (0, import_nanoid.nanoid)();
|
337
|
+
let responseMessage = {
|
338
|
+
id: replyId,
|
339
|
+
createdAt,
|
340
|
+
content: "",
|
341
|
+
role: "assistant"
|
342
|
+
};
|
343
|
+
while (true) {
|
344
|
+
const { done, value } = await reader.read();
|
345
|
+
if (done) {
|
346
|
+
break;
|
347
|
+
}
|
348
|
+
streamedResponse += decode(value);
|
349
|
+
if (streamedResponse.startsWith('{"function_call":')) {
|
350
|
+
responseMessage["function_call"] = streamedResponse;
|
351
|
+
} else {
|
352
|
+
responseMessage["content"] = streamedResponse;
|
353
|
+
}
|
354
|
+
appendMessage({ ...responseMessage });
|
355
|
+
if ((abortController == null ? void 0 : abortController()) === null) {
|
356
|
+
reader.cancel();
|
357
|
+
break;
|
358
|
+
}
|
359
|
+
}
|
360
|
+
if (streamedResponse.startsWith('{"function_call":')) {
|
361
|
+
const parsedFunctionCall = JSON.parse(streamedResponse).function_call;
|
362
|
+
responseMessage["function_call"] = parsedFunctionCall;
|
363
|
+
appendMessage({ ...responseMessage });
|
364
|
+
}
|
365
|
+
if (onFinish) {
|
366
|
+
onFinish(responseMessage);
|
367
|
+
}
|
368
|
+
return responseMessage;
|
369
|
+
}
|
370
|
+
}
|
371
|
+
|
372
|
+
// shared/process-chat-stream.ts
|
373
|
+
async function processChatStream({
|
374
|
+
getStreamedResponse,
|
375
|
+
experimental_onFunctionCall,
|
376
|
+
updateChatRequest,
|
377
|
+
getCurrentMessages
|
378
|
+
}) {
|
379
|
+
while (true) {
|
380
|
+
const messagesAndDataOrJustMessage = await getStreamedResponse();
|
381
|
+
if ("messages" in messagesAndDataOrJustMessage) {
|
382
|
+
let hasFollowingResponse = false;
|
383
|
+
for (const message of messagesAndDataOrJustMessage.messages) {
|
384
|
+
if (message.function_call === void 0 || typeof message.function_call === "string") {
|
385
|
+
continue;
|
386
|
+
}
|
387
|
+
hasFollowingResponse = true;
|
388
|
+
if (experimental_onFunctionCall) {
|
389
|
+
const functionCall = message.function_call;
|
390
|
+
const functionCallResponse = await experimental_onFunctionCall(
|
391
|
+
getCurrentMessages(),
|
392
|
+
functionCall
|
393
|
+
);
|
394
|
+
if (functionCallResponse === void 0) {
|
395
|
+
hasFollowingResponse = false;
|
396
|
+
break;
|
397
|
+
}
|
398
|
+
updateChatRequest(functionCallResponse);
|
399
|
+
}
|
400
|
+
}
|
401
|
+
if (!hasFollowingResponse) {
|
402
|
+
break;
|
403
|
+
}
|
404
|
+
} else {
|
405
|
+
const streamedResponseMessage = messagesAndDataOrJustMessage;
|
406
|
+
if (streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") {
|
407
|
+
break;
|
408
|
+
}
|
409
|
+
if (experimental_onFunctionCall) {
|
410
|
+
const functionCall = streamedResponseMessage.function_call;
|
411
|
+
const functionCallResponse = await experimental_onFunctionCall(getCurrentMessages(), functionCall);
|
412
|
+
if (functionCallResponse === void 0)
|
413
|
+
break;
|
414
|
+
updateChatRequest(functionCallResponse);
|
415
|
+
}
|
416
|
+
}
|
417
|
+
}
|
418
|
+
}
|
77
419
|
|
78
420
|
// solid/use-chat.ts
|
79
421
|
var uniqueId = 0;
|
@@ -90,6 +432,7 @@ function useChat({
|
|
90
432
|
initialMessages = [],
|
91
433
|
initialInput = "",
|
92
434
|
sendExtraMessageFields,
|
435
|
+
experimental_onFunctionCall,
|
93
436
|
onResponse,
|
94
437
|
onFinish,
|
95
438
|
onError,
|
@@ -99,18 +442,20 @@ function useChat({
|
|
99
442
|
} = {}) {
|
100
443
|
const chatId = id || `chat-${uniqueId++}`;
|
101
444
|
const key = `${api}|${chatId}`;
|
102
|
-
const
|
445
|
+
const messages = (0, import_solid_swr_store.useSWRStore)(chatApiStore, () => [key], {
|
103
446
|
initialData: initialMessages
|
104
447
|
});
|
105
|
-
const mutate = (
|
106
|
-
store[key] =
|
448
|
+
const mutate = (data) => {
|
449
|
+
store[key] = data;
|
107
450
|
return chatApiStore.mutate([key], {
|
108
451
|
status: "success",
|
109
|
-
data
|
452
|
+
data
|
110
453
|
});
|
111
454
|
};
|
112
|
-
const messages = data;
|
113
455
|
const [error, setError] = (0, import_solid_js.createSignal)(void 0);
|
456
|
+
const [streamData, setStreamData] = (0, import_solid_js.createSignal)(
|
457
|
+
void 0
|
458
|
+
);
|
114
459
|
const [isLoading, setIsLoading] = (0, import_solid_js.createSignal)(false);
|
115
460
|
let abortController = null;
|
116
461
|
async function triggerRequest(messagesSnapshot, options) {
|
@@ -118,91 +463,64 @@ function useChat({
|
|
118
463
|
setError(void 0);
|
119
464
|
setIsLoading(true);
|
120
465
|
abortController = new AbortController();
|
121
|
-
const
|
466
|
+
const getCurrentMessages = () => chatApiStore.get([key], {
|
122
467
|
shouldRevalidate: false
|
123
468
|
});
|
469
|
+
const previousMessages = getCurrentMessages();
|
124
470
|
mutate(messagesSnapshot);
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
471
|
+
let chatRequest = {
|
472
|
+
messages: messagesSnapshot,
|
473
|
+
options
|
474
|
+
};
|
475
|
+
await processChatStream({
|
476
|
+
getStreamedResponse: async () => {
|
477
|
+
var _a;
|
478
|
+
const existingData = (_a = streamData()) != null ? _a : [];
|
479
|
+
return await callApi({
|
480
|
+
api,
|
481
|
+
messages: sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(
|
482
|
+
({ role, content, name, function_call }) => ({
|
483
|
+
role,
|
484
|
+
content,
|
485
|
+
...name !== void 0 && { name },
|
486
|
+
...function_call !== void 0 && {
|
487
|
+
function_call
|
488
|
+
}
|
489
|
+
})
|
490
|
+
),
|
491
|
+
body: {
|
492
|
+
...body,
|
493
|
+
...options == null ? void 0 : options.body
|
494
|
+
},
|
495
|
+
headers: {
|
496
|
+
...headers,
|
497
|
+
...options == null ? void 0 : options.headers
|
498
|
+
},
|
499
|
+
abortController: () => abortController,
|
500
|
+
credentials,
|
501
|
+
onResponse,
|
502
|
+
onUpdate(merged, data) {
|
503
|
+
mutate([...chatRequest.messages, ...merged]);
|
504
|
+
setStreamData([...existingData, ...data != null ? data : []]);
|
505
|
+
},
|
506
|
+
onFinish,
|
507
|
+
appendMessage(message) {
|
508
|
+
mutate([...chatRequest.messages, message]);
|
509
|
+
},
|
510
|
+
restoreMessagesOnFailure() {
|
511
|
+
if (previousMessages.status === "success") {
|
512
|
+
mutate(previousMessages.data);
|
135
513
|
}
|
136
|
-
}
|
137
|
-
)
|
138
|
-
...body,
|
139
|
-
...options == null ? void 0 : options.body
|
140
|
-
}),
|
141
|
-
headers: {
|
142
|
-
...headers,
|
143
|
-
...options == null ? void 0 : options.headers
|
514
|
+
}
|
515
|
+
});
|
144
516
|
},
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
}
|
151
|
-
throw err;
|
517
|
+
experimental_onFunctionCall,
|
518
|
+
updateChatRequest(newChatRequest) {
|
519
|
+
chatRequest = newChatRequest;
|
520
|
+
},
|
521
|
+
getCurrentMessages: () => getCurrentMessages().data
|
152
522
|
});
|
153
|
-
if (onResponse) {
|
154
|
-
try {
|
155
|
-
await onResponse(res);
|
156
|
-
} catch (err) {
|
157
|
-
throw err;
|
158
|
-
}
|
159
|
-
}
|
160
|
-
if (!res.ok) {
|
161
|
-
if (previousMessages.status === "success") {
|
162
|
-
mutate(previousMessages.data);
|
163
|
-
}
|
164
|
-
throw new Error(
|
165
|
-
await res.text() || "Failed to fetch the chat response."
|
166
|
-
);
|
167
|
-
}
|
168
|
-
if (!res.body) {
|
169
|
-
throw new Error("The response body is empty.");
|
170
|
-
}
|
171
|
-
let result = "";
|
172
|
-
const createdAt = /* @__PURE__ */ new Date();
|
173
|
-
const replyId = nanoid();
|
174
|
-
const reader = res.body.getReader();
|
175
|
-
const decoder = createChunkDecoder();
|
176
|
-
while (true) {
|
177
|
-
const { done, value } = await reader.read();
|
178
|
-
if (done) {
|
179
|
-
break;
|
180
|
-
}
|
181
|
-
result += decoder(value);
|
182
|
-
mutate([
|
183
|
-
...messagesSnapshot,
|
184
|
-
{
|
185
|
-
id: replyId,
|
186
|
-
createdAt,
|
187
|
-
content: result,
|
188
|
-
role: "assistant"
|
189
|
-
}
|
190
|
-
]);
|
191
|
-
if (abortController === null) {
|
192
|
-
reader.cancel();
|
193
|
-
break;
|
194
|
-
}
|
195
|
-
}
|
196
|
-
if (onFinish) {
|
197
|
-
onFinish({
|
198
|
-
id: replyId,
|
199
|
-
createdAt,
|
200
|
-
content: result,
|
201
|
-
role: "assistant"
|
202
|
-
});
|
203
|
-
}
|
204
523
|
abortController = null;
|
205
|
-
return result;
|
206
524
|
} catch (err) {
|
207
525
|
if (err.name === "AbortError") {
|
208
526
|
abortController = null;
|
@@ -268,7 +586,8 @@ function useChat({
|
|
268
586
|
input,
|
269
587
|
setInput,
|
270
588
|
handleSubmit,
|
271
|
-
isLoading
|
589
|
+
isLoading,
|
590
|
+
data: streamData
|
272
591
|
};
|
273
592
|
}
|
274
593
|
|