@assistant-ui/react 0.0.20 → 0.0.22
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/LICENSE +21 -0
- package/dist/index.d.mts +180 -88
- package/dist/index.d.ts +180 -88
- package/dist/index.js +910 -773
- package/dist/index.mjs +923 -799
- package/package.json +16 -8
package/dist/index.mjs
CHANGED
@@ -4,6 +4,156 @@ var __export = (target, all) => {
|
|
4
4
|
__defProp(target, name, { get: all[name], enumerable: true });
|
5
5
|
};
|
6
6
|
|
7
|
+
// src/actions/useCopyMessage.tsx
|
8
|
+
import { useCallback } from "react";
|
9
|
+
|
10
|
+
// src/context/MessageContext.ts
|
11
|
+
import { createContext, useContext } from "react";
|
12
|
+
var MessageContext = createContext(null);
|
13
|
+
var useMessageContext = () => {
|
14
|
+
const context = useContext(MessageContext);
|
15
|
+
if (!context)
|
16
|
+
throw new Error(
|
17
|
+
"This component can only be used inside a component passed to <ThreadPrimitive.Messages components={...} />."
|
18
|
+
);
|
19
|
+
return context;
|
20
|
+
};
|
21
|
+
|
22
|
+
// src/utils/combined/useCombinedStore.ts
|
23
|
+
import { useMemo } from "react";
|
24
|
+
|
25
|
+
// src/utils/combined/createCombinedStore.ts
|
26
|
+
import { useSyncExternalStore } from "react";
|
27
|
+
var createCombinedStore = (stores) => {
|
28
|
+
const subscribe = (callback) => {
|
29
|
+
const unsubscribes = stores.map((store) => store.subscribe(callback));
|
30
|
+
return () => {
|
31
|
+
for (const unsub of unsubscribes) {
|
32
|
+
unsub();
|
33
|
+
}
|
34
|
+
};
|
35
|
+
};
|
36
|
+
return (selector) => {
|
37
|
+
const getSnapshot = () => selector(...stores.map((store) => store.getState()));
|
38
|
+
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
39
|
+
};
|
40
|
+
};
|
41
|
+
|
42
|
+
// src/utils/combined/useCombinedStore.ts
|
43
|
+
var useCombinedStore = (stores, selector) => {
|
44
|
+
const useCombined = useMemo(() => createCombinedStore(stores), stores);
|
45
|
+
return useCombined(selector);
|
46
|
+
};
|
47
|
+
|
48
|
+
// src/utils/getMessageText.tsx
|
49
|
+
var getMessageText = (message) => {
|
50
|
+
const textParts = message.content.filter(
|
51
|
+
(part) => part.type === "text"
|
52
|
+
);
|
53
|
+
return textParts.map((part) => part.text).join("\n\n");
|
54
|
+
};
|
55
|
+
|
56
|
+
// src/actions/useCopyMessage.tsx
|
57
|
+
var useCopyMessage = ({ copiedDuration = 3e3 }) => {
|
58
|
+
const { useMessage, useComposer } = useMessageContext();
|
59
|
+
const hasCopyableContent = useCombinedStore(
|
60
|
+
[useMessage, useComposer],
|
61
|
+
(m, c) => {
|
62
|
+
return c.isEditing || m.message.content.some((c2) => c2.type === "text");
|
63
|
+
}
|
64
|
+
);
|
65
|
+
const callback = useCallback(() => {
|
66
|
+
const { isEditing, value: composerValue } = useComposer.getState();
|
67
|
+
const { message, setIsCopied } = useMessage.getState();
|
68
|
+
const valueToCopy = isEditing ? composerValue : getMessageText(message);
|
69
|
+
navigator.clipboard.writeText(valueToCopy);
|
70
|
+
setIsCopied(true);
|
71
|
+
setTimeout(() => setIsCopied(false), copiedDuration);
|
72
|
+
}, [useComposer, useMessage, copiedDuration]);
|
73
|
+
if (!hasCopyableContent) return null;
|
74
|
+
return callback;
|
75
|
+
};
|
76
|
+
|
77
|
+
// src/actions/useReloadMessage.tsx
|
78
|
+
import { useCallback as useCallback2 } from "react";
|
79
|
+
|
80
|
+
// src/context/ThreadContext.ts
|
81
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
82
|
+
var ThreadContext = createContext2(null);
|
83
|
+
var useThreadContext = () => {
|
84
|
+
const context = useContext2(ThreadContext);
|
85
|
+
if (!context)
|
86
|
+
throw new Error("This component must be used within an AssistantProvider.");
|
87
|
+
return context;
|
88
|
+
};
|
89
|
+
|
90
|
+
// src/actions/useReloadMessage.tsx
|
91
|
+
var useReloadMessage = () => {
|
92
|
+
const { useThread, useViewport } = useThreadContext();
|
93
|
+
const { useMessage } = useMessageContext();
|
94
|
+
const disabled = useCombinedStore(
|
95
|
+
[useThread, useMessage],
|
96
|
+
(t, m) => t.isRunning || m.message.role !== "assistant"
|
97
|
+
);
|
98
|
+
const callback = useCallback2(() => {
|
99
|
+
const { parentId } = useMessage.getState();
|
100
|
+
useThread.getState().startRun(parentId);
|
101
|
+
useViewport.getState().scrollToBottom();
|
102
|
+
}, [useMessage, useThread, useViewport]);
|
103
|
+
if (disabled) return null;
|
104
|
+
return callback;
|
105
|
+
};
|
106
|
+
|
107
|
+
// src/actions/useBeginMessageEdit.tsx
|
108
|
+
import { useCallback as useCallback3 } from "react";
|
109
|
+
var useBeginMessageEdit = () => {
|
110
|
+
const { useMessage, useComposer } = useMessageContext();
|
111
|
+
const disabled = useCombinedStore(
|
112
|
+
[useMessage, useComposer],
|
113
|
+
(m, c) => m.message.role !== "user" || c.isEditing
|
114
|
+
);
|
115
|
+
const callback = useCallback3(() => {
|
116
|
+
const { edit } = useComposer.getState();
|
117
|
+
edit();
|
118
|
+
}, [useComposer]);
|
119
|
+
if (disabled) return null;
|
120
|
+
return callback;
|
121
|
+
};
|
122
|
+
|
123
|
+
// src/actions/useGoToNextBranch.tsx
|
124
|
+
import { useCallback as useCallback4 } from "react";
|
125
|
+
var useGoToNextBranch = () => {
|
126
|
+
const { useThread } = useThreadContext();
|
127
|
+
const { useMessage, useComposer } = useMessageContext();
|
128
|
+
const disabled = useCombinedStore(
|
129
|
+
[useMessage, useComposer],
|
130
|
+
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
|
131
|
+
);
|
132
|
+
const callback = useCallback4(() => {
|
133
|
+
const { message, branches } = useMessage.getState();
|
134
|
+
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
|
135
|
+
}, [useMessage, useThread]);
|
136
|
+
if (disabled) return null;
|
137
|
+
return callback;
|
138
|
+
};
|
139
|
+
|
140
|
+
// src/actions/useGoToPreviousBranch.tsx
|
141
|
+
import { useCallback as useCallback5 } from "react";
|
142
|
+
var useGoToPreviousBranch = () => {
|
143
|
+
const { useThread } = useThreadContext();
|
144
|
+
const { useMessage, useComposer } = useMessageContext();
|
145
|
+
const disabled = useCombinedStore(
|
146
|
+
[useMessage, useComposer],
|
147
|
+
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
|
148
|
+
);
|
149
|
+
const callback = useCallback5(() => {
|
150
|
+
const { message, branches } = useMessage.getState();
|
151
|
+
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
|
152
|
+
}, [useMessage, useThread]);
|
153
|
+
if (disabled) return null;
|
154
|
+
return callback;
|
155
|
+
};
|
156
|
+
|
7
157
|
// src/primitives/thread/index.ts
|
8
158
|
var thread_exports = {};
|
9
159
|
__export(thread_exports, {
|
@@ -28,21 +178,9 @@ var ThreadRoot = forwardRef(
|
|
28
178
|
}
|
29
179
|
);
|
30
180
|
|
31
|
-
// src/utils/context/AssistantContext.ts
|
32
|
-
import { createContext, useContext } from "react";
|
33
|
-
var AssistantContext = createContext(null);
|
34
|
-
var useAssistantContext = () => {
|
35
|
-
const context = useContext(AssistantContext);
|
36
|
-
if (!context)
|
37
|
-
throw new Error(
|
38
|
-
"This component must be used within a AssistantProvider."
|
39
|
-
);
|
40
|
-
return context;
|
41
|
-
};
|
42
|
-
|
43
181
|
// src/primitives/thread/ThreadIf.tsx
|
44
182
|
var useThreadIf = (props) => {
|
45
|
-
const { useThread } =
|
183
|
+
const { useThread } = useThreadContext();
|
46
184
|
return useThread((thread) => {
|
47
185
|
if (props.empty === true && thread.messages.length !== 0) return false;
|
48
186
|
if (props.empty === false && thread.messages.length === 0) return false;
|
@@ -113,7 +251,7 @@ import { useCallbackRef as useCallbackRef2 } from "@radix-ui/react-use-callback-
|
|
113
251
|
import { useEffect as useEffect2 } from "react";
|
114
252
|
var useOnScrollToBottom = (callback) => {
|
115
253
|
const callbackRef = useCallbackRef2(callback);
|
116
|
-
const { useViewport } =
|
254
|
+
const { useViewport } = useThreadContext();
|
117
255
|
useEffect2(() => {
|
118
256
|
return useViewport.getState().onScrollToBottom(() => {
|
119
257
|
callbackRef();
|
@@ -127,7 +265,7 @@ var ThreadViewport = forwardRef2(({ autoScroll = true, onScroll, children, ...re
|
|
127
265
|
const messagesEndRef = useRef(null);
|
128
266
|
const divRef = useRef(null);
|
129
267
|
const ref = useComposedRefs(forwardedRef, divRef);
|
130
|
-
const { useViewport } =
|
268
|
+
const { useViewport } = useThreadContext();
|
131
269
|
const firstRenderRef = useRef(true);
|
132
270
|
const isScrollingToBottomRef = useRef(false);
|
133
271
|
const lastScrollTop = useRef(0);
|
@@ -175,78 +313,23 @@ var ThreadViewport = forwardRef2(({ autoScroll = true, onScroll, children, ...re
|
|
175
313
|
);
|
176
314
|
});
|
177
315
|
|
178
|
-
// src/
|
179
|
-
import {
|
180
|
-
|
181
|
-
// src/utils/context/useMessageContext.ts
|
182
|
-
import { createContext as createContext2, useContext as useContext2 } from "react";
|
183
|
-
var MessageContext = createContext2(null);
|
184
|
-
var useMessageContext = () => {
|
185
|
-
const context = useContext2(MessageContext);
|
186
|
-
if (!context)
|
187
|
-
throw new Error(
|
188
|
-
"This component must be used within a MessagePrimitive.Provider."
|
189
|
-
);
|
190
|
-
return context;
|
191
|
-
};
|
192
|
-
|
193
|
-
// src/utils/context/useComposerContext.ts
|
194
|
-
var useComposerContext = () => {
|
195
|
-
const { useComposer: useAssisstantComposer } = useAssistantContext();
|
196
|
-
const { useComposer: useMessageComposer } = useContext3(MessageContext) ?? {};
|
197
|
-
return {
|
198
|
-
useComposer: useMessageComposer ?? useAssisstantComposer,
|
199
|
-
type: useMessageComposer ? "message" : "assistant"
|
200
|
-
};
|
201
|
-
};
|
202
|
-
|
203
|
-
// src/primitives/composer/ComposerIf.tsx
|
204
|
-
var useComposerIf = (props) => {
|
205
|
-
const { useComposer } = useComposerContext();
|
206
|
-
return useComposer((composer) => {
|
207
|
-
if (props.editing === true && !composer.isEditing) return false;
|
208
|
-
if (props.editing === false && composer.isEditing) return false;
|
209
|
-
return true;
|
210
|
-
});
|
211
|
-
};
|
212
|
-
var ComposerIf = ({ children, ...query }) => {
|
213
|
-
const result = useComposerIf(query);
|
214
|
-
return result ? children : null;
|
215
|
-
};
|
216
|
-
|
217
|
-
// src/primitives/message/index.ts
|
218
|
-
var message_exports = {};
|
219
|
-
__export(message_exports, {
|
220
|
-
Content: () => MessageContent,
|
221
|
-
If: () => MessageIf,
|
222
|
-
InProgress: () => MessageInProgress,
|
223
|
-
Provider: () => MessageProvider,
|
224
|
-
Root: () => MessageRoot
|
225
|
-
});
|
226
|
-
|
227
|
-
// src/primitives/message/MessageProvider.tsx
|
228
|
-
import { useMemo, useState } from "react";
|
316
|
+
// src/context/providers/MessageProvider.tsx
|
317
|
+
import { useEffect as useEffect3, useState } from "react";
|
229
318
|
import { create as create2 } from "zustand";
|
230
319
|
|
231
|
-
// src/
|
232
|
-
|
233
|
-
const textParts = message.content.filter(
|
234
|
-
(part) => part.type === "text"
|
235
|
-
);
|
236
|
-
return textParts.map((part) => part.text).join("\n\n");
|
237
|
-
};
|
320
|
+
// src/context/stores/MessageComposer.ts
|
321
|
+
import { create } from "zustand";
|
238
322
|
|
239
|
-
// src/
|
240
|
-
import {
|
241
|
-
create
|
242
|
-
} from "zustand";
|
323
|
+
// src/context/stores/BaseComposer.ts
|
243
324
|
var makeBaseComposer = (set) => ({
|
244
325
|
value: "",
|
245
326
|
setValue: (value) => {
|
246
327
|
set({ value });
|
247
328
|
}
|
248
329
|
});
|
249
|
-
|
330
|
+
|
331
|
+
// src/context/stores/MessageComposer.ts
|
332
|
+
var makeEditComposerStore = ({
|
250
333
|
onEdit,
|
251
334
|
onSend
|
252
335
|
}) => create()((set, get, store) => ({
|
@@ -267,34 +350,30 @@ var makeMessageComposerStore = ({
|
|
267
350
|
return true;
|
268
351
|
}
|
269
352
|
}));
|
270
|
-
var makeThreadComposerStore = (useThread) => create()((set, get, store) => {
|
271
|
-
return {
|
272
|
-
...makeBaseComposer(set, get, store),
|
273
|
-
isEditing: true,
|
274
|
-
send: () => {
|
275
|
-
const { value } = get();
|
276
|
-
set({ value: "" });
|
277
|
-
useThread.getState().append({
|
278
|
-
parentId: useThread.getState().messages.at(-1)?.id ?? null,
|
279
|
-
content: [{ type: "text", text: value }]
|
280
|
-
});
|
281
|
-
},
|
282
|
-
cancel: () => {
|
283
|
-
const thread = useThread.getState();
|
284
|
-
if (!thread.isRunning) return false;
|
285
|
-
useThread.getState().cancelRun();
|
286
|
-
return true;
|
287
|
-
}
|
288
|
-
};
|
289
|
-
});
|
290
353
|
|
291
|
-
// src/
|
354
|
+
// src/context/providers/MessageProvider.tsx
|
292
355
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
293
356
|
var getIsLast = (thread, message) => {
|
294
357
|
return thread.messages[thread.messages.length - 1]?.id === message.id;
|
295
358
|
};
|
296
|
-
var
|
297
|
-
const
|
359
|
+
var syncMessage = (thread, useMessage, messageIndex) => {
|
360
|
+
const parentId = thread.messages[messageIndex - 1]?.id ?? null;
|
361
|
+
const message = thread.messages[messageIndex];
|
362
|
+
if (!message) return;
|
363
|
+
const isLast = getIsLast(thread, message);
|
364
|
+
const branches = thread.getBranches(message.id);
|
365
|
+
const currentState = useMessage.getState();
|
366
|
+
if (currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
|
367
|
+
return;
|
368
|
+
useMessage.setState({
|
369
|
+
message,
|
370
|
+
parentId,
|
371
|
+
branches,
|
372
|
+
isLast
|
373
|
+
});
|
374
|
+
};
|
375
|
+
var useMessageContext2 = (messageIndex) => {
|
376
|
+
const { useThread } = useThreadContext();
|
298
377
|
const [context] = useState(() => {
|
299
378
|
const useMessage = create2((set) => ({
|
300
379
|
message: null,
|
@@ -314,7 +393,7 @@ var useMessageContext2 = () => {
|
|
314
393
|
set({ isHovering: value });
|
315
394
|
}
|
316
395
|
}));
|
317
|
-
const useComposer =
|
396
|
+
const useComposer = makeEditComposerStore({
|
318
397
|
onEdit: () => {
|
319
398
|
const message = useMessage.getState().message;
|
320
399
|
if (message.role !== "user")
|
@@ -339,58 +418,51 @@ var useMessageContext2 = () => {
|
|
339
418
|
});
|
340
419
|
}
|
341
420
|
});
|
421
|
+
syncMessage(useThread.getState(), useMessage, messageIndex);
|
342
422
|
return { useMessage, useComposer };
|
343
423
|
});
|
424
|
+
useEffect3(() => {
|
425
|
+
return useThread.subscribe((thread) => {
|
426
|
+
syncMessage(thread, context.useMessage, messageIndex);
|
427
|
+
});
|
428
|
+
}, [context, useThread, messageIndex]);
|
344
429
|
return context;
|
345
430
|
};
|
346
431
|
var MessageProvider = ({
|
347
|
-
|
348
|
-
parentId,
|
432
|
+
messageIndex,
|
349
433
|
children
|
350
434
|
}) => {
|
351
|
-
const
|
352
|
-
const context = useMessageContext2();
|
353
|
-
const isLast = useThread((thread) => getIsLast(thread, message));
|
354
|
-
const branches = useThread((thread) => thread.getBranches(message.id));
|
355
|
-
useMemo(() => {
|
356
|
-
context.useMessage.setState({
|
357
|
-
message,
|
358
|
-
parentId,
|
359
|
-
branches,
|
360
|
-
isLast
|
361
|
-
});
|
362
|
-
}, [context, message, parentId, branches, isLast]);
|
435
|
+
const context = useMessageContext2(messageIndex);
|
363
436
|
return /* @__PURE__ */ jsx4(MessageContext.Provider, { value: context, children });
|
364
437
|
};
|
365
438
|
|
366
|
-
// src/
|
367
|
-
import {
|
368
|
-
|
369
|
-
|
370
|
-
}
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
);
|
439
|
+
// src/context/ComposerContext.ts
|
440
|
+
import { useContext as useContext3, useMemo as useMemo2 } from "react";
|
441
|
+
var useComposerContext = () => {
|
442
|
+
const { useComposer } = useThreadContext();
|
443
|
+
const { useComposer: useEditComposer } = useContext3(MessageContext) ?? {};
|
444
|
+
return useMemo2(
|
445
|
+
() => ({
|
446
|
+
useComposer: useEditComposer ?? useComposer,
|
447
|
+
type: useEditComposer ? "edit" : "new"
|
448
|
+
}),
|
449
|
+
[useEditComposer, useComposer]
|
450
|
+
);
|
451
|
+
};
|
452
|
+
|
453
|
+
// src/primitives/composer/ComposerIf.tsx
|
454
|
+
var useComposerIf = (props) => {
|
455
|
+
const { useComposer } = useComposerContext();
|
456
|
+
return useComposer((composer) => {
|
457
|
+
if (props.editing === true && !composer.isEditing) return false;
|
458
|
+
if (props.editing === false && composer.isEditing) return false;
|
459
|
+
return true;
|
460
|
+
});
|
461
|
+
};
|
462
|
+
var ComposerIf = ({ children, ...query }) => {
|
463
|
+
const result = useComposerIf(query);
|
464
|
+
return result ? children : null;
|
465
|
+
};
|
394
466
|
|
395
467
|
// src/primitives/message/MessageIf.tsx
|
396
468
|
var useMessageIf = (props) => {
|
@@ -410,162 +482,8 @@ var MessageIf = ({ children, ...query }) => {
|
|
410
482
|
return result ? children : null;
|
411
483
|
};
|
412
484
|
|
413
|
-
// src/utils/context/combined/useCombinedStore.ts
|
414
|
-
import { useMemo as useMemo2 } from "react";
|
415
|
-
|
416
|
-
// src/utils/context/combined/createCombinedStore.ts
|
417
|
-
import { useSyncExternalStore } from "react";
|
418
|
-
var createCombinedStore = (stores) => {
|
419
|
-
const subscribe = (callback) => {
|
420
|
-
const unsubscribes = stores.map((store) => store.subscribe(callback));
|
421
|
-
return () => {
|
422
|
-
for (const unsub of unsubscribes) {
|
423
|
-
unsub();
|
424
|
-
}
|
425
|
-
};
|
426
|
-
};
|
427
|
-
return (selector) => {
|
428
|
-
const getSnapshot = () => selector(...stores.map((store) => store.getState()));
|
429
|
-
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
430
|
-
};
|
431
|
-
};
|
432
|
-
|
433
|
-
// src/utils/context/combined/useCombinedStore.ts
|
434
|
-
var useCombinedStore = (stores, selector) => {
|
435
|
-
const useCombined = useMemo2(() => createCombinedStore(stores), stores);
|
436
|
-
return useCombined(selector);
|
437
|
-
};
|
438
|
-
|
439
|
-
// src/utils/context/useContentPartContext.ts
|
440
|
-
import { createContext as createContext3, useContext as useContext4 } from "react";
|
441
|
-
var ContentPartContext = createContext3(null);
|
442
|
-
var useContentPartContext = () => {
|
443
|
-
const context = useContext4(ContentPartContext);
|
444
|
-
if (!context)
|
445
|
-
throw new Error(
|
446
|
-
"This component must be used within a ContentPartPrimitive.Provider."
|
447
|
-
);
|
448
|
-
return context;
|
449
|
-
};
|
450
|
-
|
451
|
-
// src/primitives/contentPart/ContentPartInProgressIndicator.tsx
|
452
|
-
var ContentPartInProgressIndicator = () => {
|
453
|
-
const { useMessage } = useMessageContext();
|
454
|
-
const { useContentPart } = useContentPartContext();
|
455
|
-
const indicator = useCombinedStore(
|
456
|
-
[useMessage, useContentPart],
|
457
|
-
(m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
|
458
|
-
);
|
459
|
-
return indicator;
|
460
|
-
};
|
461
|
-
|
462
|
-
// src/primitives/contentPart/ContentPartProvider.tsx
|
463
|
-
import { useMemo as useMemo3, useState as useState2 } from "react";
|
464
|
-
import { create as create3 } from "zustand";
|
465
|
-
import { jsx as jsx6 } from "react/jsx-runtime";
|
466
|
-
var useContentPartContext2 = () => {
|
467
|
-
const [context] = useState2(() => {
|
468
|
-
const useContentPart = create3(() => ({
|
469
|
-
part: null,
|
470
|
-
status: "done"
|
471
|
-
}));
|
472
|
-
return { useContentPart };
|
473
|
-
});
|
474
|
-
return context;
|
475
|
-
};
|
476
|
-
var ContentPartProvider = ({
|
477
|
-
part,
|
478
|
-
status,
|
479
|
-
children
|
480
|
-
}) => {
|
481
|
-
const context = useContentPartContext2();
|
482
|
-
useMemo3(() => {
|
483
|
-
context.useContentPart.setState(
|
484
|
-
{
|
485
|
-
part,
|
486
|
-
status
|
487
|
-
},
|
488
|
-
true
|
489
|
-
);
|
490
|
-
}, [context, part, status]);
|
491
|
-
return /* @__PURE__ */ jsx6(ContentPartContext.Provider, { value: context, children });
|
492
|
-
};
|
493
|
-
|
494
|
-
// src/primitives/message/MessageContent.tsx
|
495
|
-
import { Fragment, jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
|
496
|
-
var defaultComponents = {
|
497
|
-
Text: ({ part }) => /* @__PURE__ */ jsxs2(Fragment, { children: [
|
498
|
-
part.text,
|
499
|
-
/* @__PURE__ */ jsx7(ContentPartInProgressIndicator, {})
|
500
|
-
] }),
|
501
|
-
Image: () => null,
|
502
|
-
UI: ({ part }) => part.display,
|
503
|
-
tools: {
|
504
|
-
Fallback: () => null
|
505
|
-
}
|
506
|
-
};
|
507
|
-
var MessageContent = ({
|
508
|
-
components: {
|
509
|
-
Text = defaultComponents.Text,
|
510
|
-
Image = defaultComponents.Image,
|
511
|
-
UI = defaultComponents.UI,
|
512
|
-
tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
|
513
|
-
} = {}
|
514
|
-
}) => {
|
515
|
-
const { useMessage } = useMessageContext();
|
516
|
-
const message = useMessage((s) => s.message);
|
517
|
-
const content = message.content;
|
518
|
-
const status = message.role === "assistant" ? message.status : "done";
|
519
|
-
return /* @__PURE__ */ jsx7(Fragment, { children: content.map((part, i) => {
|
520
|
-
const key = i;
|
521
|
-
const type = part.type;
|
522
|
-
let component = null;
|
523
|
-
switch (type) {
|
524
|
-
case "text":
|
525
|
-
component = /* @__PURE__ */ jsx7(Text, { part });
|
526
|
-
break;
|
527
|
-
case "image":
|
528
|
-
component = /* @__PURE__ */ jsx7(Image, { part });
|
529
|
-
break;
|
530
|
-
case "ui":
|
531
|
-
component = /* @__PURE__ */ jsx7(UI, { part });
|
532
|
-
break;
|
533
|
-
case "tool-call": {
|
534
|
-
const Tool = by_name[part.name] || Fallback;
|
535
|
-
component = /* @__PURE__ */ jsx7(Tool, { part });
|
536
|
-
break;
|
537
|
-
}
|
538
|
-
default:
|
539
|
-
throw new Error(`Unknown content part type: ${type}`);
|
540
|
-
}
|
541
|
-
return /* @__PURE__ */ jsx7(
|
542
|
-
ContentPartProvider,
|
543
|
-
{
|
544
|
-
part,
|
545
|
-
status: i === content.length - 1 ? status : "done",
|
546
|
-
children: component
|
547
|
-
},
|
548
|
-
key
|
549
|
-
);
|
550
|
-
}) });
|
551
|
-
};
|
552
|
-
|
553
|
-
// src/primitives/message/MessageInProgress.tsx
|
554
|
-
import {
|
555
|
-
Primitive as Primitive4
|
556
|
-
} from "@radix-ui/react-primitive";
|
557
|
-
import { forwardRef as forwardRef4, useMemo as useMemo4 } from "react";
|
558
|
-
import { jsx as jsx8 } from "react/jsx-runtime";
|
559
|
-
var MessageInProgress = forwardRef4((props, ref) => {
|
560
|
-
const { useMessage } = useMessageContext();
|
561
|
-
useMemo4(() => {
|
562
|
-
useMessage.getState().setInProgressIndicator(/* @__PURE__ */ jsx8(Primitive4.div, { ...props, ref }));
|
563
|
-
}, [useMessage, props, ref]);
|
564
|
-
return null;
|
565
|
-
});
|
566
|
-
|
567
485
|
// src/primitives/thread/ThreadMessages.tsx
|
568
|
-
import { Fragment
|
486
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
569
487
|
var getComponents = (components) => {
|
570
488
|
return {
|
571
489
|
EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
|
@@ -574,64 +492,62 @@ var getComponents = (components) => {
|
|
574
492
|
};
|
575
493
|
};
|
576
494
|
var ThreadMessages = ({ components }) => {
|
577
|
-
const { useThread } =
|
578
|
-
const
|
579
|
-
const messages = thread.messages;
|
495
|
+
const { useThread } = useThreadContext();
|
496
|
+
const messagesLength = useThread((t) => t.messages.length);
|
580
497
|
const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
|
581
|
-
if (
|
582
|
-
return /* @__PURE__ */
|
583
|
-
const
|
584
|
-
return /* @__PURE__ */
|
498
|
+
if (messagesLength === 0) return null;
|
499
|
+
return /* @__PURE__ */ jsx5(Fragment, { children: new Array(messagesLength).fill(null).map((_, idx) => {
|
500
|
+
const messageIndex = idx;
|
501
|
+
return /* @__PURE__ */ jsxs2(
|
585
502
|
MessageProvider,
|
586
503
|
{
|
587
|
-
|
588
|
-
parentId,
|
504
|
+
messageIndex,
|
589
505
|
children: [
|
590
|
-
/* @__PURE__ */
|
591
|
-
/* @__PURE__ */
|
592
|
-
/* @__PURE__ */
|
506
|
+
/* @__PURE__ */ jsxs2(MessageIf, { user: true, children: [
|
507
|
+
/* @__PURE__ */ jsx5(ComposerIf, { editing: false, children: /* @__PURE__ */ jsx5(UserMessage, {}) }),
|
508
|
+
/* @__PURE__ */ jsx5(ComposerIf, { editing: true, children: /* @__PURE__ */ jsx5(EditComposer, {}) })
|
593
509
|
] }),
|
594
|
-
/* @__PURE__ */
|
510
|
+
/* @__PURE__ */ jsx5(MessageIf, { assistant: true, children: /* @__PURE__ */ jsx5(AssistantMessage, {}) })
|
595
511
|
]
|
596
512
|
},
|
597
|
-
|
513
|
+
messageIndex
|
598
514
|
);
|
599
515
|
}) });
|
600
516
|
};
|
601
517
|
|
602
518
|
// src/primitives/thread/ThreadScrollToBottom.tsx
|
603
|
-
import { composeEventHandlers as
|
519
|
+
import { composeEventHandlers as composeEventHandlers2 } from "@radix-ui/primitive";
|
604
520
|
import {
|
605
|
-
Primitive as
|
521
|
+
Primitive as Primitive3
|
606
522
|
} from "@radix-ui/react-primitive";
|
607
|
-
import { forwardRef as
|
608
|
-
import { jsx as
|
609
|
-
var ThreadScrollToBottom =
|
610
|
-
const { useViewport } =
|
523
|
+
import { forwardRef as forwardRef3 } from "react";
|
524
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
525
|
+
var ThreadScrollToBottom = forwardRef3(({ onClick, ...rest }, ref) => {
|
526
|
+
const { useViewport } = useThreadContext();
|
611
527
|
const isAtBottom = useViewport((s) => s.isAtBottom);
|
612
528
|
const handleScrollToBottom = () => {
|
613
529
|
useViewport.getState().scrollToBottom();
|
614
530
|
};
|
615
|
-
return /* @__PURE__ */
|
616
|
-
|
531
|
+
return /* @__PURE__ */ jsx6(
|
532
|
+
Primitive3.button,
|
617
533
|
{
|
618
534
|
...rest,
|
619
535
|
disabled: isAtBottom,
|
620
536
|
ref,
|
621
|
-
onClick:
|
537
|
+
onClick: composeEventHandlers2(onClick, handleScrollToBottom)
|
622
538
|
}
|
623
539
|
);
|
624
540
|
});
|
625
541
|
|
626
542
|
// src/primitives/thread/ThreadSuggestion.tsx
|
627
|
-
import { composeEventHandlers as
|
543
|
+
import { composeEventHandlers as composeEventHandlers3 } from "@radix-ui/primitive";
|
628
544
|
import {
|
629
|
-
Primitive as
|
545
|
+
Primitive as Primitive4
|
630
546
|
} from "@radix-ui/react-primitive";
|
631
|
-
import { forwardRef as
|
632
|
-
import { jsx as
|
633
|
-
var ThreadSuggestion =
|
634
|
-
const { useThread, useComposer } =
|
547
|
+
import { forwardRef as forwardRef4 } from "react";
|
548
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
549
|
+
var ThreadSuggestion = forwardRef4(({ onClick, prompt, method, autoSend: send, ...rest }, ref) => {
|
550
|
+
const { useThread, useComposer } = useThreadContext();
|
635
551
|
const isDisabled = useThread((t) => t.isRunning);
|
636
552
|
const handleApplySuggestion = () => {
|
637
553
|
const thread = useThread.getState();
|
@@ -641,13 +557,13 @@ var ThreadSuggestion = forwardRef6(({ onClick, prompt, method, autoSend: send, .
|
|
641
557
|
composer.send();
|
642
558
|
}
|
643
559
|
};
|
644
|
-
return /* @__PURE__ */
|
645
|
-
|
560
|
+
return /* @__PURE__ */ jsx7(
|
561
|
+
Primitive4.button,
|
646
562
|
{
|
647
563
|
...rest,
|
648
564
|
disabled: isDisabled,
|
649
565
|
ref,
|
650
|
-
onClick:
|
566
|
+
onClick: composeEventHandlers3(onClick, handleApplySuggestion)
|
651
567
|
}
|
652
568
|
);
|
653
569
|
});
|
@@ -663,16 +579,16 @@ __export(composer_exports, {
|
|
663
579
|
});
|
664
580
|
|
665
581
|
// src/primitives/composer/ComposerRoot.tsx
|
666
|
-
import { composeEventHandlers as
|
582
|
+
import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primitive";
|
667
583
|
import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
|
668
584
|
import {
|
669
|
-
Primitive as
|
585
|
+
Primitive as Primitive5
|
670
586
|
} from "@radix-ui/react-primitive";
|
671
|
-
import { forwardRef as
|
672
|
-
import { jsx as
|
673
|
-
var ComposerRoot =
|
587
|
+
import { forwardRef as forwardRef5, useRef as useRef2 } from "react";
|
588
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
589
|
+
var ComposerRoot = forwardRef5(
|
674
590
|
({ onSubmit, ...rest }, forwardedRef) => {
|
675
|
-
const { useViewport } =
|
591
|
+
const { useViewport } = useThreadContext();
|
676
592
|
const { useComposer } = useComposerContext();
|
677
593
|
const formRef = useRef2(null);
|
678
594
|
const ref = useComposedRefs2(forwardedRef, formRef);
|
@@ -683,32 +599,32 @@ var ComposerRoot = forwardRef7(
|
|
683
599
|
composerState.send();
|
684
600
|
useViewport.getState().scrollToBottom();
|
685
601
|
};
|
686
|
-
return /* @__PURE__ */
|
687
|
-
|
602
|
+
return /* @__PURE__ */ jsx8(
|
603
|
+
Primitive5.form,
|
688
604
|
{
|
689
605
|
...rest,
|
690
606
|
ref,
|
691
|
-
onSubmit:
|
607
|
+
onSubmit: composeEventHandlers4(onSubmit, handleSubmit)
|
692
608
|
}
|
693
609
|
);
|
694
610
|
}
|
695
611
|
);
|
696
612
|
|
697
613
|
// src/primitives/composer/ComposerInput.tsx
|
698
|
-
import { composeEventHandlers as
|
614
|
+
import { composeEventHandlers as composeEventHandlers5 } from "@radix-ui/primitive";
|
699
615
|
import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
|
700
616
|
import { Slot } from "@radix-ui/react-slot";
|
701
617
|
import {
|
702
|
-
forwardRef as
|
703
|
-
useCallback,
|
704
|
-
useEffect as
|
618
|
+
forwardRef as forwardRef6,
|
619
|
+
useCallback as useCallback6,
|
620
|
+
useEffect as useEffect4,
|
705
621
|
useRef as useRef3
|
706
622
|
} from "react";
|
707
623
|
import TextareaAutosize from "react-textarea-autosize";
|
708
|
-
import { jsx as
|
709
|
-
var ComposerInput =
|
624
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
625
|
+
var ComposerInput = forwardRef6(
|
710
626
|
({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
|
711
|
-
const { useThread, useViewport } =
|
627
|
+
const { useThread, useViewport } = useThreadContext();
|
712
628
|
const { useComposer, type } = useComposerContext();
|
713
629
|
const value = useComposer((c) => {
|
714
630
|
if (!c.isEditing) return "";
|
@@ -734,7 +650,7 @@ var ComposerInput = forwardRef8(
|
|
734
650
|
const textareaRef = useRef3(null);
|
735
651
|
const ref = useComposedRefs3(forwardedRef, textareaRef);
|
736
652
|
const autoFocusEnabled = autoFocus && !disabled;
|
737
|
-
const focus =
|
653
|
+
const focus = useCallback6(() => {
|
738
654
|
const textarea = textareaRef.current;
|
739
655
|
if (!textarea || !autoFocusEnabled) return;
|
740
656
|
textarea.focus();
|
@@ -743,25 +659,25 @@ var ComposerInput = forwardRef8(
|
|
743
659
|
textareaRef.current.value.length
|
744
660
|
);
|
745
661
|
}, [autoFocusEnabled]);
|
746
|
-
|
662
|
+
useEffect4(() => focus(), [focus]);
|
747
663
|
useOnScrollToBottom(() => {
|
748
|
-
if (type === "
|
664
|
+
if (type === "new") {
|
749
665
|
focus();
|
750
666
|
}
|
751
667
|
});
|
752
|
-
return /* @__PURE__ */
|
668
|
+
return /* @__PURE__ */ jsx9(
|
753
669
|
Component,
|
754
670
|
{
|
755
671
|
value,
|
756
672
|
...rest,
|
757
673
|
ref,
|
758
674
|
disabled,
|
759
|
-
onChange:
|
675
|
+
onChange: composeEventHandlers5(onChange, (e) => {
|
760
676
|
const composerState = useComposer.getState();
|
761
677
|
if (!composerState.isEditing) return;
|
762
678
|
return composerState.setValue(e.target.value);
|
763
679
|
}),
|
764
|
-
onKeyDown:
|
680
|
+
onKeyDown: composeEventHandlers5(onKeyDown, handleKeyPress)
|
765
681
|
}
|
766
682
|
);
|
767
683
|
}
|
@@ -769,16 +685,16 @@ var ComposerInput = forwardRef8(
|
|
769
685
|
|
770
686
|
// src/primitives/composer/ComposerSend.tsx
|
771
687
|
import {
|
772
|
-
Primitive as
|
688
|
+
Primitive as Primitive6
|
773
689
|
} from "@radix-ui/react-primitive";
|
774
|
-
import { forwardRef as
|
775
|
-
import { jsx as
|
776
|
-
var ComposerSend =
|
690
|
+
import { forwardRef as forwardRef7 } from "react";
|
691
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
692
|
+
var ComposerSend = forwardRef7(
|
777
693
|
({ disabled, ...rest }, ref) => {
|
778
694
|
const { useComposer } = useComposerContext();
|
779
695
|
const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
|
780
|
-
return /* @__PURE__ */
|
781
|
-
|
696
|
+
return /* @__PURE__ */ jsx10(
|
697
|
+
Primitive6.button,
|
782
698
|
{
|
783
699
|
type: "submit",
|
784
700
|
...rest,
|
@@ -790,122 +706,253 @@ var ComposerSend = forwardRef9(
|
|
790
706
|
);
|
791
707
|
|
792
708
|
// src/primitives/composer/ComposerCancel.tsx
|
793
|
-
import { composeEventHandlers as
|
709
|
+
import { composeEventHandlers as composeEventHandlers6 } from "@radix-ui/primitive";
|
794
710
|
import {
|
795
|
-
Primitive as
|
711
|
+
Primitive as Primitive7
|
796
712
|
} from "@radix-ui/react-primitive";
|
797
|
-
import { forwardRef as
|
798
|
-
import { jsx as
|
799
|
-
var ComposerCancel =
|
713
|
+
import { forwardRef as forwardRef8 } from "react";
|
714
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
715
|
+
var ComposerCancel = forwardRef8(({ onClick, ...rest }, ref) => {
|
800
716
|
const { useComposer } = useComposerContext();
|
801
717
|
const handleCancel = () => {
|
802
718
|
useComposer.getState().cancel();
|
803
719
|
};
|
804
|
-
return /* @__PURE__ */
|
805
|
-
|
720
|
+
return /* @__PURE__ */ jsx11(
|
721
|
+
Primitive7.button,
|
806
722
|
{
|
807
723
|
type: "button",
|
808
724
|
...rest,
|
809
725
|
ref,
|
810
|
-
onClick:
|
726
|
+
onClick: composeEventHandlers6(onClick, handleCancel)
|
811
727
|
}
|
812
728
|
);
|
813
729
|
});
|
814
730
|
|
815
|
-
// src/primitives/
|
816
|
-
var
|
817
|
-
__export(
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
Root: () => BranchPickerRoot
|
731
|
+
// src/primitives/message/index.ts
|
732
|
+
var message_exports = {};
|
733
|
+
__export(message_exports, {
|
734
|
+
Content: () => MessageContent,
|
735
|
+
If: () => MessageIf,
|
736
|
+
InProgress: () => MessageInProgress,
|
737
|
+
Root: () => MessageRoot
|
823
738
|
});
|
824
739
|
|
825
|
-
// src/
|
826
|
-
import {
|
827
|
-
var useGoToNextBranch = () => {
|
828
|
-
const { useThread } = useAssistantContext();
|
829
|
-
const { useMessage, useComposer } = useMessageContext();
|
830
|
-
const disabled = useCombinedStore(
|
831
|
-
[useMessage, useComposer],
|
832
|
-
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
|
833
|
-
);
|
834
|
-
const callback = useCallback2(() => {
|
835
|
-
const { message, branches } = useMessage.getState();
|
836
|
-
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
|
837
|
-
}, [useMessage, useThread]);
|
838
|
-
if (disabled) return null;
|
839
|
-
return callback;
|
840
|
-
};
|
841
|
-
|
842
|
-
// src/utils/createActionButton.tsx
|
843
|
-
import { composeEventHandlers as composeEventHandlers8 } from "@radix-ui/primitive";
|
740
|
+
// src/primitives/message/MessageRoot.tsx
|
741
|
+
import { composeEventHandlers as composeEventHandlers7 } from "@radix-ui/primitive";
|
844
742
|
import {
|
845
|
-
Primitive as
|
743
|
+
Primitive as Primitive8
|
846
744
|
} from "@radix-ui/react-primitive";
|
847
|
-
import { forwardRef as
|
848
|
-
import { jsx as
|
849
|
-
var
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
745
|
+
import { forwardRef as forwardRef9 } from "react";
|
746
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
747
|
+
var MessageRoot = forwardRef9(
|
748
|
+
({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
|
749
|
+
const { useMessage } = useMessageContext();
|
750
|
+
const setIsHovering = useMessage((s) => s.setIsHovering);
|
751
|
+
const handleMouseEnter = () => {
|
752
|
+
setIsHovering(true);
|
753
|
+
};
|
754
|
+
const handleMouseLeave = () => {
|
755
|
+
setIsHovering(false);
|
756
|
+
};
|
757
|
+
return /* @__PURE__ */ jsx12(
|
758
|
+
Primitive8.div,
|
759
|
+
{
|
760
|
+
...rest,
|
761
|
+
ref,
|
762
|
+
onMouseEnter: composeEventHandlers7(onMouseEnter, handleMouseEnter),
|
763
|
+
onMouseLeave: composeEventHandlers7(onMouseLeave, handleMouseLeave)
|
764
|
+
}
|
765
|
+
);
|
766
|
+
}
|
767
|
+
);
|
866
768
|
|
867
|
-
// src/
|
868
|
-
|
769
|
+
// src/context/providers/ContentPartProvider.tsx
|
770
|
+
import { useEffect as useEffect5, useState as useState2 } from "react";
|
771
|
+
import { create as create3 } from "zustand";
|
869
772
|
|
870
|
-
// src/
|
871
|
-
import {
|
872
|
-
var
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
}, [useMessage, useThread]);
|
883
|
-
if (disabled) return null;
|
884
|
-
return callback;
|
773
|
+
// src/context/ContentPartContext.ts
|
774
|
+
import { createContext as createContext3, useContext as useContext4 } from "react";
|
775
|
+
var ContentPartContext = createContext3(
|
776
|
+
null
|
777
|
+
);
|
778
|
+
var useContentPartContext = () => {
|
779
|
+
const context = useContext4(ContentPartContext);
|
780
|
+
if (!context)
|
781
|
+
throw new Error(
|
782
|
+
"This component can only be used inside a component passed to <MessagePrimitive.Content components={...} >."
|
783
|
+
);
|
784
|
+
return context;
|
885
785
|
};
|
886
786
|
|
887
|
-
// src/
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
const
|
894
|
-
|
895
|
-
return /* @__PURE__ */ jsx17(Fragment3, { children: branchCount });
|
787
|
+
// src/context/providers/ContentPartProvider.tsx
|
788
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
789
|
+
var syncContentPart = ({ message }, useContentPart, partIndex) => {
|
790
|
+
const part = message.content[partIndex];
|
791
|
+
if (!part) return;
|
792
|
+
const messageStatus = message.role === "assistant" ? message.status : "done";
|
793
|
+
const status = partIndex === message.content.length - 1 ? messageStatus : "done";
|
794
|
+
useContentPart.setState({ part, status });
|
896
795
|
};
|
897
|
-
|
898
|
-
// src/primitives/branchPicker/BranchPickerNumber.tsx
|
899
|
-
import { Fragment as Fragment4, jsx as jsx18 } from "react/jsx-runtime";
|
900
|
-
var BranchPickerNumber = () => {
|
796
|
+
var useContentPartContext2 = (partIndex) => {
|
901
797
|
const { useMessage } = useMessageContext();
|
902
|
-
const
|
903
|
-
|
904
|
-
}
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
798
|
+
const [context] = useState2(() => {
|
799
|
+
const useContentPart = create3(() => ({
|
800
|
+
part: { type: "text", text: "" },
|
801
|
+
status: "done"
|
802
|
+
}));
|
803
|
+
syncContentPart(useMessage.getState(), useContentPart, partIndex);
|
804
|
+
return { useContentPart };
|
805
|
+
});
|
806
|
+
useEffect5(() => {
|
807
|
+
return useMessage.subscribe((message) => {
|
808
|
+
syncContentPart(message, context.useContentPart, partIndex);
|
809
|
+
});
|
810
|
+
}, [context, useMessage, partIndex]);
|
811
|
+
return context;
|
812
|
+
};
|
813
|
+
var ContentPartProvider = ({
|
814
|
+
partIndex,
|
815
|
+
children
|
816
|
+
}) => {
|
817
|
+
const context = useContentPartContext2(partIndex);
|
818
|
+
return /* @__PURE__ */ jsx13(ContentPartContext.Provider, { value: context, children });
|
819
|
+
};
|
820
|
+
|
821
|
+
// src/primitives/contentPart/ContentPartInProgressIndicator.tsx
|
822
|
+
var ContentPartInProgressIndicator = () => {
|
823
|
+
const { useMessage } = useMessageContext();
|
824
|
+
const { useContentPart } = useContentPartContext();
|
825
|
+
const indicator = useCombinedStore(
|
826
|
+
[useMessage, useContentPart],
|
827
|
+
(m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
|
828
|
+
);
|
829
|
+
return indicator;
|
830
|
+
};
|
831
|
+
|
832
|
+
// src/primitives/message/MessageContent.tsx
|
833
|
+
import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs3 } from "react/jsx-runtime";
|
834
|
+
var defaultComponents = {
|
835
|
+
Text: ({ part }) => /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
836
|
+
part.text,
|
837
|
+
/* @__PURE__ */ jsx14(ContentPartInProgressIndicator, {})
|
838
|
+
] }),
|
839
|
+
Image: () => null,
|
840
|
+
UI: ({ part }) => part.display,
|
841
|
+
tools: {
|
842
|
+
Fallback: () => null
|
843
|
+
}
|
844
|
+
};
|
845
|
+
var MessageContent = ({
|
846
|
+
components: {
|
847
|
+
Text = defaultComponents.Text,
|
848
|
+
Image = defaultComponents.Image,
|
849
|
+
UI = defaultComponents.UI,
|
850
|
+
tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
|
851
|
+
} = {}
|
852
|
+
}) => {
|
853
|
+
const { useMessage } = useMessageContext();
|
854
|
+
const message = useMessage((s) => s.message);
|
855
|
+
const content = message.content;
|
856
|
+
return /* @__PURE__ */ jsx14(Fragment2, { children: content.map((part, i) => {
|
857
|
+
const partIndex = i;
|
858
|
+
const type = part.type;
|
859
|
+
let component = null;
|
860
|
+
switch (type) {
|
861
|
+
case "text":
|
862
|
+
component = /* @__PURE__ */ jsx14(Text, { part });
|
863
|
+
break;
|
864
|
+
case "image":
|
865
|
+
component = /* @__PURE__ */ jsx14(Image, { part });
|
866
|
+
break;
|
867
|
+
case "ui":
|
868
|
+
component = /* @__PURE__ */ jsx14(UI, { part });
|
869
|
+
break;
|
870
|
+
case "tool-call": {
|
871
|
+
const Tool = by_name[part.name] || Fallback;
|
872
|
+
component = /* @__PURE__ */ jsx14(Tool, { part });
|
873
|
+
break;
|
874
|
+
}
|
875
|
+
default:
|
876
|
+
throw new Error(`Unknown content part type: ${type}`);
|
877
|
+
}
|
878
|
+
return /* @__PURE__ */ jsx14(ContentPartProvider, { partIndex, children: component }, partIndex);
|
879
|
+
}) });
|
880
|
+
};
|
881
|
+
|
882
|
+
// src/primitives/message/MessageInProgress.tsx
|
883
|
+
import {
|
884
|
+
Primitive as Primitive9
|
885
|
+
} from "@radix-ui/react-primitive";
|
886
|
+
import { forwardRef as forwardRef10, useMemo as useMemo3 } from "react";
|
887
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
888
|
+
var MessageInProgress = forwardRef10((props, ref) => {
|
889
|
+
const { useMessage } = useMessageContext();
|
890
|
+
useMemo3(() => {
|
891
|
+
useMessage.getState().setInProgressIndicator(/* @__PURE__ */ jsx15(Primitive9.span, { ...props, ref }));
|
892
|
+
}, [useMessage, props, ref]);
|
893
|
+
return null;
|
894
|
+
});
|
895
|
+
|
896
|
+
// src/primitives/branchPicker/index.ts
|
897
|
+
var branchPicker_exports = {};
|
898
|
+
__export(branchPicker_exports, {
|
899
|
+
Count: () => BranchPickerCount,
|
900
|
+
Next: () => BranchPickerNext,
|
901
|
+
Number: () => BranchPickerNumber,
|
902
|
+
Previous: () => BranchPickerPrevious,
|
903
|
+
Root: () => BranchPickerRoot
|
904
|
+
});
|
905
|
+
|
906
|
+
// src/utils/createActionButton.tsx
|
907
|
+
import { composeEventHandlers as composeEventHandlers8 } from "@radix-ui/primitive";
|
908
|
+
import {
|
909
|
+
Primitive as Primitive10
|
910
|
+
} from "@radix-ui/react-primitive";
|
911
|
+
import { forwardRef as forwardRef11 } from "react";
|
912
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
913
|
+
var createActionButton = (useActionButton) => {
|
914
|
+
return forwardRef11(
|
915
|
+
(props, forwardedRef) => {
|
916
|
+
const onClick = useActionButton(props);
|
917
|
+
return /* @__PURE__ */ jsx16(
|
918
|
+
Primitive10.button,
|
919
|
+
{
|
920
|
+
type: "button",
|
921
|
+
disabled: !onClick,
|
922
|
+
...props,
|
923
|
+
ref: forwardedRef,
|
924
|
+
onClick: composeEventHandlers8(props.onClick, onClick ?? void 0)
|
925
|
+
}
|
926
|
+
);
|
927
|
+
}
|
928
|
+
);
|
929
|
+
};
|
930
|
+
|
931
|
+
// src/primitives/branchPicker/BranchPickerNext.tsx
|
932
|
+
var BranchPickerNext = createActionButton(useGoToNextBranch);
|
933
|
+
|
934
|
+
// src/primitives/branchPicker/BranchPickerPrevious.tsx
|
935
|
+
var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
|
936
|
+
|
937
|
+
// src/primitives/branchPicker/BranchPickerCount.tsx
|
938
|
+
import { Fragment as Fragment3, jsx as jsx17 } from "react/jsx-runtime";
|
939
|
+
var BranchPickerCount = () => {
|
940
|
+
const { useMessage } = useMessageContext();
|
941
|
+
const branchCount = useMessage((s) => s.branches.length);
|
942
|
+
return /* @__PURE__ */ jsx17(Fragment3, { children: branchCount });
|
943
|
+
};
|
944
|
+
|
945
|
+
// src/primitives/branchPicker/BranchPickerNumber.tsx
|
946
|
+
import { Fragment as Fragment4, jsx as jsx18 } from "react/jsx-runtime";
|
947
|
+
var BranchPickerNumber = () => {
|
948
|
+
const { useMessage } = useMessageContext();
|
949
|
+
const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
|
950
|
+
return /* @__PURE__ */ jsx18(Fragment4, { children: branchIdx + 1 });
|
951
|
+
};
|
952
|
+
|
953
|
+
// src/primitives/branchPicker/BranchPickerRoot.tsx
|
954
|
+
import {
|
955
|
+
Primitive as Primitive11
|
909
956
|
} from "@radix-ui/react-primitive";
|
910
957
|
import { forwardRef as forwardRef12 } from "react";
|
911
958
|
import { jsx as jsx19 } from "react/jsx-runtime";
|
@@ -929,7 +976,7 @@ import {
|
|
929
976
|
import { forwardRef as forwardRef13 } from "react";
|
930
977
|
import { jsx as jsx20 } from "react/jsx-runtime";
|
931
978
|
var ActionBarRoot = forwardRef13(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
|
932
|
-
const { useThread } =
|
979
|
+
const { useThread } = useThreadContext();
|
933
980
|
const { useMessage } = useMessageContext();
|
934
981
|
const hideAndfloatStatus = useCombinedStore(
|
935
982
|
[useThread, useMessage],
|
@@ -954,162 +1001,31 @@ var ActionBarRoot = forwardRef13(({ hideWhenRunning, autohide, autohideFloat, ..
|
|
954
1001
|
);
|
955
1002
|
});
|
956
1003
|
|
957
|
-
// src/actions/useCopyMessage.tsx
|
958
|
-
import { useCallback as useCallback4 } from "react";
|
959
|
-
var useCopyMessage = ({ copiedDuration = 3e3 }) => {
|
960
|
-
const { useMessage, useComposer } = useMessageContext();
|
961
|
-
const hasCopyableContent = useCombinedStore(
|
962
|
-
[useMessage, useComposer],
|
963
|
-
(m, c) => {
|
964
|
-
return c.isEditing || m.message.content.some((c2) => c2.type === "text");
|
965
|
-
}
|
966
|
-
);
|
967
|
-
const callback = useCallback4(() => {
|
968
|
-
const { isEditing, value: composerValue } = useComposer.getState();
|
969
|
-
const { message, setIsCopied } = useMessage.getState();
|
970
|
-
const valueToCopy = isEditing ? composerValue : getMessageText(message);
|
971
|
-
navigator.clipboard.writeText(valueToCopy);
|
972
|
-
setIsCopied(true);
|
973
|
-
setTimeout(() => setIsCopied(false), copiedDuration);
|
974
|
-
}, [useComposer, useMessage, copiedDuration]);
|
975
|
-
if (!hasCopyableContent) return null;
|
976
|
-
return callback;
|
977
|
-
};
|
978
|
-
|
979
1004
|
// src/primitives/actionBar/ActionBarCopy.tsx
|
980
1005
|
var ActionBarCopy = createActionButton(useCopyMessage);
|
981
1006
|
|
982
|
-
// src/actions/useReloadMessage.tsx
|
983
|
-
import { useCallback as useCallback5 } from "react";
|
984
|
-
var useReloadMessage = () => {
|
985
|
-
const { useThread, useViewport } = useAssistantContext();
|
986
|
-
const { useMessage } = useMessageContext();
|
987
|
-
const disabled = useCombinedStore(
|
988
|
-
[useThread, useMessage],
|
989
|
-
(t, m) => t.isRunning || m.message.role !== "assistant"
|
990
|
-
);
|
991
|
-
const callback = useCallback5(() => {
|
992
|
-
const { parentId } = useMessage.getState();
|
993
|
-
useThread.getState().startRun(parentId);
|
994
|
-
useViewport.getState().scrollToBottom();
|
995
|
-
}, [useMessage, useThread, useViewport]);
|
996
|
-
if (disabled) return null;
|
997
|
-
return callback;
|
998
|
-
};
|
999
|
-
|
1000
1007
|
// src/primitives/actionBar/ActionBarReload.tsx
|
1001
1008
|
var ActionBarReload = createActionButton(useReloadMessage);
|
1002
1009
|
|
1003
|
-
// src/actions/useBeginMessageEdit.tsx
|
1004
|
-
import { useCallback as useCallback6 } from "react";
|
1005
|
-
var useBeginMessageEdit = () => {
|
1006
|
-
const { useMessage, useComposer } = useMessageContext();
|
1007
|
-
const disabled = useCombinedStore(
|
1008
|
-
[useMessage, useComposer],
|
1009
|
-
(m, c) => m.message.role !== "user" || c.isEditing
|
1010
|
-
);
|
1011
|
-
const callback = useCallback6(() => {
|
1012
|
-
const { edit } = useComposer.getState();
|
1013
|
-
edit();
|
1014
|
-
}, [useComposer]);
|
1015
|
-
if (disabled) return null;
|
1016
|
-
return callback;
|
1017
|
-
};
|
1018
|
-
|
1019
1010
|
// src/primitives/actionBar/ActionBarEdit.tsx
|
1020
1011
|
var ActionBarEdit = createActionButton(useBeginMessageEdit);
|
1021
1012
|
|
1022
1013
|
// src/primitives/contentPart/index.ts
|
1023
1014
|
var contentPart_exports = {};
|
1024
1015
|
__export(contentPart_exports, {
|
1025
|
-
InProgressIndicator: () => ContentPartInProgressIndicator
|
1026
|
-
Provider: () => ContentPartProvider
|
1016
|
+
InProgressIndicator: () => ContentPartInProgressIndicator
|
1027
1017
|
});
|
1028
1018
|
|
1029
|
-
// src/
|
1030
|
-
import { useEffect as
|
1031
|
-
|
1032
|
-
// src/adapters/core/AssistantProvider.tsx
|
1033
|
-
import {
|
1034
|
-
useEffect as useEffect4,
|
1035
|
-
useInsertionEffect,
|
1036
|
-
useRef as useRef4,
|
1037
|
-
useState as useState3
|
1038
|
-
} from "react";
|
1039
|
-
import { create as create5 } from "zustand";
|
1019
|
+
// src/runtime/vercel-ai/rsc/useVercelRSCRuntime.tsx
|
1020
|
+
import { useEffect as useEffect7, useInsertionEffect, useState as useState3 } from "react";
|
1040
1021
|
|
1041
|
-
// src/
|
1022
|
+
// src/runtime/vercel-ai/rsc/VercelRSCRuntime.tsx
|
1042
1023
|
import { create as create4 } from "zustand";
|
1043
|
-
var makeViewportStore = () => {
|
1044
|
-
const scrollToBottomListeners = /* @__PURE__ */ new Set();
|
1045
|
-
return create4(() => ({
|
1046
|
-
isAtBottom: true,
|
1047
|
-
scrollToBottom: () => {
|
1048
|
-
for (const listener of scrollToBottomListeners) {
|
1049
|
-
listener();
|
1050
|
-
}
|
1051
|
-
},
|
1052
|
-
onScrollToBottom: (callback) => {
|
1053
|
-
scrollToBottomListeners.add(callback);
|
1054
|
-
return () => {
|
1055
|
-
scrollToBottomListeners.delete(callback);
|
1056
|
-
};
|
1057
|
-
}
|
1058
|
-
}));
|
1059
|
-
};
|
1060
|
-
|
1061
|
-
// src/adapters/core/AssistantProvider.tsx
|
1062
|
-
import { jsx as jsx21 } from "react/jsx-runtime";
|
1063
|
-
var makeThreadStore = (runtimeRef) => {
|
1064
|
-
const useThread = create5(() => ({
|
1065
|
-
messages: runtimeRef.current.messages,
|
1066
|
-
isRunning: runtimeRef.current.isRunning,
|
1067
|
-
getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
|
1068
|
-
switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
|
1069
|
-
startRun: (parentId) => runtimeRef.current.startRun(parentId),
|
1070
|
-
append: (message) => runtimeRef.current.append(message),
|
1071
|
-
cancelRun: () => runtimeRef.current.cancelRun()
|
1072
|
-
}));
|
1073
|
-
const onRuntimeUpdate = () => {
|
1074
|
-
useThread.setState({
|
1075
|
-
messages: runtimeRef.current.messages,
|
1076
|
-
isRunning: runtimeRef.current.isRunning
|
1077
|
-
});
|
1078
|
-
};
|
1079
|
-
return {
|
1080
|
-
useThread,
|
1081
|
-
onRuntimeUpdate
|
1082
|
-
};
|
1083
|
-
};
|
1084
|
-
var AssistantProvider = ({ children, runtime }) => {
|
1085
|
-
const runtimeRef = useRef4(runtime);
|
1086
|
-
useInsertionEffect(() => {
|
1087
|
-
runtimeRef.current = runtime;
|
1088
|
-
});
|
1089
|
-
const [{ context, onRuntimeUpdate }] = useState3(() => {
|
1090
|
-
const { useThread, onRuntimeUpdate: onRuntimeUpdate2 } = makeThreadStore(runtimeRef);
|
1091
|
-
const useViewport = makeViewportStore();
|
1092
|
-
const useComposer = makeThreadComposerStore(useThread);
|
1093
|
-
return {
|
1094
|
-
context: {
|
1095
|
-
useViewport,
|
1096
|
-
useThread,
|
1097
|
-
useComposer
|
1098
|
-
},
|
1099
|
-
onRuntimeUpdate: onRuntimeUpdate2
|
1100
|
-
};
|
1101
|
-
});
|
1102
|
-
useEffect4(() => {
|
1103
|
-
onRuntimeUpdate();
|
1104
|
-
return runtime.subscribe(onRuntimeUpdate);
|
1105
|
-
}, [onRuntimeUpdate, runtime]);
|
1106
|
-
return /* @__PURE__ */ jsx21(AssistantContext.Provider, { value: context, children });
|
1107
|
-
};
|
1108
1024
|
|
1109
|
-
// src/
|
1110
|
-
import { useEffect as
|
1025
|
+
// src/runtime/vercel-ai/rsc/useVercelRSCSync.tsx
|
1026
|
+
import { useEffect as useEffect6, useMemo as useMemo4 } from "react";
|
1111
1027
|
|
1112
|
-
// src/
|
1028
|
+
// src/runtime/vercel-ai/utils/ThreadMessageConverter.ts
|
1113
1029
|
var ThreadMessageConverter = class {
|
1114
1030
|
cache = /* @__PURE__ */ new WeakMap();
|
1115
1031
|
convertMessages(converter, messages) {
|
@@ -1122,17 +1038,129 @@ var ThreadMessageConverter = class {
|
|
1122
1038
|
}
|
1123
1039
|
};
|
1124
1040
|
|
1125
|
-
// src/
|
1126
|
-
var
|
1127
|
-
var symbolInnerRSCMessage = Symbol("innerRSCMessage");
|
1128
|
-
var getVercelMessage = (message) => {
|
1129
|
-
return message[symbolInnerMessage];
|
1130
|
-
};
|
1041
|
+
// src/runtime/vercel-ai/rsc/getVercelRSCMessage.tsx
|
1042
|
+
var symbolInnerRSCMessage = Symbol("innerVercelRSCMessage");
|
1131
1043
|
var getVercelRSCMessage = (message) => {
|
1132
1044
|
return message[symbolInnerRSCMessage];
|
1133
1045
|
};
|
1134
1046
|
|
1135
|
-
// src/
|
1047
|
+
// src/runtime/vercel-ai/rsc/useVercelRSCSync.tsx
|
1048
|
+
var vercelToThreadMessage = (converter, rawMessage) => {
|
1049
|
+
const message = converter(rawMessage);
|
1050
|
+
return {
|
1051
|
+
id: message.id,
|
1052
|
+
role: message.role,
|
1053
|
+
content: [{ type: "ui", display: message.display }],
|
1054
|
+
createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
|
1055
|
+
...{ status: "done" },
|
1056
|
+
[symbolInnerRSCMessage]: rawMessage
|
1057
|
+
};
|
1058
|
+
};
|
1059
|
+
var useVercelRSCSync = (adapter, updateData) => {
|
1060
|
+
const [converter, convertCallback] = useMemo4(() => {
|
1061
|
+
const rscConverter = adapter.convertMessage ?? ((m) => m);
|
1062
|
+
const convertCallback2 = (m, cache) => {
|
1063
|
+
if (cache) return cache;
|
1064
|
+
return vercelToThreadMessage(rscConverter, m);
|
1065
|
+
};
|
1066
|
+
return [new ThreadMessageConverter(), convertCallback2];
|
1067
|
+
}, [adapter.convertMessage]);
|
1068
|
+
useEffect6(() => {
|
1069
|
+
updateData(converter.convertMessages(convertCallback, adapter.messages));
|
1070
|
+
}, [updateData, converter, convertCallback, adapter.messages]);
|
1071
|
+
};
|
1072
|
+
|
1073
|
+
// src/runtime/vercel-ai/rsc/VercelRSCRuntime.tsx
|
1074
|
+
var EMPTY_BRANCHES = Object.freeze([]);
|
1075
|
+
var VercelRSCRuntime = class {
|
1076
|
+
constructor(adapter) {
|
1077
|
+
this.adapter = adapter;
|
1078
|
+
this.useAdapter = create4(() => ({
|
1079
|
+
adapter
|
1080
|
+
}));
|
1081
|
+
}
|
1082
|
+
useAdapter;
|
1083
|
+
_subscriptions = /* @__PURE__ */ new Set();
|
1084
|
+
isRunning = false;
|
1085
|
+
messages = [];
|
1086
|
+
withRunning = (callback) => {
|
1087
|
+
this.isRunning = true;
|
1088
|
+
return callback.finally(() => {
|
1089
|
+
this.isRunning = false;
|
1090
|
+
});
|
1091
|
+
};
|
1092
|
+
getBranches() {
|
1093
|
+
return EMPTY_BRANCHES;
|
1094
|
+
}
|
1095
|
+
switchToBranch() {
|
1096
|
+
throw new Error(
|
1097
|
+
"Branch switching is not supported by VercelRSCAssistantProvider."
|
1098
|
+
);
|
1099
|
+
}
|
1100
|
+
async append(message) {
|
1101
|
+
if (message.parentId !== (this.messages.at(-1)?.id ?? null)) {
|
1102
|
+
if (!this.adapter.edit)
|
1103
|
+
throw new Error(
|
1104
|
+
"Message editing is not enabled, please provide an edit callback to VercelRSCAssistantProvider."
|
1105
|
+
);
|
1106
|
+
await this.withRunning(this.adapter.edit(message));
|
1107
|
+
} else {
|
1108
|
+
await this.withRunning(this.adapter.append(message));
|
1109
|
+
}
|
1110
|
+
}
|
1111
|
+
async startRun(parentId) {
|
1112
|
+
if (!this.adapter.reload)
|
1113
|
+
throw new Error(
|
1114
|
+
"Message reloading is not enabled, please provide a reload callback to VercelRSCAssistantProvider."
|
1115
|
+
);
|
1116
|
+
await this.withRunning(this.adapter.reload(parentId));
|
1117
|
+
}
|
1118
|
+
cancelRun() {
|
1119
|
+
if (process.env["NODE_ENV"] === "development") {
|
1120
|
+
console.warn(
|
1121
|
+
"Run cancellation is not supported by VercelRSCAssistantProvider."
|
1122
|
+
);
|
1123
|
+
}
|
1124
|
+
}
|
1125
|
+
subscribe(callback) {
|
1126
|
+
this._subscriptions.add(callback);
|
1127
|
+
return () => this._subscriptions.delete(callback);
|
1128
|
+
}
|
1129
|
+
onAdapterUpdated() {
|
1130
|
+
if (this.useAdapter.getState().adapter !== this.adapter) {
|
1131
|
+
this.useAdapter.setState({ adapter: this.adapter });
|
1132
|
+
}
|
1133
|
+
}
|
1134
|
+
updateData = (messages) => {
|
1135
|
+
this.messages = messages;
|
1136
|
+
for (const callback of this._subscriptions) callback();
|
1137
|
+
};
|
1138
|
+
unstable_synchronizer = () => {
|
1139
|
+
const { adapter } = this.useAdapter();
|
1140
|
+
useVercelRSCSync(adapter, this.updateData);
|
1141
|
+
return null;
|
1142
|
+
};
|
1143
|
+
};
|
1144
|
+
|
1145
|
+
// src/runtime/vercel-ai/rsc/useVercelRSCRuntime.tsx
|
1146
|
+
var useVercelRSCRuntime = (adapter) => {
|
1147
|
+
const [runtime] = useState3(() => new VercelRSCRuntime(adapter));
|
1148
|
+
useInsertionEffect(() => {
|
1149
|
+
runtime.adapter = adapter;
|
1150
|
+
});
|
1151
|
+
useEffect7(() => {
|
1152
|
+
runtime.onAdapterUpdated();
|
1153
|
+
});
|
1154
|
+
return runtime;
|
1155
|
+
};
|
1156
|
+
|
1157
|
+
// src/runtime/vercel-ai/ui/use-chat/useVercelUseChatRuntime.tsx
|
1158
|
+
import { useEffect as useEffect10, useInsertionEffect as useInsertionEffect2, useState as useState4 } from "react";
|
1159
|
+
|
1160
|
+
// src/runtime/vercel-ai/ui/VercelAIRuntime.tsx
|
1161
|
+
import { create as create5 } from "zustand";
|
1162
|
+
|
1163
|
+
// src/runtime/utils/idUtils.tsx
|
1136
1164
|
import { customAlphabet } from "nanoid/non-secure";
|
1137
1165
|
var generateId = customAlphabet(
|
1138
1166
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
@@ -1141,7 +1169,7 @@ var generateId = customAlphabet(
|
|
1141
1169
|
var optimisticPrefix = "__optimistic__";
|
1142
1170
|
var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
|
1143
1171
|
|
1144
|
-
// src/
|
1172
|
+
// src/runtime/utils/MessageRepository.tsx
|
1145
1173
|
var findHead = (message) => {
|
1146
1174
|
if (message.next) return findHead(message.next);
|
1147
1175
|
return message;
|
@@ -1210,10 +1238,10 @@ var MessageRepository = class {
|
|
1210
1238
|
level: prev ? prev.level + 1 : 0
|
1211
1239
|
};
|
1212
1240
|
this.messages.set(message.id, newItem);
|
1241
|
+
this.performOp(prev, newItem, "link");
|
1213
1242
|
if (this.head === prev) {
|
1214
1243
|
this.head = newItem;
|
1215
1244
|
}
|
1216
|
-
this.performOp(prev, newItem, "link");
|
1217
1245
|
}
|
1218
1246
|
appendOptimisticMessage(parentId, message) {
|
1219
1247
|
let optimisticId;
|
@@ -1230,14 +1258,14 @@ var MessageRepository = class {
|
|
1230
1258
|
}
|
1231
1259
|
deleteMessage(messageId, replacementId) {
|
1232
1260
|
const message = this.messages.get(messageId);
|
1233
|
-
const replacement = replacementId ? this.messages.get(replacementId) : null;
|
1234
1261
|
if (!message)
|
1235
1262
|
throw new Error(
|
1236
1263
|
"MessageRepository(deleteMessage): Optimistic message not found. This is likely an internal bug in assistant-ui."
|
1237
1264
|
);
|
1265
|
+
const replacement = replacementId === void 0 ? message.prev : replacementId === null ? null : this.messages.get(replacementId);
|
1238
1266
|
if (replacement === void 0)
|
1239
1267
|
throw new Error(
|
1240
|
-
"MessageRepository(deleteMessage):
|
1268
|
+
"MessageRepository(deleteMessage): Replacement not found. This is likely an internal bug in assistant-ui."
|
1241
1269
|
);
|
1242
1270
|
for (const child of message.children) {
|
1243
1271
|
const childMessage = this.messages.get(child);
|
@@ -1247,11 +1275,11 @@ var MessageRepository = class {
|
|
1247
1275
|
);
|
1248
1276
|
this.performOp(replacement, childMessage, "relink");
|
1249
1277
|
}
|
1278
|
+
this.performOp(null, message, "cut");
|
1250
1279
|
this.messages.delete(messageId);
|
1251
1280
|
if (this.head === message) {
|
1252
|
-
this.head = replacement;
|
1281
|
+
this.head = replacement ? findHead(replacement) : null;
|
1253
1282
|
}
|
1254
|
-
this.performOp(null, message, "cut");
|
1255
1283
|
}
|
1256
1284
|
getBranches(messageId) {
|
1257
1285
|
const message = this.messages.get(messageId);
|
@@ -1292,7 +1320,13 @@ var MessageRepository = class {
|
|
1292
1320
|
}
|
1293
1321
|
};
|
1294
1322
|
|
1295
|
-
// src/
|
1323
|
+
// src/runtime/vercel-ai/ui/getVercelAIMessage.tsx
|
1324
|
+
var symbolInnerAIMessage = Symbol("innerVercelAIUIMessage");
|
1325
|
+
var getVercelAIMessage = (message) => {
|
1326
|
+
return message[symbolInnerAIMessage];
|
1327
|
+
};
|
1328
|
+
|
1329
|
+
// src/runtime/vercel-ai/ui/utils/sliceMessagesUntil.tsx
|
1296
1330
|
var sliceMessagesUntil = (messages, messageId) => {
|
1297
1331
|
if (messageId == null) return [];
|
1298
1332
|
const messageIdx = messages.findIndex((m) => m.id === messageId);
|
@@ -1300,18 +1334,97 @@ var sliceMessagesUntil = (messages, messageId) => {
|
|
1300
1334
|
throw new Error(
|
1301
1335
|
"useVercelAIThreadState: Message not found. This is liekly an internal bug in assistant-ui."
|
1302
1336
|
);
|
1303
|
-
return messages.slice(0, messageIdx + 1);
|
1337
|
+
return messages.slice(0, messageIdx + 1);
|
1338
|
+
};
|
1339
|
+
|
1340
|
+
// src/runtime/vercel-ai/ui/utils/useVercelAIComposerSync.tsx
|
1341
|
+
import { useEffect as useEffect8 } from "react";
|
1342
|
+
var useVercelAIComposerSync = (vercel) => {
|
1343
|
+
const { useComposer } = useThreadContext();
|
1344
|
+
useEffect8(() => {
|
1345
|
+
useComposer.setState({
|
1346
|
+
value: vercel.input,
|
1347
|
+
setValue: vercel.setInput
|
1348
|
+
});
|
1349
|
+
}, [useComposer, vercel.input, vercel.setInput]);
|
1350
|
+
};
|
1351
|
+
|
1352
|
+
// src/runtime/vercel-ai/ui/utils/useVercelAIThreadSync.tsx
|
1353
|
+
import { useEffect as useEffect9, useMemo as useMemo5 } from "react";
|
1354
|
+
var getIsRunning = (vercel) => {
|
1355
|
+
if ("isLoading" in vercel) return vercel.isLoading;
|
1356
|
+
return vercel.status === "in_progress";
|
1357
|
+
};
|
1358
|
+
var vercelToThreadMessage2 = (message, status) => {
|
1359
|
+
const common = {
|
1360
|
+
id: message.id,
|
1361
|
+
createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
|
1362
|
+
[symbolInnerAIMessage]: message
|
1363
|
+
};
|
1364
|
+
switch (message.role) {
|
1365
|
+
case "user":
|
1366
|
+
return {
|
1367
|
+
...common,
|
1368
|
+
role: "user",
|
1369
|
+
content: [{ type: "text", text: message.content }]
|
1370
|
+
};
|
1371
|
+
case "assistant":
|
1372
|
+
return {
|
1373
|
+
...common,
|
1374
|
+
role: "assistant",
|
1375
|
+
content: [
|
1376
|
+
...message.content ? [{ type: "text", text: message.content }] : [],
|
1377
|
+
...message.toolInvocations?.map(
|
1378
|
+
(t) => ({
|
1379
|
+
type: "tool-call",
|
1380
|
+
name: t.toolName,
|
1381
|
+
args: t.args,
|
1382
|
+
result: "result" in t ? t.result : void 0
|
1383
|
+
})
|
1384
|
+
) ?? []
|
1385
|
+
],
|
1386
|
+
status
|
1387
|
+
};
|
1388
|
+
default:
|
1389
|
+
throw new Error(
|
1390
|
+
`You have a message with an unsupported role. The role ${message.role} is not supported.`
|
1391
|
+
);
|
1392
|
+
}
|
1393
|
+
};
|
1394
|
+
var useVercelAIThreadSync = (vercel, updateData) => {
|
1395
|
+
const isRunning = getIsRunning(vercel);
|
1396
|
+
const converter = useMemo5(() => new ThreadMessageConverter(), []);
|
1397
|
+
useEffect9(() => {
|
1398
|
+
const lastMessageId = vercel.messages.at(-1)?.id;
|
1399
|
+
const convertCallback = (message, cache) => {
|
1400
|
+
const status = lastMessageId === message.id && isRunning ? "in_progress" : "done";
|
1401
|
+
if (cache && (cache.role === "user" || cache.status === status))
|
1402
|
+
return cache;
|
1403
|
+
return vercelToThreadMessage2(message, status);
|
1404
|
+
};
|
1405
|
+
const messages = converter.convertMessages(
|
1406
|
+
convertCallback,
|
1407
|
+
vercel.messages
|
1408
|
+
);
|
1409
|
+
updateData(isRunning, messages);
|
1410
|
+
}, [updateData, isRunning, vercel.messages, converter]);
|
1304
1411
|
};
|
1412
|
+
|
1413
|
+
// src/runtime/vercel-ai/ui/VercelAIRuntime.tsx
|
1305
1414
|
var hasUpcomingMessage = (isRunning, messages) => {
|
1306
1415
|
return isRunning && messages[messages.length - 1]?.role !== "assistant";
|
1307
1416
|
};
|
1308
|
-
var
|
1417
|
+
var VercelAIRuntime = class {
|
1309
1418
|
constructor(vercel) {
|
1310
1419
|
this.vercel = vercel;
|
1420
|
+
this.useVercel = create5(() => ({
|
1421
|
+
vercel
|
1422
|
+
}));
|
1311
1423
|
}
|
1312
1424
|
_subscriptions = /* @__PURE__ */ new Set();
|
1313
1425
|
repository = new MessageRepository();
|
1314
1426
|
assistantOptimisticId = null;
|
1427
|
+
useVercel;
|
1315
1428
|
messages = [];
|
1316
1429
|
isRunning = false;
|
1317
1430
|
getBranches(messageId) {
|
@@ -1319,9 +1432,7 @@ var VercelUseChatRuntime = class {
|
|
1319
1432
|
}
|
1320
1433
|
switchToBranch(branchId) {
|
1321
1434
|
this.repository.switchToBranch(branchId);
|
1322
|
-
this.
|
1323
|
-
this.repository.getMessages().map(getVercelMessage).filter((m) => m != null)
|
1324
|
-
);
|
1435
|
+
this.updateVercelMessages(this.repository.getMessages());
|
1325
1436
|
}
|
1326
1437
|
async append(message) {
|
1327
1438
|
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
@@ -1347,20 +1458,44 @@ var VercelUseChatRuntime = class {
|
|
1347
1458
|
await reloadMaybe();
|
1348
1459
|
}
|
1349
1460
|
cancelRun() {
|
1350
|
-
const
|
1461
|
+
const previousMessage = this.vercel.messages.at(-1);
|
1351
1462
|
this.vercel.stop();
|
1352
|
-
if (
|
1353
|
-
this.
|
1463
|
+
if (this.assistantOptimisticId) {
|
1464
|
+
this.repository.deleteMessage(this.assistantOptimisticId);
|
1465
|
+
this.assistantOptimisticId = null;
|
1466
|
+
}
|
1467
|
+
let messages = this.repository.getMessages();
|
1468
|
+
if (previousMessage?.role === "user" && previousMessage.id === messages.at(-1)?.id) {
|
1469
|
+
this.vercel.setInput(previousMessage.content);
|
1470
|
+
this.repository.deleteMessage(previousMessage.id);
|
1471
|
+
messages = this.repository.getMessages();
|
1472
|
+
}
|
1473
|
+
setTimeout(() => {
|
1474
|
+
this.updateVercelMessages(messages);
|
1475
|
+
}, 0);
|
1476
|
+
}
|
1477
|
+
subscribe(callback) {
|
1478
|
+
this._subscriptions.add(callback);
|
1479
|
+
return () => this._subscriptions.delete(callback);
|
1480
|
+
}
|
1481
|
+
updateVercelMessages = (messages) => {
|
1482
|
+
this.vercel.setMessages(
|
1483
|
+
messages.map(getVercelAIMessage).filter((m) => m != null)
|
1484
|
+
);
|
1485
|
+
};
|
1486
|
+
onVercelUpdated() {
|
1487
|
+
if (this.useVercel.getState().vercel !== this.vercel) {
|
1488
|
+
this.useVercel.setState({ vercel: this.vercel });
|
1354
1489
|
}
|
1355
1490
|
}
|
1356
|
-
updateData(isRunning, vm) {
|
1491
|
+
updateData = (isRunning, vm) => {
|
1357
1492
|
for (let i = 0; i < vm.length; i++) {
|
1358
1493
|
const message = vm[i];
|
1359
1494
|
const parent = vm[i - 1];
|
1360
1495
|
this.repository.addOrUpdateMessage(parent?.id ?? null, message);
|
1361
1496
|
}
|
1362
1497
|
if (this.assistantOptimisticId) {
|
1363
|
-
this.repository.deleteMessage(this.assistantOptimisticId
|
1498
|
+
this.repository.deleteMessage(this.assistantOptimisticId);
|
1364
1499
|
this.assistantOptimisticId = null;
|
1365
1500
|
}
|
1366
1501
|
if (hasUpcomingMessage(isRunning, vm)) {
|
@@ -1378,211 +1513,194 @@ var VercelUseChatRuntime = class {
|
|
1378
1513
|
this.messages = this.repository.getMessages();
|
1379
1514
|
this.isRunning = isRunning;
|
1380
1515
|
for (const callback of this._subscriptions) callback();
|
1381
|
-
}
|
1382
|
-
subscribe(callback) {
|
1383
|
-
this._subscriptions.add(callback);
|
1384
|
-
return () => this._subscriptions.delete(callback);
|
1385
|
-
}
|
1386
|
-
};
|
1387
|
-
|
1388
|
-
// src/adapters/core/vercel-use-chat/useVercelUseChatRuntime.tsx
|
1389
|
-
var getIsRunning = (vercel) => {
|
1390
|
-
if ("isLoading" in vercel) return vercel.isLoading;
|
1391
|
-
return vercel.status === "in_progress";
|
1392
|
-
};
|
1393
|
-
var vercelToThreadMessage = (message, status) => {
|
1394
|
-
const common = {
|
1395
|
-
id: message.id,
|
1396
|
-
createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
|
1397
|
-
[symbolInnerMessage]: message
|
1398
1516
|
};
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
};
|
1406
|
-
case "assistant":
|
1407
|
-
return {
|
1408
|
-
...common,
|
1409
|
-
role: "assistant",
|
1410
|
-
content: [
|
1411
|
-
...message.content ? [{ type: "text", text: message.content }] : [],
|
1412
|
-
...message.toolInvocations?.map(
|
1413
|
-
(t) => ({
|
1414
|
-
type: "tool-call",
|
1415
|
-
name: t.toolName,
|
1416
|
-
args: t.args,
|
1417
|
-
result: "result" in t ? t.result : void 0
|
1418
|
-
})
|
1419
|
-
) ?? []
|
1420
|
-
],
|
1421
|
-
status
|
1422
|
-
};
|
1423
|
-
default:
|
1424
|
-
throw new Error(
|
1425
|
-
`You have a message with an unsupported role. The role ${message.role} is not supported.`
|
1426
|
-
);
|
1427
|
-
}
|
1517
|
+
unstable_synchronizer = () => {
|
1518
|
+
const { vercel } = this.useVercel();
|
1519
|
+
useVercelAIThreadSync(vercel, this.updateData);
|
1520
|
+
useVercelAIComposerSync(vercel);
|
1521
|
+
return null;
|
1522
|
+
};
|
1428
1523
|
};
|
1429
|
-
|
1430
|
-
|
1524
|
+
|
1525
|
+
// src/runtime/vercel-ai/ui/use-chat/useVercelUseChatRuntime.tsx
|
1526
|
+
var useVercelUseChatRuntime = (chatHelpers) => {
|
1527
|
+
const [runtime] = useState4(() => new VercelAIRuntime(chatHelpers));
|
1431
1528
|
useInsertionEffect2(() => {
|
1432
|
-
runtime.vercel =
|
1529
|
+
runtime.vercel = chatHelpers;
|
1530
|
+
});
|
1531
|
+
useEffect10(() => {
|
1532
|
+
runtime.onVercelUpdated();
|
1433
1533
|
});
|
1434
|
-
const isRunning = getIsRunning(vercel);
|
1435
|
-
const converter = useMemo5(() => new ThreadMessageConverter(), []);
|
1436
|
-
const messages = useMemo5(() => {
|
1437
|
-
const lastMessageId = vercel.messages.at(-1)?.id;
|
1438
|
-
const convertCallback = (message, cache) => {
|
1439
|
-
const status = lastMessageId === message.id && isRunning ? "in_progress" : "done";
|
1440
|
-
if (cache && (cache.role === "user" || cache.status === status))
|
1441
|
-
return cache;
|
1442
|
-
return vercelToThreadMessage(message, status);
|
1443
|
-
};
|
1444
|
-
return converter.convertMessages(convertCallback, vercel.messages);
|
1445
|
-
}, [isRunning, vercel.messages, converter]);
|
1446
|
-
useEffect5(() => {
|
1447
|
-
runtime.updateData(isRunning, messages);
|
1448
|
-
}, [runtime, isRunning, messages]);
|
1449
1534
|
return runtime;
|
1450
1535
|
};
|
1451
1536
|
|
1452
|
-
// src/
|
1453
|
-
import {
|
1454
|
-
var
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
] });
|
1464
|
-
};
|
1465
|
-
var ComposerSync = ({
|
1466
|
-
vercel
|
1467
|
-
}) => {
|
1468
|
-
const { useComposer } = useAssistantContext();
|
1469
|
-
useEffect6(() => {
|
1470
|
-
useComposer.setState({
|
1471
|
-
value: vercel.input,
|
1472
|
-
setValue: vercel.setInput
|
1473
|
-
});
|
1474
|
-
}, [useComposer, vercel.input, vercel.setInput]);
|
1475
|
-
return null;
|
1537
|
+
// src/runtime/vercel-ai/ui/use-assistant/useVercelUseAssistantRuntime.tsx
|
1538
|
+
import { useEffect as useEffect11, useInsertionEffect as useInsertionEffect3, useState as useState5 } from "react";
|
1539
|
+
var useVercelUseAssistantRuntime = (assistantHelpers) => {
|
1540
|
+
const [runtime] = useState5(() => new VercelAIRuntime(assistantHelpers));
|
1541
|
+
useInsertionEffect3(() => {
|
1542
|
+
runtime.vercel = assistantHelpers;
|
1543
|
+
});
|
1544
|
+
useEffect11(() => {
|
1545
|
+
runtime.onVercelUpdated();
|
1546
|
+
});
|
1547
|
+
return runtime;
|
1476
1548
|
};
|
1477
1549
|
|
1478
|
-
// src/
|
1479
|
-
import {
|
1550
|
+
// src/context/providers/AssistantRuntimeProvider.tsx
|
1551
|
+
import { memo } from "react";
|
1480
1552
|
|
1481
|
-
// src/
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
}
|
1504
|
-
async append(message) {
|
1505
|
-
if (message.parentId !== (this.messages.at(-1)?.id ?? null)) {
|
1506
|
-
if (!this.adapter.edit)
|
1507
|
-
throw new Error(
|
1508
|
-
"Message editing is not enabled, please provide an edit callback to VercelRSCAssistantProvider."
|
1509
|
-
);
|
1510
|
-
await this.withRunning(this.adapter.edit(message));
|
1511
|
-
} else {
|
1512
|
-
await this.withRunning(this.adapter.append(message));
|
1513
|
-
}
|
1514
|
-
}
|
1515
|
-
async startRun(parentId) {
|
1516
|
-
if (!this.adapter.reload)
|
1517
|
-
throw new Error(
|
1518
|
-
"Message reloading is not enabled, please provide a reload callback to VercelRSCAssistantProvider."
|
1519
|
-
);
|
1520
|
-
await this.withRunning(this.adapter.reload(parentId));
|
1521
|
-
}
|
1522
|
-
cancelRun() {
|
1523
|
-
if (process.env["NODE_ENV"] === "development") {
|
1524
|
-
console.warn(
|
1525
|
-
"Run cancellation is not supported by VercelRSCAssistantProvider."
|
1526
|
-
);
|
1553
|
+
// src/context/providers/ThreadProvider.tsx
|
1554
|
+
import { useEffect as useEffect12, useInsertionEffect as useInsertionEffect4, useRef as useRef4, useState as useState6 } from "react";
|
1555
|
+
|
1556
|
+
// src/context/stores/Composer.ts
|
1557
|
+
import { create as create6 } from "zustand";
|
1558
|
+
var makeComposerStore = (useThread) => create6()((set, get, store) => {
|
1559
|
+
return {
|
1560
|
+
...makeBaseComposer(set, get, store),
|
1561
|
+
isEditing: true,
|
1562
|
+
send: () => {
|
1563
|
+
const { setValue, value } = get();
|
1564
|
+
setValue("");
|
1565
|
+
useThread.getState().append({
|
1566
|
+
parentId: useThread.getState().messages.at(-1)?.id ?? null,
|
1567
|
+
content: [{ type: "text", text: value }]
|
1568
|
+
});
|
1569
|
+
},
|
1570
|
+
cancel: () => {
|
1571
|
+
const thread = useThread.getState();
|
1572
|
+
if (!thread.isRunning) return false;
|
1573
|
+
useThread.getState().cancelRun();
|
1574
|
+
return true;
|
1527
1575
|
}
|
1528
|
-
}
|
1529
|
-
|
1530
|
-
this.messages = messages;
|
1531
|
-
for (const callback of this._subscriptions) callback();
|
1532
|
-
}
|
1533
|
-
subscribe(callback) {
|
1534
|
-
this._subscriptions.add(callback);
|
1535
|
-
return () => this._subscriptions.delete(callback);
|
1536
|
-
}
|
1537
|
-
};
|
1576
|
+
};
|
1577
|
+
});
|
1538
1578
|
|
1539
|
-
// src/
|
1540
|
-
|
1541
|
-
|
1579
|
+
// src/context/stores/Thread.ts
|
1580
|
+
import { create as create7 } from "zustand";
|
1581
|
+
var makeThreadStore = (runtimeRef) => {
|
1582
|
+
const useThread = create7(() => ({
|
1583
|
+
messages: runtimeRef.current.messages,
|
1584
|
+
isRunning: runtimeRef.current.isRunning,
|
1585
|
+
getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
|
1586
|
+
switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
|
1587
|
+
startRun: (parentId) => runtimeRef.current.startRun(parentId),
|
1588
|
+
append: (message) => runtimeRef.current.append(message),
|
1589
|
+
cancelRun: () => runtimeRef.current.cancelRun()
|
1590
|
+
}));
|
1591
|
+
const onRuntimeUpdate = () => {
|
1592
|
+
useThread.setState({
|
1593
|
+
messages: runtimeRef.current.messages,
|
1594
|
+
isRunning: runtimeRef.current.isRunning
|
1595
|
+
});
|
1596
|
+
};
|
1542
1597
|
return {
|
1543
|
-
|
1544
|
-
|
1545
|
-
content: [{ type: "ui", display: message.display }],
|
1546
|
-
createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
|
1547
|
-
...{ status: "done" },
|
1548
|
-
[symbolInnerRSCMessage]: rawMessage
|
1598
|
+
useThread,
|
1599
|
+
onRuntimeUpdate
|
1549
1600
|
};
|
1550
1601
|
};
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1602
|
+
|
1603
|
+
// src/context/stores/ThreadViewport.tsx
|
1604
|
+
import { create as create8 } from "zustand";
|
1605
|
+
var makeThreadViewportStore = () => {
|
1606
|
+
const scrollToBottomListeners = /* @__PURE__ */ new Set();
|
1607
|
+
return create8(() => ({
|
1608
|
+
isAtBottom: true,
|
1609
|
+
scrollToBottom: () => {
|
1610
|
+
for (const listener of scrollToBottomListeners) {
|
1611
|
+
listener();
|
1612
|
+
}
|
1613
|
+
},
|
1614
|
+
onScrollToBottom: (callback) => {
|
1615
|
+
scrollToBottomListeners.add(callback);
|
1616
|
+
return () => {
|
1617
|
+
scrollToBottomListeners.delete(callback);
|
1618
|
+
};
|
1619
|
+
}
|
1620
|
+
}));
|
1621
|
+
};
|
1622
|
+
|
1623
|
+
// src/context/providers/ThreadProvider.tsx
|
1624
|
+
import { jsx as jsx21, jsxs as jsxs4 } from "react/jsx-runtime";
|
1625
|
+
var ThreadProvider = ({
|
1626
|
+
children,
|
1627
|
+
runtime
|
1628
|
+
}) => {
|
1629
|
+
const runtimeRef = useRef4(runtime);
|
1630
|
+
useInsertionEffect4(() => {
|
1631
|
+
runtimeRef.current = runtime;
|
1555
1632
|
});
|
1556
|
-
const [
|
1557
|
-
const
|
1558
|
-
const
|
1559
|
-
|
1560
|
-
|
1633
|
+
const [{ context, onRuntimeUpdate }] = useState6(() => {
|
1634
|
+
const { useThread, onRuntimeUpdate: onRuntimeUpdate2 } = makeThreadStore(runtimeRef);
|
1635
|
+
const useViewport = makeThreadViewportStore();
|
1636
|
+
const useComposer = makeComposerStore(useThread);
|
1637
|
+
return {
|
1638
|
+
context: {
|
1639
|
+
useViewport,
|
1640
|
+
useThread,
|
1641
|
+
useComposer
|
1642
|
+
},
|
1643
|
+
onRuntimeUpdate: onRuntimeUpdate2
|
1561
1644
|
};
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
runtime.
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1645
|
+
});
|
1646
|
+
useEffect12(() => {
|
1647
|
+
onRuntimeUpdate();
|
1648
|
+
return runtime.subscribe(onRuntimeUpdate);
|
1649
|
+
}, [onRuntimeUpdate, runtime]);
|
1650
|
+
const RuntimeSynchronizer = runtime.unstable_synchronizer;
|
1651
|
+
return /* @__PURE__ */ jsxs4(ThreadContext.Provider, { value: context, children: [
|
1652
|
+
RuntimeSynchronizer && /* @__PURE__ */ jsx21(RuntimeSynchronizer, {}),
|
1653
|
+
children
|
1654
|
+
] });
|
1570
1655
|
};
|
1571
1656
|
|
1572
|
-
// src/
|
1657
|
+
// src/context/providers/AssistantRuntimeProvider.tsx
|
1658
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
1659
|
+
var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
|
1660
|
+
return /* @__PURE__ */ jsx22(ThreadProvider, { runtime, children });
|
1661
|
+
};
|
1662
|
+
var AssistantRuntimeProvider = memo(AssistantRuntimeProviderImpl);
|
1663
|
+
|
1664
|
+
// src/runtime/vercel-deprecated/VercelAIAssistantProvider.tsx
|
1573
1665
|
import { jsx as jsx23 } from "react/jsx-runtime";
|
1666
|
+
var VercelUseChatRuntimeProvider = ({
|
1667
|
+
chat,
|
1668
|
+
children
|
1669
|
+
}) => {
|
1670
|
+
const runtime = useVercelUseChatRuntime(chat);
|
1671
|
+
return /* @__PURE__ */ jsx23(AssistantRuntimeProvider, { runtime, children });
|
1672
|
+
};
|
1673
|
+
var VercelUseAssistantRuntimeProvider = ({
|
1674
|
+
assistant,
|
1675
|
+
children
|
1676
|
+
}) => {
|
1677
|
+
const runtime = useVercelUseAssistantRuntime(assistant);
|
1678
|
+
return /* @__PURE__ */ jsx23(AssistantRuntimeProvider, { runtime, children });
|
1679
|
+
};
|
1680
|
+
var VercelAIAssistantProvider = ({
|
1681
|
+
children,
|
1682
|
+
...rest
|
1683
|
+
}) => {
|
1684
|
+
if ("chat" in rest) {
|
1685
|
+
return /* @__PURE__ */ jsx23(VercelUseChatRuntimeProvider, { chat: rest.chat, children });
|
1686
|
+
}
|
1687
|
+
return /* @__PURE__ */ jsx23(VercelUseAssistantRuntimeProvider, { assistant: rest.assistant, children });
|
1688
|
+
};
|
1689
|
+
|
1690
|
+
// src/runtime/vercel-deprecated/VercelRSCAssistantProvider.tsx
|
1691
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
1574
1692
|
var VercelRSCAssistantProvider = ({
|
1575
1693
|
children,
|
1576
1694
|
...adapter
|
1577
1695
|
}) => {
|
1578
1696
|
const runtime = useVercelRSCRuntime(adapter);
|
1579
|
-
return /* @__PURE__ */
|
1697
|
+
return /* @__PURE__ */ jsx24(AssistantRuntimeProvider, { runtime, children });
|
1580
1698
|
};
|
1581
1699
|
|
1582
|
-
// src/
|
1583
|
-
import { useInsertionEffect as
|
1700
|
+
// src/runtime/local/useLocalRuntime.tsx
|
1701
|
+
import { useInsertionEffect as useInsertionEffect5, useState as useState7 } from "react";
|
1584
1702
|
|
1585
|
-
// src/
|
1703
|
+
// src/runtime/local/LocalRuntime.tsx
|
1586
1704
|
var LocalRuntime = class {
|
1587
1705
|
constructor(adapter) {
|
1588
1706
|
this.adapter = adapter;
|
@@ -1665,16 +1783,16 @@ var LocalRuntime = class {
|
|
1665
1783
|
}
|
1666
1784
|
};
|
1667
1785
|
|
1668
|
-
// src/
|
1786
|
+
// src/runtime/local/useLocalRuntime.tsx
|
1669
1787
|
var useLocalRuntime = (adapter) => {
|
1670
|
-
const [runtime] =
|
1671
|
-
|
1788
|
+
const [runtime] = useState7(() => new LocalRuntime(adapter));
|
1789
|
+
useInsertionEffect5(() => {
|
1672
1790
|
runtime.adapter = adapter;
|
1673
1791
|
});
|
1674
1792
|
return runtime;
|
1675
1793
|
};
|
1676
1794
|
|
1677
|
-
// src/
|
1795
|
+
// src/runtime/local/vercel/VercelModelAdapter.tsx
|
1678
1796
|
import { streamText } from "ai";
|
1679
1797
|
var VercelModelAdapter = class {
|
1680
1798
|
constructor(model) {
|
@@ -1717,6 +1835,7 @@ var VercelModelAdapter = class {
|
|
1717
1835
|
};
|
1718
1836
|
export {
|
1719
1837
|
actionBar_exports as ActionBarPrimitive,
|
1838
|
+
AssistantRuntimeProvider,
|
1720
1839
|
branchPicker_exports as BranchPickerPrimitive,
|
1721
1840
|
composer_exports as ComposerPrimitive,
|
1722
1841
|
contentPart_exports as ContentPartPrimitive,
|
@@ -1724,15 +1843,20 @@ export {
|
|
1724
1843
|
thread_exports as ThreadPrimitive,
|
1725
1844
|
VercelAIAssistantProvider,
|
1726
1845
|
VercelRSCAssistantProvider,
|
1727
|
-
|
1846
|
+
getVercelAIMessage,
|
1847
|
+
getVercelRSCMessage,
|
1728
1848
|
VercelModelAdapter as unstable_VercelModelAdapter,
|
1729
|
-
|
1730
|
-
|
1849
|
+
useComposerContext as unstable_useComposerContext,
|
1850
|
+
useContentPartContext as unstable_useContentPartContext,
|
1731
1851
|
useLocalRuntime as unstable_useLocalRuntime,
|
1732
1852
|
useMessageContext as unstable_useMessageContext,
|
1853
|
+
useThreadContext as unstable_useThreadContext,
|
1733
1854
|
useBeginMessageEdit,
|
1734
1855
|
useCopyMessage,
|
1735
1856
|
useGoToNextBranch,
|
1736
1857
|
useGoToPreviousBranch,
|
1737
|
-
useReloadMessage
|
1858
|
+
useReloadMessage,
|
1859
|
+
useVercelRSCRuntime,
|
1860
|
+
useVercelUseAssistantRuntime,
|
1861
|
+
useVercelUseChatRuntime
|
1738
1862
|
};
|