@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.mjs
CHANGED
@@ -12,6 +12,7 @@ __export(thread_exports, {
|
|
12
12
|
Messages: () => ThreadMessages,
|
13
13
|
Root: () => ThreadRoot,
|
14
14
|
ScrollToBottom: () => ThreadScrollToBottom,
|
15
|
+
Suggestion: () => ThreadSuggestion,
|
15
16
|
Viewport: () => ThreadViewport
|
16
17
|
});
|
17
18
|
|
@@ -34,7 +35,7 @@ var useAssistantContext = () => {
|
|
34
35
|
const context = useContext(AssistantContext);
|
35
36
|
if (!context)
|
36
37
|
throw new Error(
|
37
|
-
"
|
38
|
+
"This component must be used within a AssistantProvider"
|
38
39
|
);
|
39
40
|
return context;
|
40
41
|
};
|
@@ -186,7 +187,7 @@ var MessageContext = createContext2(null);
|
|
186
187
|
var useMessageContext = () => {
|
187
188
|
const context = useContext2(MessageContext);
|
188
189
|
if (!context)
|
189
|
-
throw new Error("
|
190
|
+
throw new Error("This component must be used within a MessageProvider");
|
190
191
|
return context;
|
191
192
|
};
|
192
193
|
|
@@ -293,6 +294,7 @@ var useMessageContext2 = () => {
|
|
293
294
|
const [context] = useState(() => {
|
294
295
|
const useMessage = create2(() => ({
|
295
296
|
message: null,
|
297
|
+
parentId: null,
|
296
298
|
branches: [],
|
297
299
|
isLast: false,
|
298
300
|
isCopied: false,
|
@@ -307,15 +309,19 @@ var useMessageContext2 = () => {
|
|
307
309
|
const message = useMessage.getState().message;
|
308
310
|
if (message.role !== "user")
|
309
311
|
throw new Error("Editing is only supported for user messages");
|
310
|
-
|
311
|
-
|
312
|
-
return message.content[0].text;
|
312
|
+
const text = message.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
|
313
|
+
return text;
|
313
314
|
},
|
314
315
|
onSend: (text) => {
|
315
|
-
const message = useMessage.getState()
|
316
|
+
const { message, parentId } = useMessage.getState();
|
317
|
+
if (message.role !== "user")
|
318
|
+
throw new Error("Editing is only supported for user messages");
|
319
|
+
const nonTextParts = message.content.filter(
|
320
|
+
(part) => part.type !== "text" && part.type !== "ui"
|
321
|
+
);
|
316
322
|
useThread.getState().append({
|
317
|
-
parentId
|
318
|
-
content: [{ type: "text", text }]
|
323
|
+
parentId,
|
324
|
+
content: [{ type: "text", text }, ...nonTextParts]
|
319
325
|
});
|
320
326
|
}
|
321
327
|
});
|
@@ -325,6 +331,7 @@ var useMessageContext2 = () => {
|
|
325
331
|
};
|
326
332
|
var MessageProvider = ({
|
327
333
|
message,
|
334
|
+
parentId,
|
328
335
|
children
|
329
336
|
}) => {
|
330
337
|
const { useThread } = useAssistantContext();
|
@@ -337,6 +344,7 @@ var MessageProvider = ({
|
|
337
344
|
context.useMessage.setState(
|
338
345
|
{
|
339
346
|
message,
|
347
|
+
parentId,
|
340
348
|
branches,
|
341
349
|
isLast,
|
342
350
|
isCopied,
|
@@ -346,7 +354,7 @@ var MessageProvider = ({
|
|
346
354
|
},
|
347
355
|
true
|
348
356
|
);
|
349
|
-
}, [context, message, branches, isLast, isCopied, isHovering]);
|
357
|
+
}, [context, message, parentId, branches, isLast, isCopied, isHovering]);
|
350
358
|
return /* @__PURE__ */ jsx4(MessageContext.Provider, { value: context, children });
|
351
359
|
};
|
352
360
|
|
@@ -459,15 +467,21 @@ var ThreadMessages = ({ components }) => {
|
|
459
467
|
if (messages.length === 0)
|
460
468
|
return null;
|
461
469
|
return /* @__PURE__ */ jsx7(Fragment2, { children: messages.map((message, idx) => {
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
470
|
+
const parentId = messages[idx - 1]?.id ?? null;
|
471
|
+
return /* @__PURE__ */ jsxs2(
|
472
|
+
MessageProvider,
|
473
|
+
{
|
474
|
+
message,
|
475
|
+
parentId,
|
476
|
+
children: [
|
477
|
+
/* @__PURE__ */ jsxs2(MessageIf, { user: true, children: [
|
478
|
+
/* @__PURE__ */ jsx7(ComposerIf, { editing: false, children: /* @__PURE__ */ jsx7(UserMessage, {}) }),
|
479
|
+
/* @__PURE__ */ jsx7(ComposerIf, { editing: true, children: /* @__PURE__ */ jsx7(EditComposer, {}) })
|
480
|
+
] }),
|
481
|
+
/* @__PURE__ */ jsx7(MessageIf, { assistant: true, children: /* @__PURE__ */ jsx7(AssistantMessage, {}) })
|
482
|
+
]
|
483
|
+
},
|
484
|
+
parentId ?? "__ROOT__"
|
471
485
|
);
|
472
486
|
}) });
|
473
487
|
};
|
@@ -496,6 +510,35 @@ var ThreadScrollToBottom = forwardRef4(({ onClick, ...rest }, ref) => {
|
|
496
510
|
);
|
497
511
|
});
|
498
512
|
|
513
|
+
// src/primitives/thread/ThreadSuggestion.tsx
|
514
|
+
import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primitive";
|
515
|
+
import {
|
516
|
+
Primitive as Primitive5
|
517
|
+
} from "@radix-ui/react-primitive";
|
518
|
+
import { forwardRef as forwardRef5 } from "react";
|
519
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
520
|
+
var ThreadSuggestion = forwardRef5(({ onClick, prompt, method, autoSend: send, ...rest }, ref) => {
|
521
|
+
const { useThread, useComposer } = useAssistantContext();
|
522
|
+
const isDisabled = useThread((t) => t.isRunning);
|
523
|
+
const handleApplySuggestion = () => {
|
524
|
+
const thread = useThread.getState();
|
525
|
+
const composer = useComposer.getState();
|
526
|
+
composer.setValue(prompt);
|
527
|
+
if (send && !thread.isRunning) {
|
528
|
+
composer.send();
|
529
|
+
}
|
530
|
+
};
|
531
|
+
return /* @__PURE__ */ jsx9(
|
532
|
+
Primitive5.button,
|
533
|
+
{
|
534
|
+
...rest,
|
535
|
+
disabled: isDisabled,
|
536
|
+
ref,
|
537
|
+
onClick: composeEventHandlers4(onClick, handleApplySuggestion)
|
538
|
+
}
|
539
|
+
);
|
540
|
+
});
|
541
|
+
|
499
542
|
// src/primitives/composer/index.ts
|
500
543
|
var composer_exports = {};
|
501
544
|
__export(composer_exports, {
|
@@ -507,14 +550,14 @@ __export(composer_exports, {
|
|
507
550
|
});
|
508
551
|
|
509
552
|
// src/primitives/composer/ComposerRoot.tsx
|
510
|
-
import { composeEventHandlers as
|
553
|
+
import { composeEventHandlers as composeEventHandlers5 } from "@radix-ui/primitive";
|
511
554
|
import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
|
512
555
|
import {
|
513
|
-
Primitive as
|
556
|
+
Primitive as Primitive6
|
514
557
|
} from "@radix-ui/react-primitive";
|
515
|
-
import { forwardRef as
|
516
|
-
import { jsx as
|
517
|
-
var ComposerRoot =
|
558
|
+
import { forwardRef as forwardRef6, useRef as useRef4 } from "react";
|
559
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
560
|
+
var ComposerRoot = forwardRef6(
|
518
561
|
({ onSubmit, ...rest }, forwardedRef) => {
|
519
562
|
const { useViewport } = useAssistantContext();
|
520
563
|
const { useComposer } = useComposerContext();
|
@@ -528,31 +571,31 @@ var ComposerRoot = forwardRef5(
|
|
528
571
|
composerState.send();
|
529
572
|
useViewport.getState().scrollToBottom();
|
530
573
|
};
|
531
|
-
return /* @__PURE__ */
|
532
|
-
|
574
|
+
return /* @__PURE__ */ jsx10(
|
575
|
+
Primitive6.form,
|
533
576
|
{
|
534
577
|
...rest,
|
535
578
|
ref,
|
536
|
-
onSubmit:
|
579
|
+
onSubmit: composeEventHandlers5(onSubmit, handleSubmit)
|
537
580
|
}
|
538
581
|
);
|
539
582
|
}
|
540
583
|
);
|
541
584
|
|
542
585
|
// src/primitives/composer/ComposerInput.tsx
|
543
|
-
import { composeEventHandlers as
|
586
|
+
import { composeEventHandlers as composeEventHandlers6 } from "@radix-ui/primitive";
|
544
587
|
import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
|
545
588
|
import { Slot } from "@radix-ui/react-slot";
|
546
589
|
import {
|
547
|
-
forwardRef as
|
590
|
+
forwardRef as forwardRef7,
|
548
591
|
useCallback,
|
549
592
|
useEffect as useEffect2,
|
550
593
|
useRef as useRef5
|
551
594
|
} from "react";
|
552
595
|
import TextareaAutosize from "react-textarea-autosize";
|
553
|
-
import { jsx as
|
554
|
-
var ComposerInput =
|
555
|
-
({ autoFocus, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
|
596
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
597
|
+
var ComposerInput = forwardRef7(
|
598
|
+
({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
|
556
599
|
const { useThread, useViewport } = useAssistantContext();
|
557
600
|
const { useComposer, type } = useComposerContext();
|
558
601
|
const value = useComposer((c) => {
|
@@ -580,7 +623,7 @@ var ComposerInput = forwardRef6(
|
|
580
623
|
};
|
581
624
|
const textareaRef = useRef5(null);
|
582
625
|
const ref = useComposedRefs3(forwardedRef, textareaRef);
|
583
|
-
const autoFocusEnabled = autoFocus
|
626
|
+
const autoFocusEnabled = autoFocus && !disabled;
|
584
627
|
const focus = useCallback(() => {
|
585
628
|
const textarea = textareaRef.current;
|
586
629
|
if (!textarea || !autoFocusEnabled)
|
@@ -597,20 +640,20 @@ var ComposerInput = forwardRef6(
|
|
597
640
|
focus();
|
598
641
|
}
|
599
642
|
});
|
600
|
-
return /* @__PURE__ */
|
643
|
+
return /* @__PURE__ */ jsx11(
|
601
644
|
Component,
|
602
645
|
{
|
603
646
|
value,
|
604
647
|
...rest,
|
605
648
|
ref,
|
606
649
|
disabled,
|
607
|
-
onChange:
|
650
|
+
onChange: composeEventHandlers6(onChange, (e) => {
|
608
651
|
const composerState = useComposer.getState();
|
609
652
|
if (!composerState.isEditing)
|
610
653
|
return;
|
611
654
|
return composerState.setValue(e.target.value);
|
612
655
|
}),
|
613
|
-
onKeyDown:
|
656
|
+
onKeyDown: composeEventHandlers6(onKeyDown, handleKeyPress)
|
614
657
|
}
|
615
658
|
);
|
616
659
|
}
|
@@ -618,16 +661,16 @@ var ComposerInput = forwardRef6(
|
|
618
661
|
|
619
662
|
// src/primitives/composer/ComposerSend.tsx
|
620
663
|
import {
|
621
|
-
Primitive as
|
664
|
+
Primitive as Primitive7
|
622
665
|
} from "@radix-ui/react-primitive";
|
623
|
-
import { forwardRef as
|
624
|
-
import { jsx as
|
625
|
-
var ComposerSend =
|
666
|
+
import { forwardRef as forwardRef8 } from "react";
|
667
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
668
|
+
var ComposerSend = forwardRef8(
|
626
669
|
({ disabled, ...rest }, ref) => {
|
627
670
|
const { useComposer } = useComposerContext();
|
628
671
|
const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
|
629
|
-
return /* @__PURE__ */
|
630
|
-
|
672
|
+
return /* @__PURE__ */ jsx12(
|
673
|
+
Primitive7.button,
|
631
674
|
{
|
632
675
|
type: "submit",
|
633
676
|
...rest,
|
@@ -639,24 +682,24 @@ var ComposerSend = forwardRef7(
|
|
639
682
|
);
|
640
683
|
|
641
684
|
// src/primitives/composer/ComposerCancel.tsx
|
642
|
-
import { composeEventHandlers as
|
685
|
+
import { composeEventHandlers as composeEventHandlers7 } from "@radix-ui/primitive";
|
643
686
|
import {
|
644
|
-
Primitive as
|
687
|
+
Primitive as Primitive8
|
645
688
|
} from "@radix-ui/react-primitive";
|
646
|
-
import { forwardRef as
|
647
|
-
import { jsx as
|
648
|
-
var ComposerCancel =
|
689
|
+
import { forwardRef as forwardRef9 } from "react";
|
690
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
691
|
+
var ComposerCancel = forwardRef9(({ onClick, ...rest }, ref) => {
|
649
692
|
const { useComposer } = useComposerContext();
|
650
693
|
const handleCancel = () => {
|
651
694
|
useComposer.getState().cancel();
|
652
695
|
};
|
653
|
-
return /* @__PURE__ */
|
654
|
-
|
696
|
+
return /* @__PURE__ */ jsx13(
|
697
|
+
Primitive8.button,
|
655
698
|
{
|
656
699
|
type: "button",
|
657
700
|
...rest,
|
658
701
|
ref,
|
659
|
-
onClick:
|
702
|
+
onClick: composeEventHandlers7(onClick, handleCancel)
|
660
703
|
}
|
661
704
|
);
|
662
705
|
});
|
@@ -714,24 +757,24 @@ var useGoToNextBranch = () => {
|
|
714
757
|
};
|
715
758
|
|
716
759
|
// src/utils/createActionButton.tsx
|
717
|
-
import { composeEventHandlers as
|
760
|
+
import { composeEventHandlers as composeEventHandlers8 } from "@radix-ui/primitive";
|
718
761
|
import {
|
719
|
-
Primitive as
|
762
|
+
Primitive as Primitive9
|
720
763
|
} from "@radix-ui/react-primitive";
|
721
|
-
import { forwardRef as
|
722
|
-
import { jsx as
|
764
|
+
import { forwardRef as forwardRef10 } from "react";
|
765
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
723
766
|
var createActionButton = (useActionButton) => {
|
724
|
-
return
|
767
|
+
return forwardRef10(
|
725
768
|
(props, forwardedRef) => {
|
726
769
|
const onClick = useActionButton(props);
|
727
|
-
return /* @__PURE__ */
|
728
|
-
|
770
|
+
return /* @__PURE__ */ jsx14(
|
771
|
+
Primitive9.button,
|
729
772
|
{
|
730
773
|
type: "button",
|
731
774
|
disabled: !onClick,
|
732
775
|
...props,
|
733
776
|
ref: forwardedRef,
|
734
|
-
onClick:
|
777
|
+
onClick: composeEventHandlers8(props.onClick, onClick ?? void 0)
|
735
778
|
}
|
736
779
|
);
|
737
780
|
}
|
@@ -764,29 +807,29 @@ var useGoToPreviousBranch = () => {
|
|
764
807
|
var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
|
765
808
|
|
766
809
|
// src/primitives/branchPicker/BranchPickerCount.tsx
|
767
|
-
import { Fragment as Fragment3, jsx as
|
810
|
+
import { Fragment as Fragment3, jsx as jsx15 } from "react/jsx-runtime";
|
768
811
|
var BranchPickerCount = () => {
|
769
812
|
const { useMessage } = useMessageContext();
|
770
813
|
const branchCount = useMessage((s) => s.branches.length);
|
771
|
-
return /* @__PURE__ */
|
814
|
+
return /* @__PURE__ */ jsx15(Fragment3, { children: branchCount });
|
772
815
|
};
|
773
816
|
|
774
817
|
// src/primitives/branchPicker/BranchPickerNumber.tsx
|
775
|
-
import { Fragment as Fragment4, jsx as
|
818
|
+
import { Fragment as Fragment4, jsx as jsx16 } from "react/jsx-runtime";
|
776
819
|
var BranchPickerNumber = () => {
|
777
820
|
const { useMessage } = useMessageContext();
|
778
821
|
const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
|
779
|
-
return /* @__PURE__ */
|
822
|
+
return /* @__PURE__ */ jsx16(Fragment4, { children: branchIdx + 1 });
|
780
823
|
};
|
781
824
|
|
782
825
|
// src/primitives/branchPicker/BranchPickerRoot.tsx
|
783
826
|
import {
|
784
|
-
Primitive as
|
827
|
+
Primitive as Primitive10
|
785
828
|
} from "@radix-ui/react-primitive";
|
786
|
-
import { forwardRef as
|
787
|
-
import { jsx as
|
788
|
-
var BranchPickerRoot =
|
789
|
-
return /* @__PURE__ */
|
829
|
+
import { forwardRef as forwardRef11 } from "react";
|
830
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
831
|
+
var BranchPickerRoot = forwardRef11(({ hideWhenSingleBranch, ...rest }, ref) => {
|
832
|
+
return /* @__PURE__ */ jsx17(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ jsx17(Primitive10.div, { ...rest, ref }) });
|
790
833
|
});
|
791
834
|
|
792
835
|
// src/primitives/actionBar/index.ts
|
@@ -800,11 +843,11 @@ __export(actionBar_exports, {
|
|
800
843
|
|
801
844
|
// src/primitives/actionBar/ActionBarRoot.tsx
|
802
845
|
import {
|
803
|
-
Primitive as
|
846
|
+
Primitive as Primitive11
|
804
847
|
} from "@radix-ui/react-primitive";
|
805
|
-
import { forwardRef as
|
806
|
-
import { jsx as
|
807
|
-
var ActionBarRoot =
|
848
|
+
import { forwardRef as forwardRef12 } from "react";
|
849
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
850
|
+
var ActionBarRoot = forwardRef12(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
|
808
851
|
const { useThread } = useAssistantContext();
|
809
852
|
const { useMessage } = useMessageContext();
|
810
853
|
const hideAndfloatStatus = useCombinedStore(
|
@@ -824,8 +867,8 @@ var ActionBarRoot = forwardRef11(({ hideWhenRunning, autohide, autohideFloat, ..
|
|
824
867
|
);
|
825
868
|
if (hideAndfloatStatus === "hidden" /* Hidden */)
|
826
869
|
return null;
|
827
|
-
return /* @__PURE__ */
|
828
|
-
|
870
|
+
return /* @__PURE__ */ jsx18(
|
871
|
+
Primitive11.div,
|
829
872
|
{
|
830
873
|
"data-floating": hideAndfloatStatus === "floating" /* Floating */,
|
831
874
|
...rest,
|
@@ -864,10 +907,10 @@ var useReloadMessage = () => {
|
|
864
907
|
if (disabled)
|
865
908
|
return null;
|
866
909
|
return () => {
|
867
|
-
const message = useMessage.getState()
|
910
|
+
const { message, parentId } = useMessage.getState();
|
868
911
|
if (message.role !== "assistant")
|
869
912
|
throw new Error("Reloading is only supported on assistant messages");
|
870
|
-
useThread.getState().startRun(
|
913
|
+
useThread.getState().startRun(parentId);
|
871
914
|
useViewport.getState().scrollToBottom();
|
872
915
|
};
|
873
916
|
};
|
@@ -894,7 +937,7 @@ var useBeginMessageEdit = () => {
|
|
894
937
|
var ActionBarEdit = createActionButton(useBeginMessageEdit);
|
895
938
|
|
896
939
|
// src/adapters/vercel/VercelAIAssistantProvider.tsx
|
897
|
-
import {
|
940
|
+
import { useMemo as useMemo4 } from "react";
|
898
941
|
|
899
942
|
// src/adapters/vercel/useDummyAIAssistantContext.tsx
|
900
943
|
import { useState as useState2 } from "react";
|
@@ -952,7 +995,7 @@ var useDummyAIAssistantContext = () => {
|
|
952
995
|
return context;
|
953
996
|
};
|
954
997
|
|
955
|
-
// src/adapters/vercel/
|
998
|
+
// src/adapters/vercel/useVercelAIThreadState.tsx
|
956
999
|
import { useCallback as useCallback2, useMemo as useMemo3, useRef as useRef6, useState as useState3 } from "react";
|
957
1000
|
|
958
1001
|
// src/adapters/MessageRepository.tsx
|
@@ -981,17 +1024,26 @@ var MessageRepository = class {
|
|
981
1024
|
}
|
982
1025
|
return messages;
|
983
1026
|
}
|
984
|
-
|
1027
|
+
// TODO previousId is confusing
|
1028
|
+
// TODO previousId does not fix children
|
1029
|
+
// TODO cut / link operations
|
1030
|
+
addOrUpdateMessage(parentId, message, previousId = message.id) {
|
985
1031
|
const item = this.messages.get(message.id);
|
986
1032
|
if (item) {
|
987
|
-
if (item.current.
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
1033
|
+
if (item.prev?.current.id !== parentId) {
|
1034
|
+
if ((item.prev?.current.id ?? null) !== parentId) {
|
1035
|
+
this.deleteMessage(message.id);
|
1036
|
+
} else {
|
1037
|
+
item.current = message;
|
1038
|
+
if (previousId !== message.id) {
|
1039
|
+
this.messages.delete(previousId);
|
1040
|
+
this.messages.set(message.id, item);
|
1041
|
+
}
|
1042
|
+
return;
|
1043
|
+
}
|
992
1044
|
}
|
993
1045
|
}
|
994
|
-
const prev =
|
1046
|
+
const prev = parentId ? this.messages.get(parentId) : null;
|
995
1047
|
if (prev === void 0)
|
996
1048
|
throw new Error("Unexpected: Parent message not found");
|
997
1049
|
const newItem = {
|
@@ -1040,16 +1092,27 @@ var MessageRepository = class {
|
|
1040
1092
|
this.head = message.prev ? findHead(message.prev) : null;
|
1041
1093
|
}
|
1042
1094
|
}
|
1043
|
-
getOptimisticId
|
1095
|
+
getOptimisticId() {
|
1044
1096
|
let optimisticId;
|
1045
1097
|
do {
|
1046
1098
|
optimisticId = generateOptimisticId();
|
1047
1099
|
} while (this.messages.has(optimisticId));
|
1048
1100
|
return optimisticId;
|
1049
|
-
}
|
1101
|
+
}
|
1102
|
+
commitOptimisticAppend(message) {
|
1103
|
+
const optimisticIdUser = this.getOptimisticId();
|
1104
|
+
this.addOrUpdateMessage(message.parentId, {
|
1105
|
+
id: optimisticIdUser,
|
1106
|
+
role: "user",
|
1107
|
+
content: message.content,
|
1108
|
+
createdAt: /* @__PURE__ */ new Date()
|
1109
|
+
});
|
1110
|
+
const optimisticIdAssistant = this.commitOptimisticRun(optimisticIdUser);
|
1111
|
+
return [optimisticIdUser, optimisticIdAssistant];
|
1112
|
+
}
|
1050
1113
|
commitOptimisticRun(parentId) {
|
1051
1114
|
const optimisticId = this.getOptimisticId();
|
1052
|
-
this.addOrUpdateMessage({
|
1115
|
+
this.addOrUpdateMessage(parentId, {
|
1053
1116
|
id: optimisticId,
|
1054
1117
|
role: "assistant",
|
1055
1118
|
content: [
|
@@ -1058,7 +1121,6 @@ var MessageRepository = class {
|
|
1058
1121
|
text: ""
|
1059
1122
|
}
|
1060
1123
|
],
|
1061
|
-
parentId,
|
1062
1124
|
createdAt: /* @__PURE__ */ new Date()
|
1063
1125
|
});
|
1064
1126
|
return optimisticId;
|
@@ -1098,7 +1160,37 @@ var MessageRepository = class {
|
|
1098
1160
|
}
|
1099
1161
|
};
|
1100
1162
|
|
1101
|
-
// src/adapters/
|
1163
|
+
// src/adapters/ThreadMessageConverter.tsx
|
1164
|
+
var ThreadMessageConverter = class {
|
1165
|
+
constructor(converter2) {
|
1166
|
+
this.converter = converter2;
|
1167
|
+
}
|
1168
|
+
cache = /* @__PURE__ */ new WeakMap();
|
1169
|
+
convertMessages(messages) {
|
1170
|
+
return messages.map((m) => {
|
1171
|
+
const cached = this.cache.get(m);
|
1172
|
+
if (cached)
|
1173
|
+
return cached;
|
1174
|
+
const newMessage = this.converter(m);
|
1175
|
+
this.cache.set(m, newMessage);
|
1176
|
+
return newMessage;
|
1177
|
+
});
|
1178
|
+
}
|
1179
|
+
};
|
1180
|
+
|
1181
|
+
// src/adapters/vercel/useVercelAIThreadState.tsx
|
1182
|
+
var vercelToThreadMessage = (message) => {
|
1183
|
+
if (message.role !== "user" && message.role !== "assistant")
|
1184
|
+
throw new Error("Unsupported role");
|
1185
|
+
return {
|
1186
|
+
id: message.id,
|
1187
|
+
role: message.role,
|
1188
|
+
content: [{ type: "text", text: message.content }],
|
1189
|
+
createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
|
1190
|
+
innerMessage: message
|
1191
|
+
};
|
1192
|
+
};
|
1193
|
+
var converter = new ThreadMessageConverter(vercelToThreadMessage);
|
1102
1194
|
var sliceMessagesUntil = (messages, messageId) => {
|
1103
1195
|
if (messageId == null)
|
1104
1196
|
return [];
|
@@ -1112,28 +1204,36 @@ var sliceMessagesUntil = (messages, messageId) => {
|
|
1112
1204
|
var hasUpcomingMessage = (isRunning, messages) => {
|
1113
1205
|
return isRunning && messages[messages.length - 1]?.role !== "assistant";
|
1114
1206
|
};
|
1115
|
-
var
|
1207
|
+
var getIsRunning = (vercel) => {
|
1208
|
+
if ("isLoading" in vercel)
|
1209
|
+
return vercel.isLoading;
|
1210
|
+
return vercel.status === "in_progress";
|
1211
|
+
};
|
1212
|
+
var useVercelAIThreadState = (vercel) => {
|
1116
1213
|
const [data] = useState3(() => new MessageRepository());
|
1117
|
-
const
|
1214
|
+
const vercelRef = useRef6(vercel);
|
1215
|
+
vercelRef.current = vercel;
|
1216
|
+
const isRunning = getIsRunning(vercelRef.current);
|
1118
1217
|
const assistantOptimisticIdRef = useRef6(null);
|
1119
|
-
const
|
1120
|
-
|
1121
|
-
|
1218
|
+
const messages = useMemo3(() => {
|
1219
|
+
const vm = converter.convertMessages(vercel.messages);
|
1220
|
+
for (let i = 0; i < vm.length; i++) {
|
1221
|
+
const message = vm[i];
|
1222
|
+
const parent = vm[i - 1];
|
1223
|
+
data.addOrUpdateMessage(parent?.id ?? null, message);
|
1122
1224
|
}
|
1123
1225
|
if (assistantOptimisticIdRef.current) {
|
1124
1226
|
data.deleteMessage(assistantOptimisticIdRef.current);
|
1125
1227
|
assistantOptimisticIdRef.current = null;
|
1126
1228
|
}
|
1127
|
-
if (hasUpcomingMessage(isRunning,
|
1229
|
+
if (hasUpcomingMessage(isRunning, vm)) {
|
1128
1230
|
assistantOptimisticIdRef.current = data.commitOptimisticRun(
|
1129
|
-
|
1231
|
+
vm.at(-1)?.id ?? null
|
1130
1232
|
);
|
1131
1233
|
}
|
1132
|
-
data.resetHead(
|
1133
|
-
assistantOptimisticIdRef.current ?? messages.at(-1)?.id ?? null
|
1134
|
-
);
|
1234
|
+
data.resetHead(assistantOptimisticIdRef.current ?? vm.at(-1)?.id ?? null);
|
1135
1235
|
return data.getMessages();
|
1136
|
-
}, [data, isRunning, messages]);
|
1236
|
+
}, [data, isRunning, vercel.messages]);
|
1137
1237
|
const getBranches = useCallback2(
|
1138
1238
|
(messageId) => {
|
1139
1239
|
return data.getBranches(messageId);
|
@@ -1143,167 +1243,152 @@ var useVercelAIBranches = (chat, messages) => {
|
|
1143
1243
|
const switchToBranch = useCallback2(
|
1144
1244
|
(messageId) => {
|
1145
1245
|
data.switchToBranch(messageId);
|
1146
|
-
|
1246
|
+
vercelRef.current.setMessages(
|
1147
1247
|
data.getMessages().filter((m) => !isOptimisticId(m.id)).map((m) => m.innerMessage)
|
1148
1248
|
);
|
1149
1249
|
},
|
1150
|
-
[data
|
1151
|
-
);
|
1152
|
-
const reloadMaybe = "reload" in chat ? chat.reload : void 0;
|
1153
|
-
const startRun = useCallback2(
|
1154
|
-
async (parentId) => {
|
1155
|
-
if (!reloadMaybe)
|
1156
|
-
throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
|
1157
|
-
const newMessages = sliceMessagesUntil(chat.messages, parentId);
|
1158
|
-
chat.setMessages(newMessages);
|
1159
|
-
await reloadMaybe();
|
1160
|
-
},
|
1161
|
-
[chat.messages, chat.setMessages, reloadMaybe]
|
1162
|
-
);
|
1163
|
-
const append = useCallback2(
|
1164
|
-
async (message) => {
|
1165
|
-
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
1166
|
-
throw new Error("Only text content is supported by Vercel AI SDK");
|
1167
|
-
const newMessages = sliceMessagesUntil(chat.messages, message.parentId);
|
1168
|
-
chat.setMessages(newMessages);
|
1169
|
-
await chat.append({
|
1170
|
-
role: "user",
|
1171
|
-
content: message.content[0].text
|
1172
|
-
});
|
1173
|
-
},
|
1174
|
-
[chat.messages, chat.setMessages, chat.append]
|
1250
|
+
[data]
|
1175
1251
|
);
|
1252
|
+
const startRun = useCallback2(async (parentId) => {
|
1253
|
+
const reloadMaybe = "reload" in vercelRef.current ? vercelRef.current.reload : void 0;
|
1254
|
+
if (!reloadMaybe)
|
1255
|
+
throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
|
1256
|
+
const newMessages = sliceMessagesUntil(
|
1257
|
+
vercelRef.current.messages,
|
1258
|
+
parentId
|
1259
|
+
);
|
1260
|
+
vercelRef.current.setMessages(newMessages);
|
1261
|
+
await reloadMaybe();
|
1262
|
+
}, []);
|
1263
|
+
const append = useCallback2(async (message) => {
|
1264
|
+
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
1265
|
+
throw new Error("Only text content is supported by Vercel AI SDK");
|
1266
|
+
const newMessages = sliceMessagesUntil(
|
1267
|
+
vercelRef.current.messages,
|
1268
|
+
message.parentId
|
1269
|
+
);
|
1270
|
+
vercelRef.current.setMessages(newMessages);
|
1271
|
+
await vercelRef.current.append({
|
1272
|
+
role: "user",
|
1273
|
+
content: message.content[0].text
|
1274
|
+
});
|
1275
|
+
}, []);
|
1276
|
+
const cancelRun = useCallback2(() => {
|
1277
|
+
const lastMessage = vercelRef.current.messages.at(-1);
|
1278
|
+
vercelRef.current.stop();
|
1279
|
+
if (lastMessage?.role === "user") {
|
1280
|
+
vercelRef.current.setInput(lastMessage.content);
|
1281
|
+
}
|
1282
|
+
}, []);
|
1176
1283
|
return useMemo3(
|
1177
1284
|
() => ({
|
1178
|
-
|
1285
|
+
isRunning,
|
1286
|
+
messages,
|
1179
1287
|
getBranches,
|
1180
1288
|
switchToBranch,
|
1181
1289
|
append,
|
1182
|
-
startRun
|
1290
|
+
startRun,
|
1291
|
+
cancelRun
|
1183
1292
|
}),
|
1184
|
-
[
|
1293
|
+
[
|
1294
|
+
isRunning,
|
1295
|
+
messages,
|
1296
|
+
getBranches,
|
1297
|
+
switchToBranch,
|
1298
|
+
append,
|
1299
|
+
startRun,
|
1300
|
+
cancelRun
|
1301
|
+
]
|
1185
1302
|
);
|
1186
1303
|
};
|
1187
1304
|
|
1188
1305
|
// src/adapters/vercel/VercelAIAssistantProvider.tsx
|
1189
|
-
import { jsx as
|
1190
|
-
var ThreadMessageCache = /* @__PURE__ */ new WeakMap();
|
1191
|
-
var vercelToThreadMessage = (message, parentId) => {
|
1192
|
-
if (message.role !== "user" && message.role !== "assistant")
|
1193
|
-
throw new Error("Unsupported role");
|
1194
|
-
return {
|
1195
|
-
parentId,
|
1196
|
-
id: message.id,
|
1197
|
-
role: message.role,
|
1198
|
-
content: [{ type: "text", text: message.content }],
|
1199
|
-
createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
|
1200
|
-
innerMessage: message
|
1201
|
-
};
|
1202
|
-
};
|
1203
|
-
var vercelToCachedThreadMessages = (messages) => {
|
1204
|
-
return messages.map((m, idx) => {
|
1205
|
-
const cached = ThreadMessageCache.get(m);
|
1206
|
-
const parentId = messages[idx - 1]?.id ?? null;
|
1207
|
-
if (cached && cached.parentId === parentId)
|
1208
|
-
return cached;
|
1209
|
-
const newMessage = vercelToThreadMessage(m, parentId);
|
1210
|
-
ThreadMessageCache.set(m, newMessage);
|
1211
|
-
return newMessage;
|
1212
|
-
});
|
1213
|
-
};
|
1306
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
1214
1307
|
var VercelAIAssistantProvider = ({
|
1215
1308
|
children,
|
1216
1309
|
...rest
|
1217
1310
|
}) => {
|
1218
1311
|
const context = useDummyAIAssistantContext();
|
1219
1312
|
const vercel = "chat" in rest ? rest.chat : rest.assistant;
|
1220
|
-
const
|
1221
|
-
return vercelToCachedThreadMessages(vercel.messages);
|
1222
|
-
}, [vercel.messages]);
|
1223
|
-
const branches = useVercelAIBranches(vercel, messages);
|
1224
|
-
const cancelRun = useCallback3(() => {
|
1225
|
-
const lastMessage = vercel.messages.at(-1);
|
1226
|
-
vercel.stop();
|
1227
|
-
if (lastMessage?.role === "user") {
|
1228
|
-
vercel.setInput(lastMessage.content);
|
1229
|
-
}
|
1230
|
-
}, [vercel.messages, vercel.stop, vercel.setInput]);
|
1231
|
-
const isRunning = "isLoading" in vercel ? vercel.isLoading : vercel.status === "in_progress";
|
1313
|
+
const threadState = useVercelAIThreadState(vercel);
|
1232
1314
|
useMemo4(() => {
|
1233
|
-
context.useThread.setState(
|
1234
|
-
|
1235
|
-
messages: branches.messages,
|
1236
|
-
isRunning,
|
1237
|
-
getBranches: branches.getBranches,
|
1238
|
-
switchToBranch: branches.switchToBranch,
|
1239
|
-
append: branches.append,
|
1240
|
-
startRun: branches.startRun,
|
1241
|
-
cancelRun
|
1242
|
-
},
|
1243
|
-
true
|
1244
|
-
);
|
1245
|
-
}, [context, isRunning, cancelRun, branches]);
|
1315
|
+
context.useThread.setState(threadState, true);
|
1316
|
+
}, [context, threadState]);
|
1246
1317
|
useMemo4(() => {
|
1247
1318
|
context.useComposer.setState({
|
1248
1319
|
value: vercel.input,
|
1249
1320
|
setValue: vercel.setInput
|
1250
1321
|
});
|
1251
1322
|
}, [context, vercel.input, vercel.setInput]);
|
1252
|
-
return /* @__PURE__ */
|
1323
|
+
return /* @__PURE__ */ jsx19(AssistantContext.Provider, { value: context, children });
|
1253
1324
|
};
|
1254
1325
|
|
1255
1326
|
// src/adapters/vercel/VercelRSCAssistantProvider.tsx
|
1256
1327
|
import {
|
1257
|
-
useCallback as
|
1328
|
+
useCallback as useCallback3,
|
1258
1329
|
useMemo as useMemo5
|
1259
1330
|
} from "react";
|
1260
|
-
import { jsx as
|
1261
|
-
var
|
1262
|
-
var vercelToThreadMessage2 = (parentId, message) => {
|
1331
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
1332
|
+
var vercelToThreadMessage2 = (message) => {
|
1263
1333
|
if (message.role !== "user" && message.role !== "assistant")
|
1264
1334
|
throw new Error("Unsupported role");
|
1265
1335
|
return {
|
1266
|
-
parentId,
|
1267
1336
|
id: message.id,
|
1268
1337
|
role: message.role,
|
1269
1338
|
content: [{ type: "ui", display: message.display }],
|
1270
1339
|
createdAt: message.createdAt ?? /* @__PURE__ */ new Date()
|
1271
1340
|
};
|
1272
1341
|
};
|
1273
|
-
var
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
return newMessage;
|
1282
|
-
});
|
1283
|
-
};
|
1284
|
-
var VercelRSCAssistantProvider = ({ children, messages: vercelMessages, append: vercelAppend }) => {
|
1342
|
+
var VercelRSCAssistantProvider = ({
|
1343
|
+
children,
|
1344
|
+
convertMessage,
|
1345
|
+
messages: vercelMessages,
|
1346
|
+
append: appendCallback,
|
1347
|
+
edit,
|
1348
|
+
reload
|
1349
|
+
}) => {
|
1285
1350
|
const context = useDummyAIAssistantContext();
|
1351
|
+
const converter2 = useMemo5(() => {
|
1352
|
+
const rscConverter = convertMessage ?? ((m) => m);
|
1353
|
+
return new ThreadMessageConverter((m) => {
|
1354
|
+
return vercelToThreadMessage2(rscConverter(m));
|
1355
|
+
});
|
1356
|
+
}, [convertMessage]);
|
1286
1357
|
const messages = useMemo5(() => {
|
1287
|
-
return
|
1288
|
-
}, [vercelMessages]);
|
1289
|
-
const append =
|
1358
|
+
return converter2.convertMessages(vercelMessages);
|
1359
|
+
}, [converter2, vercelMessages]);
|
1360
|
+
const append = useCallback3(
|
1290
1361
|
async (message) => {
|
1291
|
-
if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null))
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1362
|
+
if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null)) {
|
1363
|
+
if (!edit)
|
1364
|
+
throw new Error(
|
1365
|
+
"Unexpected: Message editing is not supported, no edit callback was provided to VercelRSCAssistantProvider."
|
1366
|
+
);
|
1367
|
+
await edit(message);
|
1368
|
+
} else {
|
1369
|
+
await appendCallback(message);
|
1295
1370
|
}
|
1296
|
-
await vercelAppend(message);
|
1297
1371
|
},
|
1298
|
-
[context,
|
1372
|
+
[context, appendCallback, edit]
|
1373
|
+
);
|
1374
|
+
const startRun = useCallback3(
|
1375
|
+
async (parentId) => {
|
1376
|
+
if (!reload)
|
1377
|
+
throw new Error(
|
1378
|
+
"Unexpected: Message reloading is not supported, no reload callback was provided to VercelRSCAssistantProvider."
|
1379
|
+
);
|
1380
|
+
await reload(parentId);
|
1381
|
+
},
|
1382
|
+
[reload]
|
1299
1383
|
);
|
1300
1384
|
useMemo5(() => {
|
1301
1385
|
context.useThread.setState({
|
1302
1386
|
messages,
|
1303
|
-
append
|
1387
|
+
append,
|
1388
|
+
startRun
|
1304
1389
|
});
|
1305
|
-
}, [context, messages, append]);
|
1306
|
-
return /* @__PURE__ */
|
1390
|
+
}, [context, messages, append, startRun]);
|
1391
|
+
return /* @__PURE__ */ jsx20(AssistantContext.Provider, { value: context, children });
|
1307
1392
|
};
|
1308
1393
|
export {
|
1309
1394
|
actionBar_exports as ActionBarPrimitive,
|