@assistant-ui/react-ai-sdk 0.5.16 → 0.6.1
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.mts +4 -89
- package/dist/index.d.ts +4 -89
- package/dist/index.js +149 -425
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +153 -429
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -40,85 +40,56 @@ var getVercelRSCMessage = (message) => {
|
|
|
40
40
|
return getExternalStoreMessage(message);
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
// src/ui/
|
|
44
|
-
import {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// src/ui/utils/sliceMessagesUntil.tsx
|
|
62
|
-
var sliceMessagesUntil = (messages, messageId) => {
|
|
63
|
-
if (messageId == null) return [];
|
|
64
|
-
let messageIdx = messages.findIndex((m) => m.id === messageId);
|
|
65
|
-
if (messageIdx === -1)
|
|
66
|
-
throw new Error(
|
|
67
|
-
"useVercelAIThreadState: Message not found. This is liekly an internal bug in assistant-ui."
|
|
68
|
-
);
|
|
69
|
-
while (messages[messageIdx + 1]?.role === "assistant") {
|
|
70
|
-
messageIdx++;
|
|
43
|
+
// src/ui/utils/useCachedChunkedMessages.ts
|
|
44
|
+
import { useMemo } from "react";
|
|
45
|
+
var hasItems = (messages) => messages.length > 0;
|
|
46
|
+
var chunkedMessages = (messages) => {
|
|
47
|
+
const chunks = [];
|
|
48
|
+
let currentChunk = [];
|
|
49
|
+
for (const message of messages) {
|
|
50
|
+
if (message.role === "assistant" || message.role === "data") {
|
|
51
|
+
currentChunk.push(message);
|
|
52
|
+
} else {
|
|
53
|
+
if (hasItems(currentChunk)) {
|
|
54
|
+
chunks.push(currentChunk);
|
|
55
|
+
currentChunk = [];
|
|
56
|
+
}
|
|
57
|
+
chunks.push([message]);
|
|
58
|
+
}
|
|
71
59
|
}
|
|
72
|
-
|
|
60
|
+
if (hasItems(currentChunk)) {
|
|
61
|
+
chunks.push(currentChunk);
|
|
62
|
+
}
|
|
63
|
+
return chunks;
|
|
73
64
|
};
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
useEffect(() => {
|
|
81
|
-
useThreadRuntime.getState().composer.setText(vercel.input);
|
|
82
|
-
}, [useComposer, useThreadRuntime, vercel.input]);
|
|
83
|
-
useEffect(() => {
|
|
84
|
-
useComposer.setState({
|
|
85
|
-
setText: (t) => {
|
|
86
|
-
vercel.setInput(t);
|
|
87
|
-
useThreadRuntime.getState().composer.setText(t);
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
}, [useComposer, useThreadRuntime, vercel]);
|
|
65
|
+
var shallowArrayEqual = (a, b) => {
|
|
66
|
+
if (a.length !== b.length) return false;
|
|
67
|
+
for (let i = 0; i < a.length; i++) {
|
|
68
|
+
if (a[i] !== b[i]) return false;
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
91
71
|
};
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const cached = this.cache.get(key);
|
|
103
|
-
const newMessage = converter(m, cached);
|
|
104
|
-
this.cache.set(key, newMessage);
|
|
105
|
-
return newMessage;
|
|
72
|
+
var useCachedChunkedMessages = (messages) => {
|
|
73
|
+
const cache = useMemo(() => /* @__PURE__ */ new WeakMap(), []);
|
|
74
|
+
return useMemo(() => {
|
|
75
|
+
return chunkedMessages(messages).map((m) => {
|
|
76
|
+
const key = m[0];
|
|
77
|
+
if (!key) return m;
|
|
78
|
+
const cached = cache.get(key);
|
|
79
|
+
if (cached && shallowArrayEqual(cached, m)) return cached;
|
|
80
|
+
cache.set(key, m);
|
|
81
|
+
return m;
|
|
106
82
|
});
|
|
107
|
-
}
|
|
83
|
+
}, [messages, cache]);
|
|
108
84
|
};
|
|
109
85
|
|
|
110
|
-
// src/ui/utils/
|
|
111
|
-
var
|
|
112
|
-
if ("isLoading" in vercel) return vercel.isLoading;
|
|
113
|
-
return vercel.status === "in_progress";
|
|
114
|
-
};
|
|
115
|
-
var vercelToThreadMessage2 = (messages, status) => {
|
|
86
|
+
// src/ui/utils/convertMessage.ts
|
|
87
|
+
var convertMessage = (messages) => {
|
|
116
88
|
const firstMessage = messages[0];
|
|
117
89
|
if (!firstMessage) throw new Error("No messages found");
|
|
118
90
|
const common = {
|
|
119
91
|
id: firstMessage.id,
|
|
120
|
-
createdAt: firstMessage.createdAt ?? /* @__PURE__ */ new Date()
|
|
121
|
-
[symbolInnerAIMessage]: messages
|
|
92
|
+
createdAt: firstMessage.createdAt ?? /* @__PURE__ */ new Date()
|
|
122
93
|
};
|
|
123
94
|
switch (firstMessage.role) {
|
|
124
95
|
case "user":
|
|
@@ -158,8 +129,7 @@ var vercelToThreadMessage2 = (messages, status) => {
|
|
|
158
129
|
) ?? [],
|
|
159
130
|
...typeof message.data === "object" && !Array.isArray(message.data) && message.data?.["type"] === "tool-call" ? [message.data] : []
|
|
160
131
|
];
|
|
161
|
-
})
|
|
162
|
-
status
|
|
132
|
+
})
|
|
163
133
|
};
|
|
164
134
|
for (const message of messages) {
|
|
165
135
|
if (typeof message.data === "object" && !Array.isArray(message.data) && message.data?.["type"] === "tool-result") {
|
|
@@ -180,383 +150,137 @@ var vercelToThreadMessage2 = (messages, status) => {
|
|
|
180
150
|
);
|
|
181
151
|
}
|
|
182
152
|
};
|
|
183
|
-
var hasItems = (messages) => messages.length > 0;
|
|
184
|
-
var chunkedMessages = (messages) => {
|
|
185
|
-
const chunks = [];
|
|
186
|
-
let currentChunk = [];
|
|
187
|
-
for (const message of messages) {
|
|
188
|
-
if (message.role === "assistant" || message.role === "data") {
|
|
189
|
-
currentChunk.push(message);
|
|
190
|
-
} else {
|
|
191
|
-
if (hasItems(currentChunk)) {
|
|
192
|
-
chunks.push(currentChunk);
|
|
193
|
-
currentChunk = [];
|
|
194
|
-
}
|
|
195
|
-
chunks.push([message]);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
if (hasItems(currentChunk)) {
|
|
199
|
-
chunks.push(currentChunk);
|
|
200
|
-
}
|
|
201
|
-
return chunks;
|
|
202
|
-
};
|
|
203
|
-
var shallowArrayEqual = (a, b) => {
|
|
204
|
-
if (a.length !== b.length) return false;
|
|
205
|
-
for (let i = 0; i < a.length; i++) {
|
|
206
|
-
if (a[i] !== b[i]) return false;
|
|
207
|
-
}
|
|
208
|
-
return true;
|
|
209
|
-
};
|
|
210
|
-
var useVercelAIThreadSync = (vercel, updateData) => {
|
|
211
|
-
const isRunning = getIsRunning(vercel);
|
|
212
|
-
const converter = useMemo(() => new ThreadMessageConverter(), []);
|
|
213
|
-
useEffect2(() => {
|
|
214
|
-
const lastMessageId = vercel.messages.at(-1)?.id;
|
|
215
|
-
const convertCallback = (messages2, cache) => {
|
|
216
|
-
const status = lastMessageId === messages2[0].id && isRunning ? {
|
|
217
|
-
type: "running"
|
|
218
|
-
} : {
|
|
219
|
-
type: "complete",
|
|
220
|
-
reason: "unknown"
|
|
221
|
-
};
|
|
222
|
-
if (cache && shallowArrayEqual(cache.content, messages2) && (cache.role !== "assistant" || cache.status.type === status.type))
|
|
223
|
-
return cache;
|
|
224
|
-
return vercelToThreadMessage2(messages2, status);
|
|
225
|
-
};
|
|
226
|
-
const messages = converter.convertMessages(
|
|
227
|
-
chunkedMessages(vercel.messages),
|
|
228
|
-
convertCallback,
|
|
229
|
-
(m) => m[0]
|
|
230
|
-
);
|
|
231
|
-
updateData(isRunning, messages);
|
|
232
|
-
}, [updateData, isRunning, vercel.messages, converter]);
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
// src/ui/use-chat/VercelUseChatThreadRuntime.tsx
|
|
236
|
-
var { MessageRepository } = INTERNAL;
|
|
237
|
-
var hasUpcomingMessage = (isRunning, messages) => {
|
|
238
|
-
return isRunning && messages[messages.length - 1]?.role !== "assistant";
|
|
239
|
-
};
|
|
240
|
-
var CAPABILITIES = Object.freeze({
|
|
241
|
-
switchToBranch: true,
|
|
242
|
-
edit: true,
|
|
243
|
-
reload: true,
|
|
244
|
-
cancel: true,
|
|
245
|
-
copy: true
|
|
246
|
-
});
|
|
247
|
-
var VercelUseChatThreadRuntime = class {
|
|
248
|
-
constructor(vercel) {
|
|
249
|
-
this.vercel = vercel;
|
|
250
|
-
this.useVercel = create(() => ({
|
|
251
|
-
vercel
|
|
252
|
-
}));
|
|
253
|
-
}
|
|
254
|
-
_subscriptions = /* @__PURE__ */ new Set();
|
|
255
|
-
repository = new MessageRepository();
|
|
256
|
-
assistantOptimisticId = null;
|
|
257
|
-
useVercel;
|
|
258
|
-
capabilities = CAPABILITIES;
|
|
259
|
-
messages = [];
|
|
260
|
-
isDisabled = false;
|
|
261
|
-
composer = {
|
|
262
|
-
text: "",
|
|
263
|
-
setText: (value) => {
|
|
264
|
-
this.composer.text = value;
|
|
265
|
-
for (const callback of this._subscriptions) callback();
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
|
-
getBranches(messageId) {
|
|
269
|
-
return this.repository.getBranches(messageId);
|
|
270
|
-
}
|
|
271
|
-
switchToBranch(branchId) {
|
|
272
|
-
this.repository.switchToBranch(branchId);
|
|
273
|
-
this.updateVercelMessages(this.repository.getMessages());
|
|
274
|
-
}
|
|
275
|
-
async append(message) {
|
|
276
|
-
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
|
277
|
-
throw new Error(
|
|
278
|
-
"Only text content is supported by VercelUseChatRuntime. Use the Edge runtime for image support."
|
|
279
|
-
);
|
|
280
|
-
const newMessages = sliceMessagesUntil(
|
|
281
|
-
this.vercel.messages,
|
|
282
|
-
message.parentId
|
|
283
|
-
);
|
|
284
|
-
this.vercel.setMessages(newMessages);
|
|
285
|
-
await this.vercel.append({
|
|
286
|
-
role: message.role,
|
|
287
|
-
content: message.content[0].text
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
async startRun(parentId) {
|
|
291
|
-
const newMessages = sliceMessagesUntil(this.vercel.messages, parentId);
|
|
292
|
-
this.vercel.setMessages(newMessages);
|
|
293
|
-
await this.vercel.reload();
|
|
294
|
-
}
|
|
295
|
-
cancelRun() {
|
|
296
|
-
const previousMessage = this.vercel.messages.at(-1);
|
|
297
|
-
this.vercel.stop();
|
|
298
|
-
if (this.assistantOptimisticId) {
|
|
299
|
-
this.repository.deleteMessage(this.assistantOptimisticId);
|
|
300
|
-
this.assistantOptimisticId = null;
|
|
301
|
-
}
|
|
302
|
-
let messages = this.repository.getMessages();
|
|
303
|
-
if (previousMessage?.role === "user" && previousMessage.id === messages.at(-1)?.id) {
|
|
304
|
-
this.vercel.setInput(previousMessage.content);
|
|
305
|
-
this.repository.deleteMessage(previousMessage.id);
|
|
306
|
-
messages = this.repository.getMessages();
|
|
307
|
-
}
|
|
308
|
-
setTimeout(() => {
|
|
309
|
-
this.updateVercelMessages(messages);
|
|
310
|
-
}, 0);
|
|
311
|
-
}
|
|
312
|
-
subscribe(callback) {
|
|
313
|
-
this._subscriptions.add(callback);
|
|
314
|
-
return () => this._subscriptions.delete(callback);
|
|
315
|
-
}
|
|
316
|
-
updateVercelMessages = (messages) => {
|
|
317
|
-
this.vercel.setMessages(
|
|
318
|
-
messages.flatMap(getVercelAIMessage).filter((m) => m != null)
|
|
319
|
-
);
|
|
320
|
-
};
|
|
321
|
-
onVercelUpdated() {
|
|
322
|
-
if (this.useVercel.getState().vercel !== this.vercel) {
|
|
323
|
-
this.useVercel.setState({ vercel: this.vercel });
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
updateData = (isRunning, vm) => {
|
|
327
|
-
for (let i = 0; i < vm.length; i++) {
|
|
328
|
-
const message = vm[i];
|
|
329
|
-
const parent = vm[i - 1];
|
|
330
|
-
this.repository.addOrUpdateMessage(parent?.id ?? null, message);
|
|
331
|
-
}
|
|
332
|
-
if (this.assistantOptimisticId) {
|
|
333
|
-
this.repository.deleteMessage(this.assistantOptimisticId);
|
|
334
|
-
this.assistantOptimisticId = null;
|
|
335
|
-
}
|
|
336
|
-
if (hasUpcomingMessage(isRunning, vm)) {
|
|
337
|
-
this.assistantOptimisticId = this.repository.appendOptimisticMessage(
|
|
338
|
-
vm.at(-1)?.id ?? null,
|
|
339
|
-
{
|
|
340
|
-
role: "assistant",
|
|
341
|
-
content: []
|
|
342
|
-
}
|
|
343
|
-
);
|
|
344
|
-
}
|
|
345
|
-
this.repository.resetHead(
|
|
346
|
-
this.assistantOptimisticId ?? vm.at(-1)?.id ?? null
|
|
347
|
-
);
|
|
348
|
-
this.messages = this.repository.getMessages();
|
|
349
|
-
for (const callback of this._subscriptions) callback();
|
|
350
|
-
};
|
|
351
|
-
unstable_synchronizer = () => {
|
|
352
|
-
const { vercel } = this.useVercel();
|
|
353
|
-
useVercelAIThreadSync(vercel, this.updateData);
|
|
354
|
-
useVercelAIComposerSync(vercel);
|
|
355
|
-
return null;
|
|
356
|
-
};
|
|
357
|
-
addToolResult({ toolCallId, result }) {
|
|
358
|
-
this.vercel.addToolResult({ toolCallId, result });
|
|
359
|
-
}
|
|
360
|
-
};
|
|
361
|
-
|
|
362
|
-
// src/ui/use-chat/VercelUseChatRuntime.tsx
|
|
363
|
-
var { ProxyConfigProvider, BaseAssistantRuntime } = INTERNAL2;
|
|
364
|
-
var VercelUseChatRuntime = class extends BaseAssistantRuntime {
|
|
365
|
-
_proxyConfigProvider = new ProxyConfigProvider();
|
|
366
|
-
constructor(vercel) {
|
|
367
|
-
super(new VercelUseChatThreadRuntime(vercel));
|
|
368
|
-
}
|
|
369
|
-
set vercel(vercel) {
|
|
370
|
-
this.thread.vercel = vercel;
|
|
371
|
-
}
|
|
372
|
-
onVercelUpdated() {
|
|
373
|
-
return this.thread.onVercelUpdated();
|
|
374
|
-
}
|
|
375
|
-
getModelConfig() {
|
|
376
|
-
return this._proxyConfigProvider.getModelConfig();
|
|
377
|
-
}
|
|
378
|
-
registerModelConfigProvider(provider) {
|
|
379
|
-
return this._proxyConfigProvider.registerModelConfigProvider(provider);
|
|
380
|
-
}
|
|
381
|
-
switchToThread(threadId) {
|
|
382
|
-
if (threadId) {
|
|
383
|
-
throw new Error(
|
|
384
|
-
"VercelAIRuntime does not yet support switching threads."
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
this.thread.vercel.messages = [];
|
|
388
|
-
this.thread.vercel.input = "";
|
|
389
|
-
this.thread.vercel.setMessages([]);
|
|
390
|
-
this.thread.vercel.setInput("");
|
|
391
|
-
this.thread = new VercelUseChatThreadRuntime(this.thread.vercel);
|
|
392
|
-
}
|
|
393
|
-
};
|
|
394
153
|
|
|
395
154
|
// src/ui/use-chat/useVercelUseChatRuntime.tsx
|
|
396
|
-
|
|
397
|
-
const [runtime] = useState(() => new VercelUseChatRuntime(chatHelpers));
|
|
398
|
-
useInsertionEffect(() => {
|
|
399
|
-
runtime.vercel = chatHelpers;
|
|
400
|
-
});
|
|
401
|
-
useEffect3(() => {
|
|
402
|
-
runtime.onVercelUpdated();
|
|
403
|
-
});
|
|
404
|
-
return runtime;
|
|
405
|
-
};
|
|
155
|
+
import { useExternalStoreRuntime as useExternalStoreRuntime2 } from "@assistant-ui/react";
|
|
406
156
|
|
|
407
|
-
// src/ui/
|
|
408
|
-
import {
|
|
409
|
-
|
|
410
|
-
// src/ui/use-assistant/VercelUseAssistantRuntime.tsx
|
|
157
|
+
// src/ui/utils/useInputSync.tsx
|
|
158
|
+
import { useRef, useEffect } from "react";
|
|
411
159
|
import {
|
|
412
|
-
|
|
160
|
+
subscribeToMainThread
|
|
413
161
|
} from "@assistant-ui/react";
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
edit: false,
|
|
421
|
-
reload: false,
|
|
422
|
-
cancel: false,
|
|
423
|
-
copy: true
|
|
424
|
-
});
|
|
425
|
-
var VercelUseAssistantThreadRuntime = class {
|
|
426
|
-
constructor(vercel) {
|
|
427
|
-
this.vercel = vercel;
|
|
428
|
-
this.useVercel = create2(() => ({
|
|
429
|
-
vercel
|
|
430
|
-
}));
|
|
431
|
-
}
|
|
432
|
-
_subscriptions = /* @__PURE__ */ new Set();
|
|
433
|
-
capabilities = CAPABILITIES2;
|
|
434
|
-
useVercel;
|
|
435
|
-
messages = [];
|
|
436
|
-
composer = {
|
|
437
|
-
text: "",
|
|
438
|
-
setText: (value) => {
|
|
439
|
-
this.composer.text = value;
|
|
440
|
-
for (const callback of this._subscriptions) callback();
|
|
162
|
+
var useInputSync = (helpers, runtime) => {
|
|
163
|
+
const helpersRef = useRef(helpers);
|
|
164
|
+
useEffect(() => {
|
|
165
|
+
helpersRef.current = helpers;
|
|
166
|
+
if (runtime.thread.composer.text !== helpers.input) {
|
|
167
|
+
runtime.thread.composer.setText(helpers.input);
|
|
441
168
|
}
|
|
442
|
-
};
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
throw new Error(
|
|
449
|
-
"VercelUseAssistantRuntime does not support switching branches."
|
|
450
|
-
);
|
|
451
|
-
}
|
|
452
|
-
async append(message) {
|
|
453
|
-
if (message.role !== "user")
|
|
454
|
-
throw new Error(
|
|
455
|
-
"Only appending user messages are supported in VercelUseAssistantRuntime. This is likely an internal bug in assistant-ui."
|
|
456
|
-
);
|
|
457
|
-
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
|
458
|
-
throw new Error("VercelUseAssistantRuntime only supports text content.");
|
|
459
|
-
if (message.parentId !== (this.messages.at(-1)?.id ?? null))
|
|
460
|
-
throw new Error(
|
|
461
|
-
"VercelUseAssistantRuntime does not support editing messages."
|
|
462
|
-
);
|
|
463
|
-
await this.vercel.append({
|
|
464
|
-
role: "user",
|
|
465
|
-
content: message.content[0].text
|
|
169
|
+
}, [helpers, runtime]);
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
return subscribeToMainThread(runtime, () => {
|
|
172
|
+
if (runtime.thread.composer.text !== helpersRef.current.input) {
|
|
173
|
+
helpersRef.current.setInput(runtime.thread.composer.text);
|
|
174
|
+
}
|
|
466
175
|
});
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
this.vercel.setInput(previousMessage.content);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
subscribe(callback) {
|
|
479
|
-
this._subscriptions.add(callback);
|
|
480
|
-
return () => this._subscriptions.delete(callback);
|
|
481
|
-
}
|
|
482
|
-
onVercelUpdated() {
|
|
483
|
-
if (this.useVercel.getState().vercel !== this.vercel) {
|
|
484
|
-
this.useVercel.setState({ vercel: this.vercel });
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
updateData = (isRunning, vm) => {
|
|
488
|
-
if (hasUpcomingMessage2(isRunning, vm)) {
|
|
489
|
-
vm.push({
|
|
490
|
-
id: "__optimistic__result",
|
|
491
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
492
|
-
status: { type: "running" },
|
|
493
|
-
role: "assistant",
|
|
494
|
-
content: []
|
|
495
|
-
});
|
|
496
|
-
}
|
|
497
|
-
this.messages = vm;
|
|
498
|
-
for (const callback of this._subscriptions) callback();
|
|
499
|
-
};
|
|
500
|
-
unstable_synchronizer = () => {
|
|
501
|
-
const { vercel } = this.useVercel();
|
|
502
|
-
useVercelAIThreadSync(vercel, this.updateData);
|
|
503
|
-
useVercelAIComposerSync(vercel);
|
|
504
|
-
return null;
|
|
505
|
-
};
|
|
506
|
-
addToolResult() {
|
|
176
|
+
}, [runtime]);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// src/ui/utils/sliceMessagesUntil.tsx
|
|
180
|
+
var sliceMessagesUntil = (messages, messageId) => {
|
|
181
|
+
if (messageId == null) return [];
|
|
182
|
+
let messageIdx = messages.findIndex((m) => m.id === messageId);
|
|
183
|
+
if (messageIdx === -1)
|
|
507
184
|
throw new Error(
|
|
508
|
-
"
|
|
185
|
+
"useVercelAIThreadState: Message not found. This is liekly an internal bug in assistant-ui."
|
|
509
186
|
);
|
|
187
|
+
while (messages[messageIdx + 1]?.role === "assistant") {
|
|
188
|
+
messageIdx++;
|
|
510
189
|
}
|
|
190
|
+
return messages.slice(0, messageIdx + 1);
|
|
511
191
|
};
|
|
512
192
|
|
|
513
|
-
// src/ui/use-
|
|
514
|
-
var
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
193
|
+
// src/ui/use-chat/useVercelUseChatRuntime.tsx
|
|
194
|
+
var useVercelUseChatRuntime = (chatHelpers) => {
|
|
195
|
+
const messages = useCachedChunkedMessages(chatHelpers.messages);
|
|
196
|
+
const runtime = useExternalStoreRuntime2({
|
|
197
|
+
isRunning: chatHelpers.isLoading,
|
|
198
|
+
messages,
|
|
199
|
+
setMessages: (messages2) => chatHelpers.setMessages(messages2.flat()),
|
|
200
|
+
onCancel: async () => chatHelpers.stop(),
|
|
201
|
+
onNew: async (message) => {
|
|
202
|
+
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
|
203
|
+
throw new Error(
|
|
204
|
+
"Only text content is supported by VercelUseChatRuntime. Use the Edge runtime for image support."
|
|
205
|
+
);
|
|
206
|
+
await chatHelpers.append({
|
|
207
|
+
role: message.role,
|
|
208
|
+
content: message.content[0].text
|
|
209
|
+
});
|
|
210
|
+
},
|
|
211
|
+
onEdit: async (message) => {
|
|
212
|
+
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
|
213
|
+
throw new Error(
|
|
214
|
+
"Only text content is supported by VercelUseChatRuntime. Use the Edge runtime for image support."
|
|
215
|
+
);
|
|
216
|
+
const newMessages = sliceMessagesUntil(
|
|
217
|
+
chatHelpers.messages,
|
|
218
|
+
message.parentId
|
|
219
|
+
);
|
|
220
|
+
chatHelpers.setMessages(newMessages);
|
|
221
|
+
await chatHelpers.append({
|
|
222
|
+
role: message.role,
|
|
223
|
+
content: message.content[0].text
|
|
224
|
+
});
|
|
225
|
+
},
|
|
226
|
+
onReload: async (parentId) => {
|
|
227
|
+
const newMessages = sliceMessagesUntil(chatHelpers.messages, parentId);
|
|
228
|
+
chatHelpers.setMessages(newMessages);
|
|
229
|
+
await chatHelpers.reload();
|
|
230
|
+
},
|
|
231
|
+
onAddToolResult: ({ toolCallId, result }) => {
|
|
232
|
+
chatHelpers.addToolResult({ toolCallId, result });
|
|
233
|
+
},
|
|
234
|
+
// onCopy // TODO
|
|
235
|
+
onNewThread: () => {
|
|
236
|
+
chatHelpers.messages = [];
|
|
237
|
+
chatHelpers.input = "";
|
|
238
|
+
chatHelpers.setMessages([]);
|
|
239
|
+
chatHelpers.setInput("");
|
|
240
|
+
},
|
|
241
|
+
convertMessage
|
|
242
|
+
});
|
|
243
|
+
useInputSync(chatHelpers, runtime);
|
|
244
|
+
return runtime;
|
|
545
245
|
};
|
|
546
246
|
|
|
547
247
|
// src/ui/use-assistant/useVercelUseAssistantRuntime.tsx
|
|
248
|
+
import { useExternalStoreRuntime as useExternalStoreRuntime3 } from "@assistant-ui/react";
|
|
548
249
|
var useVercelUseAssistantRuntime = (assistantHelpers) => {
|
|
549
|
-
const
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
250
|
+
const messages = useCachedChunkedMessages(assistantHelpers.messages);
|
|
251
|
+
const runtime = useExternalStoreRuntime3({
|
|
252
|
+
isRunning: assistantHelpers.status === "in_progress",
|
|
253
|
+
messages,
|
|
254
|
+
onCancel: async () => assistantHelpers.stop(),
|
|
255
|
+
onNew: async (message) => {
|
|
256
|
+
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
|
257
|
+
throw new Error(
|
|
258
|
+
"VercelUseAssistantRuntime only supports text content."
|
|
259
|
+
);
|
|
260
|
+
await assistantHelpers.append({
|
|
261
|
+
role: message.role,
|
|
262
|
+
content: message.content[0].text
|
|
263
|
+
});
|
|
264
|
+
},
|
|
265
|
+
onNewThread: () => {
|
|
266
|
+
assistantHelpers.messages = [];
|
|
267
|
+
assistantHelpers.input = "";
|
|
268
|
+
assistantHelpers.setMessages([]);
|
|
269
|
+
assistantHelpers.setInput("");
|
|
270
|
+
},
|
|
271
|
+
convertMessage
|
|
557
272
|
});
|
|
273
|
+
useInputSync(assistantHelpers, runtime);
|
|
558
274
|
return runtime;
|
|
559
275
|
};
|
|
276
|
+
|
|
277
|
+
// src/ui/getVercelAIMessage.tsx
|
|
278
|
+
import {
|
|
279
|
+
getExternalStoreMessage as getExternalStoreMessage2
|
|
280
|
+
} from "@assistant-ui/react";
|
|
281
|
+
var getVercelAIMessage = (message) => {
|
|
282
|
+
return getExternalStoreMessage2(message);
|
|
283
|
+
};
|
|
560
284
|
export {
|
|
561
285
|
getVercelAIMessage,
|
|
562
286
|
getVercelRSCMessage,
|