@assistant-ui/react 0.0.12 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +48 -30
- package/dist/index.d.ts +48 -30
- package/dist/index.js +311 -228
- package/dist/index.mjs +293 -208
- package/package.json +1 -1
package/dist/index.js
CHANGED
@@ -54,6 +54,7 @@ __export(thread_exports, {
|
|
54
54
|
Messages: () => ThreadMessages,
|
55
55
|
Root: () => ThreadRoot,
|
56
56
|
ScrollToBottom: () => ThreadScrollToBottom,
|
57
|
+
Suggestion: () => ThreadSuggestion,
|
57
58
|
Viewport: () => ThreadViewport
|
58
59
|
});
|
59
60
|
|
@@ -74,7 +75,7 @@ var useAssistantContext = () => {
|
|
74
75
|
const context = (0, import_react2.useContext)(AssistantContext);
|
75
76
|
if (!context)
|
76
77
|
throw new Error(
|
77
|
-
"
|
78
|
+
"This component must be used within a AssistantProvider"
|
78
79
|
);
|
79
80
|
return context;
|
80
81
|
};
|
@@ -224,7 +225,7 @@ var MessageContext = (0, import_react6.createContext)(null);
|
|
224
225
|
var useMessageContext = () => {
|
225
226
|
const context = (0, import_react6.useContext)(MessageContext);
|
226
227
|
if (!context)
|
227
|
-
throw new Error("
|
228
|
+
throw new Error("This component must be used within a MessageProvider");
|
228
229
|
return context;
|
229
230
|
};
|
230
231
|
|
@@ -329,6 +330,7 @@ var useMessageContext2 = () => {
|
|
329
330
|
const [context] = (0, import_react8.useState)(() => {
|
330
331
|
const useMessage = (0, import_zustand2.create)(() => ({
|
331
332
|
message: null,
|
333
|
+
parentId: null,
|
332
334
|
branches: [],
|
333
335
|
isLast: false,
|
334
336
|
isCopied: false,
|
@@ -343,15 +345,19 @@ var useMessageContext2 = () => {
|
|
343
345
|
const message = useMessage.getState().message;
|
344
346
|
if (message.role !== "user")
|
345
347
|
throw new Error("Editing is only supported for user messages");
|
346
|
-
|
347
|
-
|
348
|
-
return message.content[0].text;
|
348
|
+
const text = message.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
|
349
|
+
return text;
|
349
350
|
},
|
350
351
|
onSend: (text) => {
|
351
|
-
const message = useMessage.getState()
|
352
|
+
const { message, parentId } = useMessage.getState();
|
353
|
+
if (message.role !== "user")
|
354
|
+
throw new Error("Editing is only supported for user messages");
|
355
|
+
const nonTextParts = message.content.filter(
|
356
|
+
(part) => part.type !== "text" && part.type !== "ui"
|
357
|
+
);
|
352
358
|
useThread.getState().append({
|
353
|
-
parentId
|
354
|
-
content: [{ type: "text", text }]
|
359
|
+
parentId,
|
360
|
+
content: [{ type: "text", text }, ...nonTextParts]
|
355
361
|
});
|
356
362
|
}
|
357
363
|
});
|
@@ -361,6 +367,7 @@ var useMessageContext2 = () => {
|
|
361
367
|
};
|
362
368
|
var MessageProvider = ({
|
363
369
|
message,
|
370
|
+
parentId,
|
364
371
|
children
|
365
372
|
}) => {
|
366
373
|
const { useThread } = useAssistantContext();
|
@@ -373,6 +380,7 @@ var MessageProvider = ({
|
|
373
380
|
context.useMessage.setState(
|
374
381
|
{
|
375
382
|
message,
|
383
|
+
parentId,
|
376
384
|
branches,
|
377
385
|
isLast,
|
378
386
|
isCopied,
|
@@ -382,7 +390,7 @@ var MessageProvider = ({
|
|
382
390
|
},
|
383
391
|
true
|
384
392
|
);
|
385
|
-
}, [context, message, branches, isLast, isCopied, isHovering]);
|
393
|
+
}, [context, message, parentId, branches, isLast, isCopied, isHovering]);
|
386
394
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MessageContext.Provider, { value: context, children });
|
387
395
|
};
|
388
396
|
|
@@ -493,15 +501,21 @@ var ThreadMessages = ({ components }) => {
|
|
493
501
|
if (messages.length === 0)
|
494
502
|
return null;
|
495
503
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: messages.map((message, idx) => {
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
504
|
+
const parentId = messages[idx - 1]?.id ?? null;
|
505
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
506
|
+
MessageProvider,
|
507
|
+
{
|
508
|
+
message,
|
509
|
+
parentId,
|
510
|
+
children: [
|
511
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(MessageIf, { user: true, children: [
|
512
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ComposerIf, { editing: false, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(UserMessage, {}) }),
|
513
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ComposerIf, { editing: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(EditComposer, {}) })
|
514
|
+
] }),
|
515
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AssistantMessage, {}) })
|
516
|
+
]
|
517
|
+
},
|
518
|
+
parentId ?? "__ROOT__"
|
505
519
|
);
|
506
520
|
}) });
|
507
521
|
};
|
@@ -528,6 +542,33 @@ var ThreadScrollToBottom = (0, import_react10.forwardRef)(({ onClick, ...rest },
|
|
528
542
|
);
|
529
543
|
});
|
530
544
|
|
545
|
+
// src/primitives/thread/ThreadSuggestion.tsx
|
546
|
+
var import_primitive4 = require("@radix-ui/primitive");
|
547
|
+
var import_react_primitive5 = require("@radix-ui/react-primitive");
|
548
|
+
var import_react11 = require("react");
|
549
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
550
|
+
var ThreadSuggestion = (0, import_react11.forwardRef)(({ onClick, prompt, method, autoSend: send, ...rest }, ref) => {
|
551
|
+
const { useThread, useComposer } = useAssistantContext();
|
552
|
+
const isDisabled = useThread((t) => t.isRunning);
|
553
|
+
const handleApplySuggestion = () => {
|
554
|
+
const thread = useThread.getState();
|
555
|
+
const composer = useComposer.getState();
|
556
|
+
composer.setValue(prompt);
|
557
|
+
if (send && !thread.isRunning) {
|
558
|
+
composer.send();
|
559
|
+
}
|
560
|
+
};
|
561
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
562
|
+
import_react_primitive5.Primitive.button,
|
563
|
+
{
|
564
|
+
...rest,
|
565
|
+
disabled: isDisabled,
|
566
|
+
ref,
|
567
|
+
onClick: (0, import_primitive4.composeEventHandlers)(onClick, handleApplySuggestion)
|
568
|
+
}
|
569
|
+
);
|
570
|
+
});
|
571
|
+
|
531
572
|
// src/primitives/composer/index.ts
|
532
573
|
var composer_exports = {};
|
533
574
|
__export(composer_exports, {
|
@@ -539,16 +580,16 @@ __export(composer_exports, {
|
|
539
580
|
});
|
540
581
|
|
541
582
|
// src/primitives/composer/ComposerRoot.tsx
|
542
|
-
var
|
583
|
+
var import_primitive5 = require("@radix-ui/primitive");
|
543
584
|
var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
|
544
|
-
var
|
545
|
-
var
|
546
|
-
var
|
547
|
-
var ComposerRoot = (0,
|
585
|
+
var import_react_primitive6 = require("@radix-ui/react-primitive");
|
586
|
+
var import_react12 = require("react");
|
587
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
588
|
+
var ComposerRoot = (0, import_react12.forwardRef)(
|
548
589
|
({ onSubmit, ...rest }, forwardedRef) => {
|
549
590
|
const { useViewport } = useAssistantContext();
|
550
591
|
const { useComposer } = useComposerContext();
|
551
|
-
const formRef = (0,
|
592
|
+
const formRef = (0, import_react12.useRef)(null);
|
552
593
|
const ref = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, formRef);
|
553
594
|
const handleSubmit = (e) => {
|
554
595
|
const composerState = useComposer.getState();
|
@@ -558,26 +599,26 @@ var ComposerRoot = (0, import_react11.forwardRef)(
|
|
558
599
|
composerState.send();
|
559
600
|
useViewport.getState().scrollToBottom();
|
560
601
|
};
|
561
|
-
return /* @__PURE__ */ (0,
|
562
|
-
|
602
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
603
|
+
import_react_primitive6.Primitive.form,
|
563
604
|
{
|
564
605
|
...rest,
|
565
606
|
ref,
|
566
|
-
onSubmit: (0,
|
607
|
+
onSubmit: (0, import_primitive5.composeEventHandlers)(onSubmit, handleSubmit)
|
567
608
|
}
|
568
609
|
);
|
569
610
|
}
|
570
611
|
);
|
571
612
|
|
572
613
|
// src/primitives/composer/ComposerInput.tsx
|
573
|
-
var
|
614
|
+
var import_primitive6 = require("@radix-ui/primitive");
|
574
615
|
var import_react_compose_refs3 = require("@radix-ui/react-compose-refs");
|
575
616
|
var import_react_slot = require("@radix-ui/react-slot");
|
576
|
-
var
|
617
|
+
var import_react13 = require("react");
|
577
618
|
var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
|
578
|
-
var
|
579
|
-
var ComposerInput = (0,
|
580
|
-
({ autoFocus, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
|
619
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
620
|
+
var ComposerInput = (0, import_react13.forwardRef)(
|
621
|
+
({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
|
581
622
|
const { useThread, useViewport } = useAssistantContext();
|
582
623
|
const { useComposer, type } = useComposerContext();
|
583
624
|
const value = useComposer((c) => {
|
@@ -603,10 +644,10 @@ var ComposerInput = (0, import_react12.forwardRef)(
|
|
603
644
|
}
|
604
645
|
}
|
605
646
|
};
|
606
|
-
const textareaRef = (0,
|
647
|
+
const textareaRef = (0, import_react13.useRef)(null);
|
607
648
|
const ref = (0, import_react_compose_refs3.useComposedRefs)(forwardedRef, textareaRef);
|
608
|
-
const autoFocusEnabled = autoFocus
|
609
|
-
const focus = (0,
|
649
|
+
const autoFocusEnabled = autoFocus && !disabled;
|
650
|
+
const focus = (0, import_react13.useCallback)(() => {
|
610
651
|
const textarea = textareaRef.current;
|
611
652
|
if (!textarea || !autoFocusEnabled)
|
612
653
|
return;
|
@@ -616,41 +657,41 @@ var ComposerInput = (0, import_react12.forwardRef)(
|
|
616
657
|
textareaRef.current.value.length
|
617
658
|
);
|
618
659
|
}, [autoFocusEnabled]);
|
619
|
-
(0,
|
660
|
+
(0, import_react13.useEffect)(() => focus(), [focus]);
|
620
661
|
useOnScrollToBottom(() => {
|
621
662
|
if (type === "assistant") {
|
622
663
|
focus();
|
623
664
|
}
|
624
665
|
});
|
625
|
-
return /* @__PURE__ */ (0,
|
666
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
626
667
|
Component,
|
627
668
|
{
|
628
669
|
value,
|
629
670
|
...rest,
|
630
671
|
ref,
|
631
672
|
disabled,
|
632
|
-
onChange: (0,
|
673
|
+
onChange: (0, import_primitive6.composeEventHandlers)(onChange, (e) => {
|
633
674
|
const composerState = useComposer.getState();
|
634
675
|
if (!composerState.isEditing)
|
635
676
|
return;
|
636
677
|
return composerState.setValue(e.target.value);
|
637
678
|
}),
|
638
|
-
onKeyDown: (0,
|
679
|
+
onKeyDown: (0, import_primitive6.composeEventHandlers)(onKeyDown, handleKeyPress)
|
639
680
|
}
|
640
681
|
);
|
641
682
|
}
|
642
683
|
);
|
643
684
|
|
644
685
|
// src/primitives/composer/ComposerSend.tsx
|
645
|
-
var
|
646
|
-
var
|
647
|
-
var
|
648
|
-
var ComposerSend = (0,
|
686
|
+
var import_react_primitive7 = require("@radix-ui/react-primitive");
|
687
|
+
var import_react14 = require("react");
|
688
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
689
|
+
var ComposerSend = (0, import_react14.forwardRef)(
|
649
690
|
({ disabled, ...rest }, ref) => {
|
650
691
|
const { useComposer } = useComposerContext();
|
651
692
|
const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
|
652
|
-
return /* @__PURE__ */ (0,
|
653
|
-
|
693
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
694
|
+
import_react_primitive7.Primitive.button,
|
654
695
|
{
|
655
696
|
type: "submit",
|
656
697
|
...rest,
|
@@ -662,22 +703,22 @@ var ComposerSend = (0, import_react13.forwardRef)(
|
|
662
703
|
);
|
663
704
|
|
664
705
|
// src/primitives/composer/ComposerCancel.tsx
|
665
|
-
var
|
666
|
-
var
|
667
|
-
var
|
668
|
-
var
|
669
|
-
var ComposerCancel = (0,
|
706
|
+
var import_primitive7 = require("@radix-ui/primitive");
|
707
|
+
var import_react_primitive8 = require("@radix-ui/react-primitive");
|
708
|
+
var import_react15 = require("react");
|
709
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
710
|
+
var ComposerCancel = (0, import_react15.forwardRef)(({ onClick, ...rest }, ref) => {
|
670
711
|
const { useComposer } = useComposerContext();
|
671
712
|
const handleCancel = () => {
|
672
713
|
useComposer.getState().cancel();
|
673
714
|
};
|
674
|
-
return /* @__PURE__ */ (0,
|
675
|
-
|
715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
716
|
+
import_react_primitive8.Primitive.button,
|
676
717
|
{
|
677
718
|
type: "button",
|
678
719
|
...rest,
|
679
720
|
ref,
|
680
|
-
onClick: (0,
|
721
|
+
onClick: (0, import_primitive7.composeEventHandlers)(onClick, handleCancel)
|
681
722
|
}
|
682
723
|
);
|
683
724
|
});
|
@@ -693,10 +734,10 @@ __export(branchPicker_exports, {
|
|
693
734
|
});
|
694
735
|
|
695
736
|
// src/utils/context/combined/useCombinedStore.ts
|
696
|
-
var
|
737
|
+
var import_react17 = require("react");
|
697
738
|
|
698
739
|
// src/utils/context/combined/createCombinedStore.ts
|
699
|
-
var
|
740
|
+
var import_react16 = require("react");
|
700
741
|
var createCombinedStore = (stores) => {
|
701
742
|
const subscribe = (callback) => {
|
702
743
|
const unsubscribes = stores.map((store) => store.subscribe(callback));
|
@@ -708,13 +749,13 @@ var createCombinedStore = (stores) => {
|
|
708
749
|
};
|
709
750
|
return (selector) => {
|
710
751
|
const getSnapshot = () => selector(...stores.map((store) => store.getState()));
|
711
|
-
return (0,
|
752
|
+
return (0, import_react16.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
712
753
|
};
|
713
754
|
};
|
714
755
|
|
715
756
|
// src/utils/context/combined/useCombinedStore.ts
|
716
757
|
var useCombinedStore = (stores, selector) => {
|
717
|
-
const useCombined = (0,
|
758
|
+
const useCombined = (0, import_react17.useMemo)(() => createCombinedStore(stores), stores);
|
718
759
|
return useCombined(selector);
|
719
760
|
};
|
720
761
|
|
@@ -735,22 +776,22 @@ var useGoToNextBranch = () => {
|
|
735
776
|
};
|
736
777
|
|
737
778
|
// src/utils/createActionButton.tsx
|
738
|
-
var
|
739
|
-
var
|
740
|
-
var
|
741
|
-
var
|
779
|
+
var import_primitive8 = require("@radix-ui/primitive");
|
780
|
+
var import_react_primitive9 = require("@radix-ui/react-primitive");
|
781
|
+
var import_react18 = require("react");
|
782
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
742
783
|
var createActionButton = (useActionButton) => {
|
743
|
-
return (0,
|
784
|
+
return (0, import_react18.forwardRef)(
|
744
785
|
(props, forwardedRef) => {
|
745
786
|
const onClick = useActionButton(props);
|
746
|
-
return /* @__PURE__ */ (0,
|
747
|
-
|
787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
788
|
+
import_react_primitive9.Primitive.button,
|
748
789
|
{
|
749
790
|
type: "button",
|
750
791
|
disabled: !onClick,
|
751
792
|
...props,
|
752
793
|
ref: forwardedRef,
|
753
|
-
onClick: (0,
|
794
|
+
onClick: (0, import_primitive8.composeEventHandlers)(props.onClick, onClick ?? void 0)
|
754
795
|
}
|
755
796
|
);
|
756
797
|
}
|
@@ -783,27 +824,27 @@ var useGoToPreviousBranch = () => {
|
|
783
824
|
var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
|
784
825
|
|
785
826
|
// src/primitives/branchPicker/BranchPickerCount.tsx
|
786
|
-
var
|
827
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
787
828
|
var BranchPickerCount = () => {
|
788
829
|
const { useMessage } = useMessageContext();
|
789
830
|
const branchCount = useMessage((s) => s.branches.length);
|
790
|
-
return /* @__PURE__ */ (0,
|
831
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children: branchCount });
|
791
832
|
};
|
792
833
|
|
793
834
|
// src/primitives/branchPicker/BranchPickerNumber.tsx
|
794
|
-
var
|
835
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
795
836
|
var BranchPickerNumber = () => {
|
796
837
|
const { useMessage } = useMessageContext();
|
797
838
|
const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
|
798
|
-
return /* @__PURE__ */ (0,
|
839
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: branchIdx + 1 });
|
799
840
|
};
|
800
841
|
|
801
842
|
// src/primitives/branchPicker/BranchPickerRoot.tsx
|
802
|
-
var
|
803
|
-
var
|
804
|
-
var
|
805
|
-
var BranchPickerRoot = (0,
|
806
|
-
return /* @__PURE__ */ (0,
|
843
|
+
var import_react_primitive10 = require("@radix-ui/react-primitive");
|
844
|
+
var import_react19 = require("react");
|
845
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
846
|
+
var BranchPickerRoot = (0, import_react19.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
|
847
|
+
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 }) });
|
807
848
|
});
|
808
849
|
|
809
850
|
// src/primitives/actionBar/index.ts
|
@@ -816,10 +857,10 @@ __export(actionBar_exports, {
|
|
816
857
|
});
|
817
858
|
|
818
859
|
// src/primitives/actionBar/ActionBarRoot.tsx
|
819
|
-
var
|
820
|
-
var
|
821
|
-
var
|
822
|
-
var ActionBarRoot = (0,
|
860
|
+
var import_react_primitive11 = require("@radix-ui/react-primitive");
|
861
|
+
var import_react20 = require("react");
|
862
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
863
|
+
var ActionBarRoot = (0, import_react20.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
|
823
864
|
const { useThread } = useAssistantContext();
|
824
865
|
const { useMessage } = useMessageContext();
|
825
866
|
const hideAndfloatStatus = useCombinedStore(
|
@@ -839,8 +880,8 @@ var ActionBarRoot = (0, import_react19.forwardRef)(({ hideWhenRunning, autohide,
|
|
839
880
|
);
|
840
881
|
if (hideAndfloatStatus === "hidden" /* Hidden */)
|
841
882
|
return null;
|
842
|
-
return /* @__PURE__ */ (0,
|
843
|
-
|
883
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
884
|
+
import_react_primitive11.Primitive.div,
|
844
885
|
{
|
845
886
|
"data-floating": hideAndfloatStatus === "floating" /* Floating */,
|
846
887
|
...rest,
|
@@ -879,10 +920,10 @@ var useReloadMessage = () => {
|
|
879
920
|
if (disabled)
|
880
921
|
return null;
|
881
922
|
return () => {
|
882
|
-
const message = useMessage.getState()
|
923
|
+
const { message, parentId } = useMessage.getState();
|
883
924
|
if (message.role !== "assistant")
|
884
925
|
throw new Error("Reloading is only supported on assistant messages");
|
885
|
-
useThread.getState().startRun(
|
926
|
+
useThread.getState().startRun(parentId);
|
886
927
|
useViewport.getState().scrollToBottom();
|
887
928
|
};
|
888
929
|
};
|
@@ -909,10 +950,10 @@ var useBeginMessageEdit = () => {
|
|
909
950
|
var ActionBarEdit = createActionButton(useBeginMessageEdit);
|
910
951
|
|
911
952
|
// src/adapters/vercel/VercelAIAssistantProvider.tsx
|
912
|
-
var
|
953
|
+
var import_react23 = require("react");
|
913
954
|
|
914
955
|
// src/adapters/vercel/useDummyAIAssistantContext.tsx
|
915
|
-
var
|
956
|
+
var import_react21 = require("react");
|
916
957
|
var import_zustand4 = require("zustand");
|
917
958
|
|
918
959
|
// src/utils/context/stores/ViewportStore.tsx
|
@@ -958,7 +999,7 @@ var makeDummyThreadStore = () => {
|
|
958
999
|
}));
|
959
1000
|
};
|
960
1001
|
var useDummyAIAssistantContext = () => {
|
961
|
-
const [context] = (0,
|
1002
|
+
const [context] = (0, import_react21.useState)(() => {
|
962
1003
|
const useThread = makeDummyThreadStore();
|
963
1004
|
const useViewport = makeViewportStore();
|
964
1005
|
const useComposer = makeThreadComposerStore(useThread);
|
@@ -967,8 +1008,8 @@ var useDummyAIAssistantContext = () => {
|
|
967
1008
|
return context;
|
968
1009
|
};
|
969
1010
|
|
970
|
-
// src/adapters/vercel/
|
971
|
-
var
|
1011
|
+
// src/adapters/vercel/useVercelAIThreadState.tsx
|
1012
|
+
var import_react22 = require("react");
|
972
1013
|
|
973
1014
|
// src/adapters/MessageRepository.tsx
|
974
1015
|
var import_non_secure = require("nanoid/non-secure");
|
@@ -996,17 +1037,26 @@ var MessageRepository = class {
|
|
996
1037
|
}
|
997
1038
|
return messages;
|
998
1039
|
}
|
999
|
-
|
1040
|
+
// TODO previousId is confusing
|
1041
|
+
// TODO previousId does not fix children
|
1042
|
+
// TODO cut / link operations
|
1043
|
+
addOrUpdateMessage(parentId, message, previousId = message.id) {
|
1000
1044
|
const item = this.messages.get(message.id);
|
1001
1045
|
if (item) {
|
1002
|
-
if (item.current.
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1046
|
+
if (item.prev?.current.id !== parentId) {
|
1047
|
+
if ((item.prev?.current.id ?? null) !== parentId) {
|
1048
|
+
this.deleteMessage(message.id);
|
1049
|
+
} else {
|
1050
|
+
item.current = message;
|
1051
|
+
if (previousId !== message.id) {
|
1052
|
+
this.messages.delete(previousId);
|
1053
|
+
this.messages.set(message.id, item);
|
1054
|
+
}
|
1055
|
+
return;
|
1056
|
+
}
|
1007
1057
|
}
|
1008
1058
|
}
|
1009
|
-
const prev =
|
1059
|
+
const prev = parentId ? this.messages.get(parentId) : null;
|
1010
1060
|
if (prev === void 0)
|
1011
1061
|
throw new Error("Unexpected: Parent message not found");
|
1012
1062
|
const newItem = {
|
@@ -1055,16 +1105,27 @@ var MessageRepository = class {
|
|
1055
1105
|
this.head = message.prev ? findHead(message.prev) : null;
|
1056
1106
|
}
|
1057
1107
|
}
|
1058
|
-
getOptimisticId
|
1108
|
+
getOptimisticId() {
|
1059
1109
|
let optimisticId;
|
1060
1110
|
do {
|
1061
1111
|
optimisticId = generateOptimisticId();
|
1062
1112
|
} while (this.messages.has(optimisticId));
|
1063
1113
|
return optimisticId;
|
1064
|
-
}
|
1114
|
+
}
|
1115
|
+
commitOptimisticAppend(message) {
|
1116
|
+
const optimisticIdUser = this.getOptimisticId();
|
1117
|
+
this.addOrUpdateMessage(message.parentId, {
|
1118
|
+
id: optimisticIdUser,
|
1119
|
+
role: "user",
|
1120
|
+
content: message.content,
|
1121
|
+
createdAt: /* @__PURE__ */ new Date()
|
1122
|
+
});
|
1123
|
+
const optimisticIdAssistant = this.commitOptimisticRun(optimisticIdUser);
|
1124
|
+
return [optimisticIdUser, optimisticIdAssistant];
|
1125
|
+
}
|
1065
1126
|
commitOptimisticRun(parentId) {
|
1066
1127
|
const optimisticId = this.getOptimisticId();
|
1067
|
-
this.addOrUpdateMessage({
|
1128
|
+
this.addOrUpdateMessage(parentId, {
|
1068
1129
|
id: optimisticId,
|
1069
1130
|
role: "assistant",
|
1070
1131
|
content: [
|
@@ -1073,7 +1134,6 @@ var MessageRepository = class {
|
|
1073
1134
|
text: ""
|
1074
1135
|
}
|
1075
1136
|
],
|
1076
|
-
parentId,
|
1077
1137
|
createdAt: /* @__PURE__ */ new Date()
|
1078
1138
|
});
|
1079
1139
|
return optimisticId;
|
@@ -1113,7 +1173,37 @@ var MessageRepository = class {
|
|
1113
1173
|
}
|
1114
1174
|
};
|
1115
1175
|
|
1116
|
-
// src/adapters/
|
1176
|
+
// src/adapters/ThreadMessageConverter.tsx
|
1177
|
+
var ThreadMessageConverter = class {
|
1178
|
+
constructor(converter2) {
|
1179
|
+
this.converter = converter2;
|
1180
|
+
}
|
1181
|
+
cache = /* @__PURE__ */ new WeakMap();
|
1182
|
+
convertMessages(messages) {
|
1183
|
+
return messages.map((m) => {
|
1184
|
+
const cached = this.cache.get(m);
|
1185
|
+
if (cached)
|
1186
|
+
return cached;
|
1187
|
+
const newMessage = this.converter(m);
|
1188
|
+
this.cache.set(m, newMessage);
|
1189
|
+
return newMessage;
|
1190
|
+
});
|
1191
|
+
}
|
1192
|
+
};
|
1193
|
+
|
1194
|
+
// src/adapters/vercel/useVercelAIThreadState.tsx
|
1195
|
+
var vercelToThreadMessage = (message) => {
|
1196
|
+
if (message.role !== "user" && message.role !== "assistant")
|
1197
|
+
throw new Error("Unsupported role");
|
1198
|
+
return {
|
1199
|
+
id: message.id,
|
1200
|
+
role: message.role,
|
1201
|
+
content: [{ type: "text", text: message.content }],
|
1202
|
+
createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
|
1203
|
+
innerMessage: message
|
1204
|
+
};
|
1205
|
+
};
|
1206
|
+
var converter = new ThreadMessageConverter(vercelToThreadMessage);
|
1117
1207
|
var sliceMessagesUntil = (messages, messageId) => {
|
1118
1208
|
if (messageId == null)
|
1119
1209
|
return [];
|
@@ -1127,195 +1217,188 @@ var sliceMessagesUntil = (messages, messageId) => {
|
|
1127
1217
|
var hasUpcomingMessage = (isRunning, messages) => {
|
1128
1218
|
return isRunning && messages[messages.length - 1]?.role !== "assistant";
|
1129
1219
|
};
|
1130
|
-
var
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1220
|
+
var getIsRunning = (vercel) => {
|
1221
|
+
if ("isLoading" in vercel)
|
1222
|
+
return vercel.isLoading;
|
1223
|
+
return vercel.status === "in_progress";
|
1224
|
+
};
|
1225
|
+
var useVercelAIThreadState = (vercel) => {
|
1226
|
+
const [data] = (0, import_react22.useState)(() => new MessageRepository());
|
1227
|
+
const vercelRef = (0, import_react22.useRef)(vercel);
|
1228
|
+
vercelRef.current = vercel;
|
1229
|
+
const isRunning = getIsRunning(vercelRef.current);
|
1230
|
+
const assistantOptimisticIdRef = (0, import_react22.useRef)(null);
|
1231
|
+
const messages = (0, import_react22.useMemo)(() => {
|
1232
|
+
const vm = converter.convertMessages(vercel.messages);
|
1233
|
+
for (let i = 0; i < vm.length; i++) {
|
1234
|
+
const message = vm[i];
|
1235
|
+
const parent = vm[i - 1];
|
1236
|
+
data.addOrUpdateMessage(parent?.id ?? null, message);
|
1137
1237
|
}
|
1138
1238
|
if (assistantOptimisticIdRef.current) {
|
1139
1239
|
data.deleteMessage(assistantOptimisticIdRef.current);
|
1140
1240
|
assistantOptimisticIdRef.current = null;
|
1141
1241
|
}
|
1142
|
-
if (hasUpcomingMessage(isRunning,
|
1242
|
+
if (hasUpcomingMessage(isRunning, vm)) {
|
1143
1243
|
assistantOptimisticIdRef.current = data.commitOptimisticRun(
|
1144
|
-
|
1244
|
+
vm.at(-1)?.id ?? null
|
1145
1245
|
);
|
1146
1246
|
}
|
1147
|
-
data.resetHead(
|
1148
|
-
assistantOptimisticIdRef.current ?? messages.at(-1)?.id ?? null
|
1149
|
-
);
|
1247
|
+
data.resetHead(assistantOptimisticIdRef.current ?? vm.at(-1)?.id ?? null);
|
1150
1248
|
return data.getMessages();
|
1151
|
-
}, [data, isRunning, messages]);
|
1152
|
-
const getBranches = (0,
|
1249
|
+
}, [data, isRunning, vercel.messages]);
|
1250
|
+
const getBranches = (0, import_react22.useCallback)(
|
1153
1251
|
(messageId) => {
|
1154
1252
|
return data.getBranches(messageId);
|
1155
1253
|
},
|
1156
1254
|
[data]
|
1157
1255
|
);
|
1158
|
-
const switchToBranch = (0,
|
1256
|
+
const switchToBranch = (0, import_react22.useCallback)(
|
1159
1257
|
(messageId) => {
|
1160
1258
|
data.switchToBranch(messageId);
|
1161
|
-
|
1259
|
+
vercelRef.current.setMessages(
|
1162
1260
|
data.getMessages().filter((m) => !isOptimisticId(m.id)).map((m) => m.innerMessage)
|
1163
1261
|
);
|
1164
1262
|
},
|
1165
|
-
[data
|
1166
|
-
);
|
1167
|
-
const reloadMaybe = "reload" in chat ? chat.reload : void 0;
|
1168
|
-
const startRun = (0, import_react21.useCallback)(
|
1169
|
-
async (parentId) => {
|
1170
|
-
if (!reloadMaybe)
|
1171
|
-
throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
|
1172
|
-
const newMessages = sliceMessagesUntil(chat.messages, parentId);
|
1173
|
-
chat.setMessages(newMessages);
|
1174
|
-
await reloadMaybe();
|
1175
|
-
},
|
1176
|
-
[chat.messages, chat.setMessages, reloadMaybe]
|
1177
|
-
);
|
1178
|
-
const append = (0, import_react21.useCallback)(
|
1179
|
-
async (message) => {
|
1180
|
-
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
1181
|
-
throw new Error("Only text content is supported by Vercel AI SDK");
|
1182
|
-
const newMessages = sliceMessagesUntil(chat.messages, message.parentId);
|
1183
|
-
chat.setMessages(newMessages);
|
1184
|
-
await chat.append({
|
1185
|
-
role: "user",
|
1186
|
-
content: message.content[0].text
|
1187
|
-
});
|
1188
|
-
},
|
1189
|
-
[chat.messages, chat.setMessages, chat.append]
|
1263
|
+
[data]
|
1190
1264
|
);
|
1191
|
-
|
1265
|
+
const startRun = (0, import_react22.useCallback)(async (parentId) => {
|
1266
|
+
const reloadMaybe = "reload" in vercelRef.current ? vercelRef.current.reload : void 0;
|
1267
|
+
if (!reloadMaybe)
|
1268
|
+
throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
|
1269
|
+
const newMessages = sliceMessagesUntil(
|
1270
|
+
vercelRef.current.messages,
|
1271
|
+
parentId
|
1272
|
+
);
|
1273
|
+
vercelRef.current.setMessages(newMessages);
|
1274
|
+
await reloadMaybe();
|
1275
|
+
}, []);
|
1276
|
+
const append = (0, import_react22.useCallback)(async (message) => {
|
1277
|
+
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
1278
|
+
throw new Error("Only text content is supported by Vercel AI SDK");
|
1279
|
+
const newMessages = sliceMessagesUntil(
|
1280
|
+
vercelRef.current.messages,
|
1281
|
+
message.parentId
|
1282
|
+
);
|
1283
|
+
vercelRef.current.setMessages(newMessages);
|
1284
|
+
await vercelRef.current.append({
|
1285
|
+
role: "user",
|
1286
|
+
content: message.content[0].text
|
1287
|
+
});
|
1288
|
+
}, []);
|
1289
|
+
const cancelRun = (0, import_react22.useCallback)(() => {
|
1290
|
+
const lastMessage = vercelRef.current.messages.at(-1);
|
1291
|
+
vercelRef.current.stop();
|
1292
|
+
if (lastMessage?.role === "user") {
|
1293
|
+
vercelRef.current.setInput(lastMessage.content);
|
1294
|
+
}
|
1295
|
+
}, []);
|
1296
|
+
return (0, import_react22.useMemo)(
|
1192
1297
|
() => ({
|
1193
|
-
|
1298
|
+
isRunning,
|
1299
|
+
messages,
|
1194
1300
|
getBranches,
|
1195
1301
|
switchToBranch,
|
1196
1302
|
append,
|
1197
|
-
startRun
|
1303
|
+
startRun,
|
1304
|
+
cancelRun
|
1198
1305
|
}),
|
1199
|
-
[
|
1306
|
+
[
|
1307
|
+
isRunning,
|
1308
|
+
messages,
|
1309
|
+
getBranches,
|
1310
|
+
switchToBranch,
|
1311
|
+
append,
|
1312
|
+
startRun,
|
1313
|
+
cancelRun
|
1314
|
+
]
|
1200
1315
|
);
|
1201
1316
|
};
|
1202
1317
|
|
1203
1318
|
// src/adapters/vercel/VercelAIAssistantProvider.tsx
|
1204
|
-
var
|
1205
|
-
var ThreadMessageCache = /* @__PURE__ */ new WeakMap();
|
1206
|
-
var vercelToThreadMessage = (message, parentId) => {
|
1207
|
-
if (message.role !== "user" && message.role !== "assistant")
|
1208
|
-
throw new Error("Unsupported role");
|
1209
|
-
return {
|
1210
|
-
parentId,
|
1211
|
-
id: message.id,
|
1212
|
-
role: message.role,
|
1213
|
-
content: [{ type: "text", text: message.content }],
|
1214
|
-
createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
|
1215
|
-
innerMessage: message
|
1216
|
-
};
|
1217
|
-
};
|
1218
|
-
var vercelToCachedThreadMessages = (messages) => {
|
1219
|
-
return messages.map((m, idx) => {
|
1220
|
-
const cached = ThreadMessageCache.get(m);
|
1221
|
-
const parentId = messages[idx - 1]?.id ?? null;
|
1222
|
-
if (cached && cached.parentId === parentId)
|
1223
|
-
return cached;
|
1224
|
-
const newMessage = vercelToThreadMessage(m, parentId);
|
1225
|
-
ThreadMessageCache.set(m, newMessage);
|
1226
|
-
return newMessage;
|
1227
|
-
});
|
1228
|
-
};
|
1319
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
1229
1320
|
var VercelAIAssistantProvider = ({
|
1230
1321
|
children,
|
1231
1322
|
...rest
|
1232
1323
|
}) => {
|
1233
1324
|
const context = useDummyAIAssistantContext();
|
1234
1325
|
const vercel = "chat" in rest ? rest.chat : rest.assistant;
|
1235
|
-
const
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
const lastMessage = vercel.messages.at(-1);
|
1241
|
-
vercel.stop();
|
1242
|
-
if (lastMessage?.role === "user") {
|
1243
|
-
vercel.setInput(lastMessage.content);
|
1244
|
-
}
|
1245
|
-
}, [vercel.messages, vercel.stop, vercel.setInput]);
|
1246
|
-
const isRunning = "isLoading" in vercel ? vercel.isLoading : vercel.status === "in_progress";
|
1247
|
-
(0, import_react22.useMemo)(() => {
|
1248
|
-
context.useThread.setState(
|
1249
|
-
{
|
1250
|
-
messages: branches.messages,
|
1251
|
-
isRunning,
|
1252
|
-
getBranches: branches.getBranches,
|
1253
|
-
switchToBranch: branches.switchToBranch,
|
1254
|
-
append: branches.append,
|
1255
|
-
startRun: branches.startRun,
|
1256
|
-
cancelRun
|
1257
|
-
},
|
1258
|
-
true
|
1259
|
-
);
|
1260
|
-
}, [context, isRunning, cancelRun, branches]);
|
1261
|
-
(0, import_react22.useMemo)(() => {
|
1326
|
+
const threadState = useVercelAIThreadState(vercel);
|
1327
|
+
(0, import_react23.useMemo)(() => {
|
1328
|
+
context.useThread.setState(threadState, true);
|
1329
|
+
}, [context, threadState]);
|
1330
|
+
(0, import_react23.useMemo)(() => {
|
1262
1331
|
context.useComposer.setState({
|
1263
1332
|
value: vercel.input,
|
1264
1333
|
setValue: vercel.setInput
|
1265
1334
|
});
|
1266
1335
|
}, [context, vercel.input, vercel.setInput]);
|
1267
|
-
return /* @__PURE__ */ (0,
|
1336
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(AssistantContext.Provider, { value: context, children });
|
1268
1337
|
};
|
1269
1338
|
|
1270
1339
|
// src/adapters/vercel/VercelRSCAssistantProvider.tsx
|
1271
|
-
var
|
1272
|
-
var
|
1273
|
-
var
|
1274
|
-
var vercelToThreadMessage2 = (parentId, message) => {
|
1340
|
+
var import_react24 = require("react");
|
1341
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
1342
|
+
var vercelToThreadMessage2 = (message) => {
|
1275
1343
|
if (message.role !== "user" && message.role !== "assistant")
|
1276
1344
|
throw new Error("Unsupported role");
|
1277
1345
|
return {
|
1278
|
-
parentId,
|
1279
1346
|
id: message.id,
|
1280
1347
|
role: message.role,
|
1281
1348
|
content: [{ type: "ui", display: message.display }],
|
1282
1349
|
createdAt: message.createdAt ?? /* @__PURE__ */ new Date()
|
1283
1350
|
};
|
1284
1351
|
};
|
1285
|
-
var
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
return newMessage;
|
1294
|
-
});
|
1295
|
-
};
|
1296
|
-
var VercelRSCAssistantProvider = ({ children, messages: vercelMessages, append: vercelAppend }) => {
|
1352
|
+
var VercelRSCAssistantProvider = ({
|
1353
|
+
children,
|
1354
|
+
convertMessage,
|
1355
|
+
messages: vercelMessages,
|
1356
|
+
append: appendCallback,
|
1357
|
+
edit,
|
1358
|
+
reload
|
1359
|
+
}) => {
|
1297
1360
|
const context = useDummyAIAssistantContext();
|
1298
|
-
const
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1361
|
+
const converter2 = (0, import_react24.useMemo)(() => {
|
1362
|
+
const rscConverter = convertMessage ?? ((m) => m);
|
1363
|
+
return new ThreadMessageConverter((m) => {
|
1364
|
+
return vercelToThreadMessage2(rscConverter(m));
|
1365
|
+
});
|
1366
|
+
}, [convertMessage]);
|
1367
|
+
const messages = (0, import_react24.useMemo)(() => {
|
1368
|
+
return converter2.convertMessages(vercelMessages);
|
1369
|
+
}, [converter2, vercelMessages]);
|
1370
|
+
const append = (0, import_react24.useCallback)(
|
1302
1371
|
async (message) => {
|
1303
|
-
if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null))
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1372
|
+
if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null)) {
|
1373
|
+
if (!edit)
|
1374
|
+
throw new Error(
|
1375
|
+
"Unexpected: Message editing is not supported, no edit callback was provided to VercelRSCAssistantProvider."
|
1376
|
+
);
|
1377
|
+
await edit(message);
|
1378
|
+
} else {
|
1379
|
+
await appendCallback(message);
|
1307
1380
|
}
|
1308
|
-
await vercelAppend(message);
|
1309
1381
|
},
|
1310
|
-
[context,
|
1382
|
+
[context, appendCallback, edit]
|
1311
1383
|
);
|
1312
|
-
(0,
|
1384
|
+
const startRun = (0, import_react24.useCallback)(
|
1385
|
+
async (parentId) => {
|
1386
|
+
if (!reload)
|
1387
|
+
throw new Error(
|
1388
|
+
"Unexpected: Message reloading is not supported, no reload callback was provided to VercelRSCAssistantProvider."
|
1389
|
+
);
|
1390
|
+
await reload(parentId);
|
1391
|
+
},
|
1392
|
+
[reload]
|
1393
|
+
);
|
1394
|
+
(0, import_react24.useMemo)(() => {
|
1313
1395
|
context.useThread.setState({
|
1314
1396
|
messages,
|
1315
|
-
append
|
1397
|
+
append,
|
1398
|
+
startRun
|
1316
1399
|
});
|
1317
|
-
}, [context, messages, append]);
|
1318
|
-
return /* @__PURE__ */ (0,
|
1400
|
+
}, [context, messages, append, startRun]);
|
1401
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(AssistantContext.Provider, { value: context, children });
|
1319
1402
|
};
|
1320
1403
|
// Annotate the CommonJS export names for ESM import in node:
|
1321
1404
|
0 && (module.exports = {
|