@assistant-ui/react 0.0.15 → 0.0.17

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.js CHANGED
@@ -33,10 +33,13 @@ __export(src_exports, {
33
33
  ActionBarPrimitive: () => actionBar_exports,
34
34
  BranchPickerPrimitive: () => branchPicker_exports,
35
35
  ComposerPrimitive: () => composer_exports,
36
+ ContentPartPrimitive: () => contentPart_exports,
36
37
  MessagePrimitive: () => message_exports,
37
38
  ThreadPrimitive: () => thread_exports,
38
39
  VercelAIAssistantProvider: () => VercelAIAssistantProvider,
39
40
  VercelRSCAssistantProvider: () => VercelRSCAssistantProvider,
41
+ unstable_getVercelMessage: () => getVercelMessage,
42
+ unstable_getVercelRSCMessage: () => getVercelRSCMessage,
40
43
  unstable_useMessageContext: () => useMessageContext,
41
44
  useBeginMessageEdit: () => useBeginMessageEdit,
42
45
  useCopyMessage: () => useCopyMessage,
@@ -109,15 +112,15 @@ var import_react_primitive2 = require("@radix-ui/react-primitive");
109
112
  var import_react5 = require("react");
110
113
 
111
114
  // src/utils/hooks/useOnResizeContent.tsx
115
+ var import_react_use_callback_ref = require("@radix-ui/react-use-callback-ref");
112
116
  var import_react3 = require("react");
113
117
  var useOnResizeContent = (ref, callback) => {
114
- const callbackRef = (0, import_react3.useRef)(callback);
115
- callbackRef.current = callback;
116
- (0, import_react3.useLayoutEffect)(() => {
118
+ const callbackRef = (0, import_react_use_callback_ref.useCallbackRef)(callback);
119
+ (0, import_react3.useEffect)(() => {
117
120
  const el = ref.current;
118
121
  if (!el) return;
119
122
  const resizeObserver = new ResizeObserver(() => {
120
- callbackRef.current();
123
+ callbackRef();
121
124
  });
122
125
  const mutationObserver = new MutationObserver((mutations) => {
123
126
  for (const mutation of mutations) {
@@ -132,7 +135,7 @@ var useOnResizeContent = (ref, callback) => {
132
135
  }
133
136
  }
134
137
  }
135
- callbackRef.current();
138
+ callbackRef();
136
139
  });
137
140
  resizeObserver.observe(el);
138
141
  mutationObserver.observe(el, { childList: true });
@@ -143,20 +146,20 @@ var useOnResizeContent = (ref, callback) => {
143
146
  resizeObserver.disconnect();
144
147
  mutationObserver.disconnect();
145
148
  };
146
- }, [ref.current]);
149
+ }, [ref.current, callbackRef]);
147
150
  };
148
151
 
149
152
  // src/utils/hooks/useOnScrollToBottom.tsx
153
+ var import_react_use_callback_ref2 = require("@radix-ui/react-use-callback-ref");
150
154
  var import_react4 = require("react");
151
155
  var useOnScrollToBottom = (callback) => {
152
- const callbackRef = (0, import_react4.useRef)(callback);
153
- callbackRef.current = callback;
156
+ const callbackRef = (0, import_react_use_callback_ref2.useCallbackRef)(callback);
154
157
  const { useViewport } = useAssistantContext();
155
158
  (0, import_react4.useEffect)(() => {
156
159
  return useViewport.getState().onScrollToBottom(() => {
157
- callbackRef.current();
160
+ callbackRef();
158
161
  });
159
- }, [useViewport]);
162
+ }, [useViewport, callbackRef]);
160
163
  };
161
164
 
162
165
  // src/primitives/thread/ThreadViewport.tsx
@@ -217,7 +220,9 @@ var MessageContext = (0, import_react6.createContext)(null);
217
220
  var useMessageContext = () => {
218
221
  const context = (0, import_react6.useContext)(MessageContext);
219
222
  if (!context)
220
- throw new Error("This component must be used within a MessageProvider.");
223
+ throw new Error(
224
+ "This component must be used within a MessagePrimitive.Provider."
225
+ );
221
226
  return context;
222
227
  };
223
228
 
@@ -250,6 +255,7 @@ var message_exports = {};
250
255
  __export(message_exports, {
251
256
  Content: () => MessageContent,
252
257
  If: () => MessageIf,
258
+ InProgress: () => MessageInProgress,
253
259
  Provider: () => MessageProvider,
254
260
  Root: () => MessageRoot
255
261
  });
@@ -329,8 +335,12 @@ var useMessageContext2 = () => {
329
335
  parentId: null,
330
336
  branches: [],
331
337
  isLast: false,
338
+ inProgressIndicator: null,
332
339
  isCopied: false,
333
340
  isHovering: false,
341
+ setInProgressIndicator: (value) => {
342
+ set({ inProgressIndicator: value });
343
+ },
334
344
  setIsCopied: (value) => {
335
345
  set({ isCopied: value });
336
346
  },
@@ -432,10 +442,94 @@ var MessageIf = ({ children, ...query }) => {
432
442
  return result ? children : null;
433
443
  };
434
444
 
435
- // src/primitives/message/MessageContent.tsx
445
+ // src/utils/context/combined/useCombinedStore.ts
446
+ var import_react11 = require("react");
447
+
448
+ // src/utils/context/combined/createCombinedStore.ts
449
+ var import_react10 = require("react");
450
+ var createCombinedStore = (stores) => {
451
+ const subscribe = (callback) => {
452
+ const unsubscribes = stores.map((store) => store.subscribe(callback));
453
+ return () => {
454
+ for (const unsub of unsubscribes) {
455
+ unsub();
456
+ }
457
+ };
458
+ };
459
+ return (selector) => {
460
+ const getSnapshot = () => selector(...stores.map((store) => store.getState()));
461
+ return (0, import_react10.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
462
+ };
463
+ };
464
+
465
+ // src/utils/context/combined/useCombinedStore.ts
466
+ var useCombinedStore = (stores, selector) => {
467
+ const useCombined = (0, import_react11.useMemo)(() => createCombinedStore(stores), stores);
468
+ return useCombined(selector);
469
+ };
470
+
471
+ // src/utils/context/useContentPartContext.ts
472
+ var import_react12 = require("react");
473
+ var ContentPartContext = (0, import_react12.createContext)(null);
474
+ var useContentPartContext = () => {
475
+ const context = (0, import_react12.useContext)(ContentPartContext);
476
+ if (!context)
477
+ throw new Error(
478
+ "This component must be used within a ContentPartPrimitive.Provider."
479
+ );
480
+ return context;
481
+ };
482
+
483
+ // src/primitives/contentPart/ContentPartInProgressIndicator.tsx
484
+ var ContentPartInProgressIndicator = () => {
485
+ const { useMessage } = useMessageContext();
486
+ const { useContentPart } = useContentPartContext();
487
+ const indicator = useCombinedStore(
488
+ [useMessage, useContentPart],
489
+ (m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
490
+ );
491
+ return indicator;
492
+ };
493
+
494
+ // src/primitives/contentPart/ContentPartProvider.tsx
495
+ var import_react13 = require("react");
496
+ var import_zustand3 = require("zustand");
436
497
  var import_jsx_runtime6 = require("react/jsx-runtime");
498
+ var useContentPartContext2 = () => {
499
+ const [context] = (0, import_react13.useState)(() => {
500
+ const useContentPart = (0, import_zustand3.create)(() => ({
501
+ part: null,
502
+ status: "done"
503
+ }));
504
+ return { useContentPart };
505
+ });
506
+ return context;
507
+ };
508
+ var ContentPartProvider = ({
509
+ part,
510
+ status,
511
+ children
512
+ }) => {
513
+ const context = useContentPartContext2();
514
+ (0, import_react13.useMemo)(() => {
515
+ context.useContentPart.setState(
516
+ {
517
+ part,
518
+ status
519
+ },
520
+ true
521
+ );
522
+ }, [context, part, status]);
523
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ContentPartContext.Provider, { value: context, children });
524
+ };
525
+
526
+ // src/primitives/message/MessageContent.tsx
527
+ var import_jsx_runtime7 = require("react/jsx-runtime");
437
528
  var defaultComponents = {
438
- Text: ({ part }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: part.text }),
529
+ Text: ({ part }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
530
+ part.text,
531
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ContentPartInProgressIndicator, {})
532
+ ] }),
439
533
  Image: () => null,
440
534
  UI: ({ part }) => part.display,
441
535
  tools: {
@@ -451,28 +545,57 @@ var MessageContent = ({
451
545
  } = {}
452
546
  }) => {
453
547
  const { useMessage } = useMessageContext();
454
- const content = useMessage((s) => s.message.content);
455
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: content.map((part, i) => {
548
+ const message = useMessage((s) => s.message);
549
+ const content = message.content;
550
+ const status = message.role === "assistant" ? message.status : "done";
551
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: content.map((part, i) => {
456
552
  const key = i;
457
- switch (part.type) {
553
+ const type = part.type;
554
+ let component = null;
555
+ switch (type) {
458
556
  case "text":
459
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { part }, key);
557
+ component = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { part });
558
+ break;
460
559
  case "image":
461
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Image, { part }, key);
560
+ component = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Image, { part });
561
+ break;
462
562
  case "ui":
463
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(UI, { part }, key);
563
+ component = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(UI, { part });
564
+ break;
464
565
  case "tool-call": {
465
566
  const Tool = by_name[part.name] || Fallback;
466
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Tool, { part }, key);
567
+ component = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Tool, { part });
568
+ break;
467
569
  }
468
570
  default:
469
- return null;
571
+ throw new Error(`Unknown content part type: ${type}`);
470
572
  }
573
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
574
+ ContentPartProvider,
575
+ {
576
+ part,
577
+ status: i === content.length - 1 ? status : "done",
578
+ children: component
579
+ },
580
+ key
581
+ );
471
582
  }) });
472
583
  };
473
584
 
585
+ // src/primitives/message/MessageInProgress.tsx
586
+ var import_react_primitive4 = require("@radix-ui/react-primitive");
587
+ var import_react14 = require("react");
588
+ var import_jsx_runtime8 = require("react/jsx-runtime");
589
+ var MessageInProgress = (0, import_react14.forwardRef)((props, ref) => {
590
+ const { useMessage } = useMessageContext();
591
+ (0, import_react14.useMemo)(() => {
592
+ useMessage.getState().setInProgressIndicator(/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_primitive4.Primitive.div, { ...props, ref }));
593
+ }, [useMessage, props, ref]);
594
+ return null;
595
+ });
596
+
474
597
  // src/primitives/thread/ThreadMessages.tsx
475
- var import_jsx_runtime7 = require("react/jsx-runtime");
598
+ var import_jsx_runtime9 = require("react/jsx-runtime");
476
599
  var getComponents = (components) => {
477
600
  return {
478
601
  EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
@@ -486,19 +609,19 @@ var ThreadMessages = ({ components }) => {
486
609
  const messages = thread.messages;
487
610
  const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
488
611
  if (messages.length === 0) return null;
489
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: messages.map((message, idx) => {
612
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: messages.map((message, idx) => {
490
613
  const parentId = messages[idx - 1]?.id ?? null;
491
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
614
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
492
615
  MessageProvider,
493
616
  {
494
617
  message,
495
618
  parentId,
496
619
  children: [
497
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(MessageIf, { user: true, children: [
498
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ComposerIf, { editing: false, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(UserMessage, {}) }),
499
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ComposerIf, { editing: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(EditComposer, {}) })
620
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(MessageIf, { user: true, children: [
621
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComposerIf, { editing: false, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(UserMessage, {}) }),
622
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ComposerIf, { editing: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(EditComposer, {}) })
500
623
  ] }),
501
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AssistantMessage, {}) })
624
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AssistantMessage, {}) })
502
625
  ]
503
626
  },
504
627
  parentId ?? "__ROOT__"
@@ -508,17 +631,17 @@ var ThreadMessages = ({ components }) => {
508
631
 
509
632
  // src/primitives/thread/ThreadScrollToBottom.tsx
510
633
  var import_primitive3 = require("@radix-ui/primitive");
511
- var import_react_primitive4 = require("@radix-ui/react-primitive");
512
- var import_react10 = require("react");
513
- var import_jsx_runtime8 = require("react/jsx-runtime");
514
- var ThreadScrollToBottom = (0, import_react10.forwardRef)(({ onClick, ...rest }, ref) => {
634
+ var import_react_primitive5 = require("@radix-ui/react-primitive");
635
+ var import_react15 = require("react");
636
+ var import_jsx_runtime10 = require("react/jsx-runtime");
637
+ var ThreadScrollToBottom = (0, import_react15.forwardRef)(({ onClick, ...rest }, ref) => {
515
638
  const { useViewport } = useAssistantContext();
516
639
  const isAtBottom = useViewport((s) => s.isAtBottom);
517
640
  const handleScrollToBottom = () => {
518
641
  useViewport.getState().scrollToBottom();
519
642
  };
520
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
521
- import_react_primitive4.Primitive.button,
643
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
644
+ import_react_primitive5.Primitive.button,
522
645
  {
523
646
  ...rest,
524
647
  disabled: isAtBottom,
@@ -530,10 +653,10 @@ var ThreadScrollToBottom = (0, import_react10.forwardRef)(({ onClick, ...rest },
530
653
 
531
654
  // src/primitives/thread/ThreadSuggestion.tsx
532
655
  var import_primitive4 = require("@radix-ui/primitive");
533
- var import_react_primitive5 = require("@radix-ui/react-primitive");
534
- var import_react11 = require("react");
535
- var import_jsx_runtime9 = require("react/jsx-runtime");
536
- var ThreadSuggestion = (0, import_react11.forwardRef)(({ onClick, prompt, method, autoSend: send, ...rest }, ref) => {
656
+ var import_react_primitive6 = require("@radix-ui/react-primitive");
657
+ var import_react16 = require("react");
658
+ var import_jsx_runtime11 = require("react/jsx-runtime");
659
+ var ThreadSuggestion = (0, import_react16.forwardRef)(({ onClick, prompt, method, autoSend: send, ...rest }, ref) => {
537
660
  const { useThread, useComposer } = useAssistantContext();
538
661
  const isDisabled = useThread((t) => t.isRunning);
539
662
  const handleApplySuggestion = () => {
@@ -544,8 +667,8 @@ var ThreadSuggestion = (0, import_react11.forwardRef)(({ onClick, prompt, method
544
667
  composer.send();
545
668
  }
546
669
  };
547
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
548
- import_react_primitive5.Primitive.button,
670
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
671
+ import_react_primitive6.Primitive.button,
549
672
  {
550
673
  ...rest,
551
674
  disabled: isDisabled,
@@ -568,14 +691,14 @@ __export(composer_exports, {
568
691
  // src/primitives/composer/ComposerRoot.tsx
569
692
  var import_primitive5 = require("@radix-ui/primitive");
570
693
  var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
571
- var import_react_primitive6 = require("@radix-ui/react-primitive");
572
- var import_react12 = require("react");
573
- var import_jsx_runtime10 = require("react/jsx-runtime");
574
- var ComposerRoot = (0, import_react12.forwardRef)(
694
+ var import_react_primitive7 = require("@radix-ui/react-primitive");
695
+ var import_react17 = require("react");
696
+ var import_jsx_runtime12 = require("react/jsx-runtime");
697
+ var ComposerRoot = (0, import_react17.forwardRef)(
575
698
  ({ onSubmit, ...rest }, forwardedRef) => {
576
699
  const { useViewport } = useAssistantContext();
577
700
  const { useComposer } = useComposerContext();
578
- const formRef = (0, import_react12.useRef)(null);
701
+ const formRef = (0, import_react17.useRef)(null);
579
702
  const ref = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, formRef);
580
703
  const handleSubmit = (e) => {
581
704
  const composerState = useComposer.getState();
@@ -584,8 +707,8 @@ var ComposerRoot = (0, import_react12.forwardRef)(
584
707
  composerState.send();
585
708
  useViewport.getState().scrollToBottom();
586
709
  };
587
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
588
- import_react_primitive6.Primitive.form,
710
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
711
+ import_react_primitive7.Primitive.form,
589
712
  {
590
713
  ...rest,
591
714
  ref,
@@ -599,10 +722,10 @@ var ComposerRoot = (0, import_react12.forwardRef)(
599
722
  var import_primitive6 = require("@radix-ui/primitive");
600
723
  var import_react_compose_refs3 = require("@radix-ui/react-compose-refs");
601
724
  var import_react_slot = require("@radix-ui/react-slot");
602
- var import_react13 = require("react");
725
+ var import_react18 = require("react");
603
726
  var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
604
- var import_jsx_runtime11 = require("react/jsx-runtime");
605
- var ComposerInput = (0, import_react13.forwardRef)(
727
+ var import_jsx_runtime13 = require("react/jsx-runtime");
728
+ var ComposerInput = (0, import_react18.forwardRef)(
606
729
  ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
607
730
  const { useThread, useViewport } = useAssistantContext();
608
731
  const { useComposer, type } = useComposerContext();
@@ -627,10 +750,10 @@ var ComposerInput = (0, import_react13.forwardRef)(
627
750
  }
628
751
  }
629
752
  };
630
- const textareaRef = (0, import_react13.useRef)(null);
753
+ const textareaRef = (0, import_react18.useRef)(null);
631
754
  const ref = (0, import_react_compose_refs3.useComposedRefs)(forwardedRef, textareaRef);
632
755
  const autoFocusEnabled = autoFocus && !disabled;
633
- const focus = (0, import_react13.useCallback)(() => {
756
+ const focus = (0, import_react18.useCallback)(() => {
634
757
  const textarea = textareaRef.current;
635
758
  if (!textarea || !autoFocusEnabled) return;
636
759
  textarea.focus();
@@ -639,13 +762,13 @@ var ComposerInput = (0, import_react13.forwardRef)(
639
762
  textareaRef.current.value.length
640
763
  );
641
764
  }, [autoFocusEnabled]);
642
- (0, import_react13.useEffect)(() => focus(), [focus]);
765
+ (0, import_react18.useEffect)(() => focus(), [focus]);
643
766
  useOnScrollToBottom(() => {
644
767
  if (type === "assistant") {
645
768
  focus();
646
769
  }
647
770
  });
648
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
771
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
649
772
  Component,
650
773
  {
651
774
  value,
@@ -664,15 +787,15 @@ var ComposerInput = (0, import_react13.forwardRef)(
664
787
  );
665
788
 
666
789
  // src/primitives/composer/ComposerSend.tsx
667
- var import_react_primitive7 = require("@radix-ui/react-primitive");
668
- var import_react14 = require("react");
669
- var import_jsx_runtime12 = require("react/jsx-runtime");
670
- var ComposerSend = (0, import_react14.forwardRef)(
790
+ var import_react_primitive8 = require("@radix-ui/react-primitive");
791
+ var import_react19 = require("react");
792
+ var import_jsx_runtime14 = require("react/jsx-runtime");
793
+ var ComposerSend = (0, import_react19.forwardRef)(
671
794
  ({ disabled, ...rest }, ref) => {
672
795
  const { useComposer } = useComposerContext();
673
796
  const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
674
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
675
- import_react_primitive7.Primitive.button,
797
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
798
+ import_react_primitive8.Primitive.button,
676
799
  {
677
800
  type: "submit",
678
801
  ...rest,
@@ -685,16 +808,16 @@ var ComposerSend = (0, import_react14.forwardRef)(
685
808
 
686
809
  // src/primitives/composer/ComposerCancel.tsx
687
810
  var import_primitive7 = require("@radix-ui/primitive");
688
- var import_react_primitive8 = require("@radix-ui/react-primitive");
689
- var import_react15 = require("react");
690
- var import_jsx_runtime13 = require("react/jsx-runtime");
691
- var ComposerCancel = (0, import_react15.forwardRef)(({ onClick, ...rest }, ref) => {
811
+ var import_react_primitive9 = require("@radix-ui/react-primitive");
812
+ var import_react20 = require("react");
813
+ var import_jsx_runtime15 = require("react/jsx-runtime");
814
+ var ComposerCancel = (0, import_react20.forwardRef)(({ onClick, ...rest }, ref) => {
692
815
  const { useComposer } = useComposerContext();
693
816
  const handleCancel = () => {
694
817
  useComposer.getState().cancel();
695
818
  };
696
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
697
- import_react_primitive8.Primitive.button,
819
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
820
+ import_react_primitive9.Primitive.button,
698
821
  {
699
822
  type: "button",
700
823
  ...rest,
@@ -714,32 +837,6 @@ __export(branchPicker_exports, {
714
837
  Root: () => BranchPickerRoot
715
838
  });
716
839
 
717
- // src/utils/context/combined/useCombinedStore.ts
718
- var import_react17 = require("react");
719
-
720
- // src/utils/context/combined/createCombinedStore.ts
721
- var import_react16 = require("react");
722
- var createCombinedStore = (stores) => {
723
- const subscribe = (callback) => {
724
- const unsubscribes = stores.map((store) => store.subscribe(callback));
725
- return () => {
726
- for (const unsub of unsubscribes) {
727
- unsub();
728
- }
729
- };
730
- };
731
- return (selector) => {
732
- const getSnapshot = () => selector(...stores.map((store) => store.getState()));
733
- return (0, import_react16.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
734
- };
735
- };
736
-
737
- // src/utils/context/combined/useCombinedStore.ts
738
- var useCombinedStore = (stores, selector) => {
739
- const useCombined = (0, import_react17.useMemo)(() => createCombinedStore(stores), stores);
740
- return useCombined(selector);
741
- };
742
-
743
840
  // src/actions/useGoToNextBranch.tsx
744
841
  var useGoToNextBranch = () => {
745
842
  const { useThread } = useAssistantContext();
@@ -757,15 +854,15 @@ var useGoToNextBranch = () => {
757
854
 
758
855
  // src/utils/createActionButton.tsx
759
856
  var import_primitive8 = require("@radix-ui/primitive");
760
- var import_react_primitive9 = require("@radix-ui/react-primitive");
761
- var import_react18 = require("react");
762
- var import_jsx_runtime14 = require("react/jsx-runtime");
857
+ var import_react_primitive10 = require("@radix-ui/react-primitive");
858
+ var import_react21 = require("react");
859
+ var import_jsx_runtime16 = require("react/jsx-runtime");
763
860
  var createActionButton = (useActionButton) => {
764
- return (0, import_react18.forwardRef)(
861
+ return (0, import_react21.forwardRef)(
765
862
  (props, forwardedRef) => {
766
863
  const onClick = useActionButton(props);
767
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
768
- import_react_primitive9.Primitive.button,
864
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
865
+ import_react_primitive10.Primitive.button,
769
866
  {
770
867
  type: "button",
771
868
  disabled: !onClick,
@@ -794,7 +891,6 @@ var useGoToPreviousBranch = () => {
794
891
  const { message, branches } = useMessage.getState();
795
892
  useThread.getState().switchToBranch(
796
893
  branches[branches.indexOf(message.id) - 1]
797
- // TODO probably there's a more elegant way to do this
798
894
  );
799
895
  };
800
896
  };
@@ -803,27 +899,27 @@ var useGoToPreviousBranch = () => {
803
899
  var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
804
900
 
805
901
  // src/primitives/branchPicker/BranchPickerCount.tsx
806
- var import_jsx_runtime15 = require("react/jsx-runtime");
902
+ var import_jsx_runtime17 = require("react/jsx-runtime");
807
903
  var BranchPickerCount = () => {
808
904
  const { useMessage } = useMessageContext();
809
905
  const branchCount = useMessage((s) => s.branches.length);
810
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children: branchCount });
906
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children: branchCount });
811
907
  };
812
908
 
813
909
  // src/primitives/branchPicker/BranchPickerNumber.tsx
814
- var import_jsx_runtime16 = require("react/jsx-runtime");
910
+ var import_jsx_runtime18 = require("react/jsx-runtime");
815
911
  var BranchPickerNumber = () => {
816
912
  const { useMessage } = useMessageContext();
817
913
  const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
818
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: branchIdx + 1 });
914
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: branchIdx + 1 });
819
915
  };
820
916
 
821
917
  // src/primitives/branchPicker/BranchPickerRoot.tsx
822
- var import_react_primitive10 = require("@radix-ui/react-primitive");
823
- var import_react19 = require("react");
824
- var import_jsx_runtime17 = require("react/jsx-runtime");
825
- var BranchPickerRoot = (0, import_react19.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
826
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_primitive10.Primitive.div, { ...rest, ref }) });
918
+ var import_react_primitive11 = require("@radix-ui/react-primitive");
919
+ var import_react22 = require("react");
920
+ var import_jsx_runtime19 = require("react/jsx-runtime");
921
+ var BranchPickerRoot = (0, import_react22.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
922
+ 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 }) });
827
923
  });
828
924
 
829
925
  // src/primitives/actionBar/index.ts
@@ -836,10 +932,10 @@ __export(actionBar_exports, {
836
932
  });
837
933
 
838
934
  // src/primitives/actionBar/ActionBarRoot.tsx
839
- var import_react_primitive11 = require("@radix-ui/react-primitive");
840
- var import_react20 = require("react");
841
- var import_jsx_runtime18 = require("react/jsx-runtime");
842
- var ActionBarRoot = (0, import_react20.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
935
+ var import_react_primitive12 = require("@radix-ui/react-primitive");
936
+ var import_react23 = require("react");
937
+ var import_jsx_runtime20 = require("react/jsx-runtime");
938
+ var ActionBarRoot = (0, import_react23.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
843
939
  const { useThread } = useAssistantContext();
844
940
  const { useMessage } = useMessageContext();
845
941
  const hideAndfloatStatus = useCombinedStore(
@@ -855,8 +951,8 @@ var ActionBarRoot = (0, import_react20.forwardRef)(({ hideWhenRunning, autohide,
855
951
  }
856
952
  );
857
953
  if (hideAndfloatStatus === "hidden" /* Hidden */) return null;
858
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
859
- import_react_primitive11.Primitive.div,
954
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
955
+ import_react_primitive12.Primitive.div,
860
956
  {
861
957
  "data-floating": hideAndfloatStatus === "floating" /* Floating */,
862
958
  ...rest,
@@ -924,18 +1020,25 @@ var useBeginMessageEdit = () => {
924
1020
  // src/primitives/actionBar/ActionBarEdit.tsx
925
1021
  var ActionBarEdit = createActionButton(useBeginMessageEdit);
926
1022
 
1023
+ // src/primitives/contentPart/index.ts
1024
+ var contentPart_exports = {};
1025
+ __export(contentPart_exports, {
1026
+ InProgressIndicator: () => ContentPartInProgressIndicator,
1027
+ Provider: () => ContentPartProvider
1028
+ });
1029
+
927
1030
  // src/adapters/vercel/VercelAIAssistantProvider.tsx
928
- var import_react23 = require("react");
1031
+ var import_react26 = require("react");
929
1032
 
930
1033
  // src/adapters/vercel/useDummyAIAssistantContext.tsx
931
- var import_react21 = require("react");
932
- var import_zustand4 = require("zustand");
1034
+ var import_react24 = require("react");
1035
+ var import_zustand5 = require("zustand");
933
1036
 
934
1037
  // src/utils/context/stores/ViewportStore.tsx
935
- var import_zustand3 = require("zustand");
1038
+ var import_zustand4 = require("zustand");
936
1039
  var makeViewportStore = () => {
937
1040
  const scrollToBottomListeners = /* @__PURE__ */ new Set();
938
- return (0, import_zustand3.create)(() => ({
1041
+ return (0, import_zustand4.create)(() => ({
939
1042
  isAtBottom: true,
940
1043
  scrollToBottom: () => {
941
1044
  for (const listener of scrollToBottomListeners) {
@@ -953,7 +1056,7 @@ var makeViewportStore = () => {
953
1056
 
954
1057
  // src/adapters/vercel/useDummyAIAssistantContext.tsx
955
1058
  var makeDummyThreadStore = () => {
956
- return (0, import_zustand4.create)(() => ({
1059
+ return (0, import_zustand5.create)(() => ({
957
1060
  messages: [],
958
1061
  isRunning: false,
959
1062
  getBranches: () => {
@@ -974,7 +1077,7 @@ var makeDummyThreadStore = () => {
974
1077
  }));
975
1078
  };
976
1079
  var useDummyAIAssistantContext = () => {
977
- const [context] = (0, import_react21.useState)(() => {
1080
+ const [context] = (0, import_react24.useState)(() => {
978
1081
  const useThread = makeDummyThreadStore();
979
1082
  const useViewport = makeViewportStore();
980
1083
  const useComposer = makeThreadComposerStore(useThread);
@@ -984,7 +1087,8 @@ var useDummyAIAssistantContext = () => {
984
1087
  };
985
1088
 
986
1089
  // src/adapters/vercel/useVercelAIThreadState.tsx
987
- var import_react22 = require("react");
1090
+ var import_react_use_callback_ref3 = require("@radix-ui/react-use-callback-ref");
1091
+ var import_react25 = require("react");
988
1092
 
989
1093
  // src/adapters/MessageRepository.tsx
990
1094
  var import_non_secure = require("nanoid/non-secure");
@@ -994,7 +1098,6 @@ var generateId = (0, import_non_secure.customAlphabet)(
994
1098
  );
995
1099
  var optimisticPrefix = "__optimistic__";
996
1100
  var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
997
- var isOptimisticId = (id) => id.startsWith(optimisticPrefix);
998
1101
  var findHead = (message) => {
999
1102
  if (message.next) return findHead(message.next);
1000
1103
  return message;
@@ -1003,7 +1106,41 @@ var MessageRepository = class {
1003
1106
  messages = /* @__PURE__ */ new Map();
1004
1107
  // message_id -> item
1005
1108
  head = null;
1006
- rootChildren = [];
1109
+ root = {
1110
+ children: []
1111
+ };
1112
+ getFallbackChild(p) {
1113
+ const childId = p.children.at(-1);
1114
+ const child = childId ? this.messages.get(childId) : null;
1115
+ if (child === void 0)
1116
+ throw new Error(
1117
+ "MessageRepository(getFallbackChild): Child message not found. This is likely an internal bug in assistant-ui."
1118
+ );
1119
+ return child;
1120
+ }
1121
+ performOp(newParent, child, operation) {
1122
+ const parentOrRoot = child.prev ?? this.root;
1123
+ const newParentOrRoot = newParent ?? this.root;
1124
+ if (operation === "relink" && parentOrRoot === newParentOrRoot) return;
1125
+ if (operation !== "link") {
1126
+ parentOrRoot.children = parentOrRoot.children.filter(
1127
+ (m) => m !== child.current.id
1128
+ );
1129
+ if (child.prev?.next === child) {
1130
+ child.prev.next = this.getFallbackChild(child.prev);
1131
+ }
1132
+ }
1133
+ if (operation !== "cut") {
1134
+ newParentOrRoot.children = [
1135
+ ...newParentOrRoot.children,
1136
+ child.current.id
1137
+ ];
1138
+ if (newParent && (findHead(child) === this.head || newParent.next === null)) {
1139
+ newParent.next = child;
1140
+ }
1141
+ child.prev = newParent;
1142
+ }
1143
+ }
1007
1144
  getMessages() {
1008
1145
  const messages = new Array(this.head?.level ?? 0);
1009
1146
  for (let current = this.head; current; current = current.prev) {
@@ -1012,20 +1149,17 @@ var MessageRepository = class {
1012
1149
  return messages;
1013
1150
  }
1014
1151
  addOrUpdateMessage(parentId, message) {
1015
- const item = this.messages.get(message.id);
1016
- if (item) {
1017
- if ((item.prev?.current.id ?? null) !== parentId) {
1018
- this.deleteMessage(message.id);
1019
- } else {
1020
- item.current = message;
1021
- return;
1022
- }
1023
- }
1152
+ const existingItem = this.messages.get(message.id);
1024
1153
  const prev = parentId ? this.messages.get(parentId) : null;
1025
1154
  if (prev === void 0)
1026
1155
  throw new Error(
1027
1156
  "MessageRepository(addOrUpdateMessage): Parent message not found. This is likely an internal bug in assistant-ui."
1028
1157
  );
1158
+ if (existingItem) {
1159
+ existingItem.current = message;
1160
+ this.performOp(prev, existingItem, "relink");
1161
+ return;
1162
+ }
1029
1163
  const newItem = {
1030
1164
  prev,
1031
1165
  current: message,
@@ -1034,80 +1168,57 @@ var MessageRepository = class {
1034
1168
  level: prev ? prev.level + 1 : 0
1035
1169
  };
1036
1170
  this.messages.set(message.id, newItem);
1037
- if (prev) {
1038
- prev.children = [...prev.children, message.id];
1039
- prev.next = newItem;
1040
- } else {
1041
- this.rootChildren = [...this.rootChildren, message.id];
1042
- }
1043
1171
  if (this.head === prev) {
1044
1172
  this.head = newItem;
1045
1173
  }
1174
+ this.performOp(prev, newItem, "link");
1046
1175
  }
1047
- deleteMessage(messageId) {
1048
- const message = this.messages.get(messageId);
1049
- if (!message)
1050
- throw new Error(
1051
- "MessageRepository(deleteMessage): Message not found. This is likely an internal bug in assistant-ui."
1052
- );
1053
- if (message.children.length > 0) {
1054
- for (const child of message.children) {
1055
- this.deleteMessage(child);
1056
- }
1057
- }
1058
- this.messages.delete(messageId);
1059
- if (message.prev) {
1060
- message.prev.children = message.prev.children.filter(
1061
- (m) => m !== messageId
1062
- );
1063
- if (message.prev.next === message) {
1064
- const childId = message.prev.children.at(-1);
1065
- const child = childId ? this.messages.get(childId) : null;
1066
- if (child === void 0)
1067
- throw new Error(
1068
- "MessageRepository(deleteMessage): Child message not found. This is likely an internal bug in assistant-ui."
1069
- );
1070
- message.prev.next = child;
1071
- }
1072
- } else {
1073
- this.rootChildren = this.rootChildren.filter((m) => m !== messageId);
1074
- }
1075
- if (this.head === message) {
1076
- this.head = message.prev ? findHead(message.prev) : null;
1077
- }
1078
- }
1079
- getOptimisticId() {
1176
+ appendOptimisticMessage(parentId, message) {
1080
1177
  let optimisticId;
1081
1178
  do {
1082
1179
  optimisticId = generateOptimisticId();
1083
1180
  } while (this.messages.has(optimisticId));
1084
- return optimisticId;
1085
- }
1086
- commitOptimisticRun(parentId) {
1087
- const optimisticId = this.getOptimisticId();
1088
1181
  this.addOrUpdateMessage(parentId, {
1182
+ ...message,
1089
1183
  id: optimisticId,
1090
- role: "assistant",
1091
- content: [
1092
- {
1093
- type: "text",
1094
- text: ""
1095
- }
1096
- ],
1097
- createdAt: /* @__PURE__ */ new Date()
1184
+ createdAt: /* @__PURE__ */ new Date(),
1185
+ ...message.role === "assistant" ? { status: "in_progress" } : void 0
1098
1186
  });
1099
1187
  return optimisticId;
1100
1188
  }
1189
+ deleteMessage(messageId, newParentId) {
1190
+ const message = this.messages.get(messageId);
1191
+ const newParent = newParentId ? this.messages.get(newParentId) : null;
1192
+ if (!message)
1193
+ throw new Error(
1194
+ "MessageRepository(deleteMessage): Optimistic message not found. This is likely an internal bug in assistant-ui."
1195
+ );
1196
+ if (newParent === void 0)
1197
+ throw new Error(
1198
+ "MessageRepository(deleteMessage): New message not found. This is likely an internal bug in assistant-ui."
1199
+ );
1200
+ for (const child of message.children) {
1201
+ const childMessage = this.messages.get(child);
1202
+ if (!childMessage)
1203
+ throw new Error(
1204
+ "MessageRepository(deleteMessage): Child message not found. This is likely an internal bug in assistant-ui."
1205
+ );
1206
+ this.performOp(newParent, childMessage, "relink");
1207
+ }
1208
+ this.messages.delete(messageId);
1209
+ if (this.head === message) {
1210
+ this.head = this.getFallbackChild(message.prev ?? this.root);
1211
+ }
1212
+ this.performOp(null, message, "cut");
1213
+ }
1101
1214
  getBranches(messageId) {
1102
1215
  const message = this.messages.get(messageId);
1103
1216
  if (!message)
1104
1217
  throw new Error(
1105
1218
  "MessageRepository(getBranches): Message not found. This is likely an internal bug in assistant-ui."
1106
1219
  );
1107
- if (message.prev) {
1108
- return message.prev.children;
1109
- }
1110
- return this.rootChildren;
1220
+ const { children } = message.prev ?? this.root;
1221
+ return children;
1111
1222
  }
1112
1223
  switchToBranch(messageId) {
1113
1224
  const message = this.messages.get(messageId);
@@ -1121,28 +1232,28 @@ var MessageRepository = class {
1121
1232
  this.head = findHead(message);
1122
1233
  }
1123
1234
  resetHead(messageId) {
1124
- if (messageId) {
1125
- const message = this.messages.get(messageId);
1126
- if (!message)
1127
- throw new Error(
1128
- "MessageRepository(resetHead): Branch not found. This is likely an internal bug in assistant-ui."
1129
- );
1130
- this.head = message;
1131
- for (let current = message; current; current = current.prev) {
1132
- if (current.prev) {
1133
- current.prev.next = current;
1134
- }
1135
- }
1136
- } else {
1235
+ if (messageId === null) {
1137
1236
  this.head = null;
1237
+ return;
1238
+ }
1239
+ const message = this.messages.get(messageId);
1240
+ if (!message)
1241
+ throw new Error(
1242
+ "MessageRepository(resetHead): Branch not found. This is likely an internal bug in assistant-ui."
1243
+ );
1244
+ this.head = message;
1245
+ for (let current = message; current; current = current.prev) {
1246
+ if (current.prev) {
1247
+ current.prev.next = current;
1248
+ }
1138
1249
  }
1139
1250
  }
1140
1251
  };
1141
1252
 
1142
1253
  // src/adapters/ThreadMessageConverter.tsx
1143
1254
  var ThreadMessageConverter = class {
1144
- constructor(converter2) {
1145
- this.converter = converter2;
1255
+ constructor(converter) {
1256
+ this.converter = converter;
1146
1257
  }
1147
1258
  cache = /* @__PURE__ */ new WeakMap();
1148
1259
  convertMessages(messages) {
@@ -1156,33 +1267,55 @@ var ThreadMessageConverter = class {
1156
1267
  }
1157
1268
  };
1158
1269
 
1270
+ // src/adapters/vercel/VercelThreadMessage.tsx
1271
+ var symbolInnerMessage = Symbol("innerMessage");
1272
+ var symbolInnerRSCMessage = Symbol("innerRSCMessage");
1273
+ var getVercelMessage = (message) => {
1274
+ return message[symbolInnerMessage];
1275
+ };
1276
+ var getVercelRSCMessage = (message) => {
1277
+ return message[symbolInnerRSCMessage];
1278
+ };
1279
+
1159
1280
  // src/adapters/vercel/useVercelAIThreadState.tsx
1160
- var vercelToThreadMessage = (message) => {
1161
- if (message.role !== "user" && message.role !== "assistant")
1162
- throw new Error(
1163
- `You have a message with an unsupported role. The role ${message.role} is not supported.`
1164
- );
1165
- return {
1281
+ var vercelToThreadMessage = (message, status) => {
1282
+ const common = {
1166
1283
  id: message.id,
1167
- role: message.role,
1168
- content: [
1169
- ...message.content ? [{ type: "text", text: message.content }] : [],
1170
- ...message.toolInvocations?.map((t) => ({
1171
- type: "tool-call",
1172
- name: t.toolName,
1173
- args: t.args,
1174
- result: "result" in t ? t.result : void 0
1175
- })) ?? []
1176
- ],
1177
- // ignore type mismatch for now
1178
1284
  createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
1179
- innerMessage: message
1285
+ [symbolInnerMessage]: message
1180
1286
  };
1287
+ switch (message.role) {
1288
+ case "user":
1289
+ return {
1290
+ ...common,
1291
+ role: "user",
1292
+ content: [{ type: "text", text: message.content }]
1293
+ };
1294
+ case "assistant":
1295
+ return {
1296
+ ...common,
1297
+ role: "assistant",
1298
+ content: [
1299
+ ...message.content ? [{ type: "text", text: message.content }] : [],
1300
+ ...message.toolInvocations?.map(
1301
+ (t) => ({
1302
+ type: "tool-call",
1303
+ name: t.toolName,
1304
+ args: t.args,
1305
+ result: "result" in t ? t.result : void 0
1306
+ })
1307
+ ) ?? []
1308
+ ],
1309
+ status
1310
+ };
1311
+ default:
1312
+ throw new Error(
1313
+ `You have a message with an unsupported role. The role ${message.role} is not supported.`
1314
+ );
1315
+ }
1181
1316
  };
1182
- var converter = new ThreadMessageConverter(vercelToThreadMessage);
1183
1317
  var sliceMessagesUntil = (messages, messageId) => {
1184
1318
  if (messageId == null) return [];
1185
- if (isOptimisticId(messageId)) return messages;
1186
1319
  const messageIdx = messages.findIndex((m) => m.id === messageId);
1187
1320
  if (messageIdx === -1)
1188
1321
  throw new Error(
@@ -1198,12 +1331,17 @@ var getIsRunning = (vercel) => {
1198
1331
  return vercel.status === "in_progress";
1199
1332
  };
1200
1333
  var useVercelAIThreadState = (vercel) => {
1201
- const [data] = (0, import_react22.useState)(() => new MessageRepository());
1202
- const vercelRef = (0, import_react22.useRef)(vercel);
1203
- vercelRef.current = vercel;
1204
- const isRunning = getIsRunning(vercelRef.current);
1205
- const assistantOptimisticIdRef = (0, import_react22.useRef)(null);
1206
- const messages = (0, import_react22.useMemo)(() => {
1334
+ const [data] = (0, import_react25.useState)(() => new MessageRepository());
1335
+ const isRunning = getIsRunning(vercel);
1336
+ const convertCallback = (0, import_react_use_callback_ref3.useCallbackRef)((message) => {
1337
+ return vercelToThreadMessage(
1338
+ message,
1339
+ vercel.messages.at(-1) === message && isRunning ? "in_progress" : "done"
1340
+ );
1341
+ });
1342
+ const converter = new ThreadMessageConverter(convertCallback);
1343
+ const assistantOptimisticIdRef = (0, import_react25.useRef)(null);
1344
+ const messages = (0, import_react25.useMemo)(() => {
1207
1345
  const vm = converter.convertMessages(vercel.messages);
1208
1346
  for (let i = 0; i < vm.length; i++) {
1209
1347
  const message = vm[i];
@@ -1211,66 +1349,61 @@ var useVercelAIThreadState = (vercel) => {
1211
1349
  data.addOrUpdateMessage(parent?.id ?? null, message);
1212
1350
  }
1213
1351
  if (assistantOptimisticIdRef.current) {
1214
- data.deleteMessage(assistantOptimisticIdRef.current);
1352
+ data.deleteMessage(assistantOptimisticIdRef.current, null);
1215
1353
  assistantOptimisticIdRef.current = null;
1216
1354
  }
1217
1355
  if (hasUpcomingMessage(isRunning, vm)) {
1218
- assistantOptimisticIdRef.current = data.commitOptimisticRun(
1219
- vm.at(-1)?.id ?? null
1356
+ assistantOptimisticIdRef.current = data.appendOptimisticMessage(
1357
+ vm.at(-1)?.id ?? null,
1358
+ {
1359
+ role: "assistant",
1360
+ content: [{ type: "text", text: "" }]
1361
+ }
1220
1362
  );
1221
1363
  }
1222
1364
  data.resetHead(assistantOptimisticIdRef.current ?? vm.at(-1)?.id ?? null);
1223
1365
  return data.getMessages();
1224
- }, [data, isRunning, vercel.messages]);
1225
- const getBranches2 = (0, import_react22.useCallback)(
1366
+ }, [converter, data, isRunning, vercel.messages]);
1367
+ const getBranches2 = (0, import_react25.useCallback)(
1226
1368
  (messageId) => {
1227
1369
  return data.getBranches(messageId);
1228
1370
  },
1229
1371
  [data]
1230
1372
  );
1231
- const switchToBranch2 = (0, import_react22.useCallback)(
1232
- (messageId) => {
1233
- data.switchToBranch(messageId);
1234
- vercelRef.current.setMessages(
1235
- data.getMessages().filter((m) => !isOptimisticId(m.id)).map((m) => m.innerMessage)
1236
- );
1237
- },
1238
- [data]
1239
- );
1240
- const startRun = (0, import_react22.useCallback)(async (parentId) => {
1241
- const reloadMaybe = "reload" in vercelRef.current ? vercelRef.current.reload : void 0;
1373
+ const switchToBranch2 = (0, import_react_use_callback_ref3.useCallbackRef)((messageId) => {
1374
+ data.switchToBranch(messageId);
1375
+ vercel.setMessages(
1376
+ data.getMessages().map(getVercelMessage).filter((m) => m != null)
1377
+ );
1378
+ });
1379
+ const startRun = (0, import_react_use_callback_ref3.useCallbackRef)(async (parentId) => {
1380
+ const reloadMaybe = "reload" in vercel ? vercel.reload : void 0;
1242
1381
  if (!reloadMaybe)
1243
1382
  throw new Error(
1244
1383
  "Reload is not supported by Vercel AI SDK's useAssistant."
1245
1384
  );
1246
- const newMessages = sliceMessagesUntil(
1247
- vercelRef.current.messages,
1248
- parentId
1249
- );
1250
- vercelRef.current.setMessages(newMessages);
1385
+ const newMessages = sliceMessagesUntil(vercel.messages, parentId);
1386
+ vercel.setMessages(newMessages);
1251
1387
  await reloadMaybe();
1252
- }, []);
1253
- const append = (0, import_react22.useCallback)(async (message) => {
1388
+ });
1389
+ const append = (0, import_react_use_callback_ref3.useCallbackRef)(async (message) => {
1254
1390
  if (message.content.length !== 1 || message.content[0]?.type !== "text")
1255
1391
  throw new Error("Only text content is supported by Vercel AI SDK.");
1256
- const newMessages = sliceMessagesUntil(
1257
- vercelRef.current.messages,
1258
- message.parentId
1259
- );
1260
- vercelRef.current.setMessages(newMessages);
1261
- await vercelRef.current.append({
1392
+ const newMessages = sliceMessagesUntil(vercel.messages, message.parentId);
1393
+ vercel.setMessages(newMessages);
1394
+ await vercel.append({
1262
1395
  role: "user",
1263
1396
  content: message.content[0].text
1264
1397
  });
1265
- }, []);
1266
- const cancelRun2 = (0, import_react22.useCallback)(() => {
1267
- const lastMessage = vercelRef.current.messages.at(-1);
1268
- vercelRef.current.stop();
1398
+ });
1399
+ const cancelRun2 = (0, import_react_use_callback_ref3.useCallbackRef)(() => {
1400
+ const lastMessage = vercel.messages.at(-1);
1401
+ vercel.stop();
1269
1402
  if (lastMessage?.role === "user") {
1270
- vercelRef.current.setInput(lastMessage.content);
1403
+ vercel.setInput(lastMessage.content);
1271
1404
  }
1272
- }, []);
1273
- return (0, import_react22.useMemo)(
1405
+ });
1406
+ return (0, import_react25.useMemo)(
1274
1407
  () => ({
1275
1408
  isRunning,
1276
1409
  messages,
@@ -1293,7 +1426,7 @@ var useVercelAIThreadState = (vercel) => {
1293
1426
  };
1294
1427
 
1295
1428
  // src/adapters/vercel/VercelAIAssistantProvider.tsx
1296
- var import_jsx_runtime19 = require("react/jsx-runtime");
1429
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1297
1430
  var VercelAIAssistantProvider = ({
1298
1431
  children,
1299
1432
  ...rest
@@ -1301,27 +1434,30 @@ var VercelAIAssistantProvider = ({
1301
1434
  const context = useDummyAIAssistantContext();
1302
1435
  const vercel = "chat" in rest ? rest.chat : rest.assistant;
1303
1436
  const threadState = useVercelAIThreadState(vercel);
1304
- (0, import_react23.useMemo)(() => {
1437
+ (0, import_react26.useMemo)(() => {
1305
1438
  context.useThread.setState(threadState, true);
1306
1439
  }, [context, threadState]);
1307
- (0, import_react23.useMemo)(() => {
1440
+ (0, import_react26.useMemo)(() => {
1308
1441
  context.useComposer.setState({
1309
1442
  value: vercel.input,
1310
1443
  setValue: vercel.setInput
1311
1444
  });
1312
1445
  }, [context, vercel.input, vercel.setInput]);
1313
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(AssistantContext.Provider, { value: context, children });
1446
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AssistantContext.Provider, { value: context, children });
1314
1447
  };
1315
1448
 
1316
1449
  // src/adapters/vercel/VercelRSCAssistantProvider.tsx
1317
- var import_react24 = require("react");
1318
- var import_jsx_runtime20 = require("react/jsx-runtime");
1319
- var vercelToThreadMessage2 = (message) => {
1450
+ var import_react27 = require("react");
1451
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1452
+ var vercelToThreadMessage2 = (converter, rawMessage) => {
1453
+ const message = converter(rawMessage);
1320
1454
  return {
1321
1455
  id: message.id,
1322
1456
  role: message.role,
1323
1457
  content: [{ type: "ui", display: message.display }],
1324
- createdAt: message.createdAt ?? /* @__PURE__ */ new Date()
1458
+ createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
1459
+ ...{ status: "done" },
1460
+ [symbolInnerRSCMessage]: rawMessage
1325
1461
  };
1326
1462
  };
1327
1463
  var EMPTY_BRANCHES = [];
@@ -1349,21 +1485,21 @@ var VercelRSCAssistantProvider = ({
1349
1485
  reload
1350
1486
  }) => {
1351
1487
  const context = useDummyAIAssistantContext();
1352
- const [isRunning, setIsRunning] = (0, import_react24.useState)(false);
1353
- const withRunning = (0, import_react24.useCallback)((callback) => {
1488
+ const [isRunning, setIsRunning] = (0, import_react27.useState)(false);
1489
+ const withRunning = (0, import_react27.useCallback)((callback) => {
1354
1490
  setIsRunning(true);
1355
1491
  return callback.finally(() => setIsRunning(false));
1356
1492
  }, []);
1357
- const converter2 = (0, import_react24.useMemo)(() => {
1493
+ const converter = (0, import_react27.useMemo)(() => {
1358
1494
  const rscConverter = convertMessage ?? ((m) => m);
1359
1495
  return new ThreadMessageConverter((m) => {
1360
- return vercelToThreadMessage2(rscConverter(m));
1496
+ return vercelToThreadMessage2(rscConverter, m);
1361
1497
  });
1362
1498
  }, [convertMessage]);
1363
- const messages = (0, import_react24.useMemo)(() => {
1364
- return converter2.convertMessages(vercelMessages);
1365
- }, [converter2, vercelMessages]);
1366
- const append = (0, import_react24.useCallback)(
1499
+ const messages = (0, import_react27.useMemo)(() => {
1500
+ return converter.convertMessages(vercelMessages);
1501
+ }, [converter, vercelMessages]);
1502
+ const append = (0, import_react27.useCallback)(
1367
1503
  async (message) => {
1368
1504
  if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null)) {
1369
1505
  if (!edit)
@@ -1377,7 +1513,7 @@ var VercelRSCAssistantProvider = ({
1377
1513
  },
1378
1514
  [context, withRunning, appendCallback, edit]
1379
1515
  );
1380
- const startRun = (0, import_react24.useCallback)(
1516
+ const startRun = (0, import_react27.useCallback)(
1381
1517
  async (parentId) => {
1382
1518
  if (!reload)
1383
1519
  throw new Error(
@@ -1387,7 +1523,7 @@ var VercelRSCAssistantProvider = ({
1387
1523
  },
1388
1524
  [withRunning, reload]
1389
1525
  );
1390
- (0, import_react24.useMemo)(() => {
1526
+ (0, import_react27.useMemo)(() => {
1391
1527
  context.useThread.setState(
1392
1528
  {
1393
1529
  messages,
@@ -1401,17 +1537,20 @@ var VercelRSCAssistantProvider = ({
1401
1537
  true
1402
1538
  );
1403
1539
  }, [context, messages, isRunning, append, startRun]);
1404
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(AssistantContext.Provider, { value: context, children });
1540
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AssistantContext.Provider, { value: context, children });
1405
1541
  };
1406
1542
  // Annotate the CommonJS export names for ESM import in node:
1407
1543
  0 && (module.exports = {
1408
1544
  ActionBarPrimitive,
1409
1545
  BranchPickerPrimitive,
1410
1546
  ComposerPrimitive,
1547
+ ContentPartPrimitive,
1411
1548
  MessagePrimitive,
1412
1549
  ThreadPrimitive,
1413
1550
  VercelAIAssistantProvider,
1414
1551
  VercelRSCAssistantProvider,
1552
+ unstable_getVercelMessage,
1553
+ unstable_getVercelRSCMessage,
1415
1554
  unstable_useMessageContext,
1416
1555
  useBeginMessageEdit,
1417
1556
  useCopyMessage,