@ai-sdk/react 1.2.12 → 2.0.0-alpha.10
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 +358 -26
- package/README.md +1 -1
- package/dist/index.d.mts +25 -160
- package/dist/index.d.ts +25 -160
- package/dist/index.js +147 -566
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +145 -574
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -11
package/dist/index.mjs
CHANGED
|
@@ -1,187 +1,67 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
}
|
|
1
|
+
var __accessCheck = (obj, member, msg) => {
|
|
2
|
+
if (!member.has(obj))
|
|
3
|
+
throw TypeError("Cannot " + msg);
|
|
4
|
+
};
|
|
5
|
+
var __privateGet = (obj, member, getter) => {
|
|
6
|
+
__accessCheck(obj, member, "read from private field");
|
|
7
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
8
|
+
};
|
|
9
|
+
var __privateAdd = (obj, member, value) => {
|
|
10
|
+
if (member.has(obj))
|
|
11
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
12
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
13
|
+
};
|
|
14
|
+
var __privateSet = (obj, member, value, setter) => {
|
|
15
|
+
__accessCheck(obj, member, "write to private field");
|
|
16
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
17
|
+
return value;
|
|
18
|
+
};
|
|
170
19
|
|
|
171
20
|
// src/use-chat.ts
|
|
21
|
+
import { useCallback, useRef, useSyncExternalStore } from "react";
|
|
22
|
+
|
|
23
|
+
// src/chat.react.ts
|
|
172
24
|
import {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
25
|
+
AbstractChat
|
|
26
|
+
} from "ai";
|
|
27
|
+
var _messages;
|
|
28
|
+
var ReactChatState = class {
|
|
29
|
+
constructor(messages = []) {
|
|
30
|
+
__privateAdd(this, _messages, void 0);
|
|
31
|
+
this.status = "ready";
|
|
32
|
+
this.error = void 0;
|
|
33
|
+
this.pushMessage = (message) => {
|
|
34
|
+
__privateSet(this, _messages, this.messages.concat(message));
|
|
35
|
+
};
|
|
36
|
+
this.popMessage = () => {
|
|
37
|
+
__privateSet(this, _messages, this.messages.slice(0, -1));
|
|
38
|
+
};
|
|
39
|
+
this.replaceMessage = (index, message) => {
|
|
40
|
+
__privateSet(this, _messages, [
|
|
41
|
+
...__privateGet(this, _messages).slice(0, index),
|
|
42
|
+
message,
|
|
43
|
+
...__privateGet(this, _messages).slice(index + 1)
|
|
44
|
+
]);
|
|
45
|
+
};
|
|
46
|
+
this.snapshot = (value) => structuredClone(value);
|
|
47
|
+
__privateSet(this, _messages, messages);
|
|
48
|
+
}
|
|
49
|
+
get messages() {
|
|
50
|
+
return __privateGet(this, _messages);
|
|
51
|
+
}
|
|
52
|
+
set messages(messages) {
|
|
53
|
+
__privateSet(this, _messages, [...messages]);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
_messages = new WeakMap();
|
|
57
|
+
var Chat = class extends AbstractChat {
|
|
58
|
+
constructor({
|
|
59
|
+
messages,
|
|
60
|
+
...init
|
|
61
|
+
}) {
|
|
62
|
+
super({ ...init, state: new ReactChatState(messages) });
|
|
63
|
+
}
|
|
64
|
+
};
|
|
185
65
|
|
|
186
66
|
// src/throttle.ts
|
|
187
67
|
import throttleFunction from "throttleit";
|
|
@@ -189,367 +69,69 @@ function throttle(fn, waitMs) {
|
|
|
189
69
|
return waitMs != null ? throttleFunction(fn, waitMs) : fn;
|
|
190
70
|
}
|
|
191
71
|
|
|
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
72
|
// src/use-chat.ts
|
|
206
73
|
function useChat({
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
initialMessages,
|
|
210
|
-
initialInput = "",
|
|
211
|
-
sendExtraMessageFields,
|
|
212
|
-
onToolCall,
|
|
213
|
-
experimental_prepareRequestBody,
|
|
214
|
-
maxSteps = 1,
|
|
215
|
-
streamProtocol = "data",
|
|
216
|
-
onResponse,
|
|
217
|
-
onFinish,
|
|
218
|
-
onError,
|
|
219
|
-
credentials,
|
|
220
|
-
headers,
|
|
221
|
-
body,
|
|
222
|
-
generateId: generateId2 = generateIdFunc,
|
|
223
|
-
fetch: fetch2,
|
|
224
|
-
keepLastMessageOnError = true,
|
|
225
|
-
experimental_throttle: throttleWaitMs
|
|
74
|
+
experimental_throttle: throttleWaitMs,
|
|
75
|
+
...options
|
|
226
76
|
} = {}) {
|
|
227
|
-
const
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
null,
|
|
238
|
-
{ fallbackData: processedInitialMessages }
|
|
239
|
-
);
|
|
240
|
-
const messagesRef = useRef2(messages || []);
|
|
241
|
-
useEffect2(() => {
|
|
242
|
-
messagesRef.current = messages || [];
|
|
243
|
-
}, [messages]);
|
|
244
|
-
const { data: streamData, mutate: mutateStreamData } = useSWR([chatKey, "streamData"], null);
|
|
245
|
-
const streamDataRef = useRef2(streamData);
|
|
246
|
-
useEffect2(() => {
|
|
247
|
-
streamDataRef.current = streamData;
|
|
248
|
-
}, [streamData]);
|
|
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);
|
|
366
|
-
}
|
|
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 });
|
|
77
|
+
const chatRef = useRef("chat" in options ? options.chat : new Chat(options));
|
|
78
|
+
const subscribe = useCallback(
|
|
79
|
+
({
|
|
80
|
+
onStoreChange,
|
|
81
|
+
eventType
|
|
82
|
+
}) => chatRef.current.subscribe({
|
|
83
|
+
onChange: (event) => {
|
|
84
|
+
if (event.type !== eventType)
|
|
85
|
+
return;
|
|
86
|
+
onStoreChange();
|
|
378
87
|
}
|
|
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
|
-
]
|
|
88
|
+
}),
|
|
89
|
+
[chatRef]
|
|
404
90
|
);
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
|
|
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
|
-
});
|
|
423
|
-
return triggerRequest({ messages: messages2, headers: headers2, body: body2, data });
|
|
424
|
-
},
|
|
425
|
-
[triggerRequest, generateId2]
|
|
91
|
+
const addToolResult = useCallback(
|
|
92
|
+
(options2) => chatRef.current.addToolResult(options2),
|
|
93
|
+
[chatRef]
|
|
426
94
|
);
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
return triggerRequest({
|
|
435
|
-
messages: lastMessage.role === "assistant" ? messages2.slice(0, -1) : messages2,
|
|
436
|
-
headers: headers2,
|
|
437
|
-
body: body2,
|
|
438
|
-
data
|
|
439
|
-
});
|
|
440
|
-
},
|
|
441
|
-
[triggerRequest]
|
|
442
|
-
);
|
|
443
|
-
const stop = useCallback2(() => {
|
|
444
|
-
if (abortControllerRef.current) {
|
|
445
|
-
abortControllerRef.current.abort();
|
|
446
|
-
abortControllerRef.current = null;
|
|
447
|
-
}
|
|
448
|
-
}, []);
|
|
449
|
-
const experimental_resume = useCallback2(async () => {
|
|
450
|
-
const messages2 = messagesRef.current;
|
|
451
|
-
triggerRequest({ messages: messages2 }, "resume");
|
|
452
|
-
}, [triggerRequest]);
|
|
453
|
-
const setMessages = useCallback2(
|
|
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]
|
|
463
|
-
);
|
|
464
|
-
const setData = useCallback2(
|
|
465
|
-
(data) => {
|
|
466
|
-
if (typeof data === "function") {
|
|
467
|
-
data = data(streamDataRef.current);
|
|
468
|
-
}
|
|
469
|
-
mutateStreamData(data, false);
|
|
470
|
-
streamDataRef.current = data;
|
|
471
|
-
},
|
|
472
|
-
[mutateStreamData]
|
|
95
|
+
const status = useSyncExternalStore(
|
|
96
|
+
(callback) => subscribe({
|
|
97
|
+
onStoreChange: callback,
|
|
98
|
+
eventType: "status-changed"
|
|
99
|
+
}),
|
|
100
|
+
() => chatRef.current.status,
|
|
101
|
+
() => chatRef.current.status
|
|
473
102
|
);
|
|
474
|
-
const
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
if (!input && !options.allowEmptySubmit)
|
|
480
|
-
return;
|
|
481
|
-
if (metadata) {
|
|
482
|
-
extraMetadataRef.current = {
|
|
483
|
-
...extraMetadataRef.current,
|
|
484
|
-
...metadata
|
|
485
|
-
};
|
|
486
|
-
}
|
|
487
|
-
const attachmentsForRequest = await prepareAttachmentsForRequest(
|
|
488
|
-
options.experimental_attachments
|
|
489
|
-
);
|
|
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 }]
|
|
103
|
+
const subscribeToChatStoreForMessages = useCallback(
|
|
104
|
+
(callback) => {
|
|
105
|
+
return subscribe({
|
|
106
|
+
onStoreChange: throttleWaitMs ? throttle(callback, throttleWaitMs) : callback,
|
|
107
|
+
eventType: "messages-changed"
|
|
497
108
|
});
|
|
498
|
-
const chatRequest = {
|
|
499
|
-
messages: messages2,
|
|
500
|
-
headers: options.headers,
|
|
501
|
-
body: options.body,
|
|
502
|
-
data: options.data
|
|
503
|
-
};
|
|
504
|
-
triggerRequest(chatRequest);
|
|
505
|
-
setInput("");
|
|
506
109
|
},
|
|
507
|
-
[
|
|
110
|
+
[subscribe, throttleWaitMs]
|
|
508
111
|
);
|
|
509
|
-
const
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
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 });
|
|
112
|
+
const messages = useSyncExternalStore(
|
|
113
|
+
(callback) => subscribeToChatStoreForMessages(callback),
|
|
114
|
+
() => chatRef.current.messages,
|
|
115
|
+
() => chatRef.current.messages
|
|
116
|
+
);
|
|
117
|
+
const setMessages = useCallback(
|
|
118
|
+
(messagesParam) => {
|
|
119
|
+
if (typeof messagesParam === "function") {
|
|
120
|
+
messagesParam = messagesParam(messages);
|
|
533
121
|
}
|
|
122
|
+
chatRef.current.messages = messagesParam;
|
|
534
123
|
},
|
|
535
|
-
[
|
|
124
|
+
[chatRef, messages]
|
|
536
125
|
);
|
|
537
126
|
return {
|
|
538
|
-
|
|
539
|
-
|
|
127
|
+
id: chatRef.current.id,
|
|
128
|
+
messages,
|
|
540
129
|
setMessages,
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
stop,
|
|
547
|
-
experimental_resume,
|
|
548
|
-
input,
|
|
549
|
-
setInput,
|
|
550
|
-
handleInputChange,
|
|
551
|
-
handleSubmit,
|
|
552
|
-
isLoading: status === "submitted" || status === "streaming",
|
|
130
|
+
sendMessage: chatRef.current.sendMessage,
|
|
131
|
+
reload: chatRef.current.reload,
|
|
132
|
+
stop: chatRef.current.stop,
|
|
133
|
+
error: chatRef.current.error,
|
|
134
|
+
experimental_resume: chatRef.current.experimental_resume,
|
|
553
135
|
status,
|
|
554
136
|
addToolResult
|
|
555
137
|
};
|
|
@@ -558,9 +140,9 @@ function useChat({
|
|
|
558
140
|
// src/use-completion.ts
|
|
559
141
|
import {
|
|
560
142
|
callCompletionApi
|
|
561
|
-
} from "
|
|
562
|
-
import { useCallback as
|
|
563
|
-
import
|
|
143
|
+
} from "ai";
|
|
144
|
+
import { useCallback as useCallback2, useEffect, useId, useRef as useRef2, useState } from "react";
|
|
145
|
+
import useSWR from "swr";
|
|
564
146
|
function useCompletion({
|
|
565
147
|
api = "/api/completion",
|
|
566
148
|
id,
|
|
@@ -571,37 +153,35 @@ function useCompletion({
|
|
|
571
153
|
body,
|
|
572
154
|
streamProtocol = "data",
|
|
573
155
|
fetch: fetch2,
|
|
574
|
-
onResponse,
|
|
575
156
|
onFinish,
|
|
576
157
|
onError,
|
|
577
158
|
experimental_throttle: throttleWaitMs
|
|
578
159
|
} = {}) {
|
|
579
160
|
const hookId = useId();
|
|
580
161
|
const completionId = id || hookId;
|
|
581
|
-
const { data, mutate } =
|
|
162
|
+
const { data, mutate } = useSWR([api, completionId], null, {
|
|
582
163
|
fallbackData: initialCompletion
|
|
583
164
|
});
|
|
584
|
-
const { data: isLoading = false, mutate: mutateLoading } =
|
|
165
|
+
const { data: isLoading = false, mutate: mutateLoading } = useSWR(
|
|
585
166
|
[completionId, "loading"],
|
|
586
167
|
null
|
|
587
168
|
);
|
|
588
|
-
const
|
|
589
|
-
const [error, setError] = useState4(void 0);
|
|
169
|
+
const [error, setError] = useState(void 0);
|
|
590
170
|
const completion = data;
|
|
591
|
-
const [abortController, setAbortController] =
|
|
592
|
-
const extraMetadataRef =
|
|
171
|
+
const [abortController, setAbortController] = useState(null);
|
|
172
|
+
const extraMetadataRef = useRef2({
|
|
593
173
|
credentials,
|
|
594
174
|
headers,
|
|
595
175
|
body
|
|
596
176
|
});
|
|
597
|
-
|
|
177
|
+
useEffect(() => {
|
|
598
178
|
extraMetadataRef.current = {
|
|
599
179
|
credentials,
|
|
600
180
|
headers,
|
|
601
181
|
body
|
|
602
182
|
};
|
|
603
183
|
}, [credentials, headers, body]);
|
|
604
|
-
const triggerRequest =
|
|
184
|
+
const triggerRequest = useCallback2(
|
|
605
185
|
async (prompt, options) => callCompletionApi({
|
|
606
186
|
api,
|
|
607
187
|
prompt,
|
|
@@ -618,14 +198,9 @@ function useCompletion({
|
|
|
618
198
|
(completion2) => mutate(completion2, false),
|
|
619
199
|
throttleWaitMs
|
|
620
200
|
),
|
|
621
|
-
onData: throttle(
|
|
622
|
-
(data2) => mutateStreamData([...streamData != null ? streamData : [], ...data2 != null ? data2 : []], false),
|
|
623
|
-
throttleWaitMs
|
|
624
|
-
),
|
|
625
201
|
setLoading: mutateLoading,
|
|
626
202
|
setError,
|
|
627
203
|
setAbortController,
|
|
628
|
-
onResponse,
|
|
629
204
|
onFinish,
|
|
630
205
|
onError
|
|
631
206
|
}),
|
|
@@ -635,37 +210,34 @@ function useCompletion({
|
|
|
635
210
|
api,
|
|
636
211
|
extraMetadataRef,
|
|
637
212
|
setAbortController,
|
|
638
|
-
onResponse,
|
|
639
213
|
onFinish,
|
|
640
214
|
onError,
|
|
641
215
|
setError,
|
|
642
|
-
streamData,
|
|
643
216
|
streamProtocol,
|
|
644
217
|
fetch2,
|
|
645
|
-
mutateStreamData,
|
|
646
218
|
throttleWaitMs
|
|
647
219
|
]
|
|
648
220
|
);
|
|
649
|
-
const stop =
|
|
221
|
+
const stop = useCallback2(() => {
|
|
650
222
|
if (abortController) {
|
|
651
223
|
abortController.abort();
|
|
652
224
|
setAbortController(null);
|
|
653
225
|
}
|
|
654
226
|
}, [abortController]);
|
|
655
|
-
const setCompletion =
|
|
227
|
+
const setCompletion = useCallback2(
|
|
656
228
|
(completion2) => {
|
|
657
229
|
mutate(completion2, false);
|
|
658
230
|
},
|
|
659
231
|
[mutate]
|
|
660
232
|
);
|
|
661
|
-
const complete =
|
|
233
|
+
const complete = useCallback2(
|
|
662
234
|
async (prompt, options) => {
|
|
663
235
|
return triggerRequest(prompt, options);
|
|
664
236
|
},
|
|
665
237
|
[triggerRequest]
|
|
666
238
|
);
|
|
667
|
-
const [input, setInput] =
|
|
668
|
-
const handleSubmit =
|
|
239
|
+
const [input, setInput] = useState(initialInput);
|
|
240
|
+
const handleSubmit = useCallback2(
|
|
669
241
|
(event) => {
|
|
670
242
|
var _a;
|
|
671
243
|
(_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
|
|
@@ -673,7 +245,7 @@ function useCompletion({
|
|
|
673
245
|
},
|
|
674
246
|
[input, complete]
|
|
675
247
|
);
|
|
676
|
-
const handleInputChange =
|
|
248
|
+
const handleInputChange = useCallback2(
|
|
677
249
|
(e) => {
|
|
678
250
|
setInput(e.target.value);
|
|
679
251
|
},
|
|
@@ -689,24 +261,23 @@ function useCompletion({
|
|
|
689
261
|
setInput,
|
|
690
262
|
handleInputChange,
|
|
691
263
|
handleSubmit,
|
|
692
|
-
isLoading
|
|
693
|
-
data: streamData
|
|
264
|
+
isLoading
|
|
694
265
|
};
|
|
695
266
|
}
|
|
696
267
|
|
|
697
268
|
// src/use-object.ts
|
|
698
269
|
import {
|
|
699
|
-
isAbortError
|
|
270
|
+
isAbortError,
|
|
700
271
|
safeValidateTypes
|
|
701
272
|
} from "@ai-sdk/provider-utils";
|
|
702
273
|
import {
|
|
703
274
|
asSchema,
|
|
704
|
-
isDeepEqualData
|
|
275
|
+
isDeepEqualData,
|
|
705
276
|
parsePartialJson
|
|
706
|
-
} from "
|
|
707
|
-
import { useCallback as
|
|
708
|
-
import
|
|
709
|
-
var
|
|
277
|
+
} from "ai";
|
|
278
|
+
import { useCallback as useCallback3, useId as useId2, useRef as useRef3, useState as useState2 } from "react";
|
|
279
|
+
import useSWR2 from "swr";
|
|
280
|
+
var getOriginalFetch = () => fetch;
|
|
710
281
|
function useObject({
|
|
711
282
|
api,
|
|
712
283
|
id,
|
|
@@ -721,15 +292,15 @@ function useObject({
|
|
|
721
292
|
}) {
|
|
722
293
|
const hookId = useId2();
|
|
723
294
|
const completionId = id != null ? id : hookId;
|
|
724
|
-
const { data, mutate } =
|
|
295
|
+
const { data, mutate } = useSWR2(
|
|
725
296
|
[api, completionId],
|
|
726
297
|
null,
|
|
727
298
|
{ fallbackData: initialValue }
|
|
728
299
|
);
|
|
729
|
-
const [error, setError] =
|
|
730
|
-
const [isLoading, setIsLoading] =
|
|
731
|
-
const abortControllerRef =
|
|
732
|
-
const stop =
|
|
300
|
+
const [error, setError] = useState2(void 0);
|
|
301
|
+
const [isLoading, setIsLoading] = useState2(false);
|
|
302
|
+
const abortControllerRef = useRef3(null);
|
|
303
|
+
const stop = useCallback3(() => {
|
|
733
304
|
var _a;
|
|
734
305
|
try {
|
|
735
306
|
(_a = abortControllerRef.current) == null ? void 0 : _a.abort();
|
|
@@ -747,7 +318,7 @@ function useObject({
|
|
|
747
318
|
setError(void 0);
|
|
748
319
|
const abortController = new AbortController();
|
|
749
320
|
abortControllerRef.current = abortController;
|
|
750
|
-
const actualFetch = fetch2 != null ? fetch2 :
|
|
321
|
+
const actualFetch = fetch2 != null ? fetch2 : getOriginalFetch();
|
|
751
322
|
const response = await actualFetch(api, {
|
|
752
323
|
method: "POST",
|
|
753
324
|
headers: {
|
|
@@ -770,20 +341,20 @@ function useObject({
|
|
|
770
341
|
let latestObject = void 0;
|
|
771
342
|
await response.body.pipeThrough(new TextDecoderStream()).pipeTo(
|
|
772
343
|
new WritableStream({
|
|
773
|
-
write(chunk) {
|
|
344
|
+
async write(chunk) {
|
|
774
345
|
accumulatedText += chunk;
|
|
775
|
-
const { value } = parsePartialJson(accumulatedText);
|
|
346
|
+
const { value } = await parsePartialJson(accumulatedText);
|
|
776
347
|
const currentObject = value;
|
|
777
|
-
if (!
|
|
348
|
+
if (!isDeepEqualData(latestObject, currentObject)) {
|
|
778
349
|
latestObject = currentObject;
|
|
779
350
|
mutate(currentObject);
|
|
780
351
|
}
|
|
781
352
|
},
|
|
782
|
-
close() {
|
|
353
|
+
async close() {
|
|
783
354
|
setIsLoading(false);
|
|
784
355
|
abortControllerRef.current = null;
|
|
785
356
|
if (onFinish != null) {
|
|
786
|
-
const validationResult = safeValidateTypes({
|
|
357
|
+
const validationResult = await safeValidateTypes({
|
|
787
358
|
value: latestObject,
|
|
788
359
|
schema: asSchema(schema)
|
|
789
360
|
});
|
|
@@ -795,7 +366,7 @@ function useObject({
|
|
|
795
366
|
})
|
|
796
367
|
);
|
|
797
368
|
} catch (error2) {
|
|
798
|
-
if (
|
|
369
|
+
if (isAbortError(error2)) {
|
|
799
370
|
return;
|
|
800
371
|
}
|
|
801
372
|
if (onError && error2 instanceof Error) {
|
|
@@ -815,8 +386,8 @@ function useObject({
|
|
|
815
386
|
}
|
|
816
387
|
var experimental_useObject = useObject;
|
|
817
388
|
export {
|
|
389
|
+
Chat,
|
|
818
390
|
experimental_useObject,
|
|
819
|
-
useAssistant,
|
|
820
391
|
useChat,
|
|
821
392
|
useCompletion
|
|
822
393
|
};
|