@ai-sdk/react 1.2.12 → 2.0.0-alpha.2
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/CHANGELOG.md +268 -26
- package/README.md +1 -1
- package/dist/index.d.mts +29 -122
- package/dist/index.d.ts +29 -122
- package/dist/index.js +164 -550
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +164 -558
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -10
package/dist/index.mjs
CHANGED
|
@@ -1,545 +1,156 @@
|
|
|
1
|
-
// src/use-assistant.ts
|
|
2
|
-
import { isAbortError } from "@ai-sdk/provider-utils";
|
|
3
|
-
import {
|
|
4
|
-
generateId,
|
|
5
|
-
processAssistantStream
|
|
6
|
-
} from "@ai-sdk/ui-utils";
|
|
7
|
-
import { useCallback, useRef, useState } from "react";
|
|
8
|
-
var getOriginalFetch = () => fetch;
|
|
9
|
-
function useAssistant({
|
|
10
|
-
api,
|
|
11
|
-
threadId: threadIdParam,
|
|
12
|
-
credentials,
|
|
13
|
-
headers,
|
|
14
|
-
body,
|
|
15
|
-
onError,
|
|
16
|
-
fetch: fetch2
|
|
17
|
-
}) {
|
|
18
|
-
const [messages, setMessages] = useState([]);
|
|
19
|
-
const [input, setInput] = useState("");
|
|
20
|
-
const [currentThreadId, setCurrentThreadId] = useState(
|
|
21
|
-
void 0
|
|
22
|
-
);
|
|
23
|
-
const [status, setStatus] = useState("awaiting_message");
|
|
24
|
-
const [error, setError] = useState(void 0);
|
|
25
|
-
const handleInputChange = (event) => {
|
|
26
|
-
setInput(event.target.value);
|
|
27
|
-
};
|
|
28
|
-
const abortControllerRef = useRef(null);
|
|
29
|
-
const stop = useCallback(() => {
|
|
30
|
-
if (abortControllerRef.current) {
|
|
31
|
-
abortControllerRef.current.abort();
|
|
32
|
-
abortControllerRef.current = null;
|
|
33
|
-
}
|
|
34
|
-
}, []);
|
|
35
|
-
const append = async (message, requestOptions) => {
|
|
36
|
-
var _a, _b;
|
|
37
|
-
setStatus("in_progress");
|
|
38
|
-
setMessages((messages2) => {
|
|
39
|
-
var _a2;
|
|
40
|
-
return [
|
|
41
|
-
...messages2,
|
|
42
|
-
{
|
|
43
|
-
...message,
|
|
44
|
-
id: (_a2 = message.id) != null ? _a2 : generateId()
|
|
45
|
-
}
|
|
46
|
-
];
|
|
47
|
-
});
|
|
48
|
-
setInput("");
|
|
49
|
-
const abortController = new AbortController();
|
|
50
|
-
try {
|
|
51
|
-
abortControllerRef.current = abortController;
|
|
52
|
-
const actualFetch = fetch2 != null ? fetch2 : getOriginalFetch();
|
|
53
|
-
const response = await actualFetch(api, {
|
|
54
|
-
method: "POST",
|
|
55
|
-
credentials,
|
|
56
|
-
signal: abortController.signal,
|
|
57
|
-
headers: { "Content-Type": "application/json", ...headers },
|
|
58
|
-
body: JSON.stringify({
|
|
59
|
-
...body,
|
|
60
|
-
// always use user-provided threadId when available:
|
|
61
|
-
threadId: (_a = threadIdParam != null ? threadIdParam : currentThreadId) != null ? _a : null,
|
|
62
|
-
message: message.content,
|
|
63
|
-
// optional request data:
|
|
64
|
-
data: requestOptions == null ? void 0 : requestOptions.data
|
|
65
|
-
})
|
|
66
|
-
});
|
|
67
|
-
if (!response.ok) {
|
|
68
|
-
throw new Error(
|
|
69
|
-
(_b = await response.text()) != null ? _b : "Failed to fetch the assistant response."
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
if (response.body == null) {
|
|
73
|
-
throw new Error("The response body is empty.");
|
|
74
|
-
}
|
|
75
|
-
await processAssistantStream({
|
|
76
|
-
stream: response.body,
|
|
77
|
-
onAssistantMessagePart(value) {
|
|
78
|
-
setMessages((messages2) => [
|
|
79
|
-
...messages2,
|
|
80
|
-
{
|
|
81
|
-
id: value.id,
|
|
82
|
-
role: value.role,
|
|
83
|
-
content: value.content[0].text.value,
|
|
84
|
-
parts: []
|
|
85
|
-
}
|
|
86
|
-
]);
|
|
87
|
-
},
|
|
88
|
-
onTextPart(value) {
|
|
89
|
-
setMessages((messages2) => {
|
|
90
|
-
const lastMessage = messages2[messages2.length - 1];
|
|
91
|
-
return [
|
|
92
|
-
...messages2.slice(0, messages2.length - 1),
|
|
93
|
-
{
|
|
94
|
-
id: lastMessage.id,
|
|
95
|
-
role: lastMessage.role,
|
|
96
|
-
content: lastMessage.content + value,
|
|
97
|
-
parts: lastMessage.parts
|
|
98
|
-
}
|
|
99
|
-
];
|
|
100
|
-
});
|
|
101
|
-
},
|
|
102
|
-
onAssistantControlDataPart(value) {
|
|
103
|
-
setCurrentThreadId(value.threadId);
|
|
104
|
-
setMessages((messages2) => {
|
|
105
|
-
const lastMessage = messages2[messages2.length - 1];
|
|
106
|
-
lastMessage.id = value.messageId;
|
|
107
|
-
return [...messages2.slice(0, messages2.length - 1), lastMessage];
|
|
108
|
-
});
|
|
109
|
-
},
|
|
110
|
-
onDataMessagePart(value) {
|
|
111
|
-
setMessages((messages2) => {
|
|
112
|
-
var _a2;
|
|
113
|
-
return [
|
|
114
|
-
...messages2,
|
|
115
|
-
{
|
|
116
|
-
id: (_a2 = value.id) != null ? _a2 : generateId(),
|
|
117
|
-
role: "data",
|
|
118
|
-
content: "",
|
|
119
|
-
data: value.data,
|
|
120
|
-
parts: []
|
|
121
|
-
}
|
|
122
|
-
];
|
|
123
|
-
});
|
|
124
|
-
},
|
|
125
|
-
onErrorPart(value) {
|
|
126
|
-
setError(new Error(value));
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
} catch (error2) {
|
|
130
|
-
if (isAbortError(error2) && abortController.signal.aborted) {
|
|
131
|
-
abortControllerRef.current = null;
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
if (onError && error2 instanceof Error) {
|
|
135
|
-
onError(error2);
|
|
136
|
-
}
|
|
137
|
-
setError(error2);
|
|
138
|
-
} finally {
|
|
139
|
-
abortControllerRef.current = null;
|
|
140
|
-
setStatus("awaiting_message");
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
const submitMessage = async (event, requestOptions) => {
|
|
144
|
-
var _a;
|
|
145
|
-
(_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
|
|
146
|
-
if (input === "") {
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
append({ role: "user", content: input, parts: [] }, requestOptions);
|
|
150
|
-
};
|
|
151
|
-
const setThreadId = (threadId) => {
|
|
152
|
-
setCurrentThreadId(threadId);
|
|
153
|
-
setMessages([]);
|
|
154
|
-
};
|
|
155
|
-
return {
|
|
156
|
-
append,
|
|
157
|
-
messages,
|
|
158
|
-
setMessages,
|
|
159
|
-
threadId: currentThreadId,
|
|
160
|
-
setThreadId,
|
|
161
|
-
input,
|
|
162
|
-
setInput,
|
|
163
|
-
handleInputChange,
|
|
164
|
-
submitMessage,
|
|
165
|
-
status,
|
|
166
|
-
error,
|
|
167
|
-
stop
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
|
|
171
1
|
// src/use-chat.ts
|
|
172
2
|
import {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
isAssistantMessageWithCompletedToolCalls,
|
|
179
|
-
prepareAttachmentsForRequest,
|
|
180
|
-
shouldResubmitMessages,
|
|
181
|
-
updateToolCallResult
|
|
182
|
-
} from "@ai-sdk/ui-utils";
|
|
183
|
-
import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState3 } from "react";
|
|
184
|
-
import useSWR from "swr";
|
|
185
|
-
|
|
186
|
-
// src/throttle.ts
|
|
187
|
-
import throttleFunction from "throttleit";
|
|
188
|
-
function throttle(fn, waitMs) {
|
|
189
|
-
return waitMs != null ? throttleFunction(fn, waitMs) : fn;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// src/util/use-stable-value.ts
|
|
193
|
-
import { isDeepEqualData } from "@ai-sdk/ui-utils";
|
|
194
|
-
import { useEffect, useState as useState2 } from "react";
|
|
195
|
-
function useStableValue(latestValue) {
|
|
196
|
-
const [value, setValue] = useState2(latestValue);
|
|
197
|
-
useEffect(() => {
|
|
198
|
-
if (!isDeepEqualData(latestValue, value)) {
|
|
199
|
-
setValue(latestValue);
|
|
200
|
-
}
|
|
201
|
-
}, [latestValue, value]);
|
|
202
|
-
return value;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// src/use-chat.ts
|
|
3
|
+
convertFileListToFileUIParts,
|
|
4
|
+
defaultChatStore,
|
|
5
|
+
generateId as generateIdFunc
|
|
6
|
+
} from "ai";
|
|
7
|
+
import { useCallback, useRef, useState, useSyncExternalStore } from "react";
|
|
206
8
|
function useChat({
|
|
207
|
-
|
|
208
|
-
id,
|
|
209
|
-
initialMessages,
|
|
9
|
+
chatId,
|
|
210
10
|
initialInput = "",
|
|
211
|
-
sendExtraMessageFields,
|
|
212
11
|
onToolCall,
|
|
213
|
-
experimental_prepareRequestBody,
|
|
214
|
-
maxSteps = 1,
|
|
215
|
-
streamProtocol = "data",
|
|
216
|
-
onResponse,
|
|
217
12
|
onFinish,
|
|
218
13
|
onError,
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
generateId: generateId2 = generateIdFunc,
|
|
223
|
-
fetch: fetch2,
|
|
224
|
-
keepLastMessageOnError = true,
|
|
225
|
-
experimental_throttle: throttleWaitMs
|
|
14
|
+
generateId = generateIdFunc,
|
|
15
|
+
experimental_throttle: throttleWaitMs,
|
|
16
|
+
chatStore: chatStoreArg
|
|
226
17
|
} = {}) {
|
|
227
|
-
const [hookId] =
|
|
228
|
-
const
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
18
|
+
const [hookId] = useState(generateId);
|
|
19
|
+
const stableChatId = chatId != null ? chatId : hookId;
|
|
20
|
+
const chatStore = useRef(
|
|
21
|
+
chatStoreArg != null ? chatStoreArg : defaultChatStore({
|
|
22
|
+
api: "/api/chat",
|
|
23
|
+
generateId
|
|
24
|
+
})
|
|
234
25
|
);
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
const { data: status = "ready", mutate: mutateStatus } = useSWR([chatKey, "status"], null);
|
|
250
|
-
const { data: error = void 0, mutate: setError } = useSWR([chatKey, "error"], null);
|
|
251
|
-
const abortControllerRef = useRef2(null);
|
|
252
|
-
const extraMetadataRef = useRef2({
|
|
253
|
-
credentials,
|
|
254
|
-
headers,
|
|
255
|
-
body
|
|
256
|
-
});
|
|
257
|
-
useEffect2(() => {
|
|
258
|
-
extraMetadataRef.current = {
|
|
259
|
-
credentials,
|
|
260
|
-
headers,
|
|
261
|
-
body
|
|
262
|
-
};
|
|
263
|
-
}, [credentials, headers, body]);
|
|
264
|
-
const triggerRequest = useCallback2(
|
|
265
|
-
async (chatRequest, requestType = "generate") => {
|
|
266
|
-
var _a, _b;
|
|
267
|
-
mutateStatus("submitted");
|
|
268
|
-
setError(void 0);
|
|
269
|
-
const chatMessages = fillMessageParts(chatRequest.messages);
|
|
270
|
-
const messageCount = chatMessages.length;
|
|
271
|
-
const maxStep = extractMaxToolInvocationStep(
|
|
272
|
-
(_a = chatMessages[chatMessages.length - 1]) == null ? void 0 : _a.toolInvocations
|
|
273
|
-
);
|
|
274
|
-
try {
|
|
275
|
-
const abortController = new AbortController();
|
|
276
|
-
abortControllerRef.current = abortController;
|
|
277
|
-
const throttledMutate = throttle(mutate, throttleWaitMs);
|
|
278
|
-
const throttledMutateStreamData = throttle(
|
|
279
|
-
mutateStreamData,
|
|
280
|
-
throttleWaitMs
|
|
281
|
-
);
|
|
282
|
-
const previousMessages = messagesRef.current;
|
|
283
|
-
throttledMutate(chatMessages, false);
|
|
284
|
-
const constructedMessagesPayload = sendExtraMessageFields ? chatMessages : chatMessages.map(
|
|
285
|
-
({
|
|
286
|
-
role,
|
|
287
|
-
content,
|
|
288
|
-
experimental_attachments,
|
|
289
|
-
data,
|
|
290
|
-
annotations,
|
|
291
|
-
toolInvocations,
|
|
292
|
-
parts
|
|
293
|
-
}) => ({
|
|
294
|
-
role,
|
|
295
|
-
content,
|
|
296
|
-
...experimental_attachments !== void 0 && {
|
|
297
|
-
experimental_attachments
|
|
298
|
-
},
|
|
299
|
-
...data !== void 0 && { data },
|
|
300
|
-
...annotations !== void 0 && { annotations },
|
|
301
|
-
...toolInvocations !== void 0 && { toolInvocations },
|
|
302
|
-
...parts !== void 0 && { parts }
|
|
303
|
-
})
|
|
304
|
-
);
|
|
305
|
-
const existingData = streamDataRef.current;
|
|
306
|
-
await callChatApi({
|
|
307
|
-
api,
|
|
308
|
-
body: (_b = experimental_prepareRequestBody == null ? void 0 : experimental_prepareRequestBody({
|
|
309
|
-
id: chatId,
|
|
310
|
-
messages: chatMessages,
|
|
311
|
-
requestData: chatRequest.data,
|
|
312
|
-
requestBody: chatRequest.body
|
|
313
|
-
})) != null ? _b : {
|
|
314
|
-
id: chatId,
|
|
315
|
-
messages: constructedMessagesPayload,
|
|
316
|
-
data: chatRequest.data,
|
|
317
|
-
...extraMetadataRef.current.body,
|
|
318
|
-
...chatRequest.body
|
|
319
|
-
},
|
|
320
|
-
streamProtocol,
|
|
321
|
-
credentials: extraMetadataRef.current.credentials,
|
|
322
|
-
headers: {
|
|
323
|
-
...extraMetadataRef.current.headers,
|
|
324
|
-
...chatRequest.headers
|
|
325
|
-
},
|
|
326
|
-
abortController: () => abortControllerRef.current,
|
|
327
|
-
restoreMessagesOnFailure() {
|
|
328
|
-
if (!keepLastMessageOnError) {
|
|
329
|
-
throttledMutate(previousMessages, false);
|
|
330
|
-
}
|
|
331
|
-
},
|
|
332
|
-
onResponse,
|
|
333
|
-
onUpdate({ message, data, replaceLastMessage }) {
|
|
334
|
-
mutateStatus("streaming");
|
|
335
|
-
throttledMutate(
|
|
336
|
-
[
|
|
337
|
-
...replaceLastMessage ? chatMessages.slice(0, chatMessages.length - 1) : chatMessages,
|
|
338
|
-
message
|
|
339
|
-
],
|
|
340
|
-
false
|
|
341
|
-
);
|
|
342
|
-
if (data == null ? void 0 : data.length) {
|
|
343
|
-
throttledMutateStreamData(
|
|
344
|
-
[...existingData != null ? existingData : [], ...data],
|
|
345
|
-
false
|
|
346
|
-
);
|
|
347
|
-
}
|
|
348
|
-
},
|
|
349
|
-
onToolCall,
|
|
350
|
-
onFinish,
|
|
351
|
-
generateId: generateId2,
|
|
352
|
-
fetch: fetch2,
|
|
353
|
-
lastMessage: chatMessages[chatMessages.length - 1],
|
|
354
|
-
requestType
|
|
355
|
-
});
|
|
356
|
-
abortControllerRef.current = null;
|
|
357
|
-
mutateStatus("ready");
|
|
358
|
-
} catch (err) {
|
|
359
|
-
if (err.name === "AbortError") {
|
|
360
|
-
abortControllerRef.current = null;
|
|
361
|
-
mutateStatus("ready");
|
|
362
|
-
return null;
|
|
363
|
-
}
|
|
364
|
-
if (onError && err instanceof Error) {
|
|
365
|
-
onError(err);
|
|
26
|
+
if (!chatStore.current.hasChat(stableChatId)) {
|
|
27
|
+
chatStore.current.addChat(stableChatId, []);
|
|
28
|
+
}
|
|
29
|
+
const subscribe = useCallback(
|
|
30
|
+
({
|
|
31
|
+
onStoreChange,
|
|
32
|
+
eventType
|
|
33
|
+
}) => {
|
|
34
|
+
return chatStore.current.subscribe({
|
|
35
|
+
onChatChanged: (event) => {
|
|
36
|
+
if (event.chatId !== stableChatId || event.type !== eventType) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
onStoreChange();
|
|
366
40
|
}
|
|
367
|
-
setError(err);
|
|
368
|
-
mutateStatus("error");
|
|
369
|
-
}
|
|
370
|
-
const messages2 = messagesRef.current;
|
|
371
|
-
if (shouldResubmitMessages({
|
|
372
|
-
originalMaxToolInvocationStep: maxStep,
|
|
373
|
-
originalMessageCount: messageCount,
|
|
374
|
-
maxSteps,
|
|
375
|
-
messages: messages2
|
|
376
|
-
})) {
|
|
377
|
-
await triggerRequest({ messages: messages2 });
|
|
378
|
-
}
|
|
379
|
-
},
|
|
380
|
-
[
|
|
381
|
-
mutate,
|
|
382
|
-
mutateStatus,
|
|
383
|
-
api,
|
|
384
|
-
extraMetadataRef,
|
|
385
|
-
onResponse,
|
|
386
|
-
onFinish,
|
|
387
|
-
onError,
|
|
388
|
-
setError,
|
|
389
|
-
mutateStreamData,
|
|
390
|
-
streamDataRef,
|
|
391
|
-
streamProtocol,
|
|
392
|
-
sendExtraMessageFields,
|
|
393
|
-
experimental_prepareRequestBody,
|
|
394
|
-
onToolCall,
|
|
395
|
-
maxSteps,
|
|
396
|
-
messagesRef,
|
|
397
|
-
abortControllerRef,
|
|
398
|
-
generateId2,
|
|
399
|
-
fetch2,
|
|
400
|
-
keepLastMessageOnError,
|
|
401
|
-
throttleWaitMs,
|
|
402
|
-
chatId
|
|
403
|
-
]
|
|
404
|
-
);
|
|
405
|
-
const append = useCallback2(
|
|
406
|
-
async (message, {
|
|
407
|
-
data,
|
|
408
|
-
headers: headers2,
|
|
409
|
-
body: body2,
|
|
410
|
-
experimental_attachments = message.experimental_attachments
|
|
411
|
-
} = {}) => {
|
|
412
|
-
var _a, _b;
|
|
413
|
-
const attachmentsForRequest = await prepareAttachmentsForRequest(
|
|
414
|
-
experimental_attachments
|
|
415
|
-
);
|
|
416
|
-
const messages2 = messagesRef.current.concat({
|
|
417
|
-
...message,
|
|
418
|
-
id: (_a = message.id) != null ? _a : generateId2(),
|
|
419
|
-
createdAt: (_b = message.createdAt) != null ? _b : /* @__PURE__ */ new Date(),
|
|
420
|
-
experimental_attachments: attachmentsForRequest.length > 0 ? attachmentsForRequest : void 0,
|
|
421
|
-
parts: getMessageParts(message)
|
|
422
41
|
});
|
|
423
|
-
return triggerRequest({ messages: messages2, headers: headers2, body: body2, data });
|
|
424
42
|
},
|
|
425
|
-
[
|
|
43
|
+
[chatStore, stableChatId]
|
|
426
44
|
);
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
45
|
+
const addToolResult = useCallback(
|
|
46
|
+
(options) => chatStore.current.addToolResult({ chatId: stableChatId, ...options }),
|
|
47
|
+
[chatStore, stableChatId]
|
|
48
|
+
);
|
|
49
|
+
const stopStream = useCallback(() => {
|
|
50
|
+
chatStore.current.stopStream({ chatId: stableChatId });
|
|
51
|
+
}, [chatStore, stableChatId]);
|
|
52
|
+
const error = useSyncExternalStore(
|
|
53
|
+
(callback) => subscribe({
|
|
54
|
+
onStoreChange: callback,
|
|
55
|
+
eventType: "chat-status-changed"
|
|
56
|
+
}),
|
|
57
|
+
() => chatStore.current.getError(stableChatId),
|
|
58
|
+
() => chatStore.current.getError(stableChatId)
|
|
59
|
+
);
|
|
60
|
+
const status = useSyncExternalStore(
|
|
61
|
+
(callback) => subscribe({
|
|
62
|
+
onStoreChange: callback,
|
|
63
|
+
eventType: "chat-status-changed"
|
|
64
|
+
}),
|
|
65
|
+
() => chatStore.current.getStatus(stableChatId),
|
|
66
|
+
() => chatStore.current.getStatus(stableChatId)
|
|
67
|
+
);
|
|
68
|
+
const messages = useSyncExternalStore(
|
|
69
|
+
(callback) => {
|
|
70
|
+
return subscribe({
|
|
71
|
+
onStoreChange: callback,
|
|
72
|
+
eventType: "chat-messages-changed"
|
|
439
73
|
});
|
|
440
74
|
},
|
|
441
|
-
|
|
75
|
+
() => chatStore.current.getMessages(stableChatId),
|
|
76
|
+
() => chatStore.current.getMessages(stableChatId)
|
|
442
77
|
);
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
(messages2) => {
|
|
455
|
-
if (typeof messages2 === "function") {
|
|
456
|
-
messages2 = messages2(messagesRef.current);
|
|
457
|
-
}
|
|
458
|
-
const messagesWithParts = fillMessageParts(messages2);
|
|
459
|
-
mutate(messagesWithParts, false);
|
|
460
|
-
messagesRef.current = messagesWithParts;
|
|
461
|
-
},
|
|
462
|
-
[mutate]
|
|
78
|
+
const append = useCallback(
|
|
79
|
+
(message, { headers, body } = {}) => chatStore.current.submitMessage({
|
|
80
|
+
chatId: stableChatId,
|
|
81
|
+
message,
|
|
82
|
+
headers,
|
|
83
|
+
body,
|
|
84
|
+
onError,
|
|
85
|
+
onToolCall,
|
|
86
|
+
onFinish
|
|
87
|
+
}),
|
|
88
|
+
[chatStore, stableChatId, onError, onToolCall, onFinish]
|
|
463
89
|
);
|
|
464
|
-
const
|
|
465
|
-
(
|
|
466
|
-
|
|
467
|
-
|
|
90
|
+
const reload = useCallback(
|
|
91
|
+
async ({ headers, body } = {}) => chatStore.current.resubmitLastUserMessage({
|
|
92
|
+
chatId: stableChatId,
|
|
93
|
+
headers,
|
|
94
|
+
body,
|
|
95
|
+
onError,
|
|
96
|
+
onToolCall,
|
|
97
|
+
onFinish
|
|
98
|
+
}),
|
|
99
|
+
[chatStore, stableChatId, onError, onToolCall, onFinish]
|
|
100
|
+
);
|
|
101
|
+
const stop = useCallback(() => stopStream(), [stopStream]);
|
|
102
|
+
const experimental_resume = useCallback(
|
|
103
|
+
async () => chatStore.current.resumeStream({
|
|
104
|
+
chatId: stableChatId,
|
|
105
|
+
onError,
|
|
106
|
+
onToolCall,
|
|
107
|
+
onFinish
|
|
108
|
+
}),
|
|
109
|
+
[chatStore, stableChatId, onError, onToolCall, onFinish]
|
|
110
|
+
);
|
|
111
|
+
const setMessages = useCallback(
|
|
112
|
+
(messagesParam) => {
|
|
113
|
+
if (typeof messagesParam === "function") {
|
|
114
|
+
messagesParam = messagesParam(messages);
|
|
468
115
|
}
|
|
469
|
-
|
|
470
|
-
|
|
116
|
+
chatStore.current.setMessages({
|
|
117
|
+
id: stableChatId,
|
|
118
|
+
messages: messagesParam
|
|
119
|
+
});
|
|
471
120
|
},
|
|
472
|
-
[
|
|
121
|
+
[stableChatId, messages]
|
|
473
122
|
);
|
|
474
|
-
const [input, setInput] =
|
|
475
|
-
const handleSubmit =
|
|
476
|
-
async (event, options = {}
|
|
123
|
+
const [input, setInput] = useState(initialInput);
|
|
124
|
+
const handleSubmit = useCallback(
|
|
125
|
+
async (event, options = {}) => {
|
|
477
126
|
var _a;
|
|
478
127
|
(_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
|
|
479
|
-
|
|
128
|
+
const fileParts = Array.isArray(options == null ? void 0 : options.files) ? options.files : await convertFileListToFileUIParts(options == null ? void 0 : options.files);
|
|
129
|
+
if (!input && fileParts.length === 0)
|
|
480
130
|
return;
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
131
|
+
append(
|
|
132
|
+
{
|
|
133
|
+
id: generateId(),
|
|
134
|
+
role: "user",
|
|
135
|
+
metadata: void 0,
|
|
136
|
+
parts: [...fileParts, { type: "text", text: input }]
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
headers: options.headers,
|
|
140
|
+
body: options.body
|
|
141
|
+
}
|
|
489
142
|
);
|
|
490
|
-
const messages2 = messagesRef.current.concat({
|
|
491
|
-
id: generateId2(),
|
|
492
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
493
|
-
role: "user",
|
|
494
|
-
content: input,
|
|
495
|
-
experimental_attachments: attachmentsForRequest.length > 0 ? attachmentsForRequest : void 0,
|
|
496
|
-
parts: [{ type: "text", text: input }]
|
|
497
|
-
});
|
|
498
|
-
const chatRequest = {
|
|
499
|
-
messages: messages2,
|
|
500
|
-
headers: options.headers,
|
|
501
|
-
body: options.body,
|
|
502
|
-
data: options.data
|
|
503
|
-
};
|
|
504
|
-
triggerRequest(chatRequest);
|
|
505
143
|
setInput("");
|
|
506
144
|
},
|
|
507
|
-
[input,
|
|
145
|
+
[input, generateId, append]
|
|
508
146
|
);
|
|
509
147
|
const handleInputChange = (e) => {
|
|
510
148
|
setInput(e.target.value);
|
|
511
149
|
};
|
|
512
|
-
const addToolResult = useCallback2(
|
|
513
|
-
({ toolCallId, result }) => {
|
|
514
|
-
const currentMessages = messagesRef.current;
|
|
515
|
-
updateToolCallResult({
|
|
516
|
-
messages: currentMessages,
|
|
517
|
-
toolCallId,
|
|
518
|
-
toolResult: result
|
|
519
|
-
});
|
|
520
|
-
mutate(
|
|
521
|
-
[
|
|
522
|
-
...currentMessages.slice(0, currentMessages.length - 1),
|
|
523
|
-
{ ...currentMessages[currentMessages.length - 1] }
|
|
524
|
-
],
|
|
525
|
-
false
|
|
526
|
-
);
|
|
527
|
-
if (status === "submitted" || status === "streaming") {
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
530
|
-
const lastMessage = currentMessages[currentMessages.length - 1];
|
|
531
|
-
if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {
|
|
532
|
-
triggerRequest({ messages: currentMessages });
|
|
533
|
-
}
|
|
534
|
-
},
|
|
535
|
-
[mutate, status, triggerRequest]
|
|
536
|
-
);
|
|
537
150
|
return {
|
|
538
|
-
messages
|
|
539
|
-
|
|
151
|
+
messages,
|
|
152
|
+
chatId: stableChatId,
|
|
540
153
|
setMessages,
|
|
541
|
-
data: streamData,
|
|
542
|
-
setData,
|
|
543
154
|
error,
|
|
544
155
|
append,
|
|
545
156
|
reload,
|
|
@@ -549,7 +160,6 @@ function useChat({
|
|
|
549
160
|
setInput,
|
|
550
161
|
handleInputChange,
|
|
551
162
|
handleSubmit,
|
|
552
|
-
isLoading: status === "submitted" || status === "streaming",
|
|
553
163
|
status,
|
|
554
164
|
addToolResult
|
|
555
165
|
};
|
|
@@ -558,9 +168,17 @@ function useChat({
|
|
|
558
168
|
// src/use-completion.ts
|
|
559
169
|
import {
|
|
560
170
|
callCompletionApi
|
|
561
|
-
} from "
|
|
562
|
-
import { useCallback as
|
|
563
|
-
import
|
|
171
|
+
} from "ai";
|
|
172
|
+
import { useCallback as useCallback2, useEffect, useId, useRef as useRef2, useState as useState2 } from "react";
|
|
173
|
+
import useSWR from "swr";
|
|
174
|
+
|
|
175
|
+
// src/throttle.ts
|
|
176
|
+
import throttleFunction from "throttleit";
|
|
177
|
+
function throttle(fn, waitMs) {
|
|
178
|
+
return waitMs != null ? throttleFunction(fn, waitMs) : fn;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// src/use-completion.ts
|
|
564
182
|
function useCompletion({
|
|
565
183
|
api = "/api/completion",
|
|
566
184
|
id,
|
|
@@ -571,37 +189,35 @@ function useCompletion({
|
|
|
571
189
|
body,
|
|
572
190
|
streamProtocol = "data",
|
|
573
191
|
fetch: fetch2,
|
|
574
|
-
onResponse,
|
|
575
192
|
onFinish,
|
|
576
193
|
onError,
|
|
577
194
|
experimental_throttle: throttleWaitMs
|
|
578
195
|
} = {}) {
|
|
579
196
|
const hookId = useId();
|
|
580
197
|
const completionId = id || hookId;
|
|
581
|
-
const { data, mutate } =
|
|
198
|
+
const { data, mutate } = useSWR([api, completionId], null, {
|
|
582
199
|
fallbackData: initialCompletion
|
|
583
200
|
});
|
|
584
|
-
const { data: isLoading = false, mutate: mutateLoading } =
|
|
201
|
+
const { data: isLoading = false, mutate: mutateLoading } = useSWR(
|
|
585
202
|
[completionId, "loading"],
|
|
586
203
|
null
|
|
587
204
|
);
|
|
588
|
-
const
|
|
589
|
-
const [error, setError] = useState4(void 0);
|
|
205
|
+
const [error, setError] = useState2(void 0);
|
|
590
206
|
const completion = data;
|
|
591
|
-
const [abortController, setAbortController] =
|
|
592
|
-
const extraMetadataRef =
|
|
207
|
+
const [abortController, setAbortController] = useState2(null);
|
|
208
|
+
const extraMetadataRef = useRef2({
|
|
593
209
|
credentials,
|
|
594
210
|
headers,
|
|
595
211
|
body
|
|
596
212
|
});
|
|
597
|
-
|
|
213
|
+
useEffect(() => {
|
|
598
214
|
extraMetadataRef.current = {
|
|
599
215
|
credentials,
|
|
600
216
|
headers,
|
|
601
217
|
body
|
|
602
218
|
};
|
|
603
219
|
}, [credentials, headers, body]);
|
|
604
|
-
const triggerRequest =
|
|
220
|
+
const triggerRequest = useCallback2(
|
|
605
221
|
async (prompt, options) => callCompletionApi({
|
|
606
222
|
api,
|
|
607
223
|
prompt,
|
|
@@ -618,14 +234,9 @@ function useCompletion({
|
|
|
618
234
|
(completion2) => mutate(completion2, false),
|
|
619
235
|
throttleWaitMs
|
|
620
236
|
),
|
|
621
|
-
onData: throttle(
|
|
622
|
-
(data2) => mutateStreamData([...streamData != null ? streamData : [], ...data2 != null ? data2 : []], false),
|
|
623
|
-
throttleWaitMs
|
|
624
|
-
),
|
|
625
237
|
setLoading: mutateLoading,
|
|
626
238
|
setError,
|
|
627
239
|
setAbortController,
|
|
628
|
-
onResponse,
|
|
629
240
|
onFinish,
|
|
630
241
|
onError
|
|
631
242
|
}),
|
|
@@ -635,37 +246,34 @@ function useCompletion({
|
|
|
635
246
|
api,
|
|
636
247
|
extraMetadataRef,
|
|
637
248
|
setAbortController,
|
|
638
|
-
onResponse,
|
|
639
249
|
onFinish,
|
|
640
250
|
onError,
|
|
641
251
|
setError,
|
|
642
|
-
streamData,
|
|
643
252
|
streamProtocol,
|
|
644
253
|
fetch2,
|
|
645
|
-
mutateStreamData,
|
|
646
254
|
throttleWaitMs
|
|
647
255
|
]
|
|
648
256
|
);
|
|
649
|
-
const stop =
|
|
257
|
+
const stop = useCallback2(() => {
|
|
650
258
|
if (abortController) {
|
|
651
259
|
abortController.abort();
|
|
652
260
|
setAbortController(null);
|
|
653
261
|
}
|
|
654
262
|
}, [abortController]);
|
|
655
|
-
const setCompletion =
|
|
263
|
+
const setCompletion = useCallback2(
|
|
656
264
|
(completion2) => {
|
|
657
265
|
mutate(completion2, false);
|
|
658
266
|
},
|
|
659
267
|
[mutate]
|
|
660
268
|
);
|
|
661
|
-
const complete =
|
|
269
|
+
const complete = useCallback2(
|
|
662
270
|
async (prompt, options) => {
|
|
663
271
|
return triggerRequest(prompt, options);
|
|
664
272
|
},
|
|
665
273
|
[triggerRequest]
|
|
666
274
|
);
|
|
667
|
-
const [input, setInput] =
|
|
668
|
-
const handleSubmit =
|
|
275
|
+
const [input, setInput] = useState2(initialInput);
|
|
276
|
+
const handleSubmit = useCallback2(
|
|
669
277
|
(event) => {
|
|
670
278
|
var _a;
|
|
671
279
|
(_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
|
|
@@ -673,7 +281,7 @@ function useCompletion({
|
|
|
673
281
|
},
|
|
674
282
|
[input, complete]
|
|
675
283
|
);
|
|
676
|
-
const handleInputChange =
|
|
284
|
+
const handleInputChange = useCallback2(
|
|
677
285
|
(e) => {
|
|
678
286
|
setInput(e.target.value);
|
|
679
287
|
},
|
|
@@ -689,24 +297,23 @@ function useCompletion({
|
|
|
689
297
|
setInput,
|
|
690
298
|
handleInputChange,
|
|
691
299
|
handleSubmit,
|
|
692
|
-
isLoading
|
|
693
|
-
data: streamData
|
|
300
|
+
isLoading
|
|
694
301
|
};
|
|
695
302
|
}
|
|
696
303
|
|
|
697
304
|
// src/use-object.ts
|
|
698
305
|
import {
|
|
699
|
-
isAbortError
|
|
306
|
+
isAbortError,
|
|
700
307
|
safeValidateTypes
|
|
701
308
|
} from "@ai-sdk/provider-utils";
|
|
702
309
|
import {
|
|
703
310
|
asSchema,
|
|
704
|
-
isDeepEqualData
|
|
311
|
+
isDeepEqualData,
|
|
705
312
|
parsePartialJson
|
|
706
|
-
} from "
|
|
707
|
-
import { useCallback as
|
|
708
|
-
import
|
|
709
|
-
var
|
|
313
|
+
} from "ai";
|
|
314
|
+
import { useCallback as useCallback3, useId as useId2, useRef as useRef3, useState as useState3 } from "react";
|
|
315
|
+
import useSWR2 from "swr";
|
|
316
|
+
var getOriginalFetch = () => fetch;
|
|
710
317
|
function useObject({
|
|
711
318
|
api,
|
|
712
319
|
id,
|
|
@@ -721,15 +328,15 @@ function useObject({
|
|
|
721
328
|
}) {
|
|
722
329
|
const hookId = useId2();
|
|
723
330
|
const completionId = id != null ? id : hookId;
|
|
724
|
-
const { data, mutate } =
|
|
331
|
+
const { data, mutate } = useSWR2(
|
|
725
332
|
[api, completionId],
|
|
726
333
|
null,
|
|
727
334
|
{ fallbackData: initialValue }
|
|
728
335
|
);
|
|
729
|
-
const [error, setError] =
|
|
730
|
-
const [isLoading, setIsLoading] =
|
|
731
|
-
const abortControllerRef =
|
|
732
|
-
const stop =
|
|
336
|
+
const [error, setError] = useState3(void 0);
|
|
337
|
+
const [isLoading, setIsLoading] = useState3(false);
|
|
338
|
+
const abortControllerRef = useRef3(null);
|
|
339
|
+
const stop = useCallback3(() => {
|
|
733
340
|
var _a;
|
|
734
341
|
try {
|
|
735
342
|
(_a = abortControllerRef.current) == null ? void 0 : _a.abort();
|
|
@@ -747,7 +354,7 @@ function useObject({
|
|
|
747
354
|
setError(void 0);
|
|
748
355
|
const abortController = new AbortController();
|
|
749
356
|
abortControllerRef.current = abortController;
|
|
750
|
-
const actualFetch = fetch2 != null ? fetch2 :
|
|
357
|
+
const actualFetch = fetch2 != null ? fetch2 : getOriginalFetch();
|
|
751
358
|
const response = await actualFetch(api, {
|
|
752
359
|
method: "POST",
|
|
753
360
|
headers: {
|
|
@@ -770,20 +377,20 @@ function useObject({
|
|
|
770
377
|
let latestObject = void 0;
|
|
771
378
|
await response.body.pipeThrough(new TextDecoderStream()).pipeTo(
|
|
772
379
|
new WritableStream({
|
|
773
|
-
write(chunk) {
|
|
380
|
+
async write(chunk) {
|
|
774
381
|
accumulatedText += chunk;
|
|
775
|
-
const { value } = parsePartialJson(accumulatedText);
|
|
382
|
+
const { value } = await parsePartialJson(accumulatedText);
|
|
776
383
|
const currentObject = value;
|
|
777
|
-
if (!
|
|
384
|
+
if (!isDeepEqualData(latestObject, currentObject)) {
|
|
778
385
|
latestObject = currentObject;
|
|
779
386
|
mutate(currentObject);
|
|
780
387
|
}
|
|
781
388
|
},
|
|
782
|
-
close() {
|
|
389
|
+
async close() {
|
|
783
390
|
setIsLoading(false);
|
|
784
391
|
abortControllerRef.current = null;
|
|
785
392
|
if (onFinish != null) {
|
|
786
|
-
const validationResult = safeValidateTypes({
|
|
393
|
+
const validationResult = await safeValidateTypes({
|
|
787
394
|
value: latestObject,
|
|
788
395
|
schema: asSchema(schema)
|
|
789
396
|
});
|
|
@@ -795,7 +402,7 @@ function useObject({
|
|
|
795
402
|
})
|
|
796
403
|
);
|
|
797
404
|
} catch (error2) {
|
|
798
|
-
if (
|
|
405
|
+
if (isAbortError(error2)) {
|
|
799
406
|
return;
|
|
800
407
|
}
|
|
801
408
|
if (onError && error2 instanceof Error) {
|
|
@@ -816,7 +423,6 @@ function useObject({
|
|
|
816
423
|
var experimental_useObject = useObject;
|
|
817
424
|
export {
|
|
818
425
|
experimental_useObject,
|
|
819
|
-
useAssistant,
|
|
820
426
|
useChat,
|
|
821
427
|
useCompletion
|
|
822
428
|
};
|