@assistant-ui/react 0.0.19 → 0.0.21
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 +193 -105
- package/dist/index.d.ts +193 -105
- package/dist/index.js +954 -899
- package/dist/index.mjs +927 -889
- package/package.json +8 -7
package/dist/index.js
CHANGED
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
31
31
|
var src_exports = {};
|
32
32
|
__export(src_exports, {
|
33
33
|
ActionBarPrimitive: () => actionBar_exports,
|
34
|
+
AssistantRuntimeProvider: () => AssistantRuntimeProvider,
|
34
35
|
BranchPickerPrimitive: () => branchPicker_exports,
|
35
36
|
ComposerPrimitive: () => composer_exports,
|
36
37
|
ContentPartPrimitive: () => contentPart_exports,
|
@@ -38,20 +39,175 @@ __export(src_exports, {
|
|
38
39
|
ThreadPrimitive: () => thread_exports,
|
39
40
|
VercelAIAssistantProvider: () => VercelAIAssistantProvider,
|
40
41
|
VercelRSCAssistantProvider: () => VercelRSCAssistantProvider,
|
41
|
-
|
42
|
+
getVercelAIMessage: () => getVercelAIMessage,
|
43
|
+
getVercelRSCMessage: () => getVercelRSCMessage,
|
42
44
|
unstable_VercelModelAdapter: () => VercelModelAdapter,
|
43
|
-
|
44
|
-
|
45
|
+
unstable_useComposerContext: () => useComposerContext,
|
46
|
+
unstable_useContentPartContext: () => useContentPartContext,
|
45
47
|
unstable_useLocalRuntime: () => useLocalRuntime,
|
46
48
|
unstable_useMessageContext: () => useMessageContext,
|
49
|
+
unstable_useThreadContext: () => useThreadContext,
|
47
50
|
useBeginMessageEdit: () => useBeginMessageEdit,
|
48
51
|
useCopyMessage: () => useCopyMessage,
|
49
52
|
useGoToNextBranch: () => useGoToNextBranch,
|
50
53
|
useGoToPreviousBranch: () => useGoToPreviousBranch,
|
51
|
-
useReloadMessage: () => useReloadMessage
|
54
|
+
useReloadMessage: () => useReloadMessage,
|
55
|
+
useVercelRSCRuntime: () => useVercelRSCRuntime,
|
56
|
+
useVercelUseAssistantRuntime: () => useVercelUseAssistantRuntime,
|
57
|
+
useVercelUseChatRuntime: () => useVercelUseChatRuntime
|
52
58
|
});
|
53
59
|
module.exports = __toCommonJS(src_exports);
|
54
60
|
|
61
|
+
// src/actions/useCopyMessage.tsx
|
62
|
+
var import_react4 = require("react");
|
63
|
+
|
64
|
+
// src/context/MessageContext.ts
|
65
|
+
var import_react = require("react");
|
66
|
+
var MessageContext = (0, import_react.createContext)(null);
|
67
|
+
var useMessageContext = () => {
|
68
|
+
const context = (0, import_react.useContext)(MessageContext);
|
69
|
+
if (!context)
|
70
|
+
throw new Error(
|
71
|
+
"This component can only be used inside a component passed to <ThreadPrimitive.Messages components={...} />."
|
72
|
+
);
|
73
|
+
return context;
|
74
|
+
};
|
75
|
+
|
76
|
+
// src/utils/combined/useCombinedStore.ts
|
77
|
+
var import_react3 = require("react");
|
78
|
+
|
79
|
+
// src/utils/combined/createCombinedStore.ts
|
80
|
+
var import_react2 = require("react");
|
81
|
+
var createCombinedStore = (stores) => {
|
82
|
+
const subscribe = (callback) => {
|
83
|
+
const unsubscribes = stores.map((store) => store.subscribe(callback));
|
84
|
+
return () => {
|
85
|
+
for (const unsub of unsubscribes) {
|
86
|
+
unsub();
|
87
|
+
}
|
88
|
+
};
|
89
|
+
};
|
90
|
+
return (selector) => {
|
91
|
+
const getSnapshot = () => selector(...stores.map((store) => store.getState()));
|
92
|
+
return (0, import_react2.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
93
|
+
};
|
94
|
+
};
|
95
|
+
|
96
|
+
// src/utils/combined/useCombinedStore.ts
|
97
|
+
var useCombinedStore = (stores, selector) => {
|
98
|
+
const useCombined = (0, import_react3.useMemo)(() => createCombinedStore(stores), stores);
|
99
|
+
return useCombined(selector);
|
100
|
+
};
|
101
|
+
|
102
|
+
// src/utils/getMessageText.tsx
|
103
|
+
var getMessageText = (message) => {
|
104
|
+
const textParts = message.content.filter(
|
105
|
+
(part) => part.type === "text"
|
106
|
+
);
|
107
|
+
return textParts.map((part) => part.text).join("\n\n");
|
108
|
+
};
|
109
|
+
|
110
|
+
// src/actions/useCopyMessage.tsx
|
111
|
+
var useCopyMessage = ({ copiedDuration = 3e3 }) => {
|
112
|
+
const { useMessage, useComposer } = useMessageContext();
|
113
|
+
const hasCopyableContent = useCombinedStore(
|
114
|
+
[useMessage, useComposer],
|
115
|
+
(m, c) => {
|
116
|
+
return c.isEditing || m.message.content.some((c2) => c2.type === "text");
|
117
|
+
}
|
118
|
+
);
|
119
|
+
const callback = (0, import_react4.useCallback)(() => {
|
120
|
+
const { isEditing, value: composerValue } = useComposer.getState();
|
121
|
+
const { message, setIsCopied } = useMessage.getState();
|
122
|
+
const valueToCopy = isEditing ? composerValue : getMessageText(message);
|
123
|
+
navigator.clipboard.writeText(valueToCopy);
|
124
|
+
setIsCopied(true);
|
125
|
+
setTimeout(() => setIsCopied(false), copiedDuration);
|
126
|
+
}, [useComposer, useMessage, copiedDuration]);
|
127
|
+
if (!hasCopyableContent) return null;
|
128
|
+
return callback;
|
129
|
+
};
|
130
|
+
|
131
|
+
// src/actions/useReloadMessage.tsx
|
132
|
+
var import_react6 = require("react");
|
133
|
+
|
134
|
+
// src/context/ThreadContext.ts
|
135
|
+
var import_react5 = require("react");
|
136
|
+
var ThreadContext = (0, import_react5.createContext)(null);
|
137
|
+
var useThreadContext = () => {
|
138
|
+
const context = (0, import_react5.useContext)(ThreadContext);
|
139
|
+
if (!context)
|
140
|
+
throw new Error("This component must be used within an AssistantProvider.");
|
141
|
+
return context;
|
142
|
+
};
|
143
|
+
|
144
|
+
// src/actions/useReloadMessage.tsx
|
145
|
+
var useReloadMessage = () => {
|
146
|
+
const { useThread, useViewport } = useThreadContext();
|
147
|
+
const { useMessage } = useMessageContext();
|
148
|
+
const disabled = useCombinedStore(
|
149
|
+
[useThread, useMessage],
|
150
|
+
(t, m) => t.isRunning || m.message.role !== "assistant"
|
151
|
+
);
|
152
|
+
const callback = (0, import_react6.useCallback)(() => {
|
153
|
+
const { parentId } = useMessage.getState();
|
154
|
+
useThread.getState().startRun(parentId);
|
155
|
+
useViewport.getState().scrollToBottom();
|
156
|
+
}, [useMessage, useThread, useViewport]);
|
157
|
+
if (disabled) return null;
|
158
|
+
return callback;
|
159
|
+
};
|
160
|
+
|
161
|
+
// src/actions/useBeginMessageEdit.tsx
|
162
|
+
var import_react7 = require("react");
|
163
|
+
var useBeginMessageEdit = () => {
|
164
|
+
const { useMessage, useComposer } = useMessageContext();
|
165
|
+
const disabled = useCombinedStore(
|
166
|
+
[useMessage, useComposer],
|
167
|
+
(m, c) => m.message.role !== "user" || c.isEditing
|
168
|
+
);
|
169
|
+
const callback = (0, import_react7.useCallback)(() => {
|
170
|
+
const { edit } = useComposer.getState();
|
171
|
+
edit();
|
172
|
+
}, [useComposer]);
|
173
|
+
if (disabled) return null;
|
174
|
+
return callback;
|
175
|
+
};
|
176
|
+
|
177
|
+
// src/actions/useGoToNextBranch.tsx
|
178
|
+
var import_react8 = require("react");
|
179
|
+
var useGoToNextBranch = () => {
|
180
|
+
const { useThread } = useThreadContext();
|
181
|
+
const { useMessage, useComposer } = useMessageContext();
|
182
|
+
const disabled = useCombinedStore(
|
183
|
+
[useMessage, useComposer],
|
184
|
+
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
|
185
|
+
);
|
186
|
+
const callback = (0, import_react8.useCallback)(() => {
|
187
|
+
const { message, branches } = useMessage.getState();
|
188
|
+
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
|
189
|
+
}, [useMessage, useThread]);
|
190
|
+
if (disabled) return null;
|
191
|
+
return callback;
|
192
|
+
};
|
193
|
+
|
194
|
+
// src/actions/useGoToPreviousBranch.tsx
|
195
|
+
var import_react9 = require("react");
|
196
|
+
var useGoToPreviousBranch = () => {
|
197
|
+
const { useThread } = useThreadContext();
|
198
|
+
const { useMessage, useComposer } = useMessageContext();
|
199
|
+
const disabled = useCombinedStore(
|
200
|
+
[useMessage, useComposer],
|
201
|
+
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
|
202
|
+
);
|
203
|
+
const callback = (0, import_react9.useCallback)(() => {
|
204
|
+
const { message, branches } = useMessage.getState();
|
205
|
+
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
|
206
|
+
}, [useMessage, useThread]);
|
207
|
+
if (disabled) return null;
|
208
|
+
return callback;
|
209
|
+
};
|
210
|
+
|
55
211
|
// src/primitives/thread/index.ts
|
56
212
|
var thread_exports = {};
|
57
213
|
__export(thread_exports, {
|
@@ -66,29 +222,17 @@ __export(thread_exports, {
|
|
66
222
|
|
67
223
|
// src/primitives/thread/ThreadRoot.tsx
|
68
224
|
var import_react_primitive = require("@radix-ui/react-primitive");
|
69
|
-
var
|
225
|
+
var import_react10 = require("react");
|
70
226
|
var import_jsx_runtime = require("react/jsx-runtime");
|
71
|
-
var ThreadRoot = (0,
|
227
|
+
var ThreadRoot = (0, import_react10.forwardRef)(
|
72
228
|
(props, ref) => {
|
73
229
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.div, { ...props, ref });
|
74
230
|
}
|
75
231
|
);
|
76
232
|
|
77
|
-
// src/utils/context/AssistantContext.ts
|
78
|
-
var import_react2 = require("react");
|
79
|
-
var AssistantContext = (0, import_react2.createContext)(null);
|
80
|
-
var useAssistantContext = () => {
|
81
|
-
const context = (0, import_react2.useContext)(AssistantContext);
|
82
|
-
if (!context)
|
83
|
-
throw new Error(
|
84
|
-
"This component must be used within a AssistantProvider."
|
85
|
-
);
|
86
|
-
return context;
|
87
|
-
};
|
88
|
-
|
89
233
|
// src/primitives/thread/ThreadIf.tsx
|
90
234
|
var useThreadIf = (props) => {
|
91
|
-
const { useThread } =
|
235
|
+
const { useThread } = useThreadContext();
|
92
236
|
return useThread((thread) => {
|
93
237
|
if (props.empty === true && thread.messages.length !== 0) return false;
|
94
238
|
if (props.empty === false && thread.messages.length === 0) return false;
|
@@ -112,14 +256,14 @@ var ThreadEmpty = ({ children }) => {
|
|
112
256
|
var import_primitive = require("@radix-ui/primitive");
|
113
257
|
var import_react_compose_refs = require("@radix-ui/react-compose-refs");
|
114
258
|
var import_react_primitive2 = require("@radix-ui/react-primitive");
|
115
|
-
var
|
259
|
+
var import_react13 = require("react");
|
116
260
|
|
117
261
|
// src/utils/hooks/useOnResizeContent.tsx
|
118
262
|
var import_react_use_callback_ref = require("@radix-ui/react-use-callback-ref");
|
119
|
-
var
|
263
|
+
var import_react11 = require("react");
|
120
264
|
var useOnResizeContent = (ref, callback) => {
|
121
265
|
const callbackRef = (0, import_react_use_callback_ref.useCallbackRef)(callback);
|
122
|
-
(0,
|
266
|
+
(0, import_react11.useEffect)(() => {
|
123
267
|
const el = ref.current;
|
124
268
|
if (!el) return;
|
125
269
|
const resizeObserver = new ResizeObserver(() => {
|
@@ -154,11 +298,11 @@ var useOnResizeContent = (ref, callback) => {
|
|
154
298
|
|
155
299
|
// src/utils/hooks/useOnScrollToBottom.tsx
|
156
300
|
var import_react_use_callback_ref2 = require("@radix-ui/react-use-callback-ref");
|
157
|
-
var
|
301
|
+
var import_react12 = require("react");
|
158
302
|
var useOnScrollToBottom = (callback) => {
|
159
303
|
const callbackRef = (0, import_react_use_callback_ref2.useCallbackRef)(callback);
|
160
|
-
const { useViewport } =
|
161
|
-
(0,
|
304
|
+
const { useViewport } = useThreadContext();
|
305
|
+
(0, import_react12.useEffect)(() => {
|
162
306
|
return useViewport.getState().onScrollToBottom(() => {
|
163
307
|
callbackRef();
|
164
308
|
});
|
@@ -167,14 +311,14 @@ var useOnScrollToBottom = (callback) => {
|
|
167
311
|
|
168
312
|
// src/primitives/thread/ThreadViewport.tsx
|
169
313
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
170
|
-
var ThreadViewport = (0,
|
171
|
-
const messagesEndRef = (0,
|
172
|
-
const divRef = (0,
|
314
|
+
var ThreadViewport = (0, import_react13.forwardRef)(({ autoScroll = true, onScroll, children, ...rest }, forwardedRef) => {
|
315
|
+
const messagesEndRef = (0, import_react13.useRef)(null);
|
316
|
+
const divRef = (0, import_react13.useRef)(null);
|
173
317
|
const ref = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, divRef);
|
174
|
-
const { useViewport } =
|
175
|
-
const firstRenderRef = (0,
|
176
|
-
const isScrollingToBottomRef = (0,
|
177
|
-
const lastScrollTop = (0,
|
318
|
+
const { useViewport } = useThreadContext();
|
319
|
+
const firstRenderRef = (0, import_react13.useRef)(true);
|
320
|
+
const isScrollingToBottomRef = (0, import_react13.useRef)(false);
|
321
|
+
const lastScrollTop = (0, import_react13.useRef)(0);
|
178
322
|
const scrollToBottom = () => {
|
179
323
|
const div = messagesEndRef.current;
|
180
324
|
if (!div || !autoScroll) return;
|
@@ -219,76 +363,23 @@ var ThreadViewport = (0, import_react5.forwardRef)(({ autoScroll = true, onScrol
|
|
219
363
|
);
|
220
364
|
});
|
221
365
|
|
222
|
-
// src/
|
223
|
-
var
|
224
|
-
|
225
|
-
// src/utils/context/useMessageContext.ts
|
226
|
-
var import_react6 = require("react");
|
227
|
-
var MessageContext = (0, import_react6.createContext)(null);
|
228
|
-
var useMessageContext = () => {
|
229
|
-
const context = (0, import_react6.useContext)(MessageContext);
|
230
|
-
if (!context)
|
231
|
-
throw new Error(
|
232
|
-
"This component must be used within a MessagePrimitive.Provider."
|
233
|
-
);
|
234
|
-
return context;
|
235
|
-
};
|
236
|
-
|
237
|
-
// src/utils/context/useComposerContext.ts
|
238
|
-
var useComposerContext = () => {
|
239
|
-
const { useComposer: useAssisstantComposer } = useAssistantContext();
|
240
|
-
const { useComposer: useMessageComposer } = (0, import_react7.useContext)(MessageContext) ?? {};
|
241
|
-
return {
|
242
|
-
useComposer: useMessageComposer ?? useAssisstantComposer,
|
243
|
-
type: useMessageComposer ? "message" : "assistant"
|
244
|
-
};
|
245
|
-
};
|
246
|
-
|
247
|
-
// src/primitives/composer/ComposerIf.tsx
|
248
|
-
var useComposerIf = (props) => {
|
249
|
-
const { useComposer } = useComposerContext();
|
250
|
-
return useComposer((composer) => {
|
251
|
-
if (props.editing === true && !composer.isEditing) return false;
|
252
|
-
if (props.editing === false && composer.isEditing) return false;
|
253
|
-
return true;
|
254
|
-
});
|
255
|
-
};
|
256
|
-
var ComposerIf = ({ children, ...query }) => {
|
257
|
-
const result = useComposerIf(query);
|
258
|
-
return result ? children : null;
|
259
|
-
};
|
260
|
-
|
261
|
-
// src/primitives/message/index.ts
|
262
|
-
var message_exports = {};
|
263
|
-
__export(message_exports, {
|
264
|
-
Content: () => MessageContent,
|
265
|
-
If: () => MessageIf,
|
266
|
-
InProgress: () => MessageInProgress,
|
267
|
-
Provider: () => MessageProvider,
|
268
|
-
Root: () => MessageRoot
|
269
|
-
});
|
270
|
-
|
271
|
-
// src/primitives/message/MessageProvider.tsx
|
272
|
-
var import_react8 = require("react");
|
366
|
+
// src/context/providers/MessageProvider.tsx
|
367
|
+
var import_react14 = require("react");
|
273
368
|
var import_zustand2 = require("zustand");
|
274
369
|
|
275
|
-
// src/
|
276
|
-
var getMessageText = (message) => {
|
277
|
-
const textParts = message.content.filter(
|
278
|
-
(part) => part.type === "text"
|
279
|
-
);
|
280
|
-
return textParts.map((part) => part.text).join("\n\n");
|
281
|
-
};
|
282
|
-
|
283
|
-
// src/utils/context/stores/ComposerStore.ts
|
370
|
+
// src/context/stores/MessageComposer.ts
|
284
371
|
var import_zustand = require("zustand");
|
372
|
+
|
373
|
+
// src/context/stores/BaseComposer.ts
|
285
374
|
var makeBaseComposer = (set) => ({
|
286
375
|
value: "",
|
287
376
|
setValue: (value) => {
|
288
377
|
set({ value });
|
289
378
|
}
|
290
379
|
});
|
291
|
-
|
380
|
+
|
381
|
+
// src/context/stores/MessageComposer.ts
|
382
|
+
var makeEditComposerStore = ({
|
292
383
|
onEdit,
|
293
384
|
onSend
|
294
385
|
}) => (0, import_zustand.create)()((set, get, store) => ({
|
@@ -309,35 +400,31 @@ var makeMessageComposerStore = ({
|
|
309
400
|
return true;
|
310
401
|
}
|
311
402
|
}));
|
312
|
-
var makeThreadComposerStore = (useThread) => (0, import_zustand.create)()((set, get, store) => {
|
313
|
-
return {
|
314
|
-
...makeBaseComposer(set, get, store),
|
315
|
-
isEditing: true,
|
316
|
-
send: () => {
|
317
|
-
const { value } = get();
|
318
|
-
set({ value: "" });
|
319
|
-
useThread.getState().append({
|
320
|
-
parentId: useThread.getState().messages.at(-1)?.id ?? null,
|
321
|
-
content: [{ type: "text", text: value }]
|
322
|
-
});
|
323
|
-
},
|
324
|
-
cancel: () => {
|
325
|
-
const thread = useThread.getState();
|
326
|
-
if (!thread.isRunning) return false;
|
327
|
-
useThread.getState().cancelRun();
|
328
|
-
return true;
|
329
|
-
}
|
330
|
-
};
|
331
|
-
});
|
332
403
|
|
333
|
-
// src/
|
404
|
+
// src/context/providers/MessageProvider.tsx
|
334
405
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
335
406
|
var getIsLast = (thread, message) => {
|
336
407
|
return thread.messages[thread.messages.length - 1]?.id === message.id;
|
337
408
|
};
|
338
|
-
var
|
339
|
-
const
|
340
|
-
const
|
409
|
+
var syncMessage = (thread, useMessage, messageIndex) => {
|
410
|
+
const parentId = thread.messages[messageIndex - 1]?.id ?? null;
|
411
|
+
const message = thread.messages[messageIndex];
|
412
|
+
if (!message) return;
|
413
|
+
const isLast = getIsLast(thread, message);
|
414
|
+
const branches = thread.getBranches(message.id);
|
415
|
+
const currentState = useMessage.getState();
|
416
|
+
if (currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
|
417
|
+
return;
|
418
|
+
useMessage.setState({
|
419
|
+
message,
|
420
|
+
parentId,
|
421
|
+
branches,
|
422
|
+
isLast
|
423
|
+
});
|
424
|
+
};
|
425
|
+
var useMessageContext2 = (messageIndex) => {
|
426
|
+
const { useThread } = useThreadContext();
|
427
|
+
const [context] = (0, import_react14.useState)(() => {
|
341
428
|
const useMessage = (0, import_zustand2.create)((set) => ({
|
342
429
|
message: null,
|
343
430
|
parentId: null,
|
@@ -356,7 +443,7 @@ var useMessageContext2 = () => {
|
|
356
443
|
set({ isHovering: value });
|
357
444
|
}
|
358
445
|
}));
|
359
|
-
const useComposer =
|
446
|
+
const useComposer = makeEditComposerStore({
|
360
447
|
onEdit: () => {
|
361
448
|
const message = useMessage.getState().message;
|
362
449
|
if (message.role !== "user")
|
@@ -381,56 +468,51 @@ var useMessageContext2 = () => {
|
|
381
468
|
});
|
382
469
|
}
|
383
470
|
});
|
471
|
+
syncMessage(useThread.getState(), useMessage, messageIndex);
|
384
472
|
return { useMessage, useComposer };
|
385
473
|
});
|
474
|
+
(0, import_react14.useEffect)(() => {
|
475
|
+
return useThread.subscribe((thread) => {
|
476
|
+
syncMessage(thread, context.useMessage, messageIndex);
|
477
|
+
});
|
478
|
+
}, [context, useThread, messageIndex]);
|
386
479
|
return context;
|
387
480
|
};
|
388
481
|
var MessageProvider = ({
|
389
|
-
|
390
|
-
parentId,
|
482
|
+
messageIndex,
|
391
483
|
children
|
392
484
|
}) => {
|
393
|
-
const
|
394
|
-
const context = useMessageContext2();
|
395
|
-
const isLast = useThread((thread) => getIsLast(thread, message));
|
396
|
-
const branches = useThread((thread) => thread.getBranches(message.id));
|
397
|
-
(0, import_react8.useMemo)(() => {
|
398
|
-
context.useMessage.setState({
|
399
|
-
message,
|
400
|
-
parentId,
|
401
|
-
branches,
|
402
|
-
isLast
|
403
|
-
});
|
404
|
-
}, [context, message, parentId, branches, isLast]);
|
485
|
+
const context = useMessageContext2(messageIndex);
|
405
486
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MessageContext.Provider, { value: context, children });
|
406
487
|
};
|
407
488
|
|
408
|
-
// src/
|
409
|
-
var
|
410
|
-
var
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
489
|
+
// src/context/ComposerContext.ts
|
490
|
+
var import_react15 = require("react");
|
491
|
+
var useComposerContext = () => {
|
492
|
+
const { useComposer } = useThreadContext();
|
493
|
+
const { useComposer: useEditComposer } = (0, import_react15.useContext)(MessageContext) ?? {};
|
494
|
+
return (0, import_react15.useMemo)(
|
495
|
+
() => ({
|
496
|
+
useComposer: useEditComposer ?? useComposer,
|
497
|
+
type: useEditComposer ? "edit" : "new"
|
498
|
+
}),
|
499
|
+
[useEditComposer, useComposer]
|
500
|
+
);
|
501
|
+
};
|
502
|
+
|
503
|
+
// src/primitives/composer/ComposerIf.tsx
|
504
|
+
var useComposerIf = (props) => {
|
505
|
+
const { useComposer } = useComposerContext();
|
506
|
+
return useComposer((composer) => {
|
507
|
+
if (props.editing === true && !composer.isEditing) return false;
|
508
|
+
if (props.editing === false && composer.isEditing) return false;
|
509
|
+
return true;
|
510
|
+
});
|
511
|
+
};
|
512
|
+
var ComposerIf = ({ children, ...query }) => {
|
513
|
+
const result = useComposerIf(query);
|
514
|
+
return result ? children : null;
|
515
|
+
};
|
434
516
|
|
435
517
|
// src/primitives/message/MessageIf.tsx
|
436
518
|
var useMessageIf = (props) => {
|
@@ -450,160 +532,8 @@ var MessageIf = ({ children, ...query }) => {
|
|
450
532
|
return result ? children : null;
|
451
533
|
};
|
452
534
|
|
453
|
-
// src/utils/context/combined/useCombinedStore.ts
|
454
|
-
var import_react11 = require("react");
|
455
|
-
|
456
|
-
// src/utils/context/combined/createCombinedStore.ts
|
457
|
-
var import_react10 = require("react");
|
458
|
-
var createCombinedStore = (stores) => {
|
459
|
-
const subscribe = (callback) => {
|
460
|
-
const unsubscribes = stores.map((store) => store.subscribe(callback));
|
461
|
-
return () => {
|
462
|
-
for (const unsub of unsubscribes) {
|
463
|
-
unsub();
|
464
|
-
}
|
465
|
-
};
|
466
|
-
};
|
467
|
-
return (selector) => {
|
468
|
-
const getSnapshot = () => selector(...stores.map((store) => store.getState()));
|
469
|
-
return (0, import_react10.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
470
|
-
};
|
471
|
-
};
|
472
|
-
|
473
|
-
// src/utils/context/combined/useCombinedStore.ts
|
474
|
-
var useCombinedStore = (stores, selector) => {
|
475
|
-
const useCombined = (0, import_react11.useMemo)(() => createCombinedStore(stores), stores);
|
476
|
-
return useCombined(selector);
|
477
|
-
};
|
478
|
-
|
479
|
-
// src/utils/context/useContentPartContext.ts
|
480
|
-
var import_react12 = require("react");
|
481
|
-
var ContentPartContext = (0, import_react12.createContext)(null);
|
482
|
-
var useContentPartContext = () => {
|
483
|
-
const context = (0, import_react12.useContext)(ContentPartContext);
|
484
|
-
if (!context)
|
485
|
-
throw new Error(
|
486
|
-
"This component must be used within a ContentPartPrimitive.Provider."
|
487
|
-
);
|
488
|
-
return context;
|
489
|
-
};
|
490
|
-
|
491
|
-
// src/primitives/contentPart/ContentPartInProgressIndicator.tsx
|
492
|
-
var ContentPartInProgressIndicator = () => {
|
493
|
-
const { useMessage } = useMessageContext();
|
494
|
-
const { useContentPart } = useContentPartContext();
|
495
|
-
const indicator = useCombinedStore(
|
496
|
-
[useMessage, useContentPart],
|
497
|
-
(m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
|
498
|
-
);
|
499
|
-
return indicator;
|
500
|
-
};
|
501
|
-
|
502
|
-
// src/primitives/contentPart/ContentPartProvider.tsx
|
503
|
-
var import_react13 = require("react");
|
504
|
-
var import_zustand3 = require("zustand");
|
505
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
506
|
-
var useContentPartContext2 = () => {
|
507
|
-
const [context] = (0, import_react13.useState)(() => {
|
508
|
-
const useContentPart = (0, import_zustand3.create)(() => ({
|
509
|
-
part: null,
|
510
|
-
status: "done"
|
511
|
-
}));
|
512
|
-
return { useContentPart };
|
513
|
-
});
|
514
|
-
return context;
|
515
|
-
};
|
516
|
-
var ContentPartProvider = ({
|
517
|
-
part,
|
518
|
-
status,
|
519
|
-
children
|
520
|
-
}) => {
|
521
|
-
const context = useContentPartContext2();
|
522
|
-
(0, import_react13.useMemo)(() => {
|
523
|
-
context.useContentPart.setState(
|
524
|
-
{
|
525
|
-
part,
|
526
|
-
status
|
527
|
-
},
|
528
|
-
true
|
529
|
-
);
|
530
|
-
}, [context, part, status]);
|
531
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ContentPartContext.Provider, { value: context, children });
|
532
|
-
};
|
533
|
-
|
534
|
-
// src/primitives/message/MessageContent.tsx
|
535
|
-
var import_jsx_runtime7 = require("react/jsx-runtime");
|
536
|
-
var defaultComponents = {
|
537
|
-
Text: ({ part }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
538
|
-
part.text,
|
539
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ContentPartInProgressIndicator, {})
|
540
|
-
] }),
|
541
|
-
Image: () => null,
|
542
|
-
UI: ({ part }) => part.display,
|
543
|
-
tools: {
|
544
|
-
Fallback: () => null
|
545
|
-
}
|
546
|
-
};
|
547
|
-
var MessageContent = ({
|
548
|
-
components: {
|
549
|
-
Text = defaultComponents.Text,
|
550
|
-
Image = defaultComponents.Image,
|
551
|
-
UI = defaultComponents.UI,
|
552
|
-
tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
|
553
|
-
} = {}
|
554
|
-
}) => {
|
555
|
-
const { useMessage } = useMessageContext();
|
556
|
-
const message = useMessage((s) => s.message);
|
557
|
-
const content = message.content;
|
558
|
-
const status = message.role === "assistant" ? message.status : "done";
|
559
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: content.map((part, i) => {
|
560
|
-
const key = i;
|
561
|
-
const type = part.type;
|
562
|
-
let component = null;
|
563
|
-
switch (type) {
|
564
|
-
case "text":
|
565
|
-
component = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { part });
|
566
|
-
break;
|
567
|
-
case "image":
|
568
|
-
component = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Image, { part });
|
569
|
-
break;
|
570
|
-
case "ui":
|
571
|
-
component = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(UI, { part });
|
572
|
-
break;
|
573
|
-
case "tool-call": {
|
574
|
-
const Tool = by_name[part.name] || Fallback;
|
575
|
-
component = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Tool, { part });
|
576
|
-
break;
|
577
|
-
}
|
578
|
-
default:
|
579
|
-
throw new Error(`Unknown content part type: ${type}`);
|
580
|
-
}
|
581
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
582
|
-
ContentPartProvider,
|
583
|
-
{
|
584
|
-
part,
|
585
|
-
status: i === content.length - 1 ? status : "done",
|
586
|
-
children: component
|
587
|
-
},
|
588
|
-
key
|
589
|
-
);
|
590
|
-
}) });
|
591
|
-
};
|
592
|
-
|
593
|
-
// src/primitives/message/MessageInProgress.tsx
|
594
|
-
var import_react_primitive4 = require("@radix-ui/react-primitive");
|
595
|
-
var import_react14 = require("react");
|
596
|
-
var import_jsx_runtime8 = require("react/jsx-runtime");
|
597
|
-
var MessageInProgress = (0, import_react14.forwardRef)((props, ref) => {
|
598
|
-
const { useMessage } = useMessageContext();
|
599
|
-
(0, import_react14.useMemo)(() => {
|
600
|
-
useMessage.getState().setInProgressIndicator(/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_primitive4.Primitive.div, { ...props, ref }));
|
601
|
-
}, [useMessage, props, ref]);
|
602
|
-
return null;
|
603
|
-
});
|
604
|
-
|
605
535
|
// src/primitives/thread/ThreadMessages.tsx
|
606
|
-
var
|
536
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
607
537
|
var getComponents = (components) => {
|
608
538
|
return {
|
609
539
|
EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
|
@@ -612,60 +542,58 @@ var getComponents = (components) => {
|
|
612
542
|
};
|
613
543
|
};
|
614
544
|
var ThreadMessages = ({ components }) => {
|
615
|
-
const { useThread } =
|
616
|
-
const
|
617
|
-
const messages = thread.messages;
|
545
|
+
const { useThread } = useThreadContext();
|
546
|
+
const messagesLength = useThread((t) => t.messages.length);
|
618
547
|
const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
|
619
|
-
if (
|
620
|
-
return /* @__PURE__ */ (0,
|
621
|
-
const
|
622
|
-
return /* @__PURE__ */ (0,
|
548
|
+
if (messagesLength === 0) return null;
|
549
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: new Array(messagesLength).fill(null).map((_, idx) => {
|
550
|
+
const messageIndex = idx;
|
551
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
623
552
|
MessageProvider,
|
624
553
|
{
|
625
|
-
|
626
|
-
parentId,
|
554
|
+
messageIndex,
|
627
555
|
children: [
|
628
|
-
/* @__PURE__ */ (0,
|
629
|
-
/* @__PURE__ */ (0,
|
630
|
-
/* @__PURE__ */ (0,
|
556
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(MessageIf, { user: true, children: [
|
557
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ComposerIf, { editing: false, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(UserMessage, {}) }),
|
558
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ComposerIf, { editing: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EditComposer, {}) })
|
631
559
|
] }),
|
632
|
-
/* @__PURE__ */ (0,
|
560
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AssistantMessage, {}) })
|
633
561
|
]
|
634
562
|
},
|
635
|
-
|
563
|
+
messageIndex
|
636
564
|
);
|
637
565
|
}) });
|
638
566
|
};
|
639
567
|
|
640
568
|
// src/primitives/thread/ThreadScrollToBottom.tsx
|
641
|
-
var
|
642
|
-
var
|
643
|
-
var
|
644
|
-
var
|
645
|
-
var ThreadScrollToBottom = (0,
|
646
|
-
const { useViewport } =
|
569
|
+
var import_primitive2 = require("@radix-ui/primitive");
|
570
|
+
var import_react_primitive3 = require("@radix-ui/react-primitive");
|
571
|
+
var import_react16 = require("react");
|
572
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
573
|
+
var ThreadScrollToBottom = (0, import_react16.forwardRef)(({ onClick, ...rest }, ref) => {
|
574
|
+
const { useViewport } = useThreadContext();
|
647
575
|
const isAtBottom = useViewport((s) => s.isAtBottom);
|
648
576
|
const handleScrollToBottom = () => {
|
649
577
|
useViewport.getState().scrollToBottom();
|
650
578
|
};
|
651
|
-
return /* @__PURE__ */ (0,
|
652
|
-
|
579
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
580
|
+
import_react_primitive3.Primitive.button,
|
653
581
|
{
|
654
582
|
...rest,
|
655
583
|
disabled: isAtBottom,
|
656
584
|
ref,
|
657
|
-
onClick: (0,
|
585
|
+
onClick: (0, import_primitive2.composeEventHandlers)(onClick, handleScrollToBottom)
|
658
586
|
}
|
659
587
|
);
|
660
588
|
});
|
661
589
|
|
662
590
|
// src/primitives/thread/ThreadSuggestion.tsx
|
663
|
-
var
|
664
|
-
var
|
665
|
-
var
|
666
|
-
var
|
667
|
-
var ThreadSuggestion = (0,
|
668
|
-
const { useThread, useComposer } =
|
591
|
+
var import_primitive3 = require("@radix-ui/primitive");
|
592
|
+
var import_react_primitive4 = require("@radix-ui/react-primitive");
|
593
|
+
var import_react17 = require("react");
|
594
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
595
|
+
var ThreadSuggestion = (0, import_react17.forwardRef)(({ onClick, prompt, method, autoSend: send, ...rest }, ref) => {
|
596
|
+
const { useThread, useComposer } = useThreadContext();
|
669
597
|
const isDisabled = useThread((t) => t.isRunning);
|
670
598
|
const handleApplySuggestion = () => {
|
671
599
|
const thread = useThread.getState();
|
@@ -675,13 +603,13 @@ var ThreadSuggestion = (0, import_react16.forwardRef)(({ onClick, prompt, method
|
|
675
603
|
composer.send();
|
676
604
|
}
|
677
605
|
};
|
678
|
-
return /* @__PURE__ */ (0,
|
679
|
-
|
606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
607
|
+
import_react_primitive4.Primitive.button,
|
680
608
|
{
|
681
609
|
...rest,
|
682
610
|
disabled: isDisabled,
|
683
611
|
ref,
|
684
|
-
onClick: (0,
|
612
|
+
onClick: (0, import_primitive3.composeEventHandlers)(onClick, handleApplySuggestion)
|
685
613
|
}
|
686
614
|
);
|
687
615
|
});
|
@@ -697,16 +625,16 @@ __export(composer_exports, {
|
|
697
625
|
});
|
698
626
|
|
699
627
|
// src/primitives/composer/ComposerRoot.tsx
|
700
|
-
var
|
628
|
+
var import_primitive4 = require("@radix-ui/primitive");
|
701
629
|
var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
|
702
|
-
var
|
703
|
-
var
|
704
|
-
var
|
705
|
-
var ComposerRoot = (0,
|
630
|
+
var import_react_primitive5 = require("@radix-ui/react-primitive");
|
631
|
+
var import_react18 = require("react");
|
632
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
633
|
+
var ComposerRoot = (0, import_react18.forwardRef)(
|
706
634
|
({ onSubmit, ...rest }, forwardedRef) => {
|
707
|
-
const { useViewport } =
|
635
|
+
const { useViewport } = useThreadContext();
|
708
636
|
const { useComposer } = useComposerContext();
|
709
|
-
const formRef = (0,
|
637
|
+
const formRef = (0, import_react18.useRef)(null);
|
710
638
|
const ref = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, formRef);
|
711
639
|
const handleSubmit = (e) => {
|
712
640
|
const composerState = useComposer.getState();
|
@@ -715,27 +643,27 @@ var ComposerRoot = (0, import_react17.forwardRef)(
|
|
715
643
|
composerState.send();
|
716
644
|
useViewport.getState().scrollToBottom();
|
717
645
|
};
|
718
|
-
return /* @__PURE__ */ (0,
|
719
|
-
|
646
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
647
|
+
import_react_primitive5.Primitive.form,
|
720
648
|
{
|
721
649
|
...rest,
|
722
650
|
ref,
|
723
|
-
onSubmit: (0,
|
651
|
+
onSubmit: (0, import_primitive4.composeEventHandlers)(onSubmit, handleSubmit)
|
724
652
|
}
|
725
653
|
);
|
726
654
|
}
|
727
655
|
);
|
728
656
|
|
729
657
|
// src/primitives/composer/ComposerInput.tsx
|
730
|
-
var
|
658
|
+
var import_primitive5 = require("@radix-ui/primitive");
|
731
659
|
var import_react_compose_refs3 = require("@radix-ui/react-compose-refs");
|
732
660
|
var import_react_slot = require("@radix-ui/react-slot");
|
733
|
-
var
|
661
|
+
var import_react19 = require("react");
|
734
662
|
var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
|
735
|
-
var
|
736
|
-
var ComposerInput = (0,
|
663
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
664
|
+
var ComposerInput = (0, import_react19.forwardRef)(
|
737
665
|
({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
|
738
|
-
const { useThread, useViewport } =
|
666
|
+
const { useThread, useViewport } = useThreadContext();
|
739
667
|
const { useComposer, type } = useComposerContext();
|
740
668
|
const value = useComposer((c) => {
|
741
669
|
if (!c.isEditing) return "";
|
@@ -758,10 +686,10 @@ var ComposerInput = (0, import_react18.forwardRef)(
|
|
758
686
|
}
|
759
687
|
}
|
760
688
|
};
|
761
|
-
const textareaRef = (0,
|
689
|
+
const textareaRef = (0, import_react19.useRef)(null);
|
762
690
|
const ref = (0, import_react_compose_refs3.useComposedRefs)(forwardedRef, textareaRef);
|
763
691
|
const autoFocusEnabled = autoFocus && !disabled;
|
764
|
-
const focus = (0,
|
692
|
+
const focus = (0, import_react19.useCallback)(() => {
|
765
693
|
const textarea = textareaRef.current;
|
766
694
|
if (!textarea || !autoFocusEnabled) return;
|
767
695
|
textarea.focus();
|
@@ -770,40 +698,40 @@ var ComposerInput = (0, import_react18.forwardRef)(
|
|
770
698
|
textareaRef.current.value.length
|
771
699
|
);
|
772
700
|
}, [autoFocusEnabled]);
|
773
|
-
(0,
|
701
|
+
(0, import_react19.useEffect)(() => focus(), [focus]);
|
774
702
|
useOnScrollToBottom(() => {
|
775
|
-
if (type === "
|
703
|
+
if (type === "new") {
|
776
704
|
focus();
|
777
705
|
}
|
778
706
|
});
|
779
|
-
return /* @__PURE__ */ (0,
|
707
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
780
708
|
Component,
|
781
709
|
{
|
782
710
|
value,
|
783
711
|
...rest,
|
784
712
|
ref,
|
785
713
|
disabled,
|
786
|
-
onChange: (0,
|
714
|
+
onChange: (0, import_primitive5.composeEventHandlers)(onChange, (e) => {
|
787
715
|
const composerState = useComposer.getState();
|
788
716
|
if (!composerState.isEditing) return;
|
789
717
|
return composerState.setValue(e.target.value);
|
790
718
|
}),
|
791
|
-
onKeyDown: (0,
|
719
|
+
onKeyDown: (0, import_primitive5.composeEventHandlers)(onKeyDown, handleKeyPress)
|
792
720
|
}
|
793
721
|
);
|
794
722
|
}
|
795
723
|
);
|
796
724
|
|
797
725
|
// src/primitives/composer/ComposerSend.tsx
|
798
|
-
var
|
799
|
-
var
|
800
|
-
var
|
801
|
-
var ComposerSend = (0,
|
726
|
+
var import_react_primitive6 = require("@radix-ui/react-primitive");
|
727
|
+
var import_react20 = require("react");
|
728
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
729
|
+
var ComposerSend = (0, import_react20.forwardRef)(
|
802
730
|
({ disabled, ...rest }, ref) => {
|
803
731
|
const { useComposer } = useComposerContext();
|
804
732
|
const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
|
805
|
-
return /* @__PURE__ */ (0,
|
806
|
-
|
733
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
734
|
+
import_react_primitive6.Primitive.button,
|
807
735
|
{
|
808
736
|
type: "submit",
|
809
737
|
...rest,
|
@@ -815,26 +743,187 @@ var ComposerSend = (0, import_react19.forwardRef)(
|
|
815
743
|
);
|
816
744
|
|
817
745
|
// src/primitives/composer/ComposerCancel.tsx
|
818
|
-
var
|
819
|
-
var
|
820
|
-
var
|
821
|
-
var
|
822
|
-
var ComposerCancel = (0,
|
746
|
+
var import_primitive6 = require("@radix-ui/primitive");
|
747
|
+
var import_react_primitive7 = require("@radix-ui/react-primitive");
|
748
|
+
var import_react21 = require("react");
|
749
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
750
|
+
var ComposerCancel = (0, import_react21.forwardRef)(({ onClick, ...rest }, ref) => {
|
823
751
|
const { useComposer } = useComposerContext();
|
824
752
|
const handleCancel = () => {
|
825
753
|
useComposer.getState().cancel();
|
826
754
|
};
|
827
|
-
return /* @__PURE__ */ (0,
|
828
|
-
|
755
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
756
|
+
import_react_primitive7.Primitive.button,
|
829
757
|
{
|
830
758
|
type: "button",
|
831
759
|
...rest,
|
832
760
|
ref,
|
833
|
-
onClick: (0,
|
761
|
+
onClick: (0, import_primitive6.composeEventHandlers)(onClick, handleCancel)
|
834
762
|
}
|
835
763
|
);
|
836
764
|
});
|
837
765
|
|
766
|
+
// src/primitives/message/index.ts
|
767
|
+
var message_exports = {};
|
768
|
+
__export(message_exports, {
|
769
|
+
Content: () => MessageContent,
|
770
|
+
If: () => MessageIf,
|
771
|
+
InProgress: () => MessageInProgress,
|
772
|
+
Root: () => MessageRoot
|
773
|
+
});
|
774
|
+
|
775
|
+
// src/primitives/message/MessageRoot.tsx
|
776
|
+
var import_primitive7 = require("@radix-ui/primitive");
|
777
|
+
var import_react_primitive8 = require("@radix-ui/react-primitive");
|
778
|
+
var import_react22 = require("react");
|
779
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
780
|
+
var MessageRoot = (0, import_react22.forwardRef)(
|
781
|
+
({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
|
782
|
+
const { useMessage } = useMessageContext();
|
783
|
+
const setIsHovering = useMessage((s) => s.setIsHovering);
|
784
|
+
const handleMouseEnter = () => {
|
785
|
+
setIsHovering(true);
|
786
|
+
};
|
787
|
+
const handleMouseLeave = () => {
|
788
|
+
setIsHovering(false);
|
789
|
+
};
|
790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
791
|
+
import_react_primitive8.Primitive.div,
|
792
|
+
{
|
793
|
+
...rest,
|
794
|
+
ref,
|
795
|
+
onMouseEnter: (0, import_primitive7.composeEventHandlers)(onMouseEnter, handleMouseEnter),
|
796
|
+
onMouseLeave: (0, import_primitive7.composeEventHandlers)(onMouseLeave, handleMouseLeave)
|
797
|
+
}
|
798
|
+
);
|
799
|
+
}
|
800
|
+
);
|
801
|
+
|
802
|
+
// src/context/providers/ContentPartProvider.tsx
|
803
|
+
var import_react24 = require("react");
|
804
|
+
var import_zustand3 = require("zustand");
|
805
|
+
|
806
|
+
// src/context/ContentPartContext.ts
|
807
|
+
var import_react23 = require("react");
|
808
|
+
var ContentPartContext = (0, import_react23.createContext)(
|
809
|
+
null
|
810
|
+
);
|
811
|
+
var useContentPartContext = () => {
|
812
|
+
const context = (0, import_react23.useContext)(ContentPartContext);
|
813
|
+
if (!context)
|
814
|
+
throw new Error(
|
815
|
+
"This component can only be used inside a component passed to <MessagePrimitive.Content components={...} >."
|
816
|
+
);
|
817
|
+
return context;
|
818
|
+
};
|
819
|
+
|
820
|
+
// src/context/providers/ContentPartProvider.tsx
|
821
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
822
|
+
var syncContentPart = ({ message }, useContentPart, partIndex) => {
|
823
|
+
const part = message.content[partIndex];
|
824
|
+
if (!part) return;
|
825
|
+
const messageStatus = message.role === "assistant" ? message.status : "done";
|
826
|
+
const status = partIndex === message.content.length - 1 ? messageStatus : "done";
|
827
|
+
useContentPart.setState({ part, status });
|
828
|
+
};
|
829
|
+
var useContentPartContext2 = (partIndex) => {
|
830
|
+
const { useMessage } = useMessageContext();
|
831
|
+
const [context] = (0, import_react24.useState)(() => {
|
832
|
+
const useContentPart = (0, import_zustand3.create)(() => ({
|
833
|
+
part: { type: "text", text: "" },
|
834
|
+
status: "done"
|
835
|
+
}));
|
836
|
+
syncContentPart(useMessage.getState(), useContentPart, partIndex);
|
837
|
+
return { useContentPart };
|
838
|
+
});
|
839
|
+
(0, import_react24.useEffect)(() => {
|
840
|
+
return useMessage.subscribe((message) => {
|
841
|
+
syncContentPart(message, context.useContentPart, partIndex);
|
842
|
+
});
|
843
|
+
}, [context, useMessage, partIndex]);
|
844
|
+
return context;
|
845
|
+
};
|
846
|
+
var ContentPartProvider = ({
|
847
|
+
partIndex,
|
848
|
+
children
|
849
|
+
}) => {
|
850
|
+
const context = useContentPartContext2(partIndex);
|
851
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ContentPartContext.Provider, { value: context, children });
|
852
|
+
};
|
853
|
+
|
854
|
+
// src/primitives/contentPart/ContentPartInProgressIndicator.tsx
|
855
|
+
var ContentPartInProgressIndicator = () => {
|
856
|
+
const { useMessage } = useMessageContext();
|
857
|
+
const { useContentPart } = useContentPartContext();
|
858
|
+
const indicator = useCombinedStore(
|
859
|
+
[useMessage, useContentPart],
|
860
|
+
(m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
|
861
|
+
);
|
862
|
+
return indicator;
|
863
|
+
};
|
864
|
+
|
865
|
+
// src/primitives/message/MessageContent.tsx
|
866
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
867
|
+
var defaultComponents = {
|
868
|
+
Text: ({ part }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
869
|
+
part.text,
|
870
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ContentPartInProgressIndicator, {})
|
871
|
+
] }),
|
872
|
+
Image: () => null,
|
873
|
+
UI: ({ part }) => part.display,
|
874
|
+
tools: {
|
875
|
+
Fallback: () => null
|
876
|
+
}
|
877
|
+
};
|
878
|
+
var MessageContent = ({
|
879
|
+
components: {
|
880
|
+
Text = defaultComponents.Text,
|
881
|
+
Image = defaultComponents.Image,
|
882
|
+
UI = defaultComponents.UI,
|
883
|
+
tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
|
884
|
+
} = {}
|
885
|
+
}) => {
|
886
|
+
const { useMessage } = useMessageContext();
|
887
|
+
const message = useMessage((s) => s.message);
|
888
|
+
const content = message.content;
|
889
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: content.map((part, i) => {
|
890
|
+
const partIndex = i;
|
891
|
+
const type = part.type;
|
892
|
+
let component = null;
|
893
|
+
switch (type) {
|
894
|
+
case "text":
|
895
|
+
component = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Text, { part });
|
896
|
+
break;
|
897
|
+
case "image":
|
898
|
+
component = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Image, { part });
|
899
|
+
break;
|
900
|
+
case "ui":
|
901
|
+
component = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(UI, { part });
|
902
|
+
break;
|
903
|
+
case "tool-call": {
|
904
|
+
const Tool = by_name[part.name] || Fallback;
|
905
|
+
component = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Tool, { part });
|
906
|
+
break;
|
907
|
+
}
|
908
|
+
default:
|
909
|
+
throw new Error(`Unknown content part type: ${type}`);
|
910
|
+
}
|
911
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ContentPartProvider, { partIndex, children: component }, partIndex);
|
912
|
+
}) });
|
913
|
+
};
|
914
|
+
|
915
|
+
// src/primitives/message/MessageInProgress.tsx
|
916
|
+
var import_react_primitive9 = require("@radix-ui/react-primitive");
|
917
|
+
var import_react25 = require("react");
|
918
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
919
|
+
var MessageInProgress = (0, import_react25.forwardRef)((props, ref) => {
|
920
|
+
const { useMessage } = useMessageContext();
|
921
|
+
(0, import_react25.useMemo)(() => {
|
922
|
+
useMessage.getState().setInProgressIndicator(/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_primitive9.Primitive.span, { ...props, ref }));
|
923
|
+
}, [useMessage, props, ref]);
|
924
|
+
return null;
|
925
|
+
});
|
926
|
+
|
838
927
|
// src/primitives/branchPicker/index.ts
|
839
928
|
var branchPicker_exports = {};
|
840
929
|
__export(branchPicker_exports, {
|
@@ -845,30 +934,13 @@ __export(branchPicker_exports, {
|
|
845
934
|
Root: () => BranchPickerRoot
|
846
935
|
});
|
847
936
|
|
848
|
-
// src/actions/useGoToNextBranch.tsx
|
849
|
-
var import_react21 = require("react");
|
850
|
-
var useGoToNextBranch = () => {
|
851
|
-
const { useThread } = useAssistantContext();
|
852
|
-
const { useMessage, useComposer } = useMessageContext();
|
853
|
-
const disabled = useCombinedStore(
|
854
|
-
[useMessage, useComposer],
|
855
|
-
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
|
856
|
-
);
|
857
|
-
const callback = (0, import_react21.useCallback)(() => {
|
858
|
-
const { message, branches } = useMessage.getState();
|
859
|
-
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
|
860
|
-
}, [useMessage, useThread]);
|
861
|
-
if (disabled) return null;
|
862
|
-
return callback;
|
863
|
-
};
|
864
|
-
|
865
937
|
// src/utils/createActionButton.tsx
|
866
938
|
var import_primitive8 = require("@radix-ui/primitive");
|
867
939
|
var import_react_primitive10 = require("@radix-ui/react-primitive");
|
868
|
-
var
|
940
|
+
var import_react26 = require("react");
|
869
941
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
870
942
|
var createActionButton = (useActionButton) => {
|
871
|
-
return (0,
|
943
|
+
return (0, import_react26.forwardRef)(
|
872
944
|
(props, forwardedRef) => {
|
873
945
|
const onClick = useActionButton(props);
|
874
946
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
@@ -888,23 +960,6 @@ var createActionButton = (useActionButton) => {
|
|
888
960
|
// src/primitives/branchPicker/BranchPickerNext.tsx
|
889
961
|
var BranchPickerNext = createActionButton(useGoToNextBranch);
|
890
962
|
|
891
|
-
// src/actions/useGoToPreviousBranch.tsx
|
892
|
-
var import_react23 = require("react");
|
893
|
-
var useGoToPreviousBranch = () => {
|
894
|
-
const { useThread } = useAssistantContext();
|
895
|
-
const { useMessage, useComposer } = useMessageContext();
|
896
|
-
const disabled = useCombinedStore(
|
897
|
-
[useMessage, useComposer],
|
898
|
-
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
|
899
|
-
);
|
900
|
-
const callback = (0, import_react23.useCallback)(() => {
|
901
|
-
const { message, branches } = useMessage.getState();
|
902
|
-
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
|
903
|
-
}, [useMessage, useThread]);
|
904
|
-
if (disabled) return null;
|
905
|
-
return callback;
|
906
|
-
};
|
907
|
-
|
908
963
|
// src/primitives/branchPicker/BranchPickerPrevious.tsx
|
909
964
|
var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
|
910
965
|
|
@@ -926,9 +981,9 @@ var BranchPickerNumber = () => {
|
|
926
981
|
|
927
982
|
// src/primitives/branchPicker/BranchPickerRoot.tsx
|
928
983
|
var import_react_primitive11 = require("@radix-ui/react-primitive");
|
929
|
-
var
|
984
|
+
var import_react27 = require("react");
|
930
985
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
931
|
-
var BranchPickerRoot = (0,
|
986
|
+
var BranchPickerRoot = (0, import_react27.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
|
932
987
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_primitive11.Primitive.div, { ...rest, ref }) });
|
933
988
|
});
|
934
989
|
|
@@ -943,10 +998,10 @@ __export(actionBar_exports, {
|
|
943
998
|
|
944
999
|
// src/primitives/actionBar/ActionBarRoot.tsx
|
945
1000
|
var import_react_primitive12 = require("@radix-ui/react-primitive");
|
946
|
-
var
|
1001
|
+
var import_react28 = require("react");
|
947
1002
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
948
|
-
var ActionBarRoot = (0,
|
949
|
-
const { useThread } =
|
1003
|
+
var ActionBarRoot = (0, import_react28.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
|
1004
|
+
const { useThread } = useThreadContext();
|
950
1005
|
const { useMessage } = useMessageContext();
|
951
1006
|
const hideAndfloatStatus = useCombinedStore(
|
952
1007
|
[useThread, useMessage],
|
@@ -971,142 +1026,166 @@ var ActionBarRoot = (0, import_react25.forwardRef)(({ hideWhenRunning, autohide,
|
|
971
1026
|
);
|
972
1027
|
});
|
973
1028
|
|
974
|
-
// src/actions/useCopyMessage.tsx
|
975
|
-
var import_react26 = require("react");
|
976
|
-
var useCopyMessage = ({ copiedDuration = 3e3 }) => {
|
977
|
-
const { useMessage, useComposer } = useMessageContext();
|
978
|
-
const hasCopyableContent = useCombinedStore(
|
979
|
-
[useMessage, useComposer],
|
980
|
-
(m, c) => {
|
981
|
-
return c.isEditing || m.message.content.some((c2) => c2.type === "text");
|
982
|
-
}
|
983
|
-
);
|
984
|
-
const callback = (0, import_react26.useCallback)(() => {
|
985
|
-
const { isEditing, value: composerValue } = useComposer.getState();
|
986
|
-
const { message, setIsCopied } = useMessage.getState();
|
987
|
-
const valueToCopy = isEditing ? composerValue : getMessageText(message);
|
988
|
-
navigator.clipboard.writeText(valueToCopy);
|
989
|
-
setIsCopied(true);
|
990
|
-
setTimeout(() => setIsCopied(false), copiedDuration);
|
991
|
-
}, [useComposer, useMessage, copiedDuration]);
|
992
|
-
if (!hasCopyableContent) return null;
|
993
|
-
return callback;
|
994
|
-
};
|
995
|
-
|
996
1029
|
// src/primitives/actionBar/ActionBarCopy.tsx
|
997
1030
|
var ActionBarCopy = createActionButton(useCopyMessage);
|
998
1031
|
|
999
|
-
// src/actions/useReloadMessage.tsx
|
1000
|
-
var import_react27 = require("react");
|
1001
|
-
var useReloadMessage = () => {
|
1002
|
-
const { useThread, useViewport } = useAssistantContext();
|
1003
|
-
const { useMessage } = useMessageContext();
|
1004
|
-
const disabled = useCombinedStore(
|
1005
|
-
[useThread, useMessage],
|
1006
|
-
(t, m) => t.isRunning || m.message.role !== "assistant"
|
1007
|
-
);
|
1008
|
-
const callback = (0, import_react27.useCallback)(() => {
|
1009
|
-
const { parentId } = useMessage.getState();
|
1010
|
-
useThread.getState().startRun(parentId);
|
1011
|
-
useViewport.getState().scrollToBottom();
|
1012
|
-
}, [useMessage, useThread, useViewport]);
|
1013
|
-
if (disabled) return null;
|
1014
|
-
return callback;
|
1015
|
-
};
|
1016
|
-
|
1017
1032
|
// src/primitives/actionBar/ActionBarReload.tsx
|
1018
1033
|
var ActionBarReload = createActionButton(useReloadMessage);
|
1019
1034
|
|
1020
|
-
// src/actions/useBeginMessageEdit.tsx
|
1021
|
-
var import_react28 = require("react");
|
1022
|
-
var useBeginMessageEdit = () => {
|
1023
|
-
const { useMessage, useComposer } = useMessageContext();
|
1024
|
-
const disabled = useCombinedStore(
|
1025
|
-
[useMessage, useComposer],
|
1026
|
-
(m, c) => m.message.role !== "user" || c.isEditing
|
1027
|
-
);
|
1028
|
-
const callback = (0, import_react28.useCallback)(() => {
|
1029
|
-
const { edit } = useComposer.getState();
|
1030
|
-
edit();
|
1031
|
-
}, [useComposer]);
|
1032
|
-
if (disabled) return null;
|
1033
|
-
return callback;
|
1034
|
-
};
|
1035
|
-
|
1036
1035
|
// src/primitives/actionBar/ActionBarEdit.tsx
|
1037
1036
|
var ActionBarEdit = createActionButton(useBeginMessageEdit);
|
1038
1037
|
|
1039
1038
|
// src/primitives/contentPart/index.ts
|
1040
1039
|
var contentPart_exports = {};
|
1041
1040
|
__export(contentPart_exports, {
|
1042
|
-
InProgressIndicator: () => ContentPartInProgressIndicator
|
1043
|
-
Provider: () => ContentPartProvider
|
1041
|
+
InProgressIndicator: () => ContentPartInProgressIndicator
|
1044
1042
|
});
|
1045
1043
|
|
1046
|
-
// src/
|
1047
|
-
var
|
1044
|
+
// src/runtime/vercel-ai/rsc/useVercelRSCRuntime.tsx
|
1045
|
+
var import_react30 = require("react");
|
1046
|
+
|
1047
|
+
// src/runtime/vercel-ai/rsc/VercelRSCRuntime.tsx
|
1048
|
+
var import_zustand4 = require("zustand");
|
1048
1049
|
|
1049
|
-
// src/
|
1050
|
+
// src/runtime/vercel-ai/rsc/useVercelRSCSync.tsx
|
1050
1051
|
var import_react29 = require("react");
|
1051
|
-
var import_zustand5 = require("zustand");
|
1052
1052
|
|
1053
|
-
// src/
|
1054
|
-
var
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
onScrollToBottom: (callback) => {
|
1065
|
-
scrollToBottomListeners.add(callback);
|
1066
|
-
return () => {
|
1067
|
-
scrollToBottomListeners.delete(callback);
|
1068
|
-
};
|
1069
|
-
}
|
1070
|
-
}));
|
1053
|
+
// src/runtime/vercel-ai/utils/ThreadMessageConverter.ts
|
1054
|
+
var ThreadMessageConverter = class {
|
1055
|
+
cache = /* @__PURE__ */ new WeakMap();
|
1056
|
+
convertMessages(converter, messages) {
|
1057
|
+
return messages.map((m) => {
|
1058
|
+
const cached = this.cache.get(m);
|
1059
|
+
const newMessage = converter(m, cached);
|
1060
|
+
this.cache.set(m, newMessage);
|
1061
|
+
return newMessage;
|
1062
|
+
});
|
1063
|
+
}
|
1071
1064
|
};
|
1072
1065
|
|
1073
|
-
// src/
|
1074
|
-
var
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1066
|
+
// src/runtime/vercel-ai/rsc/getVercelRSCMessage.tsx
|
1067
|
+
var symbolInnerRSCMessage = Symbol("innerVercelRSCMessage");
|
1068
|
+
var getVercelRSCMessage = (message) => {
|
1069
|
+
return message[symbolInnerRSCMessage];
|
1070
|
+
};
|
1071
|
+
|
1072
|
+
// src/runtime/vercel-ai/rsc/useVercelRSCSync.tsx
|
1073
|
+
var vercelToThreadMessage = (converter, rawMessage) => {
|
1074
|
+
const message = converter(rawMessage);
|
1075
|
+
return {
|
1076
|
+
id: message.id,
|
1077
|
+
role: message.role,
|
1078
|
+
content: [{ type: "ui", display: message.display }],
|
1079
|
+
createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
|
1080
|
+
...{ status: "done" },
|
1081
|
+
[symbolInnerRSCMessage]: rawMessage
|
1082
|
+
};
|
1083
|
+
};
|
1084
|
+
var useVercelRSCSync = (adapter, updateData) => {
|
1085
|
+
const [converter, convertCallback] = (0, import_react29.useMemo)(() => {
|
1086
|
+
const rscConverter = adapter.convertMessage ?? ((m) => m);
|
1087
|
+
const convertCallback2 = (m, cache) => {
|
1088
|
+
if (cache) return cache;
|
1089
|
+
return vercelToThreadMessage(rscConverter, m);
|
1090
|
+
};
|
1091
|
+
return [new ThreadMessageConverter(), convertCallback2];
|
1092
|
+
}, [adapter.convertMessage]);
|
1093
|
+
(0, import_react29.useEffect)(() => {
|
1094
|
+
updateData(converter.convertMessages(convertCallback, adapter.messages));
|
1095
|
+
}, [updateData, converter, convertCallback, adapter.messages]);
|
1096
|
+
};
|
1097
|
+
|
1098
|
+
// src/runtime/vercel-ai/rsc/VercelRSCRuntime.tsx
|
1099
|
+
var EMPTY_BRANCHES = Object.freeze([]);
|
1100
|
+
var VercelRSCRuntime = class {
|
1101
|
+
constructor(adapter) {
|
1102
|
+
this.adapter = adapter;
|
1103
|
+
this.useAdapter = (0, import_zustand4.create)(() => ({
|
1104
|
+
adapter
|
1105
|
+
}));
|
1106
|
+
}
|
1107
|
+
useAdapter;
|
1108
|
+
_subscriptions = /* @__PURE__ */ new Set();
|
1109
|
+
isRunning = false;
|
1110
|
+
messages = [];
|
1111
|
+
withRunning = (callback) => {
|
1112
|
+
this.isRunning = true;
|
1113
|
+
return callback.finally(() => {
|
1114
|
+
this.isRunning = false;
|
1115
|
+
});
|
1116
|
+
};
|
1117
|
+
getBranches() {
|
1118
|
+
return EMPTY_BRANCHES;
|
1119
|
+
}
|
1120
|
+
switchToBranch() {
|
1121
|
+
throw new Error(
|
1122
|
+
"Branch switching is not supported by VercelRSCAssistantProvider."
|
1123
|
+
);
|
1124
|
+
}
|
1125
|
+
async append(message) {
|
1126
|
+
if (message.parentId !== (this.messages.at(-1)?.id ?? null)) {
|
1127
|
+
if (!this.adapter.edit)
|
1128
|
+
throw new Error(
|
1129
|
+
"Message editing is not enabled, please provide an edit callback to VercelRSCAssistantProvider."
|
1130
|
+
);
|
1131
|
+
await this.withRunning(this.adapter.edit(message));
|
1132
|
+
} else {
|
1133
|
+
await this.withRunning(this.adapter.append(message));
|
1092
1134
|
}
|
1093
|
-
}
|
1135
|
+
}
|
1136
|
+
async startRun(parentId) {
|
1137
|
+
if (!this.adapter.reload)
|
1138
|
+
throw new Error(
|
1139
|
+
"Message reloading is not enabled, please provide a reload callback to VercelRSCAssistantProvider."
|
1140
|
+
);
|
1141
|
+
await this.withRunning(this.adapter.reload(parentId));
|
1142
|
+
}
|
1143
|
+
cancelRun() {
|
1144
|
+
if (process.env["NODE_ENV"] === "development") {
|
1145
|
+
console.warn(
|
1146
|
+
"Run cancellation is not supported by VercelRSCAssistantProvider."
|
1147
|
+
);
|
1148
|
+
}
|
1149
|
+
}
|
1150
|
+
subscribe(callback) {
|
1151
|
+
this._subscriptions.add(callback);
|
1152
|
+
return () => this._subscriptions.delete(callback);
|
1153
|
+
}
|
1154
|
+
onAdapterUpdated() {
|
1155
|
+
if (this.useAdapter.getState().adapter !== this.adapter) {
|
1156
|
+
this.useAdapter.setState({ adapter: this.adapter });
|
1157
|
+
}
|
1158
|
+
}
|
1159
|
+
updateData = (messages) => {
|
1160
|
+
this.messages = messages;
|
1161
|
+
for (const callback of this._subscriptions) callback();
|
1162
|
+
};
|
1163
|
+
unstable_synchronizer = () => {
|
1164
|
+
const { adapter } = this.useAdapter();
|
1165
|
+
useVercelRSCSync(adapter, this.updateData);
|
1166
|
+
return null;
|
1167
|
+
};
|
1094
1168
|
};
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1169
|
+
|
1170
|
+
// src/runtime/vercel-ai/rsc/useVercelRSCRuntime.tsx
|
1171
|
+
var useVercelRSCRuntime = (adapter) => {
|
1172
|
+
const [runtime] = (0, import_react30.useState)(() => new VercelRSCRuntime(adapter));
|
1173
|
+
(0, import_react30.useInsertionEffect)(() => {
|
1174
|
+
runtime.adapter = adapter;
|
1101
1175
|
});
|
1102
|
-
|
1176
|
+
(0, import_react30.useEffect)(() => {
|
1177
|
+
runtime.onAdapterUpdated();
|
1178
|
+
});
|
1179
|
+
return runtime;
|
1103
1180
|
};
|
1104
1181
|
|
1105
|
-
// src/
|
1106
|
-
var
|
1107
|
-
|
1182
|
+
// src/runtime/vercel-ai/ui/use-chat/useVercelUseChatRuntime.tsx
|
1183
|
+
var import_react33 = require("react");
|
1184
|
+
|
1185
|
+
// src/runtime/vercel-ai/ui/VercelAIRuntime.tsx
|
1186
|
+
var import_zustand5 = require("zustand");
|
1108
1187
|
|
1109
|
-
// src/
|
1188
|
+
// src/runtime/utils/idUtils.tsx
|
1110
1189
|
var import_non_secure = require("nanoid/non-secure");
|
1111
1190
|
var generateId = (0, import_non_secure.customAlphabet)(
|
1112
1191
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
@@ -1115,7 +1194,7 @@ var generateId = (0, import_non_secure.customAlphabet)(
|
|
1115
1194
|
var optimisticPrefix = "__optimistic__";
|
1116
1195
|
var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
|
1117
1196
|
|
1118
|
-
// src/
|
1197
|
+
// src/runtime/utils/MessageRepository.tsx
|
1119
1198
|
var findHead = (message) => {
|
1120
1199
|
if (message.next) return findHead(message.next);
|
1121
1200
|
return message;
|
@@ -1184,10 +1263,10 @@ var MessageRepository = class {
|
|
1184
1263
|
level: prev ? prev.level + 1 : 0
|
1185
1264
|
};
|
1186
1265
|
this.messages.set(message.id, newItem);
|
1266
|
+
this.performOp(prev, newItem, "link");
|
1187
1267
|
if (this.head === prev) {
|
1188
1268
|
this.head = newItem;
|
1189
1269
|
}
|
1190
|
-
this.performOp(prev, newItem, "link");
|
1191
1270
|
}
|
1192
1271
|
appendOptimisticMessage(parentId, message) {
|
1193
1272
|
let optimisticId;
|
@@ -1204,14 +1283,14 @@ var MessageRepository = class {
|
|
1204
1283
|
}
|
1205
1284
|
deleteMessage(messageId, replacementId) {
|
1206
1285
|
const message = this.messages.get(messageId);
|
1207
|
-
const replacement = replacementId ? this.messages.get(replacementId) : null;
|
1208
1286
|
if (!message)
|
1209
1287
|
throw new Error(
|
1210
1288
|
"MessageRepository(deleteMessage): Optimistic message not found. This is likely an internal bug in assistant-ui."
|
1211
1289
|
);
|
1290
|
+
const replacement = replacementId === void 0 ? message.prev : replacementId === null ? null : this.messages.get(replacementId);
|
1212
1291
|
if (replacement === void 0)
|
1213
1292
|
throw new Error(
|
1214
|
-
"MessageRepository(deleteMessage):
|
1293
|
+
"MessageRepository(deleteMessage): Replacement not found. This is likely an internal bug in assistant-ui."
|
1215
1294
|
);
|
1216
1295
|
for (const child of message.children) {
|
1217
1296
|
const childMessage = this.messages.get(child);
|
@@ -1221,11 +1300,11 @@ var MessageRepository = class {
|
|
1221
1300
|
);
|
1222
1301
|
this.performOp(replacement, childMessage, "relink");
|
1223
1302
|
}
|
1303
|
+
this.performOp(null, message, "cut");
|
1224
1304
|
this.messages.delete(messageId);
|
1225
1305
|
if (this.head === message) {
|
1226
|
-
this.head = replacement;
|
1306
|
+
this.head = replacement ? findHead(replacement) : null;
|
1227
1307
|
}
|
1228
|
-
this.performOp(null, message, "cut");
|
1229
1308
|
}
|
1230
1309
|
getBranches(messageId) {
|
1231
1310
|
const message = this.messages.get(messageId);
|
@@ -1266,35 +1345,46 @@ var MessageRepository = class {
|
|
1266
1345
|
}
|
1267
1346
|
};
|
1268
1347
|
|
1269
|
-
// src/
|
1270
|
-
var
|
1271
|
-
|
1272
|
-
|
1273
|
-
return messages.map((m) => {
|
1274
|
-
const cached = this.cache.get(m);
|
1275
|
-
const newMessage = converter(m, cached);
|
1276
|
-
this.cache.set(m, newMessage);
|
1277
|
-
return newMessage;
|
1278
|
-
});
|
1279
|
-
}
|
1348
|
+
// src/runtime/vercel-ai/ui/getVercelAIMessage.tsx
|
1349
|
+
var symbolInnerAIMessage = Symbol("innerVercelAIUIMessage");
|
1350
|
+
var getVercelAIMessage = (message) => {
|
1351
|
+
return message[symbolInnerAIMessage];
|
1280
1352
|
};
|
1281
1353
|
|
1282
|
-
// src/
|
1283
|
-
var
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1354
|
+
// src/runtime/vercel-ai/ui/utils/sliceMessagesUntil.tsx
|
1355
|
+
var sliceMessagesUntil = (messages, messageId) => {
|
1356
|
+
if (messageId == null) return [];
|
1357
|
+
const messageIdx = messages.findIndex((m) => m.id === messageId);
|
1358
|
+
if (messageIdx === -1)
|
1359
|
+
throw new Error(
|
1360
|
+
"useVercelAIThreadState: Message not found. This is liekly an internal bug in assistant-ui."
|
1361
|
+
);
|
1362
|
+
return messages.slice(0, messageIdx + 1);
|
1287
1363
|
};
|
1288
|
-
|
1289
|
-
|
1364
|
+
|
1365
|
+
// src/runtime/vercel-ai/ui/utils/useVercelAIComposerSync.tsx
|
1366
|
+
var import_react31 = require("react");
|
1367
|
+
var useVercelAIComposerSync = (vercel) => {
|
1368
|
+
const { useComposer } = useThreadContext();
|
1369
|
+
(0, import_react31.useEffect)(() => {
|
1370
|
+
useComposer.setState({
|
1371
|
+
value: vercel.input,
|
1372
|
+
setValue: vercel.setInput
|
1373
|
+
});
|
1374
|
+
}, [useComposer, vercel.input, vercel.setInput]);
|
1290
1375
|
};
|
1291
1376
|
|
1292
|
-
// src/
|
1293
|
-
var
|
1377
|
+
// src/runtime/vercel-ai/ui/utils/useVercelAIThreadSync.tsx
|
1378
|
+
var import_react32 = require("react");
|
1379
|
+
var getIsRunning = (vercel) => {
|
1380
|
+
if ("isLoading" in vercel) return vercel.isLoading;
|
1381
|
+
return vercel.status === "in_progress";
|
1382
|
+
};
|
1383
|
+
var vercelToThreadMessage2 = (message, status) => {
|
1294
1384
|
const common = {
|
1295
1385
|
id: message.id,
|
1296
1386
|
createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
|
1297
|
-
[
|
1387
|
+
[symbolInnerAIMessage]: message
|
1298
1388
|
};
|
1299
1389
|
switch (message.role) {
|
1300
1390
|
case "user":
|
@@ -1326,47 +1416,115 @@ var vercelToThreadMessage = (message, status) => {
|
|
1326
1416
|
);
|
1327
1417
|
}
|
1328
1418
|
};
|
1329
|
-
var
|
1330
|
-
if (messageId == null) return [];
|
1331
|
-
const messageIdx = messages.findIndex((m) => m.id === messageId);
|
1332
|
-
if (messageIdx === -1)
|
1333
|
-
throw new Error(
|
1334
|
-
"useVercelAIThreadState: Message not found. This is liekly an internal bug in assistant-ui."
|
1335
|
-
);
|
1336
|
-
return messages.slice(0, messageIdx + 1);
|
1337
|
-
};
|
1338
|
-
var hasUpcomingMessage = (isRunning, messages) => {
|
1339
|
-
return isRunning && messages[messages.length - 1]?.role !== "assistant";
|
1340
|
-
};
|
1341
|
-
var getIsRunning = (vercel) => {
|
1342
|
-
if ("isLoading" in vercel) return vercel.isLoading;
|
1343
|
-
return vercel.status === "in_progress";
|
1344
|
-
};
|
1345
|
-
var useVercelAIThreadState = (vercel) => {
|
1346
|
-
const [data] = (0, import_react30.useState)(() => new MessageRepository());
|
1419
|
+
var useVercelAIThreadSync = (vercel, updateData) => {
|
1347
1420
|
const isRunning = getIsRunning(vercel);
|
1348
|
-
const converter = (0,
|
1349
|
-
|
1350
|
-
const messages = (0, import_react30.useMemo)(() => {
|
1421
|
+
const converter = (0, import_react32.useMemo)(() => new ThreadMessageConverter(), []);
|
1422
|
+
(0, import_react32.useEffect)(() => {
|
1351
1423
|
const lastMessageId = vercel.messages.at(-1)?.id;
|
1352
1424
|
const convertCallback = (message, cache) => {
|
1353
1425
|
const status = lastMessageId === message.id && isRunning ? "in_progress" : "done";
|
1354
1426
|
if (cache && (cache.role === "user" || cache.status === status))
|
1355
1427
|
return cache;
|
1356
|
-
return
|
1428
|
+
return vercelToThreadMessage2(message, status);
|
1357
1429
|
};
|
1358
|
-
const
|
1430
|
+
const messages = converter.convertMessages(
|
1431
|
+
convertCallback,
|
1432
|
+
vercel.messages
|
1433
|
+
);
|
1434
|
+
updateData(isRunning, messages);
|
1435
|
+
}, [updateData, isRunning, vercel.messages, converter]);
|
1436
|
+
};
|
1437
|
+
|
1438
|
+
// src/runtime/vercel-ai/ui/VercelAIRuntime.tsx
|
1439
|
+
var hasUpcomingMessage = (isRunning, messages) => {
|
1440
|
+
return isRunning && messages[messages.length - 1]?.role !== "assistant";
|
1441
|
+
};
|
1442
|
+
var VercelAIRuntime = class {
|
1443
|
+
constructor(vercel) {
|
1444
|
+
this.vercel = vercel;
|
1445
|
+
this.useVercel = (0, import_zustand5.create)(() => ({
|
1446
|
+
vercel
|
1447
|
+
}));
|
1448
|
+
}
|
1449
|
+
_subscriptions = /* @__PURE__ */ new Set();
|
1450
|
+
repository = new MessageRepository();
|
1451
|
+
assistantOptimisticId = null;
|
1452
|
+
useVercel;
|
1453
|
+
messages = [];
|
1454
|
+
isRunning = false;
|
1455
|
+
getBranches(messageId) {
|
1456
|
+
return this.repository.getBranches(messageId);
|
1457
|
+
}
|
1458
|
+
switchToBranch(branchId) {
|
1459
|
+
this.repository.switchToBranch(branchId);
|
1460
|
+
this.updateVercelMessages(this.repository.getMessages());
|
1461
|
+
}
|
1462
|
+
async append(message) {
|
1463
|
+
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
1464
|
+
throw new Error("Only text content is supported by Vercel AI SDK.");
|
1465
|
+
const newMessages = sliceMessagesUntil(
|
1466
|
+
this.vercel.messages,
|
1467
|
+
message.parentId
|
1468
|
+
);
|
1469
|
+
this.vercel.setMessages(newMessages);
|
1470
|
+
await this.vercel.append({
|
1471
|
+
role: "user",
|
1472
|
+
content: message.content[0].text
|
1473
|
+
});
|
1474
|
+
}
|
1475
|
+
async startRun(parentId) {
|
1476
|
+
const reloadMaybe = "reload" in this.vercel ? this.vercel.reload : void 0;
|
1477
|
+
if (!reloadMaybe)
|
1478
|
+
throw new Error(
|
1479
|
+
"Reload is not supported by Vercel AI SDK's useAssistant."
|
1480
|
+
);
|
1481
|
+
const newMessages = sliceMessagesUntil(this.vercel.messages, parentId);
|
1482
|
+
this.vercel.setMessages(newMessages);
|
1483
|
+
await reloadMaybe();
|
1484
|
+
}
|
1485
|
+
cancelRun() {
|
1486
|
+
const previousMessage = this.vercel.messages.at(-1);
|
1487
|
+
this.vercel.stop();
|
1488
|
+
if (this.assistantOptimisticId) {
|
1489
|
+
this.repository.deleteMessage(this.assistantOptimisticId);
|
1490
|
+
this.assistantOptimisticId = null;
|
1491
|
+
}
|
1492
|
+
let messages = this.repository.getMessages();
|
1493
|
+
if (previousMessage?.role === "user" && previousMessage.id === messages.at(-1)?.id) {
|
1494
|
+
this.vercel.setInput(previousMessage.content);
|
1495
|
+
this.repository.deleteMessage(previousMessage.id);
|
1496
|
+
messages = this.repository.getMessages();
|
1497
|
+
}
|
1498
|
+
setTimeout(() => {
|
1499
|
+
this.updateVercelMessages(messages);
|
1500
|
+
}, 0);
|
1501
|
+
}
|
1502
|
+
subscribe(callback) {
|
1503
|
+
this._subscriptions.add(callback);
|
1504
|
+
return () => this._subscriptions.delete(callback);
|
1505
|
+
}
|
1506
|
+
updateVercelMessages = (messages) => {
|
1507
|
+
this.vercel.setMessages(
|
1508
|
+
messages.map(getVercelAIMessage).filter((m) => m != null)
|
1509
|
+
);
|
1510
|
+
};
|
1511
|
+
onVercelUpdated() {
|
1512
|
+
if (this.useVercel.getState().vercel !== this.vercel) {
|
1513
|
+
this.useVercel.setState({ vercel: this.vercel });
|
1514
|
+
}
|
1515
|
+
}
|
1516
|
+
updateData = (isRunning, vm) => {
|
1359
1517
|
for (let i = 0; i < vm.length; i++) {
|
1360
1518
|
const message = vm[i];
|
1361
1519
|
const parent = vm[i - 1];
|
1362
|
-
|
1520
|
+
this.repository.addOrUpdateMessage(parent?.id ?? null, message);
|
1363
1521
|
}
|
1364
|
-
if (
|
1365
|
-
|
1366
|
-
|
1522
|
+
if (this.assistantOptimisticId) {
|
1523
|
+
this.repository.deleteMessage(this.assistantOptimisticId);
|
1524
|
+
this.assistantOptimisticId = null;
|
1367
1525
|
}
|
1368
1526
|
if (hasUpcomingMessage(isRunning, vm)) {
|
1369
|
-
|
1527
|
+
this.assistantOptimisticId = this.repository.appendOptimisticMessage(
|
1370
1528
|
vm.at(-1)?.id ?? null,
|
1371
1529
|
{
|
1372
1530
|
role: "assistant",
|
@@ -1374,321 +1532,220 @@ var useVercelAIThreadState = (vercel) => {
|
|
1374
1532
|
}
|
1375
1533
|
);
|
1376
1534
|
}
|
1377
|
-
|
1378
|
-
|
1379
|
-
}, [converter, data, isRunning, vercel.messages]);
|
1380
|
-
const getBranches2 = (0, import_react30.useCallback)(
|
1381
|
-
(messageId) => {
|
1382
|
-
return data.getBranches(messageId);
|
1383
|
-
},
|
1384
|
-
[data]
|
1385
|
-
);
|
1386
|
-
const switchToBranch2 = (0, import_react_use_callback_ref3.useCallbackRef)((messageId) => {
|
1387
|
-
data.switchToBranch(messageId);
|
1388
|
-
vercel.setMessages(
|
1389
|
-
data.getMessages().map(getVercelMessage).filter((m) => m != null)
|
1535
|
+
this.repository.resetHead(
|
1536
|
+
this.assistantOptimisticId ?? vm.at(-1)?.id ?? null
|
1390
1537
|
);
|
1538
|
+
this.messages = this.repository.getMessages();
|
1539
|
+
this.isRunning = isRunning;
|
1540
|
+
for (const callback of this._subscriptions) callback();
|
1541
|
+
};
|
1542
|
+
unstable_synchronizer = () => {
|
1543
|
+
const { vercel } = this.useVercel();
|
1544
|
+
useVercelAIThreadSync(vercel, this.updateData);
|
1545
|
+
useVercelAIComposerSync(vercel);
|
1546
|
+
return null;
|
1547
|
+
};
|
1548
|
+
};
|
1549
|
+
|
1550
|
+
// src/runtime/vercel-ai/ui/use-chat/useVercelUseChatRuntime.tsx
|
1551
|
+
var useVercelUseChatRuntime = (chatHelpers) => {
|
1552
|
+
const [runtime] = (0, import_react33.useState)(() => new VercelAIRuntime(chatHelpers));
|
1553
|
+
(0, import_react33.useInsertionEffect)(() => {
|
1554
|
+
runtime.vercel = chatHelpers;
|
1391
1555
|
});
|
1392
|
-
|
1393
|
-
|
1394
|
-
if (!reloadMaybe)
|
1395
|
-
throw new Error(
|
1396
|
-
"Reload is not supported by Vercel AI SDK's useAssistant."
|
1397
|
-
);
|
1398
|
-
const newMessages = sliceMessagesUntil(vercel.messages, parentId);
|
1399
|
-
vercel.setMessages(newMessages);
|
1400
|
-
await reloadMaybe();
|
1556
|
+
(0, import_react33.useEffect)(() => {
|
1557
|
+
runtime.onVercelUpdated();
|
1401
1558
|
});
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1559
|
+
return runtime;
|
1560
|
+
};
|
1561
|
+
|
1562
|
+
// src/runtime/vercel-ai/ui/use-assistant/useVercelUseAssistantRuntime.tsx
|
1563
|
+
var import_react34 = require("react");
|
1564
|
+
var useVercelUseAssistantRuntime = (assistantHelpers) => {
|
1565
|
+
const [runtime] = (0, import_react34.useState)(() => new VercelAIRuntime(assistantHelpers));
|
1566
|
+
(0, import_react34.useInsertionEffect)(() => {
|
1567
|
+
runtime.vercel = assistantHelpers;
|
1411
1568
|
});
|
1412
|
-
|
1413
|
-
|
1414
|
-
vercel.stop();
|
1415
|
-
if (lastMessage?.role === "user") {
|
1416
|
-
vercel.setInput(lastMessage.content);
|
1417
|
-
}
|
1569
|
+
(0, import_react34.useEffect)(() => {
|
1570
|
+
runtime.onVercelUpdated();
|
1418
1571
|
});
|
1419
|
-
return
|
1420
|
-
() => ({
|
1421
|
-
isRunning,
|
1422
|
-
messages,
|
1423
|
-
getBranches: getBranches2,
|
1424
|
-
switchToBranch: switchToBranch2,
|
1425
|
-
append,
|
1426
|
-
startRun,
|
1427
|
-
cancelRun: cancelRun2
|
1428
|
-
}),
|
1429
|
-
[
|
1430
|
-
isRunning,
|
1431
|
-
messages,
|
1432
|
-
getBranches2,
|
1433
|
-
switchToBranch2,
|
1434
|
-
append,
|
1435
|
-
startRun,
|
1436
|
-
cancelRun2
|
1437
|
-
]
|
1438
|
-
);
|
1572
|
+
return runtime;
|
1439
1573
|
};
|
1440
1574
|
|
1441
|
-
// src/
|
1442
|
-
var
|
1443
|
-
var VercelAIAssistantProvider = ({
|
1444
|
-
children,
|
1445
|
-
...rest
|
1446
|
-
}) => {
|
1447
|
-
const context = useDummyAIAssistantContext();
|
1448
|
-
const vercel = "chat" in rest ? rest.chat : rest.assistant;
|
1449
|
-
const threadState = useVercelAIThreadState(vercel);
|
1450
|
-
(0, import_react31.useMemo)(() => {
|
1451
|
-
context.useThread.setState(threadState, true);
|
1452
|
-
}, [context, threadState]);
|
1453
|
-
(0, import_react31.useMemo)(() => {
|
1454
|
-
context.useComposer.setState({
|
1455
|
-
value: vercel.input,
|
1456
|
-
setValue: vercel.setInput
|
1457
|
-
});
|
1458
|
-
}, [context, vercel.input, vercel.setInput]);
|
1459
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AssistantContext.Provider, { value: context, children });
|
1460
|
-
};
|
1575
|
+
// src/context/providers/AssistantRuntimeProvider.tsx
|
1576
|
+
var import_react36 = require("react");
|
1461
1577
|
|
1462
|
-
// src/
|
1463
|
-
var
|
1464
|
-
var import_jsx_runtime22 = require("react/jsx-runtime");
|
1465
|
-
var vercelToThreadMessage2 = (converter, rawMessage) => {
|
1466
|
-
const message = converter(rawMessage);
|
1467
|
-
return {
|
1468
|
-
id: message.id,
|
1469
|
-
role: message.role,
|
1470
|
-
content: [{ type: "ui", display: message.display }],
|
1471
|
-
createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
|
1472
|
-
...{ status: "done" },
|
1473
|
-
[symbolInnerRSCMessage]: rawMessage
|
1474
|
-
};
|
1475
|
-
};
|
1476
|
-
var EMPTY_BRANCHES = [];
|
1477
|
-
var getBranches = () => {
|
1478
|
-
return EMPTY_BRANCHES;
|
1479
|
-
};
|
1480
|
-
var switchToBranch = () => {
|
1481
|
-
throw new Error(
|
1482
|
-
"Branch switching is not supported by VercelRSCAssistantProvider."
|
1483
|
-
);
|
1484
|
-
};
|
1485
|
-
var cancelRun = () => {
|
1486
|
-
if (process.env["NODE_ENV"] === "development") {
|
1487
|
-
console.warn(
|
1488
|
-
"Run cancellation is not supported by VercelRSCAssistantProvider."
|
1489
|
-
);
|
1490
|
-
}
|
1491
|
-
};
|
1492
|
-
var VercelRSCAssistantProvider = ({
|
1493
|
-
children,
|
1494
|
-
convertMessage,
|
1495
|
-
messages: vercelMessages,
|
1496
|
-
append: appendCallback,
|
1497
|
-
edit,
|
1498
|
-
reload
|
1499
|
-
}) => {
|
1500
|
-
const context = useDummyAIAssistantContext();
|
1501
|
-
const [isRunning, setIsRunning] = (0, import_react32.useState)(false);
|
1502
|
-
const withRunning = (0, import_react32.useCallback)((callback) => {
|
1503
|
-
setIsRunning(true);
|
1504
|
-
return callback.finally(() => setIsRunning(false));
|
1505
|
-
}, []);
|
1506
|
-
const [converter, convertCallback] = (0, import_react32.useMemo)(() => {
|
1507
|
-
const rscConverter = convertMessage ?? ((m) => m);
|
1508
|
-
const convertCallback2 = (m, cache) => {
|
1509
|
-
if (cache) return cache;
|
1510
|
-
return vercelToThreadMessage2(rscConverter, m);
|
1511
|
-
};
|
1512
|
-
return [new ThreadMessageConverter(), convertCallback2];
|
1513
|
-
}, [convertMessage]);
|
1514
|
-
const messages = (0, import_react32.useMemo)(() => {
|
1515
|
-
return converter.convertMessages(convertCallback, vercelMessages);
|
1516
|
-
}, [converter, convertCallback, vercelMessages]);
|
1517
|
-
const append = (0, import_react32.useCallback)(
|
1518
|
-
async (message) => {
|
1519
|
-
if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null)) {
|
1520
|
-
if (!edit)
|
1521
|
-
throw new Error(
|
1522
|
-
"Message editing is not enabled, please provide an edit callback to VercelRSCAssistantProvider."
|
1523
|
-
);
|
1524
|
-
await withRunning(edit(message));
|
1525
|
-
} else {
|
1526
|
-
await withRunning(appendCallback(message));
|
1527
|
-
}
|
1528
|
-
},
|
1529
|
-
[context, withRunning, appendCallback, edit]
|
1530
|
-
);
|
1531
|
-
const startRun = (0, import_react32.useCallback)(
|
1532
|
-
async (parentId) => {
|
1533
|
-
if (!reload)
|
1534
|
-
throw new Error(
|
1535
|
-
"Message reloading is not enabled, please provide a reload callback to VercelRSCAssistantProvider."
|
1536
|
-
);
|
1537
|
-
await withRunning(reload(parentId));
|
1538
|
-
},
|
1539
|
-
[withRunning, reload]
|
1540
|
-
);
|
1541
|
-
(0, import_react32.useMemo)(() => {
|
1542
|
-
context.useThread.setState(
|
1543
|
-
{
|
1544
|
-
messages,
|
1545
|
-
isRunning,
|
1546
|
-
getBranches,
|
1547
|
-
switchToBranch,
|
1548
|
-
append,
|
1549
|
-
startRun,
|
1550
|
-
cancelRun
|
1551
|
-
},
|
1552
|
-
true
|
1553
|
-
);
|
1554
|
-
}, [context, messages, isRunning, append, startRun]);
|
1555
|
-
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AssistantContext.Provider, { value: context, children });
|
1556
|
-
};
|
1578
|
+
// src/context/providers/ThreadProvider.tsx
|
1579
|
+
var import_react35 = require("react");
|
1557
1580
|
|
1558
|
-
// src/
|
1559
|
-
var import_react33 = require("react");
|
1581
|
+
// src/context/stores/Composer.ts
|
1560
1582
|
var import_zustand6 = require("zustand");
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1571
|
-
withModifications(callback) {
|
1572
|
-
const res = callback(this.repository);
|
1573
|
-
this.flushCallback(this.repository.getMessages());
|
1574
|
-
return res;
|
1575
|
-
}
|
1576
|
-
};
|
1577
|
-
|
1578
|
-
// src/adapters/core/utils/useAssistantContext.tsx
|
1579
|
-
var makeThreadStore = (runtimeRef) => {
|
1580
|
-
const repository = new AssistantMessageRepository((messages) => {
|
1581
|
-
useThread.setState({ messages });
|
1582
|
-
});
|
1583
|
-
const useThread = (0, import_zustand6.create)(() => ({
|
1584
|
-
messages: [],
|
1585
|
-
isRunning: false,
|
1586
|
-
getBranches: (messageId) => repository.getBranches(messageId),
|
1587
|
-
switchToBranch: (branchId) => {
|
1588
|
-
repository.withModifications((repository2) => {
|
1589
|
-
repository2.switchToBranch(branchId);
|
1590
|
-
});
|
1591
|
-
},
|
1592
|
-
startRun: async (parentId) => {
|
1593
|
-
const optimisticId = repository.withModifications((repository2) => {
|
1594
|
-
const optimisticId2 = repository2.appendOptimisticMessage(parentId, {
|
1595
|
-
role: "assistant",
|
1596
|
-
content: [{ type: "text", text: "" }]
|
1597
|
-
});
|
1598
|
-
repository2.resetHead(optimisticId2);
|
1599
|
-
return optimisticId2;
|
1600
|
-
});
|
1601
|
-
const { id } = await runtimeRef.current.startRun(parentId);
|
1602
|
-
repository.withModifications((repository2) => {
|
1603
|
-
repository2.deleteMessage(optimisticId, id);
|
1604
|
-
});
|
1605
|
-
},
|
1606
|
-
append: async (message) => {
|
1607
|
-
const [parentOptimisticId, optimisticId] = repository.withModifications(
|
1608
|
-
(repository2) => {
|
1609
|
-
const parentOptimisticId2 = repository2.appendOptimisticMessage(
|
1610
|
-
message.parentId,
|
1611
|
-
{
|
1612
|
-
role: "user",
|
1613
|
-
content: message.content
|
1614
|
-
}
|
1615
|
-
);
|
1616
|
-
const optimisticId2 = repository2.appendOptimisticMessage(
|
1617
|
-
parentOptimisticId2,
|
1618
|
-
{
|
1619
|
-
role: "assistant",
|
1620
|
-
content: [{ type: "text", text: "" }]
|
1621
|
-
}
|
1622
|
-
);
|
1623
|
-
repository2.resetHead(optimisticId2);
|
1624
|
-
return [parentOptimisticId2, optimisticId2];
|
1625
|
-
}
|
1626
|
-
);
|
1627
|
-
const { parentId, id } = await runtimeRef.current.append(message);
|
1628
|
-
repository.withModifications((repository2) => {
|
1629
|
-
repository2.deleteMessage(parentOptimisticId, parentId);
|
1630
|
-
repository2.deleteMessage(optimisticId, id);
|
1583
|
+
var makeComposerStore = (useThread) => (0, import_zustand6.create)()((set, get, store) => {
|
1584
|
+
return {
|
1585
|
+
...makeBaseComposer(set, get, store),
|
1586
|
+
isEditing: true,
|
1587
|
+
send: () => {
|
1588
|
+
const { setValue, value } = get();
|
1589
|
+
setValue("");
|
1590
|
+
useThread.getState().append({
|
1591
|
+
parentId: useThread.getState().messages.at(-1)?.id ?? null,
|
1592
|
+
content: [{ type: "text", text: value }]
|
1631
1593
|
});
|
1632
1594
|
},
|
1595
|
+
cancel: () => {
|
1596
|
+
const thread = useThread.getState();
|
1597
|
+
if (!thread.isRunning) return false;
|
1598
|
+
useThread.getState().cancelRun();
|
1599
|
+
return true;
|
1600
|
+
}
|
1601
|
+
};
|
1602
|
+
});
|
1603
|
+
|
1604
|
+
// src/context/stores/Thread.ts
|
1605
|
+
var import_zustand7 = require("zustand");
|
1606
|
+
var makeThreadStore = (runtimeRef) => {
|
1607
|
+
const useThread = (0, import_zustand7.create)(() => ({
|
1608
|
+
messages: runtimeRef.current.messages,
|
1609
|
+
isRunning: runtimeRef.current.isRunning,
|
1610
|
+
getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
|
1611
|
+
switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
|
1612
|
+
startRun: (parentId) => runtimeRef.current.startRun(parentId),
|
1613
|
+
append: (message) => runtimeRef.current.append(message),
|
1633
1614
|
cancelRun: () => runtimeRef.current.cancelRun()
|
1634
1615
|
}));
|
1635
|
-
const
|
1636
|
-
|
1637
|
-
|
1616
|
+
const onRuntimeUpdate = () => {
|
1617
|
+
useThread.setState({
|
1618
|
+
messages: runtimeRef.current.messages,
|
1619
|
+
isRunning: runtimeRef.current.isRunning
|
1638
1620
|
});
|
1639
1621
|
};
|
1640
|
-
const onRunningChange = (isRunning) => {
|
1641
|
-
useThread.setState({ isRunning });
|
1642
|
-
};
|
1643
1622
|
return {
|
1644
1623
|
useThread,
|
1645
|
-
|
1646
|
-
onRunningChange
|
1624
|
+
onRuntimeUpdate
|
1647
1625
|
};
|
1648
1626
|
};
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1627
|
+
|
1628
|
+
// src/context/stores/ThreadViewport.tsx
|
1629
|
+
var import_zustand8 = require("zustand");
|
1630
|
+
var makeThreadViewportStore = () => {
|
1631
|
+
const scrollToBottomListeners = /* @__PURE__ */ new Set();
|
1632
|
+
return (0, import_zustand8.create)(() => ({
|
1633
|
+
isAtBottom: true,
|
1634
|
+
scrollToBottom: () => {
|
1635
|
+
for (const listener of scrollToBottomListeners) {
|
1636
|
+
listener();
|
1637
|
+
}
|
1638
|
+
},
|
1639
|
+
onScrollToBottom: (callback) => {
|
1640
|
+
scrollToBottomListeners.add(callback);
|
1641
|
+
return () => {
|
1642
|
+
scrollToBottomListeners.delete(callback);
|
1643
|
+
};
|
1644
|
+
}
|
1645
|
+
}));
|
1646
|
+
};
|
1647
|
+
|
1648
|
+
// src/context/providers/ThreadProvider.tsx
|
1649
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
1650
|
+
var ThreadProvider = ({
|
1651
|
+
children,
|
1652
|
+
runtime
|
1653
|
+
}) => {
|
1654
|
+
const runtimeRef = (0, import_react35.useRef)(runtime);
|
1655
|
+
(0, import_react35.useInsertionEffect)(() => {
|
1652
1656
|
runtimeRef.current = runtime;
|
1653
1657
|
});
|
1654
|
-
const [{ context,
|
1655
|
-
const { useThread,
|
1656
|
-
const useViewport =
|
1657
|
-
const useComposer =
|
1658
|
+
const [{ context, onRuntimeUpdate }] = (0, import_react35.useState)(() => {
|
1659
|
+
const { useThread, onRuntimeUpdate: onRuntimeUpdate2 } = makeThreadStore(runtimeRef);
|
1660
|
+
const useViewport = makeThreadViewportStore();
|
1661
|
+
const useComposer = makeComposerStore(useThread);
|
1658
1662
|
return {
|
1659
|
-
context: {
|
1660
|
-
|
1661
|
-
|
1663
|
+
context: {
|
1664
|
+
useViewport,
|
1665
|
+
useThread,
|
1666
|
+
useComposer
|
1667
|
+
},
|
1668
|
+
onRuntimeUpdate: onRuntimeUpdate2
|
1662
1669
|
};
|
1663
1670
|
});
|
1664
|
-
(0,
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
+
(0, import_react35.useEffect)(() => {
|
1672
|
+
onRuntimeUpdate();
|
1673
|
+
return runtime.subscribe(onRuntimeUpdate);
|
1674
|
+
}, [onRuntimeUpdate, runtime]);
|
1675
|
+
const RuntimeSynchronizer = runtime.unstable_synchronizer;
|
1676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(ThreadContext.Provider, { value: context, children: [
|
1677
|
+
RuntimeSynchronizer && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(RuntimeSynchronizer, {}),
|
1678
|
+
children
|
1679
|
+
] });
|
1680
|
+
};
|
1681
|
+
|
1682
|
+
// src/context/providers/AssistantRuntimeProvider.tsx
|
1683
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
1684
|
+
var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
|
1685
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ThreadProvider, { runtime, children });
|
1671
1686
|
};
|
1687
|
+
var AssistantRuntimeProvider = (0, import_react36.memo)(AssistantRuntimeProviderImpl);
|
1672
1688
|
|
1673
|
-
// src/
|
1689
|
+
// src/runtime/vercel-deprecated/VercelAIAssistantProvider.tsx
|
1674
1690
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
1675
|
-
var
|
1676
|
-
|
1677
|
-
|
1691
|
+
var VercelUseChatRuntimeProvider = ({
|
1692
|
+
chat,
|
1693
|
+
children
|
1694
|
+
}) => {
|
1695
|
+
const runtime = useVercelUseChatRuntime(chat);
|
1696
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AssistantRuntimeProvider, { runtime, children });
|
1697
|
+
};
|
1698
|
+
var VercelUseAssistantRuntimeProvider = ({
|
1699
|
+
assistant,
|
1700
|
+
children
|
1701
|
+
}) => {
|
1702
|
+
const runtime = useVercelUseAssistantRuntime(assistant);
|
1703
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AssistantRuntimeProvider, { runtime, children });
|
1704
|
+
};
|
1705
|
+
var VercelAIAssistantProvider = ({
|
1706
|
+
children,
|
1707
|
+
...rest
|
1708
|
+
}) => {
|
1709
|
+
if ("chat" in rest) {
|
1710
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(VercelUseChatRuntimeProvider, { chat: rest.chat, children });
|
1711
|
+
}
|
1712
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(VercelUseAssistantRuntimeProvider, { assistant: rest.assistant, children });
|
1678
1713
|
};
|
1679
1714
|
|
1680
|
-
// src/
|
1681
|
-
var
|
1715
|
+
// src/runtime/vercel-deprecated/VercelRSCAssistantProvider.tsx
|
1716
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
1717
|
+
var VercelRSCAssistantProvider = ({
|
1718
|
+
children,
|
1719
|
+
...adapter
|
1720
|
+
}) => {
|
1721
|
+
const runtime = useVercelRSCRuntime(adapter);
|
1722
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AssistantRuntimeProvider, { runtime, children });
|
1723
|
+
};
|
1724
|
+
|
1725
|
+
// src/runtime/local/useLocalRuntime.tsx
|
1726
|
+
var import_react37 = require("react");
|
1682
1727
|
|
1683
|
-
// src/
|
1728
|
+
// src/runtime/local/LocalRuntime.tsx
|
1684
1729
|
var LocalRuntime = class {
|
1685
1730
|
constructor(adapter) {
|
1686
1731
|
this.adapter = adapter;
|
1687
1732
|
}
|
1688
|
-
|
1689
|
-
_statusUpdateCallbacks = /* @__PURE__ */ new Set();
|
1733
|
+
_subscriptions = /* @__PURE__ */ new Set();
|
1690
1734
|
abortController = null;
|
1691
1735
|
repository = new MessageRepository();
|
1736
|
+
get messages() {
|
1737
|
+
return this.repository.getMessages();
|
1738
|
+
}
|
1739
|
+
get isRunning() {
|
1740
|
+
return this.abortController != null;
|
1741
|
+
}
|
1742
|
+
getBranches(messageId) {
|
1743
|
+
return this.repository.getBranches(messageId);
|
1744
|
+
}
|
1745
|
+
switchToBranch(branchId) {
|
1746
|
+
this.repository.switchToBranch(branchId);
|
1747
|
+
this.notifySubscribers();
|
1748
|
+
}
|
1692
1749
|
async append(message) {
|
1693
1750
|
const userMessageId = generateId();
|
1694
1751
|
const userMessage = {
|
@@ -1697,9 +1754,8 @@ var LocalRuntime = class {
|
|
1697
1754
|
content: message.content,
|
1698
1755
|
createdAt: /* @__PURE__ */ new Date()
|
1699
1756
|
};
|
1700
|
-
this.addOrUpdateMessage(message.parentId, userMessage);
|
1701
|
-
|
1702
|
-
return { parentId: userMessageId, id };
|
1757
|
+
this.repository.addOrUpdateMessage(message.parentId, userMessage);
|
1758
|
+
await this.startRun(userMessageId);
|
1703
1759
|
}
|
1704
1760
|
async startRun(parentId) {
|
1705
1761
|
const id = generateId();
|
@@ -1712,63 +1768,56 @@ var LocalRuntime = class {
|
|
1712
1768
|
content: [{ type: "text", text: "" }],
|
1713
1769
|
createdAt: /* @__PURE__ */ new Date()
|
1714
1770
|
};
|
1715
|
-
this.addOrUpdateMessage(parentId, message);
|
1716
|
-
|
1717
|
-
return { id };
|
1718
|
-
}
|
1719
|
-
addOrUpdateMessage(parentId, message) {
|
1720
|
-
const clone = { ...message };
|
1721
|
-
this.repository.addOrUpdateMessage(parentId, clone);
|
1722
|
-
for (const callback of this._messageUpdateCallbacks)
|
1723
|
-
callback(parentId, clone);
|
1724
|
-
}
|
1725
|
-
async run(parentId, messages, message) {
|
1726
|
-
this.cancelRun();
|
1727
|
-
for (const callback of this._statusUpdateCallbacks) callback(true);
|
1771
|
+
this.repository.addOrUpdateMessage(parentId, { ...message });
|
1772
|
+
this.abortController?.abort();
|
1728
1773
|
this.abortController = new AbortController();
|
1774
|
+
this.notifySubscribers();
|
1729
1775
|
try {
|
1730
1776
|
await this.adapter.run({
|
1731
1777
|
messages,
|
1732
1778
|
abortSignal: this.abortController.signal,
|
1733
1779
|
onUpdate: ({ content }) => {
|
1734
1780
|
message.content = content;
|
1735
|
-
this.addOrUpdateMessage(parentId, message);
|
1781
|
+
this.repository.addOrUpdateMessage(parentId, { ...message });
|
1782
|
+
this.notifySubscribers();
|
1736
1783
|
}
|
1737
1784
|
});
|
1738
1785
|
message.status = "done";
|
1739
|
-
this.addOrUpdateMessage(parentId, message);
|
1786
|
+
this.repository.addOrUpdateMessage(parentId, { ...message });
|
1740
1787
|
} catch (e) {
|
1741
1788
|
message.status = "error";
|
1742
|
-
this.addOrUpdateMessage(parentId, message);
|
1789
|
+
this.repository.addOrUpdateMessage(parentId, { ...message });
|
1743
1790
|
console.error(e);
|
1744
1791
|
} finally {
|
1745
|
-
this.
|
1792
|
+
this.abortController = null;
|
1793
|
+
this.notifySubscribers();
|
1746
1794
|
}
|
1747
1795
|
}
|
1748
1796
|
cancelRun() {
|
1749
1797
|
if (!this.abortController) return;
|
1750
1798
|
this.abortController.abort();
|
1751
1799
|
this.abortController = null;
|
1752
|
-
|
1800
|
+
this.notifySubscribers();
|
1753
1801
|
}
|
1754
|
-
|
1755
|
-
this.
|
1756
|
-
return () => this._messageUpdateCallbacks.delete(callback);
|
1802
|
+
notifySubscribers() {
|
1803
|
+
for (const callback of this._subscriptions) callback();
|
1757
1804
|
}
|
1758
|
-
|
1759
|
-
this.
|
1760
|
-
return () => this.
|
1805
|
+
subscribe(callback) {
|
1806
|
+
this._subscriptions.add(callback);
|
1807
|
+
return () => this._subscriptions.delete(callback);
|
1761
1808
|
}
|
1762
1809
|
};
|
1763
1810
|
|
1764
|
-
// src/
|
1811
|
+
// src/runtime/local/useLocalRuntime.tsx
|
1765
1812
|
var useLocalRuntime = (adapter) => {
|
1766
|
-
const [runtime] = (0,
|
1767
|
-
|
1813
|
+
const [runtime] = (0, import_react37.useState)(() => new LocalRuntime(adapter));
|
1814
|
+
(0, import_react37.useInsertionEffect)(() => {
|
1815
|
+
runtime.adapter = adapter;
|
1816
|
+
});
|
1768
1817
|
return runtime;
|
1769
1818
|
};
|
1770
1819
|
|
1771
|
-
// src/
|
1820
|
+
// src/runtime/local/vercel/VercelModelAdapter.tsx
|
1772
1821
|
var import_ai = require("ai");
|
1773
1822
|
var VercelModelAdapter = class {
|
1774
1823
|
constructor(model) {
|
@@ -1812,6 +1861,7 @@ var VercelModelAdapter = class {
|
|
1812
1861
|
// Annotate the CommonJS export names for ESM import in node:
|
1813
1862
|
0 && (module.exports = {
|
1814
1863
|
ActionBarPrimitive,
|
1864
|
+
AssistantRuntimeProvider,
|
1815
1865
|
BranchPickerPrimitive,
|
1816
1866
|
ComposerPrimitive,
|
1817
1867
|
ContentPartPrimitive,
|
@@ -1819,15 +1869,20 @@ var VercelModelAdapter = class {
|
|
1819
1869
|
ThreadPrimitive,
|
1820
1870
|
VercelAIAssistantProvider,
|
1821
1871
|
VercelRSCAssistantProvider,
|
1822
|
-
|
1872
|
+
getVercelAIMessage,
|
1873
|
+
getVercelRSCMessage,
|
1823
1874
|
unstable_VercelModelAdapter,
|
1824
|
-
|
1825
|
-
|
1875
|
+
unstable_useComposerContext,
|
1876
|
+
unstable_useContentPartContext,
|
1826
1877
|
unstable_useLocalRuntime,
|
1827
1878
|
unstable_useMessageContext,
|
1879
|
+
unstable_useThreadContext,
|
1828
1880
|
useBeginMessageEdit,
|
1829
1881
|
useCopyMessage,
|
1830
1882
|
useGoToNextBranch,
|
1831
1883
|
useGoToPreviousBranch,
|
1832
|
-
useReloadMessage
|
1884
|
+
useReloadMessage,
|
1885
|
+
useVercelRSCRuntime,
|
1886
|
+
useVercelUseAssistantRuntime,
|
1887
|
+
useVercelUseChatRuntime
|
1833
1888
|
});
|