@ai-sdk/react 2.0.0-canary.8 → 2.0.0
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 +949 -0
- package/README.md +4 -4
- package/dist/index.d.mts +37 -97
- package/dist/index.d.ts +37 -97
- package/dist/index.js +218 -392
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +203 -387
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -8
package/dist/index.mjs
CHANGED
|
@@ -1,17 +1,27 @@
|
|
|
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
|
+
};
|
|
19
|
+
|
|
1
20
|
// src/use-chat.ts
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
generateId as generateIdFunc,
|
|
7
|
-
getMessageParts,
|
|
8
|
-
isAssistantMessageWithCompletedToolCalls,
|
|
9
|
-
prepareAttachmentsForRequest,
|
|
10
|
-
shouldResubmitMessages,
|
|
11
|
-
updateToolCallResult
|
|
12
|
-
} from "ai";
|
|
13
|
-
import { useCallback, useEffect as useEffect2, useMemo, useRef, useState as useState2 } from "react";
|
|
14
|
-
import useSWR from "swr";
|
|
21
|
+
import { useCallback, useEffect, useRef, useSyncExternalStore } from "react";
|
|
22
|
+
|
|
23
|
+
// src/chat.react.ts
|
|
24
|
+
import { AbstractChat } from "ai";
|
|
15
25
|
|
|
16
26
|
// src/throttle.ts
|
|
17
27
|
import throttleFunction from "throttleit";
|
|
@@ -19,363 +29,170 @@ function throttle(fn, waitMs) {
|
|
|
19
29
|
return waitMs != null ? throttleFunction(fn, waitMs) : fn;
|
|
20
30
|
}
|
|
21
31
|
|
|
22
|
-
// src/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
// src/chat.react.ts
|
|
33
|
+
var _messages, _status, _error, _messagesCallbacks, _statusCallbacks, _errorCallbacks, _callMessagesCallbacks, _callStatusCallbacks, _callErrorCallbacks;
|
|
34
|
+
var ReactChatState = class {
|
|
35
|
+
constructor(initialMessages = []) {
|
|
36
|
+
__privateAdd(this, _messages, void 0);
|
|
37
|
+
__privateAdd(this, _status, "ready");
|
|
38
|
+
__privateAdd(this, _error, void 0);
|
|
39
|
+
__privateAdd(this, _messagesCallbacks, /* @__PURE__ */ new Set());
|
|
40
|
+
__privateAdd(this, _statusCallbacks, /* @__PURE__ */ new Set());
|
|
41
|
+
__privateAdd(this, _errorCallbacks, /* @__PURE__ */ new Set());
|
|
42
|
+
this.pushMessage = (message) => {
|
|
43
|
+
__privateSet(this, _messages, __privateGet(this, _messages).concat(message));
|
|
44
|
+
__privateGet(this, _callMessagesCallbacks).call(this);
|
|
45
|
+
};
|
|
46
|
+
this.popMessage = () => {
|
|
47
|
+
__privateSet(this, _messages, __privateGet(this, _messages).slice(0, -1));
|
|
48
|
+
__privateGet(this, _callMessagesCallbacks).call(this);
|
|
49
|
+
};
|
|
50
|
+
this.replaceMessage = (index, message) => {
|
|
51
|
+
__privateSet(this, _messages, [
|
|
52
|
+
...__privateGet(this, _messages).slice(0, index),
|
|
53
|
+
// We deep clone the message here to ensure the new React Compiler (currently in RC) detects deeply nested parts/metadata changes:
|
|
54
|
+
this.snapshot(message),
|
|
55
|
+
...__privateGet(this, _messages).slice(index + 1)
|
|
56
|
+
]);
|
|
57
|
+
__privateGet(this, _callMessagesCallbacks).call(this);
|
|
58
|
+
};
|
|
59
|
+
this.snapshot = (value) => structuredClone(value);
|
|
60
|
+
this["~registerMessagesCallback"] = (onChange, throttleWaitMs) => {
|
|
61
|
+
const callback = throttleWaitMs ? throttle(onChange, throttleWaitMs) : onChange;
|
|
62
|
+
__privateGet(this, _messagesCallbacks).add(callback);
|
|
63
|
+
return () => {
|
|
64
|
+
__privateGet(this, _messagesCallbacks).delete(callback);
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
this["~registerStatusCallback"] = (onChange) => {
|
|
68
|
+
__privateGet(this, _statusCallbacks).add(onChange);
|
|
69
|
+
return () => {
|
|
70
|
+
__privateGet(this, _statusCallbacks).delete(onChange);
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
this["~registerErrorCallback"] = (onChange) => {
|
|
74
|
+
__privateGet(this, _errorCallbacks).add(onChange);
|
|
75
|
+
return () => {
|
|
76
|
+
__privateGet(this, _errorCallbacks).delete(onChange);
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
__privateAdd(this, _callMessagesCallbacks, () => {
|
|
80
|
+
__privateGet(this, _messagesCallbacks).forEach((callback) => callback());
|
|
81
|
+
});
|
|
82
|
+
__privateAdd(this, _callStatusCallbacks, () => {
|
|
83
|
+
__privateGet(this, _statusCallbacks).forEach((callback) => callback());
|
|
84
|
+
});
|
|
85
|
+
__privateAdd(this, _callErrorCallbacks, () => {
|
|
86
|
+
__privateGet(this, _errorCallbacks).forEach((callback) => callback());
|
|
87
|
+
});
|
|
88
|
+
__privateSet(this, _messages, initialMessages);
|
|
89
|
+
}
|
|
90
|
+
get status() {
|
|
91
|
+
return __privateGet(this, _status);
|
|
92
|
+
}
|
|
93
|
+
set status(newStatus) {
|
|
94
|
+
__privateSet(this, _status, newStatus);
|
|
95
|
+
__privateGet(this, _callStatusCallbacks).call(this);
|
|
96
|
+
}
|
|
97
|
+
get error() {
|
|
98
|
+
return __privateGet(this, _error);
|
|
99
|
+
}
|
|
100
|
+
set error(newError) {
|
|
101
|
+
__privateSet(this, _error, newError);
|
|
102
|
+
__privateGet(this, _callErrorCallbacks).call(this);
|
|
103
|
+
}
|
|
104
|
+
get messages() {
|
|
105
|
+
return __privateGet(this, _messages);
|
|
106
|
+
}
|
|
107
|
+
set messages(newMessages) {
|
|
108
|
+
__privateSet(this, _messages, [...newMessages]);
|
|
109
|
+
__privateGet(this, _callMessagesCallbacks).call(this);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
_messages = new WeakMap();
|
|
113
|
+
_status = new WeakMap();
|
|
114
|
+
_error = new WeakMap();
|
|
115
|
+
_messagesCallbacks = new WeakMap();
|
|
116
|
+
_statusCallbacks = new WeakMap();
|
|
117
|
+
_errorCallbacks = new WeakMap();
|
|
118
|
+
_callMessagesCallbacks = new WeakMap();
|
|
119
|
+
_callStatusCallbacks = new WeakMap();
|
|
120
|
+
_callErrorCallbacks = new WeakMap();
|
|
121
|
+
var _state;
|
|
122
|
+
var Chat = class extends AbstractChat {
|
|
123
|
+
constructor({ messages, ...init }) {
|
|
124
|
+
const state = new ReactChatState(messages);
|
|
125
|
+
super({ ...init, state });
|
|
126
|
+
__privateAdd(this, _state, void 0);
|
|
127
|
+
this["~registerMessagesCallback"] = (onChange, throttleWaitMs) => __privateGet(this, _state)["~registerMessagesCallback"](onChange, throttleWaitMs);
|
|
128
|
+
this["~registerStatusCallback"] = (onChange) => __privateGet(this, _state)["~registerStatusCallback"](onChange);
|
|
129
|
+
this["~registerErrorCallback"] = (onChange) => __privateGet(this, _state)["~registerErrorCallback"](onChange);
|
|
130
|
+
__privateSet(this, _state, state);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
_state = new WeakMap();
|
|
34
134
|
|
|
35
135
|
// src/use-chat.ts
|
|
36
136
|
function useChat({
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
initialInput = "",
|
|
41
|
-
sendExtraMessageFields,
|
|
42
|
-
onToolCall,
|
|
43
|
-
experimental_prepareRequestBody,
|
|
44
|
-
maxSteps = 1,
|
|
45
|
-
streamProtocol = "data",
|
|
46
|
-
onResponse,
|
|
47
|
-
onFinish,
|
|
48
|
-
onError,
|
|
49
|
-
credentials,
|
|
50
|
-
headers,
|
|
51
|
-
body,
|
|
52
|
-
generateId = generateIdFunc,
|
|
53
|
-
fetch: fetch2,
|
|
54
|
-
keepLastMessageOnError = true,
|
|
55
|
-
experimental_throttle: throttleWaitMs
|
|
137
|
+
experimental_throttle: throttleWaitMs,
|
|
138
|
+
resume = false,
|
|
139
|
+
...options
|
|
56
140
|
} = {}) {
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
const chatKey = typeof api === "string" ? [api, chatId] : chatId;
|
|
60
|
-
const stableInitialMessages = useStableValue(initialMessages != null ? initialMessages : []);
|
|
61
|
-
const processedInitialMessages = useMemo(
|
|
62
|
-
() => fillMessageParts(stableInitialMessages),
|
|
63
|
-
[stableInitialMessages]
|
|
141
|
+
const chatRef = useRef(
|
|
142
|
+
"chat" in options ? options.chat : new Chat(options)
|
|
64
143
|
);
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
144
|
+
const shouldRecreateChat = "chat" in options && options.chat !== chatRef.current || "id" in options && chatRef.current.id !== options.id;
|
|
145
|
+
if (shouldRecreateChat) {
|
|
146
|
+
chatRef.current = "chat" in options ? options.chat : new Chat(options);
|
|
147
|
+
}
|
|
148
|
+
const optionsId = "id" in options ? options.id : null;
|
|
149
|
+
const subscribeToMessages = useCallback(
|
|
150
|
+
(update) => chatRef.current["~registerMessagesCallback"](update, throttleWaitMs),
|
|
151
|
+
// optionsId is required to trigger re-subscription when the chat ID changes
|
|
152
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
153
|
+
[throttleWaitMs, optionsId]
|
|
69
154
|
);
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const { data: streamData, mutate: mutateStreamData } = useSWR([chatKey, "streamData"], null);
|
|
75
|
-
const streamDataRef = useRef(streamData);
|
|
76
|
-
useEffect2(() => {
|
|
77
|
-
streamDataRef.current = streamData;
|
|
78
|
-
}, [streamData]);
|
|
79
|
-
const { data: status = "ready", mutate: mutateStatus } = useSWR([chatKey, "status"], null);
|
|
80
|
-
const { data: error = void 0, mutate: setError } = useSWR([chatKey, "error"], null);
|
|
81
|
-
const abortControllerRef = useRef(null);
|
|
82
|
-
const extraMetadataRef = useRef({
|
|
83
|
-
credentials,
|
|
84
|
-
headers,
|
|
85
|
-
body
|
|
86
|
-
});
|
|
87
|
-
useEffect2(() => {
|
|
88
|
-
extraMetadataRef.current = {
|
|
89
|
-
credentials,
|
|
90
|
-
headers,
|
|
91
|
-
body
|
|
92
|
-
};
|
|
93
|
-
}, [credentials, headers, body]);
|
|
94
|
-
const triggerRequest = useCallback(
|
|
95
|
-
async (chatRequest) => {
|
|
96
|
-
var _a, _b;
|
|
97
|
-
mutateStatus("submitted");
|
|
98
|
-
setError(void 0);
|
|
99
|
-
const chatMessages = fillMessageParts(chatRequest.messages);
|
|
100
|
-
const messageCount = chatMessages.length;
|
|
101
|
-
const maxStep = extractMaxToolInvocationStep(
|
|
102
|
-
(_a = chatMessages[chatMessages.length - 1]) == null ? void 0 : _a.toolInvocations
|
|
103
|
-
);
|
|
104
|
-
try {
|
|
105
|
-
const abortController = new AbortController();
|
|
106
|
-
abortControllerRef.current = abortController;
|
|
107
|
-
const throttledMutate = throttle(mutate, throttleWaitMs);
|
|
108
|
-
const throttledMutateStreamData = throttle(
|
|
109
|
-
mutateStreamData,
|
|
110
|
-
throttleWaitMs
|
|
111
|
-
);
|
|
112
|
-
const previousMessages = messagesRef.current;
|
|
113
|
-
throttledMutate(chatMessages, false);
|
|
114
|
-
const constructedMessagesPayload = sendExtraMessageFields ? chatMessages : chatMessages.map(
|
|
115
|
-
({
|
|
116
|
-
role,
|
|
117
|
-
content,
|
|
118
|
-
experimental_attachments,
|
|
119
|
-
data,
|
|
120
|
-
annotations,
|
|
121
|
-
toolInvocations,
|
|
122
|
-
parts
|
|
123
|
-
}) => ({
|
|
124
|
-
role,
|
|
125
|
-
content,
|
|
126
|
-
...experimental_attachments !== void 0 && {
|
|
127
|
-
experimental_attachments
|
|
128
|
-
},
|
|
129
|
-
...data !== void 0 && { data },
|
|
130
|
-
...annotations !== void 0 && { annotations },
|
|
131
|
-
...toolInvocations !== void 0 && { toolInvocations },
|
|
132
|
-
...parts !== void 0 && { parts }
|
|
133
|
-
})
|
|
134
|
-
);
|
|
135
|
-
const existingData = streamDataRef.current;
|
|
136
|
-
await callChatApi({
|
|
137
|
-
api,
|
|
138
|
-
body: (_b = experimental_prepareRequestBody == null ? void 0 : experimental_prepareRequestBody({
|
|
139
|
-
id: chatId,
|
|
140
|
-
messages: chatMessages,
|
|
141
|
-
requestData: chatRequest.data,
|
|
142
|
-
requestBody: chatRequest.body
|
|
143
|
-
})) != null ? _b : {
|
|
144
|
-
id: chatId,
|
|
145
|
-
messages: constructedMessagesPayload,
|
|
146
|
-
data: chatRequest.data,
|
|
147
|
-
...extraMetadataRef.current.body,
|
|
148
|
-
...chatRequest.body
|
|
149
|
-
},
|
|
150
|
-
streamProtocol,
|
|
151
|
-
credentials: extraMetadataRef.current.credentials,
|
|
152
|
-
headers: {
|
|
153
|
-
...extraMetadataRef.current.headers,
|
|
154
|
-
...chatRequest.headers
|
|
155
|
-
},
|
|
156
|
-
abortController: () => abortControllerRef.current,
|
|
157
|
-
restoreMessagesOnFailure() {
|
|
158
|
-
if (!keepLastMessageOnError) {
|
|
159
|
-
throttledMutate(previousMessages, false);
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
onResponse,
|
|
163
|
-
onUpdate({ message, data, replaceLastMessage }) {
|
|
164
|
-
mutateStatus("streaming");
|
|
165
|
-
throttledMutate(
|
|
166
|
-
[
|
|
167
|
-
...replaceLastMessage ? chatMessages.slice(0, chatMessages.length - 1) : chatMessages,
|
|
168
|
-
message
|
|
169
|
-
],
|
|
170
|
-
false
|
|
171
|
-
);
|
|
172
|
-
if (data == null ? void 0 : data.length) {
|
|
173
|
-
throttledMutateStreamData(
|
|
174
|
-
[...existingData != null ? existingData : [], ...data],
|
|
175
|
-
false
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
},
|
|
179
|
-
onToolCall,
|
|
180
|
-
onFinish,
|
|
181
|
-
generateId,
|
|
182
|
-
fetch: fetch2,
|
|
183
|
-
lastMessage: chatMessages[chatMessages.length - 1]
|
|
184
|
-
});
|
|
185
|
-
abortControllerRef.current = null;
|
|
186
|
-
mutateStatus("ready");
|
|
187
|
-
} catch (err) {
|
|
188
|
-
if (err.name === "AbortError") {
|
|
189
|
-
abortControllerRef.current = null;
|
|
190
|
-
mutateStatus("ready");
|
|
191
|
-
return null;
|
|
192
|
-
}
|
|
193
|
-
if (onError && err instanceof Error) {
|
|
194
|
-
onError(err);
|
|
195
|
-
}
|
|
196
|
-
setError(err);
|
|
197
|
-
mutateStatus("error");
|
|
198
|
-
}
|
|
199
|
-
const messages2 = messagesRef.current;
|
|
200
|
-
if (shouldResubmitMessages({
|
|
201
|
-
originalMaxToolInvocationStep: maxStep,
|
|
202
|
-
originalMessageCount: messageCount,
|
|
203
|
-
maxSteps,
|
|
204
|
-
messages: messages2
|
|
205
|
-
})) {
|
|
206
|
-
await triggerRequest({ messages: messages2 });
|
|
207
|
-
}
|
|
208
|
-
},
|
|
209
|
-
[
|
|
210
|
-
mutate,
|
|
211
|
-
mutateStatus,
|
|
212
|
-
api,
|
|
213
|
-
extraMetadataRef,
|
|
214
|
-
onResponse,
|
|
215
|
-
onFinish,
|
|
216
|
-
onError,
|
|
217
|
-
setError,
|
|
218
|
-
mutateStreamData,
|
|
219
|
-
streamDataRef,
|
|
220
|
-
streamProtocol,
|
|
221
|
-
sendExtraMessageFields,
|
|
222
|
-
experimental_prepareRequestBody,
|
|
223
|
-
onToolCall,
|
|
224
|
-
maxSteps,
|
|
225
|
-
messagesRef,
|
|
226
|
-
abortControllerRef,
|
|
227
|
-
generateId,
|
|
228
|
-
fetch2,
|
|
229
|
-
keepLastMessageOnError,
|
|
230
|
-
throttleWaitMs,
|
|
231
|
-
chatId
|
|
232
|
-
]
|
|
155
|
+
const messages = useSyncExternalStore(
|
|
156
|
+
subscribeToMessages,
|
|
157
|
+
() => chatRef.current.messages,
|
|
158
|
+
() => chatRef.current.messages
|
|
233
159
|
);
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
body: body2,
|
|
239
|
-
experimental_attachments
|
|
240
|
-
} = {}) => {
|
|
241
|
-
var _a, _b;
|
|
242
|
-
const attachmentsForRequest = await prepareAttachmentsForRequest(
|
|
243
|
-
experimental_attachments
|
|
244
|
-
);
|
|
245
|
-
const messages2 = messagesRef.current.concat({
|
|
246
|
-
...message,
|
|
247
|
-
id: (_a = message.id) != null ? _a : generateId(),
|
|
248
|
-
createdAt: (_b = message.createdAt) != null ? _b : /* @__PURE__ */ new Date(),
|
|
249
|
-
experimental_attachments: attachmentsForRequest.length > 0 ? attachmentsForRequest : void 0,
|
|
250
|
-
parts: getMessageParts(message)
|
|
251
|
-
});
|
|
252
|
-
return triggerRequest({ messages: messages2, headers: headers2, body: body2, data });
|
|
253
|
-
},
|
|
254
|
-
[triggerRequest, generateId]
|
|
160
|
+
const status = useSyncExternalStore(
|
|
161
|
+
chatRef.current["~registerStatusCallback"],
|
|
162
|
+
() => chatRef.current.status,
|
|
163
|
+
() => chatRef.current.status
|
|
255
164
|
);
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
return null;
|
|
261
|
-
}
|
|
262
|
-
const lastMessage = messages2[messages2.length - 1];
|
|
263
|
-
return triggerRequest({
|
|
264
|
-
messages: lastMessage.role === "assistant" ? messages2.slice(0, -1) : messages2,
|
|
265
|
-
headers: headers2,
|
|
266
|
-
body: body2,
|
|
267
|
-
data
|
|
268
|
-
});
|
|
269
|
-
},
|
|
270
|
-
[triggerRequest]
|
|
165
|
+
const error = useSyncExternalStore(
|
|
166
|
+
chatRef.current["~registerErrorCallback"],
|
|
167
|
+
() => chatRef.current.error,
|
|
168
|
+
() => chatRef.current.error
|
|
271
169
|
);
|
|
272
|
-
const stop = useCallback(() => {
|
|
273
|
-
if (abortControllerRef.current) {
|
|
274
|
-
abortControllerRef.current.abort();
|
|
275
|
-
abortControllerRef.current = null;
|
|
276
|
-
}
|
|
277
|
-
}, []);
|
|
278
170
|
const setMessages = useCallback(
|
|
279
|
-
(
|
|
280
|
-
if (typeof
|
|
281
|
-
|
|
282
|
-
}
|
|
283
|
-
const messagesWithParts = fillMessageParts(messages2);
|
|
284
|
-
mutate(messagesWithParts, false);
|
|
285
|
-
messagesRef.current = messagesWithParts;
|
|
286
|
-
},
|
|
287
|
-
[mutate]
|
|
288
|
-
);
|
|
289
|
-
const setData = useCallback(
|
|
290
|
-
(data) => {
|
|
291
|
-
if (typeof data === "function") {
|
|
292
|
-
data = data(streamDataRef.current);
|
|
293
|
-
}
|
|
294
|
-
mutateStreamData(data, false);
|
|
295
|
-
streamDataRef.current = data;
|
|
296
|
-
},
|
|
297
|
-
[mutateStreamData]
|
|
298
|
-
);
|
|
299
|
-
const [input, setInput] = useState2(initialInput);
|
|
300
|
-
const handleSubmit = useCallback(
|
|
301
|
-
async (event, options = {}, metadata) => {
|
|
302
|
-
var _a;
|
|
303
|
-
(_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
|
|
304
|
-
if (!input && !options.allowEmptySubmit)
|
|
305
|
-
return;
|
|
306
|
-
if (metadata) {
|
|
307
|
-
extraMetadataRef.current = {
|
|
308
|
-
...extraMetadataRef.current,
|
|
309
|
-
...metadata
|
|
310
|
-
};
|
|
171
|
+
(messagesParam) => {
|
|
172
|
+
if (typeof messagesParam === "function") {
|
|
173
|
+
messagesParam = messagesParam(chatRef.current.messages);
|
|
311
174
|
}
|
|
312
|
-
|
|
313
|
-
options.experimental_attachments
|
|
314
|
-
);
|
|
315
|
-
const messages2 = messagesRef.current.concat({
|
|
316
|
-
id: generateId(),
|
|
317
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
318
|
-
role: "user",
|
|
319
|
-
content: input,
|
|
320
|
-
experimental_attachments: attachmentsForRequest.length > 0 ? attachmentsForRequest : void 0,
|
|
321
|
-
parts: [{ type: "text", text: input }]
|
|
322
|
-
});
|
|
323
|
-
const chatRequest = {
|
|
324
|
-
messages: messages2,
|
|
325
|
-
headers: options.headers,
|
|
326
|
-
body: options.body,
|
|
327
|
-
data: options.data
|
|
328
|
-
};
|
|
329
|
-
triggerRequest(chatRequest);
|
|
330
|
-
setInput("");
|
|
175
|
+
chatRef.current.messages = messagesParam;
|
|
331
176
|
},
|
|
332
|
-
[
|
|
333
|
-
);
|
|
334
|
-
const handleInputChange = (e) => {
|
|
335
|
-
setInput(e.target.value);
|
|
336
|
-
};
|
|
337
|
-
const addToolResult = useCallback(
|
|
338
|
-
({ toolCallId, result }) => {
|
|
339
|
-
const currentMessages = messagesRef.current;
|
|
340
|
-
updateToolCallResult({
|
|
341
|
-
messages: currentMessages,
|
|
342
|
-
toolCallId,
|
|
343
|
-
toolResult: result
|
|
344
|
-
});
|
|
345
|
-
mutate(
|
|
346
|
-
[
|
|
347
|
-
...currentMessages.slice(0, currentMessages.length - 1),
|
|
348
|
-
{ ...currentMessages[currentMessages.length - 1] }
|
|
349
|
-
],
|
|
350
|
-
false
|
|
351
|
-
);
|
|
352
|
-
if (status === "submitted" || status === "streaming") {
|
|
353
|
-
return;
|
|
354
|
-
}
|
|
355
|
-
const lastMessage = currentMessages[currentMessages.length - 1];
|
|
356
|
-
if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {
|
|
357
|
-
triggerRequest({ messages: currentMessages });
|
|
358
|
-
}
|
|
359
|
-
},
|
|
360
|
-
[mutate, status, triggerRequest]
|
|
177
|
+
[chatRef]
|
|
361
178
|
);
|
|
179
|
+
useEffect(() => {
|
|
180
|
+
if (resume) {
|
|
181
|
+
chatRef.current.resumeStream();
|
|
182
|
+
}
|
|
183
|
+
}, [resume, chatRef]);
|
|
362
184
|
return {
|
|
363
|
-
|
|
364
|
-
|
|
185
|
+
id: chatRef.current.id,
|
|
186
|
+
messages,
|
|
365
187
|
setMessages,
|
|
366
|
-
|
|
367
|
-
|
|
188
|
+
sendMessage: chatRef.current.sendMessage,
|
|
189
|
+
regenerate: chatRef.current.regenerate,
|
|
190
|
+
clearError: chatRef.current.clearError,
|
|
191
|
+
stop: chatRef.current.stop,
|
|
368
192
|
error,
|
|
369
|
-
|
|
370
|
-
reload,
|
|
371
|
-
stop,
|
|
372
|
-
input,
|
|
373
|
-
setInput,
|
|
374
|
-
handleInputChange,
|
|
375
|
-
handleSubmit,
|
|
376
|
-
isLoading: status === "submitted" || status === "streaming",
|
|
193
|
+
resumeStream: chatRef.current.resumeStream,
|
|
377
194
|
status,
|
|
378
|
-
addToolResult
|
|
195
|
+
addToolResult: chatRef.current.addToolResult
|
|
379
196
|
};
|
|
380
197
|
}
|
|
381
198
|
|
|
@@ -383,8 +200,8 @@ function useChat({
|
|
|
383
200
|
import {
|
|
384
201
|
callCompletionApi
|
|
385
202
|
} from "ai";
|
|
386
|
-
import { useCallback as useCallback2, useEffect as
|
|
387
|
-
import
|
|
203
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useId, useRef as useRef2, useState } from "react";
|
|
204
|
+
import useSWR from "swr";
|
|
388
205
|
function useCompletion({
|
|
389
206
|
api = "/api/completion",
|
|
390
207
|
id,
|
|
@@ -395,30 +212,28 @@ function useCompletion({
|
|
|
395
212
|
body,
|
|
396
213
|
streamProtocol = "data",
|
|
397
214
|
fetch: fetch2,
|
|
398
|
-
onResponse,
|
|
399
215
|
onFinish,
|
|
400
216
|
onError,
|
|
401
217
|
experimental_throttle: throttleWaitMs
|
|
402
218
|
} = {}) {
|
|
403
219
|
const hookId = useId();
|
|
404
220
|
const completionId = id || hookId;
|
|
405
|
-
const { data, mutate } =
|
|
221
|
+
const { data, mutate } = useSWR([api, completionId], null, {
|
|
406
222
|
fallbackData: initialCompletion
|
|
407
223
|
});
|
|
408
|
-
const { data: isLoading = false, mutate: mutateLoading } =
|
|
224
|
+
const { data: isLoading = false, mutate: mutateLoading } = useSWR(
|
|
409
225
|
[completionId, "loading"],
|
|
410
226
|
null
|
|
411
227
|
);
|
|
412
|
-
const
|
|
413
|
-
const [error, setError] = useState3(void 0);
|
|
228
|
+
const [error, setError] = useState(void 0);
|
|
414
229
|
const completion = data;
|
|
415
|
-
const [abortController, setAbortController] =
|
|
230
|
+
const [abortController, setAbortController] = useState(null);
|
|
416
231
|
const extraMetadataRef = useRef2({
|
|
417
232
|
credentials,
|
|
418
233
|
headers,
|
|
419
234
|
body
|
|
420
235
|
});
|
|
421
|
-
|
|
236
|
+
useEffect2(() => {
|
|
422
237
|
extraMetadataRef.current = {
|
|
423
238
|
credentials,
|
|
424
239
|
headers,
|
|
@@ -442,14 +257,9 @@ function useCompletion({
|
|
|
442
257
|
(completion2) => mutate(completion2, false),
|
|
443
258
|
throttleWaitMs
|
|
444
259
|
),
|
|
445
|
-
onData: throttle(
|
|
446
|
-
(data2) => mutateStreamData([...streamData != null ? streamData : [], ...data2 != null ? data2 : []], false),
|
|
447
|
-
throttleWaitMs
|
|
448
|
-
),
|
|
449
260
|
setLoading: mutateLoading,
|
|
450
261
|
setError,
|
|
451
262
|
setAbortController,
|
|
452
|
-
onResponse,
|
|
453
263
|
onFinish,
|
|
454
264
|
onError
|
|
455
265
|
}),
|
|
@@ -459,14 +269,11 @@ function useCompletion({
|
|
|
459
269
|
api,
|
|
460
270
|
extraMetadataRef,
|
|
461
271
|
setAbortController,
|
|
462
|
-
onResponse,
|
|
463
272
|
onFinish,
|
|
464
273
|
onError,
|
|
465
274
|
setError,
|
|
466
|
-
streamData,
|
|
467
275
|
streamProtocol,
|
|
468
276
|
fetch2,
|
|
469
|
-
mutateStreamData,
|
|
470
277
|
throttleWaitMs
|
|
471
278
|
]
|
|
472
279
|
);
|
|
@@ -488,7 +295,7 @@ function useCompletion({
|
|
|
488
295
|
},
|
|
489
296
|
[triggerRequest]
|
|
490
297
|
);
|
|
491
|
-
const [input, setInput] =
|
|
298
|
+
const [input, setInput] = useState(initialInput);
|
|
492
299
|
const handleSubmit = useCallback2(
|
|
493
300
|
(event) => {
|
|
494
301
|
var _a;
|
|
@@ -513,8 +320,7 @@ function useCompletion({
|
|
|
513
320
|
setInput,
|
|
514
321
|
handleInputChange,
|
|
515
322
|
handleSubmit,
|
|
516
|
-
isLoading
|
|
517
|
-
data: streamData
|
|
323
|
+
isLoading
|
|
518
324
|
};
|
|
519
325
|
}
|
|
520
326
|
|
|
@@ -525,11 +331,11 @@ import {
|
|
|
525
331
|
} from "@ai-sdk/provider-utils";
|
|
526
332
|
import {
|
|
527
333
|
asSchema,
|
|
528
|
-
isDeepEqualData
|
|
334
|
+
isDeepEqualData,
|
|
529
335
|
parsePartialJson
|
|
530
336
|
} from "ai";
|
|
531
|
-
import { useCallback as useCallback3, useId as useId2, useRef as useRef3, useState as
|
|
532
|
-
import
|
|
337
|
+
import { useCallback as useCallback3, useId as useId2, useRef as useRef3, useState as useState2 } from "react";
|
|
338
|
+
import useSWR2 from "swr";
|
|
533
339
|
var getOriginalFetch = () => fetch;
|
|
534
340
|
function useObject({
|
|
535
341
|
api,
|
|
@@ -545,13 +351,13 @@ function useObject({
|
|
|
545
351
|
}) {
|
|
546
352
|
const hookId = useId2();
|
|
547
353
|
const completionId = id != null ? id : hookId;
|
|
548
|
-
const { data, mutate } =
|
|
354
|
+
const { data, mutate } = useSWR2(
|
|
549
355
|
[api, completionId],
|
|
550
356
|
null,
|
|
551
357
|
{ fallbackData: initialValue }
|
|
552
358
|
);
|
|
553
|
-
const [error, setError] =
|
|
554
|
-
const [isLoading, setIsLoading] =
|
|
359
|
+
const [error, setError] = useState2(void 0);
|
|
360
|
+
const [isLoading, setIsLoading] = useState2(false);
|
|
555
361
|
const abortControllerRef = useRef3(null);
|
|
556
362
|
const stop = useCallback3(() => {
|
|
557
363
|
var _a;
|
|
@@ -566,9 +372,8 @@ function useObject({
|
|
|
566
372
|
const submit = async (input) => {
|
|
567
373
|
var _a;
|
|
568
374
|
try {
|
|
569
|
-
|
|
375
|
+
clearObject();
|
|
570
376
|
setIsLoading(true);
|
|
571
|
-
setError(void 0);
|
|
572
377
|
const abortController = new AbortController();
|
|
573
378
|
abortControllerRef.current = abortController;
|
|
574
379
|
const actualFetch = fetch2 != null ? fetch2 : getOriginalFetch();
|
|
@@ -594,20 +399,20 @@ function useObject({
|
|
|
594
399
|
let latestObject = void 0;
|
|
595
400
|
await response.body.pipeThrough(new TextDecoderStream()).pipeTo(
|
|
596
401
|
new WritableStream({
|
|
597
|
-
write(chunk) {
|
|
402
|
+
async write(chunk) {
|
|
598
403
|
accumulatedText += chunk;
|
|
599
|
-
const { value } = parsePartialJson(accumulatedText);
|
|
404
|
+
const { value } = await parsePartialJson(accumulatedText);
|
|
600
405
|
const currentObject = value;
|
|
601
|
-
if (!
|
|
406
|
+
if (!isDeepEqualData(latestObject, currentObject)) {
|
|
602
407
|
latestObject = currentObject;
|
|
603
408
|
mutate(currentObject);
|
|
604
409
|
}
|
|
605
410
|
},
|
|
606
|
-
close() {
|
|
411
|
+
async close() {
|
|
607
412
|
setIsLoading(false);
|
|
608
413
|
abortControllerRef.current = null;
|
|
609
414
|
if (onFinish != null) {
|
|
610
|
-
const validationResult = safeValidateTypes({
|
|
415
|
+
const validationResult = await safeValidateTypes({
|
|
611
416
|
value: latestObject,
|
|
612
417
|
schema: asSchema(schema)
|
|
613
418
|
});
|
|
@@ -629,16 +434,27 @@ function useObject({
|
|
|
629
434
|
setError(error2 instanceof Error ? error2 : new Error(String(error2)));
|
|
630
435
|
}
|
|
631
436
|
};
|
|
437
|
+
const clear = () => {
|
|
438
|
+
stop();
|
|
439
|
+
clearObject();
|
|
440
|
+
};
|
|
441
|
+
const clearObject = () => {
|
|
442
|
+
setError(void 0);
|
|
443
|
+
setIsLoading(false);
|
|
444
|
+
mutate(void 0);
|
|
445
|
+
};
|
|
632
446
|
return {
|
|
633
447
|
submit,
|
|
634
448
|
object: data,
|
|
635
449
|
error,
|
|
636
450
|
isLoading,
|
|
637
|
-
stop
|
|
451
|
+
stop,
|
|
452
|
+
clear
|
|
638
453
|
};
|
|
639
454
|
}
|
|
640
455
|
var experimental_useObject = useObject;
|
|
641
456
|
export {
|
|
457
|
+
Chat,
|
|
642
458
|
experimental_useObject,
|
|
643
459
|
useChat,
|
|
644
460
|
useCompletion
|