@assistant-ui/react 0.0.20 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
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
- unstable_AssistantProvider: () => AssistantProvider,
42
+ getVercelAIMessage: () => getVercelAIMessage,
43
+ getVercelRSCMessage: () => getVercelRSCMessage,
42
44
  unstable_VercelModelAdapter: () => VercelModelAdapter,
43
- unstable_getVercelMessage: () => getVercelMessage,
44
- unstable_getVercelRSCMessage: () => getVercelRSCMessage,
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 import_react = require("react");
225
+ var import_react10 = require("react");
70
226
  var import_jsx_runtime = require("react/jsx-runtime");
71
- var ThreadRoot = (0, import_react.forwardRef)(
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 } = useAssistantContext();
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 import_react5 = require("react");
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 import_react3 = require("react");
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, import_react3.useEffect)(() => {
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 import_react4 = require("react");
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 } = useAssistantContext();
161
- (0, import_react4.useEffect)(() => {
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, import_react5.forwardRef)(({ autoScroll = true, onScroll, children, ...rest }, forwardedRef) => {
171
- const messagesEndRef = (0, import_react5.useRef)(null);
172
- const divRef = (0, import_react5.useRef)(null);
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 } = useAssistantContext();
175
- const firstRenderRef = (0, import_react5.useRef)(true);
176
- const isScrollingToBottomRef = (0, import_react5.useRef)(false);
177
- const lastScrollTop = (0, import_react5.useRef)(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/utils/context/useComposerContext.ts
223
- var import_react7 = require("react");
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/utils/context/getMessageText.tsx
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
- var makeMessageComposerStore = ({
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/primitives/message/MessageProvider.tsx
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 useMessageContext2 = () => {
339
- const { useThread } = useAssistantContext();
340
- const [context] = (0, import_react8.useState)(() => {
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 = makeMessageComposerStore({
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
- message,
390
- parentId,
482
+ messageIndex,
391
483
  children
392
484
  }) => {
393
- const { useThread } = useAssistantContext();
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/primitives/message/MessageRoot.tsx
409
- var import_primitive2 = require("@radix-ui/primitive");
410
- var import_react_primitive3 = require("@radix-ui/react-primitive");
411
- var import_react9 = require("react");
412
- var import_jsx_runtime5 = require("react/jsx-runtime");
413
- var MessageRoot = (0, import_react9.forwardRef)(
414
- ({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
415
- const { useMessage } = useMessageContext();
416
- const setIsHovering = useMessage((s) => s.setIsHovering);
417
- const handleMouseEnter = () => {
418
- setIsHovering(true);
419
- };
420
- const handleMouseLeave = () => {
421
- setIsHovering(false);
422
- };
423
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
424
- import_react_primitive3.Primitive.div,
425
- {
426
- ...rest,
427
- ref,
428
- onMouseEnter: (0, import_primitive2.composeEventHandlers)(onMouseEnter, handleMouseEnter),
429
- onMouseLeave: (0, import_primitive2.composeEventHandlers)(onMouseLeave, handleMouseLeave)
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 import_jsx_runtime9 = require("react/jsx-runtime");
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 } = useAssistantContext();
616
- const thread = useThread();
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 (messages.length === 0) return null;
620
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: messages.map((message, idx) => {
621
- const parentId = messages[idx - 1]?.id ?? null;
622
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
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
- message,
626
- parentId,
554
+ messageIndex,
627
555
  children: [
628
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(MessageIf, { user: true, children: [
629
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComposerIf, { editing: false, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(UserMessage, {}) }),
630
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComposerIf, { editing: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(EditComposer, {}) })
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, import_jsx_runtime9.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AssistantMessage, {}) })
560
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AssistantMessage, {}) })
633
561
  ]
634
562
  },
635
- parentId ?? "__ROOT__"
563
+ messageIndex
636
564
  );
637
565
  }) });
638
566
  };
639
567
 
640
568
  // src/primitives/thread/ThreadScrollToBottom.tsx
641
- var import_primitive3 = require("@radix-ui/primitive");
642
- var import_react_primitive5 = require("@radix-ui/react-primitive");
643
- var import_react15 = require("react");
644
- var import_jsx_runtime10 = require("react/jsx-runtime");
645
- var ThreadScrollToBottom = (0, import_react15.forwardRef)(({ onClick, ...rest }, ref) => {
646
- const { useViewport } = useAssistantContext();
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, import_jsx_runtime10.jsx)(
652
- import_react_primitive5.Primitive.button,
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, import_primitive3.composeEventHandlers)(onClick, handleScrollToBottom)
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 import_primitive4 = require("@radix-ui/primitive");
664
- var import_react_primitive6 = require("@radix-ui/react-primitive");
665
- var import_react16 = require("react");
666
- var import_jsx_runtime11 = require("react/jsx-runtime");
667
- var ThreadSuggestion = (0, import_react16.forwardRef)(({ onClick, prompt, method, autoSend: send, ...rest }, ref) => {
668
- const { useThread, useComposer } = useAssistantContext();
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, import_jsx_runtime11.jsx)(
679
- import_react_primitive6.Primitive.button,
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, import_primitive4.composeEventHandlers)(onClick, handleApplySuggestion)
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 import_primitive5 = require("@radix-ui/primitive");
628
+ var import_primitive4 = require("@radix-ui/primitive");
701
629
  var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
702
- var import_react_primitive7 = require("@radix-ui/react-primitive");
703
- var import_react17 = require("react");
704
- var import_jsx_runtime12 = require("react/jsx-runtime");
705
- var ComposerRoot = (0, import_react17.forwardRef)(
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 } = useAssistantContext();
635
+ const { useViewport } = useThreadContext();
708
636
  const { useComposer } = useComposerContext();
709
- const formRef = (0, import_react17.useRef)(null);
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, import_jsx_runtime12.jsx)(
719
- import_react_primitive7.Primitive.form,
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, import_primitive5.composeEventHandlers)(onSubmit, handleSubmit)
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 import_primitive6 = require("@radix-ui/primitive");
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 import_react18 = require("react");
661
+ var import_react19 = require("react");
734
662
  var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
735
- var import_jsx_runtime13 = require("react/jsx-runtime");
736
- var ComposerInput = (0, import_react18.forwardRef)(
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 } = useAssistantContext();
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, import_react18.useRef)(null);
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, import_react18.useCallback)(() => {
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, import_react18.useEffect)(() => focus(), [focus]);
701
+ (0, import_react19.useEffect)(() => focus(), [focus]);
774
702
  useOnScrollToBottom(() => {
775
- if (type === "assistant") {
703
+ if (type === "new") {
776
704
  focus();
777
705
  }
778
706
  });
779
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
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, import_primitive6.composeEventHandlers)(onChange, (e) => {
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, import_primitive6.composeEventHandlers)(onKeyDown, handleKeyPress)
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 import_react_primitive8 = require("@radix-ui/react-primitive");
799
- var import_react19 = require("react");
800
- var import_jsx_runtime14 = require("react/jsx-runtime");
801
- var ComposerSend = (0, import_react19.forwardRef)(
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, import_jsx_runtime14.jsx)(
806
- import_react_primitive8.Primitive.button,
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 import_primitive7 = require("@radix-ui/primitive");
819
- var import_react_primitive9 = require("@radix-ui/react-primitive");
820
- var import_react20 = require("react");
821
- var import_jsx_runtime15 = require("react/jsx-runtime");
822
- var ComposerCancel = (0, import_react20.forwardRef)(({ onClick, ...rest }, ref) => {
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, import_jsx_runtime15.jsx)(
828
- import_react_primitive9.Primitive.button,
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, import_primitive7.composeEventHandlers)(onClick, handleCancel)
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 import_react22 = require("react");
940
+ var import_react26 = require("react");
869
941
  var import_jsx_runtime16 = require("react/jsx-runtime");
870
942
  var createActionButton = (useActionButton) => {
871
- return (0, import_react22.forwardRef)(
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 import_react24 = require("react");
984
+ var import_react27 = require("react");
930
985
  var import_jsx_runtime19 = require("react/jsx-runtime");
931
- var BranchPickerRoot = (0, import_react24.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
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 import_react25 = require("react");
1001
+ var import_react28 = require("react");
947
1002
  var import_jsx_runtime20 = require("react/jsx-runtime");
948
- var ActionBarRoot = (0, import_react25.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
949
- const { useThread } = useAssistantContext();
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],
@@ -960,168 +1015,42 @@ var ActionBarRoot = (0, import_react25.forwardRef)(({ hideWhenRunning, autohide,
960
1015
  return "normal" /* Normal */;
961
1016
  }
962
1017
  );
963
- if (hideAndfloatStatus === "hidden" /* Hidden */) return null;
964
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
965
- import_react_primitive12.Primitive.div,
966
- {
967
- "data-floating": hideAndfloatStatus === "floating" /* Floating */,
968
- ...rest,
969
- ref
970
- }
971
- );
972
- });
973
-
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
- };
1018
+ if (hideAndfloatStatus === "hidden" /* Hidden */) return null;
1019
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1020
+ import_react_primitive12.Primitive.div,
1021
+ {
1022
+ "data-floating": hideAndfloatStatus === "floating" /* Floating */,
1023
+ ...rest,
1024
+ ref
1025
+ }
1026
+ );
1027
+ });
995
1028
 
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/adapters/vercel/VercelAIAssistantProvider.tsx
1047
- var import_react31 = require("react");
1048
-
1049
- // src/adapters/core/AssistantProvider.tsx
1050
- var import_react29 = require("react");
1051
- var import_zustand5 = require("zustand");
1044
+ // src/runtime/vercel-ai/rsc/useVercelRSCRuntime.tsx
1045
+ var import_react30 = require("react");
1052
1046
 
1053
- // src/utils/context/stores/ViewportStore.tsx
1047
+ // src/runtime/vercel-ai/rsc/VercelRSCRuntime.tsx
1054
1048
  var import_zustand4 = require("zustand");
1055
- var makeViewportStore = () => {
1056
- const scrollToBottomListeners = /* @__PURE__ */ new Set();
1057
- return (0, import_zustand4.create)(() => ({
1058
- isAtBottom: true,
1059
- scrollToBottom: () => {
1060
- for (const listener of scrollToBottomListeners) {
1061
- listener();
1062
- }
1063
- },
1064
- onScrollToBottom: (callback) => {
1065
- scrollToBottomListeners.add(callback);
1066
- return () => {
1067
- scrollToBottomListeners.delete(callback);
1068
- };
1069
- }
1070
- }));
1071
- };
1072
-
1073
- // src/adapters/core/AssistantProvider.tsx
1074
- var import_jsx_runtime21 = require("react/jsx-runtime");
1075
- var makeThreadStore = (runtimeRef) => {
1076
- const useThread = (0, import_zustand5.create)(() => ({
1077
- messages: runtimeRef.current.messages,
1078
- isRunning: runtimeRef.current.isRunning,
1079
- getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
1080
- switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
1081
- startRun: (parentId) => runtimeRef.current.startRun(parentId),
1082
- append: (message) => runtimeRef.current.append(message),
1083
- cancelRun: () => runtimeRef.current.cancelRun()
1084
- }));
1085
- const onRuntimeUpdate = () => {
1086
- useThread.setState({
1087
- messages: runtimeRef.current.messages,
1088
- isRunning: runtimeRef.current.isRunning
1089
- });
1090
- };
1091
- return {
1092
- useThread,
1093
- onRuntimeUpdate
1094
- };
1095
- };
1096
- var AssistantProvider = ({ children, runtime }) => {
1097
- const runtimeRef = (0, import_react29.useRef)(runtime);
1098
- (0, import_react29.useInsertionEffect)(() => {
1099
- runtimeRef.current = runtime;
1100
- });
1101
- const [{ context, onRuntimeUpdate }] = (0, import_react29.useState)(() => {
1102
- const { useThread, onRuntimeUpdate: onRuntimeUpdate2 } = makeThreadStore(runtimeRef);
1103
- const useViewport = makeViewportStore();
1104
- const useComposer = makeThreadComposerStore(useThread);
1105
- return {
1106
- context: {
1107
- useViewport,
1108
- useThread,
1109
- useComposer
1110
- },
1111
- onRuntimeUpdate: onRuntimeUpdate2
1112
- };
1113
- });
1114
- (0, import_react29.useEffect)(() => {
1115
- onRuntimeUpdate();
1116
- return runtime.subscribe(onRuntimeUpdate);
1117
- }, [onRuntimeUpdate, runtime]);
1118
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AssistantContext.Provider, { value: context, children });
1119
- };
1120
1049
 
1121
- // src/adapters/core/vercel-use-chat/useVercelUseChatRuntime.tsx
1122
- var import_react30 = require("react");
1050
+ // src/runtime/vercel-ai/rsc/useVercelRSCSync.tsx
1051
+ var import_react29 = require("react");
1123
1052
 
1124
- // src/adapters/ThreadMessageConverter.ts
1053
+ // src/runtime/vercel-ai/utils/ThreadMessageConverter.ts
1125
1054
  var ThreadMessageConverter = class {
1126
1055
  cache = /* @__PURE__ */ new WeakMap();
1127
1056
  convertMessages(converter, messages) {
@@ -1134,17 +1063,129 @@ var ThreadMessageConverter = class {
1134
1063
  }
1135
1064
  };
1136
1065
 
1137
- // src/adapters/vercel/VercelThreadMessage.tsx
1138
- var symbolInnerMessage = Symbol("innerMessage");
1139
- var symbolInnerRSCMessage = Symbol("innerRSCMessage");
1140
- var getVercelMessage = (message) => {
1141
- return message[symbolInnerMessage];
1142
- };
1066
+ // src/runtime/vercel-ai/rsc/getVercelRSCMessage.tsx
1067
+ var symbolInnerRSCMessage = Symbol("innerVercelRSCMessage");
1143
1068
  var getVercelRSCMessage = (message) => {
1144
1069
  return message[symbolInnerRSCMessage];
1145
1070
  };
1146
1071
 
1147
- // src/adapters/idUtils.tsx
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));
1134
+ }
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
+ };
1168
+ };
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;
1175
+ });
1176
+ (0, import_react30.useEffect)(() => {
1177
+ runtime.onAdapterUpdated();
1178
+ });
1179
+ return runtime;
1180
+ };
1181
+
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");
1187
+
1188
+ // src/runtime/utils/idUtils.tsx
1148
1189
  var import_non_secure = require("nanoid/non-secure");
1149
1190
  var generateId = (0, import_non_secure.customAlphabet)(
1150
1191
  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
@@ -1153,7 +1194,7 @@ var generateId = (0, import_non_secure.customAlphabet)(
1153
1194
  var optimisticPrefix = "__optimistic__";
1154
1195
  var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
1155
1196
 
1156
- // src/adapters/MessageRepository.tsx
1197
+ // src/runtime/utils/MessageRepository.tsx
1157
1198
  var findHead = (message) => {
1158
1199
  if (message.next) return findHead(message.next);
1159
1200
  return message;
@@ -1222,10 +1263,10 @@ var MessageRepository = class {
1222
1263
  level: prev ? prev.level + 1 : 0
1223
1264
  };
1224
1265
  this.messages.set(message.id, newItem);
1266
+ this.performOp(prev, newItem, "link");
1225
1267
  if (this.head === prev) {
1226
1268
  this.head = newItem;
1227
1269
  }
1228
- this.performOp(prev, newItem, "link");
1229
1270
  }
1230
1271
  appendOptimisticMessage(parentId, message) {
1231
1272
  let optimisticId;
@@ -1242,14 +1283,14 @@ var MessageRepository = class {
1242
1283
  }
1243
1284
  deleteMessage(messageId, replacementId) {
1244
1285
  const message = this.messages.get(messageId);
1245
- const replacement = replacementId ? this.messages.get(replacementId) : null;
1246
1286
  if (!message)
1247
1287
  throw new Error(
1248
1288
  "MessageRepository(deleteMessage): Optimistic message not found. This is likely an internal bug in assistant-ui."
1249
1289
  );
1290
+ const replacement = replacementId === void 0 ? message.prev : replacementId === null ? null : this.messages.get(replacementId);
1250
1291
  if (replacement === void 0)
1251
1292
  throw new Error(
1252
- "MessageRepository(deleteMessage): New message not found. This is likely an internal bug in assistant-ui."
1293
+ "MessageRepository(deleteMessage): Replacement not found. This is likely an internal bug in assistant-ui."
1253
1294
  );
1254
1295
  for (const child of message.children) {
1255
1296
  const childMessage = this.messages.get(child);
@@ -1259,11 +1300,11 @@ var MessageRepository = class {
1259
1300
  );
1260
1301
  this.performOp(replacement, childMessage, "relink");
1261
1302
  }
1303
+ this.performOp(null, message, "cut");
1262
1304
  this.messages.delete(messageId);
1263
1305
  if (this.head === message) {
1264
- this.head = replacement;
1306
+ this.head = replacement ? findHead(replacement) : null;
1265
1307
  }
1266
- this.performOp(null, message, "cut");
1267
1308
  }
1268
1309
  getBranches(messageId) {
1269
1310
  const message = this.messages.get(messageId);
@@ -1304,7 +1345,13 @@ var MessageRepository = class {
1304
1345
  }
1305
1346
  };
1306
1347
 
1307
- // src/adapters/core/vercel-use-chat/VercelUseChatRuntime.tsx
1348
+ // src/runtime/vercel-ai/ui/getVercelAIMessage.tsx
1349
+ var symbolInnerAIMessage = Symbol("innerVercelAIUIMessage");
1350
+ var getVercelAIMessage = (message) => {
1351
+ return message[symbolInnerAIMessage];
1352
+ };
1353
+
1354
+ // src/runtime/vercel-ai/ui/utils/sliceMessagesUntil.tsx
1308
1355
  var sliceMessagesUntil = (messages, messageId) => {
1309
1356
  if (messageId == null) return [];
1310
1357
  const messageIdx = messages.findIndex((m) => m.id === messageId);
@@ -1312,18 +1359,97 @@ var sliceMessagesUntil = (messages, messageId) => {
1312
1359
  throw new Error(
1313
1360
  "useVercelAIThreadState: Message not found. This is liekly an internal bug in assistant-ui."
1314
1361
  );
1315
- return messages.slice(0, messageIdx + 1);
1362
+ return messages.slice(0, messageIdx + 1);
1363
+ };
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]);
1375
+ };
1376
+
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) => {
1384
+ const common = {
1385
+ id: message.id,
1386
+ createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
1387
+ [symbolInnerAIMessage]: message
1388
+ };
1389
+ switch (message.role) {
1390
+ case "user":
1391
+ return {
1392
+ ...common,
1393
+ role: "user",
1394
+ content: [{ type: "text", text: message.content }]
1395
+ };
1396
+ case "assistant":
1397
+ return {
1398
+ ...common,
1399
+ role: "assistant",
1400
+ content: [
1401
+ ...message.content ? [{ type: "text", text: message.content }] : [],
1402
+ ...message.toolInvocations?.map(
1403
+ (t) => ({
1404
+ type: "tool-call",
1405
+ name: t.toolName,
1406
+ args: t.args,
1407
+ result: "result" in t ? t.result : void 0
1408
+ })
1409
+ ) ?? []
1410
+ ],
1411
+ status
1412
+ };
1413
+ default:
1414
+ throw new Error(
1415
+ `You have a message with an unsupported role. The role ${message.role} is not supported.`
1416
+ );
1417
+ }
1418
+ };
1419
+ var useVercelAIThreadSync = (vercel, updateData) => {
1420
+ const isRunning = getIsRunning(vercel);
1421
+ const converter = (0, import_react32.useMemo)(() => new ThreadMessageConverter(), []);
1422
+ (0, import_react32.useEffect)(() => {
1423
+ const lastMessageId = vercel.messages.at(-1)?.id;
1424
+ const convertCallback = (message, cache) => {
1425
+ const status = lastMessageId === message.id && isRunning ? "in_progress" : "done";
1426
+ if (cache && (cache.role === "user" || cache.status === status))
1427
+ return cache;
1428
+ return vercelToThreadMessage2(message, status);
1429
+ };
1430
+ const messages = converter.convertMessages(
1431
+ convertCallback,
1432
+ vercel.messages
1433
+ );
1434
+ updateData(isRunning, messages);
1435
+ }, [updateData, isRunning, vercel.messages, converter]);
1316
1436
  };
1437
+
1438
+ // src/runtime/vercel-ai/ui/VercelAIRuntime.tsx
1317
1439
  var hasUpcomingMessage = (isRunning, messages) => {
1318
1440
  return isRunning && messages[messages.length - 1]?.role !== "assistant";
1319
1441
  };
1320
- var VercelUseChatRuntime = class {
1442
+ var VercelAIRuntime = class {
1321
1443
  constructor(vercel) {
1322
1444
  this.vercel = vercel;
1445
+ this.useVercel = (0, import_zustand5.create)(() => ({
1446
+ vercel
1447
+ }));
1323
1448
  }
1324
1449
  _subscriptions = /* @__PURE__ */ new Set();
1325
1450
  repository = new MessageRepository();
1326
1451
  assistantOptimisticId = null;
1452
+ useVercel;
1327
1453
  messages = [];
1328
1454
  isRunning = false;
1329
1455
  getBranches(messageId) {
@@ -1331,9 +1457,7 @@ var VercelUseChatRuntime = class {
1331
1457
  }
1332
1458
  switchToBranch(branchId) {
1333
1459
  this.repository.switchToBranch(branchId);
1334
- this.vercel.setMessages(
1335
- this.repository.getMessages().map(getVercelMessage).filter((m) => m != null)
1336
- );
1460
+ this.updateVercelMessages(this.repository.getMessages());
1337
1461
  }
1338
1462
  async append(message) {
1339
1463
  if (message.content.length !== 1 || message.content[0]?.type !== "text")
@@ -1359,20 +1483,44 @@ var VercelUseChatRuntime = class {
1359
1483
  await reloadMaybe();
1360
1484
  }
1361
1485
  cancelRun() {
1362
- const lastMessage = this.vercel.messages.at(-1);
1486
+ const previousMessage = this.vercel.messages.at(-1);
1363
1487
  this.vercel.stop();
1364
- if (lastMessage?.role === "user") {
1365
- this.vercel.setInput(lastMessage.content);
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 });
1366
1514
  }
1367
1515
  }
1368
- updateData(isRunning, vm) {
1516
+ updateData = (isRunning, vm) => {
1369
1517
  for (let i = 0; i < vm.length; i++) {
1370
1518
  const message = vm[i];
1371
1519
  const parent = vm[i - 1];
1372
1520
  this.repository.addOrUpdateMessage(parent?.id ?? null, message);
1373
1521
  }
1374
1522
  if (this.assistantOptimisticId) {
1375
- this.repository.deleteMessage(this.assistantOptimisticId, null);
1523
+ this.repository.deleteMessage(this.assistantOptimisticId);
1376
1524
  this.assistantOptimisticId = null;
1377
1525
  }
1378
1526
  if (hasUpcomingMessage(isRunning, vm)) {
@@ -1390,211 +1538,194 @@ var VercelUseChatRuntime = class {
1390
1538
  this.messages = this.repository.getMessages();
1391
1539
  this.isRunning = isRunning;
1392
1540
  for (const callback of this._subscriptions) callback();
1393
- }
1394
- subscribe(callback) {
1395
- this._subscriptions.add(callback);
1396
- return () => this._subscriptions.delete(callback);
1397
- }
1398
- };
1399
-
1400
- // src/adapters/core/vercel-use-chat/useVercelUseChatRuntime.tsx
1401
- var getIsRunning = (vercel) => {
1402
- if ("isLoading" in vercel) return vercel.isLoading;
1403
- return vercel.status === "in_progress";
1404
- };
1405
- var vercelToThreadMessage = (message, status) => {
1406
- const common = {
1407
- id: message.id,
1408
- createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
1409
- [symbolInnerMessage]: message
1410
1541
  };
1411
- switch (message.role) {
1412
- case "user":
1413
- return {
1414
- ...common,
1415
- role: "user",
1416
- content: [{ type: "text", text: message.content }]
1417
- };
1418
- case "assistant":
1419
- return {
1420
- ...common,
1421
- role: "assistant",
1422
- content: [
1423
- ...message.content ? [{ type: "text", text: message.content }] : [],
1424
- ...message.toolInvocations?.map(
1425
- (t) => ({
1426
- type: "tool-call",
1427
- name: t.toolName,
1428
- args: t.args,
1429
- result: "result" in t ? t.result : void 0
1430
- })
1431
- ) ?? []
1432
- ],
1433
- status
1434
- };
1435
- default:
1436
- throw new Error(
1437
- `You have a message with an unsupported role. The role ${message.role} is not supported.`
1438
- );
1439
- }
1542
+ unstable_synchronizer = () => {
1543
+ const { vercel } = this.useVercel();
1544
+ useVercelAIThreadSync(vercel, this.updateData);
1545
+ useVercelAIComposerSync(vercel);
1546
+ return null;
1547
+ };
1440
1548
  };
1441
- var useVercelUseChatRuntime = (vercel) => {
1442
- const [runtime] = (0, import_react30.useState)(() => new VercelUseChatRuntime(vercel));
1443
- (0, import_react30.useInsertionEffect)(() => {
1444
- runtime.vercel = vercel;
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;
1555
+ });
1556
+ (0, import_react33.useEffect)(() => {
1557
+ runtime.onVercelUpdated();
1445
1558
  });
1446
- const isRunning = getIsRunning(vercel);
1447
- const converter = (0, import_react30.useMemo)(() => new ThreadMessageConverter(), []);
1448
- const messages = (0, import_react30.useMemo)(() => {
1449
- const lastMessageId = vercel.messages.at(-1)?.id;
1450
- const convertCallback = (message, cache) => {
1451
- const status = lastMessageId === message.id && isRunning ? "in_progress" : "done";
1452
- if (cache && (cache.role === "user" || cache.status === status))
1453
- return cache;
1454
- return vercelToThreadMessage(message, status);
1455
- };
1456
- return converter.convertMessages(convertCallback, vercel.messages);
1457
- }, [isRunning, vercel.messages, converter]);
1458
- (0, import_react30.useEffect)(() => {
1459
- runtime.updateData(isRunning, messages);
1460
- }, [runtime, isRunning, messages]);
1461
1559
  return runtime;
1462
1560
  };
1463
1561
 
1464
- // src/adapters/vercel/VercelAIAssistantProvider.tsx
1465
- var import_jsx_runtime22 = require("react/jsx-runtime");
1466
- var VercelAIAssistantProvider = ({
1467
- children,
1468
- ...rest
1469
- }) => {
1470
- const vercel = "chat" in rest ? rest.chat : rest.assistant;
1471
- const runtime = useVercelUseChatRuntime(vercel);
1472
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(AssistantProvider, { runtime, children: [
1473
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ComposerSync, { vercel }),
1474
- children
1475
- ] });
1476
- };
1477
- var ComposerSync = ({
1478
- vercel
1479
- }) => {
1480
- const { useComposer } = useAssistantContext();
1481
- (0, import_react31.useEffect)(() => {
1482
- useComposer.setState({
1483
- value: vercel.input,
1484
- setValue: vercel.setInput
1485
- });
1486
- }, [useComposer, vercel.input, vercel.setInput]);
1487
- return null;
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;
1568
+ });
1569
+ (0, import_react34.useEffect)(() => {
1570
+ runtime.onVercelUpdated();
1571
+ });
1572
+ return runtime;
1488
1573
  };
1489
1574
 
1490
- // src/adapters/core/vercel-rsc/useVercelRSCRuntime.tsx
1491
- var import_react32 = require("react");
1575
+ // src/context/providers/AssistantRuntimeProvider.tsx
1576
+ var import_react36 = require("react");
1492
1577
 
1493
- // src/adapters/core/vercel-rsc/VercelRSCRuntime.tsx
1494
- var EMPTY_BRANCHES = Object.freeze([]);
1495
- var VercelRSCRuntime = class {
1496
- constructor(adapter) {
1497
- this.adapter = adapter;
1498
- }
1499
- _subscriptions = /* @__PURE__ */ new Set();
1500
- isRunning = false;
1501
- messages = [];
1502
- withRunning = (callback) => {
1503
- this.isRunning = true;
1504
- return callback.finally(() => {
1505
- this.isRunning = false;
1506
- });
1507
- };
1508
- getBranches() {
1509
- return EMPTY_BRANCHES;
1510
- }
1511
- switchToBranch() {
1512
- throw new Error(
1513
- "Branch switching is not supported by VercelRSCAssistantProvider."
1514
- );
1515
- }
1516
- async append(message) {
1517
- if (message.parentId !== (this.messages.at(-1)?.id ?? null)) {
1518
- if (!this.adapter.edit)
1519
- throw new Error(
1520
- "Message editing is not enabled, please provide an edit callback to VercelRSCAssistantProvider."
1521
- );
1522
- await this.withRunning(this.adapter.edit(message));
1523
- } else {
1524
- await this.withRunning(this.adapter.append(message));
1525
- }
1526
- }
1527
- async startRun(parentId) {
1528
- if (!this.adapter.reload)
1529
- throw new Error(
1530
- "Message reloading is not enabled, please provide a reload callback to VercelRSCAssistantProvider."
1531
- );
1532
- await this.withRunning(this.adapter.reload(parentId));
1533
- }
1534
- cancelRun() {
1535
- if (process.env["NODE_ENV"] === "development") {
1536
- console.warn(
1537
- "Run cancellation is not supported by VercelRSCAssistantProvider."
1538
- );
1578
+ // src/context/providers/ThreadProvider.tsx
1579
+ var import_react35 = require("react");
1580
+
1581
+ // src/context/stores/Composer.ts
1582
+ var import_zustand6 = require("zustand");
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 }]
1593
+ });
1594
+ },
1595
+ cancel: () => {
1596
+ const thread = useThread.getState();
1597
+ if (!thread.isRunning) return false;
1598
+ useThread.getState().cancelRun();
1599
+ return true;
1539
1600
  }
1540
- }
1541
- updateData(messages) {
1542
- this.messages = messages;
1543
- for (const callback of this._subscriptions) callback();
1544
- }
1545
- subscribe(callback) {
1546
- this._subscriptions.add(callback);
1547
- return () => this._subscriptions.delete(callback);
1548
- }
1549
- };
1601
+ };
1602
+ });
1550
1603
 
1551
- // src/adapters/core/vercel-rsc/useVercelRSCRuntime.tsx
1552
- var vercelToThreadMessage2 = (converter, rawMessage) => {
1553
- const message = converter(rawMessage);
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),
1614
+ cancelRun: () => runtimeRef.current.cancelRun()
1615
+ }));
1616
+ const onRuntimeUpdate = () => {
1617
+ useThread.setState({
1618
+ messages: runtimeRef.current.messages,
1619
+ isRunning: runtimeRef.current.isRunning
1620
+ });
1621
+ };
1554
1622
  return {
1555
- id: message.id,
1556
- role: message.role,
1557
- content: [{ type: "ui", display: message.display }],
1558
- createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
1559
- ...{ status: "done" },
1560
- [symbolInnerRSCMessage]: rawMessage
1623
+ useThread,
1624
+ onRuntimeUpdate
1561
1625
  };
1562
1626
  };
1563
- var useVercelRSCRuntime = (adapter) => {
1564
- const [runtime] = (0, import_react32.useState)(() => new VercelRSCRuntime(adapter));
1565
- (0, import_react32.useInsertionEffect)(() => {
1566
- runtime.adapter = adapter;
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)(() => {
1656
+ runtimeRef.current = runtime;
1567
1657
  });
1568
- const [converter, convertCallback] = (0, import_react32.useMemo)(() => {
1569
- const rscConverter = adapter.convertMessage ?? ((m) => m);
1570
- const convertCallback2 = (m, cache) => {
1571
- if (cache) return cache;
1572
- return vercelToThreadMessage2(rscConverter, m);
1658
+ const [{ context, onRuntimeUpdate }] = (0, import_react35.useState)(() => {
1659
+ const { useThread, onRuntimeUpdate: onRuntimeUpdate2 } = makeThreadStore(runtimeRef);
1660
+ const useViewport = makeThreadViewportStore();
1661
+ const useComposer = makeComposerStore(useThread);
1662
+ return {
1663
+ context: {
1664
+ useViewport,
1665
+ useThread,
1666
+ useComposer
1667
+ },
1668
+ onRuntimeUpdate: onRuntimeUpdate2
1573
1669
  };
1574
- return [new ThreadMessageConverter(), convertCallback2];
1575
- }, [adapter.convertMessage]);
1576
- (0, import_react32.useEffect)(() => {
1577
- runtime.updateData(
1578
- converter.convertMessages(convertCallback, adapter.messages)
1579
- );
1580
- }, [runtime, converter, convertCallback, adapter.messages]);
1581
- return runtime;
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 });
1582
1686
  };
1687
+ var AssistantRuntimeProvider = (0, import_react36.memo)(AssistantRuntimeProviderImpl);
1583
1688
 
1584
- // src/adapters/vercel/VercelRSCAssistantProvider.tsx
1689
+ // src/runtime/vercel-deprecated/VercelAIAssistantProvider.tsx
1585
1690
  var import_jsx_runtime23 = require("react/jsx-runtime");
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 });
1713
+ };
1714
+
1715
+ // src/runtime/vercel-deprecated/VercelRSCAssistantProvider.tsx
1716
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1586
1717
  var VercelRSCAssistantProvider = ({
1587
1718
  children,
1588
1719
  ...adapter
1589
1720
  }) => {
1590
1721
  const runtime = useVercelRSCRuntime(adapter);
1591
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AssistantProvider, { runtime, children });
1722
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AssistantRuntimeProvider, { runtime, children });
1592
1723
  };
1593
1724
 
1594
- // src/adapters/core/local/useLocalRuntime.tsx
1595
- var import_react33 = require("react");
1725
+ // src/runtime/local/useLocalRuntime.tsx
1726
+ var import_react37 = require("react");
1596
1727
 
1597
- // src/adapters/core/local/LocalRuntime.tsx
1728
+ // src/runtime/local/LocalRuntime.tsx
1598
1729
  var LocalRuntime = class {
1599
1730
  constructor(adapter) {
1600
1731
  this.adapter = adapter;
@@ -1677,16 +1808,16 @@ var LocalRuntime = class {
1677
1808
  }
1678
1809
  };
1679
1810
 
1680
- // src/adapters/core/local/useLocalRuntime.tsx
1811
+ // src/runtime/local/useLocalRuntime.tsx
1681
1812
  var useLocalRuntime = (adapter) => {
1682
- const [runtime] = (0, import_react33.useState)(() => new LocalRuntime(adapter));
1683
- (0, import_react33.useInsertionEffect)(() => {
1813
+ const [runtime] = (0, import_react37.useState)(() => new LocalRuntime(adapter));
1814
+ (0, import_react37.useInsertionEffect)(() => {
1684
1815
  runtime.adapter = adapter;
1685
1816
  });
1686
1817
  return runtime;
1687
1818
  };
1688
1819
 
1689
- // src/adapters/core/local/vercel/VercelModelAdapter.tsx
1820
+ // src/runtime/local/vercel/VercelModelAdapter.tsx
1690
1821
  var import_ai = require("ai");
1691
1822
  var VercelModelAdapter = class {
1692
1823
  constructor(model) {
@@ -1730,6 +1861,7 @@ var VercelModelAdapter = class {
1730
1861
  // Annotate the CommonJS export names for ESM import in node:
1731
1862
  0 && (module.exports = {
1732
1863
  ActionBarPrimitive,
1864
+ AssistantRuntimeProvider,
1733
1865
  BranchPickerPrimitive,
1734
1866
  ComposerPrimitive,
1735
1867
  ContentPartPrimitive,
@@ -1737,15 +1869,20 @@ var VercelModelAdapter = class {
1737
1869
  ThreadPrimitive,
1738
1870
  VercelAIAssistantProvider,
1739
1871
  VercelRSCAssistantProvider,
1740
- unstable_AssistantProvider,
1872
+ getVercelAIMessage,
1873
+ getVercelRSCMessage,
1741
1874
  unstable_VercelModelAdapter,
1742
- unstable_getVercelMessage,
1743
- unstable_getVercelRSCMessage,
1875
+ unstable_useComposerContext,
1876
+ unstable_useContentPartContext,
1744
1877
  unstable_useLocalRuntime,
1745
1878
  unstable_useMessageContext,
1879
+ unstable_useThreadContext,
1746
1880
  useBeginMessageEdit,
1747
1881
  useCopyMessage,
1748
1882
  useGoToNextBranch,
1749
1883
  useGoToPreviousBranch,
1750
- useReloadMessage
1884
+ useReloadMessage,
1885
+ useVercelRSCRuntime,
1886
+ useVercelUseAssistantRuntime,
1887
+ useVercelUseChatRuntime
1751
1888
  });