@assistant-ui/react 0.0.14 → 0.0.15
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 +174 -171
- package/dist/index.mjs +176 -172
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
@@ -35,7 +35,7 @@ var useAssistantContext = () => {
|
|
35
35
|
const context = useContext(AssistantContext);
|
36
36
|
if (!context)
|
37
37
|
throw new Error(
|
38
|
-
"This component must be used within a AssistantProvider"
|
38
|
+
"This component must be used within a AssistantProvider."
|
39
39
|
);
|
40
40
|
return context;
|
41
41
|
};
|
@@ -44,14 +44,10 @@ var useAssistantContext = () => {
|
|
44
44
|
var useThreadIf = (props) => {
|
45
45
|
const { useThread } = useAssistantContext();
|
46
46
|
return useThread((thread) => {
|
47
|
-
if (props.empty === true && thread.messages.length !== 0)
|
48
|
-
|
49
|
-
if (props.
|
50
|
-
|
51
|
-
if (props.running === true && !thread.isRunning)
|
52
|
-
return false;
|
53
|
-
if (props.running === false && thread.isRunning)
|
54
|
-
return false;
|
47
|
+
if (props.empty === true && thread.messages.length !== 0) return false;
|
48
|
+
if (props.empty === false && thread.messages.length === 0) return false;
|
49
|
+
if (props.running === true && !thread.isRunning) return false;
|
50
|
+
if (props.running === false && thread.isRunning) return false;
|
55
51
|
return true;
|
56
52
|
});
|
57
53
|
};
|
@@ -81,8 +77,7 @@ var useOnResizeContent = (ref, callback) => {
|
|
81
77
|
callbackRef.current = callback;
|
82
78
|
useLayoutEffect(() => {
|
83
79
|
const el = ref.current;
|
84
|
-
if (!el)
|
85
|
-
return;
|
80
|
+
if (!el) return;
|
86
81
|
const resizeObserver = new ResizeObserver(() => {
|
87
82
|
callbackRef.current();
|
88
83
|
});
|
@@ -137,16 +132,14 @@ var ThreadViewport = forwardRef2(({ autoScroll = true, onScroll, children, ...re
|
|
137
132
|
const lastScrollTop = useRef3(0);
|
138
133
|
const scrollToBottom = () => {
|
139
134
|
const div = messagesEndRef.current;
|
140
|
-
if (!div || !autoScroll)
|
141
|
-
return;
|
135
|
+
if (!div || !autoScroll) return;
|
142
136
|
const behavior = firstRenderRef.current ? "instant" : "auto";
|
143
137
|
firstRenderRef.current = false;
|
144
138
|
useViewport.setState({ isAtBottom: true });
|
145
139
|
div.scrollIntoView({ behavior });
|
146
140
|
};
|
147
141
|
useOnResizeContent(divRef, () => {
|
148
|
-
if (!useViewport.getState().isAtBottom)
|
149
|
-
return;
|
142
|
+
if (!useViewport.getState().isAtBottom) return;
|
150
143
|
scrollToBottom();
|
151
144
|
});
|
152
145
|
useOnScrollToBottom(() => {
|
@@ -154,8 +147,7 @@ var ThreadViewport = forwardRef2(({ autoScroll = true, onScroll, children, ...re
|
|
154
147
|
});
|
155
148
|
const handleScroll = () => {
|
156
149
|
const div = divRef.current;
|
157
|
-
if (!div)
|
158
|
-
return;
|
150
|
+
if (!div) return;
|
159
151
|
const isAtBottom = useViewport.getState().isAtBottom;
|
160
152
|
const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
|
161
153
|
if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
|
@@ -187,7 +179,7 @@ var MessageContext = createContext2(null);
|
|
187
179
|
var useMessageContext = () => {
|
188
180
|
const context = useContext2(MessageContext);
|
189
181
|
if (!context)
|
190
|
-
throw new Error("This component must be used within a MessageProvider");
|
182
|
+
throw new Error("This component must be used within a MessageProvider.");
|
191
183
|
return context;
|
192
184
|
};
|
193
185
|
|
@@ -205,10 +197,8 @@ var useComposerContext = () => {
|
|
205
197
|
var useComposerIf = (props) => {
|
206
198
|
const { useComposer } = useComposerContext();
|
207
199
|
return useComposer((composer) => {
|
208
|
-
if (props.editing === true && !composer.isEditing)
|
209
|
-
|
210
|
-
if (props.editing === false && composer.isEditing)
|
211
|
-
return false;
|
200
|
+
if (props.editing === true && !composer.isEditing) return false;
|
201
|
+
if (props.editing === false && composer.isEditing) return false;
|
212
202
|
return true;
|
213
203
|
});
|
214
204
|
};
|
@@ -230,6 +220,14 @@ __export(message_exports, {
|
|
230
220
|
import { useMemo, useState } from "react";
|
231
221
|
import { create as create2 } from "zustand";
|
232
222
|
|
223
|
+
// src/utils/context/getMessageText.tsx
|
224
|
+
var getMessageText = (message) => {
|
225
|
+
const textParts = message.content.filter(
|
226
|
+
(part) => part.type === "text"
|
227
|
+
);
|
228
|
+
return textParts.map((part) => part.text).join("\n\n");
|
229
|
+
};
|
230
|
+
|
233
231
|
// src/utils/context/stores/ComposerStore.ts
|
234
232
|
import {
|
235
233
|
create
|
@@ -256,8 +254,7 @@ var makeMessageComposerStore = ({
|
|
256
254
|
onSend(value);
|
257
255
|
},
|
258
256
|
cancel: () => {
|
259
|
-
if (!get().isEditing)
|
260
|
-
return false;
|
257
|
+
if (!get().isEditing) return false;
|
261
258
|
set({ isEditing: false });
|
262
259
|
return true;
|
263
260
|
}
|
@@ -276,8 +273,7 @@ var makeThreadComposerStore = (useThread) => create()((set, get, store) => {
|
|
276
273
|
},
|
277
274
|
cancel: () => {
|
278
275
|
const thread = useThread.getState();
|
279
|
-
if (!thread.isRunning)
|
280
|
-
return false;
|
276
|
+
if (!thread.isRunning) return false;
|
281
277
|
useThread.getState().cancelRun();
|
282
278
|
return true;
|
283
279
|
}
|
@@ -292,30 +288,36 @@ var getIsLast = (thread, message) => {
|
|
292
288
|
var useMessageContext2 = () => {
|
293
289
|
const { useThread } = useAssistantContext();
|
294
290
|
const [context] = useState(() => {
|
295
|
-
const useMessage = create2(() => ({
|
291
|
+
const useMessage = create2((set) => ({
|
296
292
|
message: null,
|
297
293
|
parentId: null,
|
298
294
|
branches: [],
|
299
295
|
isLast: false,
|
300
296
|
isCopied: false,
|
301
297
|
isHovering: false,
|
302
|
-
setIsCopied: () => {
|
298
|
+
setIsCopied: (value) => {
|
299
|
+
set({ isCopied: value });
|
303
300
|
},
|
304
|
-
setIsHovering: () => {
|
301
|
+
setIsHovering: (value) => {
|
302
|
+
set({ isHovering: value });
|
305
303
|
}
|
306
304
|
}));
|
307
305
|
const useComposer = makeMessageComposerStore({
|
308
306
|
onEdit: () => {
|
309
307
|
const message = useMessage.getState().message;
|
310
308
|
if (message.role !== "user")
|
311
|
-
throw new Error(
|
312
|
-
|
309
|
+
throw new Error(
|
310
|
+
"Tried to edit a non-user message. Editing is only supported for user messages. This is likely an internal bug in assistant-ui."
|
311
|
+
);
|
312
|
+
const text = getMessageText(message);
|
313
313
|
return text;
|
314
314
|
},
|
315
315
|
onSend: (text) => {
|
316
316
|
const { message, parentId } = useMessage.getState();
|
317
317
|
if (message.role !== "user")
|
318
|
-
throw new Error(
|
318
|
+
throw new Error(
|
319
|
+
"Tried to edit a non-user message. Editing is only supported for user messages. This is likely an internal bug in assistant-ui."
|
320
|
+
);
|
319
321
|
const nonTextParts = message.content.filter(
|
320
322
|
(part) => part.type !== "text" && part.type !== "ui"
|
321
323
|
);
|
@@ -338,23 +340,14 @@ var MessageProvider = ({
|
|
338
340
|
const context = useMessageContext2();
|
339
341
|
const isLast = useThread((thread) => getIsLast(thread, message));
|
340
342
|
const branches = useThread((thread) => thread.getBranches(message.id));
|
341
|
-
const [isCopied, setIsCopied] = useState(false);
|
342
|
-
const [isHovering, setIsHovering] = useState(false);
|
343
343
|
useMemo(() => {
|
344
|
-
context.useMessage.setState(
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
isHovering,
|
352
|
-
setIsCopied,
|
353
|
-
setIsHovering
|
354
|
-
},
|
355
|
-
true
|
356
|
-
);
|
357
|
-
}, [context, message, parentId, branches, isLast, isCopied, isHovering]);
|
344
|
+
context.useMessage.setState({
|
345
|
+
message,
|
346
|
+
parentId,
|
347
|
+
branches,
|
348
|
+
isLast
|
349
|
+
});
|
350
|
+
}, [context, message, parentId, branches, isLast]);
|
358
351
|
return /* @__PURE__ */ jsx4(MessageContext.Provider, { value: context, children });
|
359
352
|
};
|
360
353
|
|
@@ -391,18 +384,12 @@ var MessageRoot = forwardRef3(
|
|
391
384
|
var useMessageIf = (props) => {
|
392
385
|
const { useMessage } = useMessageContext();
|
393
386
|
return useMessage(({ message, branches, isLast, isCopied, isHovering }) => {
|
394
|
-
if (props.hasBranches === true && branches.length < 2)
|
395
|
-
|
396
|
-
if (props.
|
397
|
-
|
398
|
-
if (props.
|
399
|
-
|
400
|
-
if (props.lastOrHover === true && !isHovering && !isLast)
|
401
|
-
return false;
|
402
|
-
if (props.copied === true && !isCopied)
|
403
|
-
return false;
|
404
|
-
if (props.copied === false && isCopied)
|
405
|
-
return false;
|
387
|
+
if (props.hasBranches === true && branches.length < 2) return false;
|
388
|
+
if (props.user && message.role !== "user") return false;
|
389
|
+
if (props.assistant && message.role !== "assistant") return false;
|
390
|
+
if (props.lastOrHover === true && !isHovering && !isLast) return false;
|
391
|
+
if (props.copied === true && !isCopied) return false;
|
392
|
+
if (props.copied === false && isCopied) return false;
|
406
393
|
return true;
|
407
394
|
});
|
408
395
|
};
|
@@ -464,8 +451,7 @@ var ThreadMessages = ({ components }) => {
|
|
464
451
|
const thread = useThread();
|
465
452
|
const messages = thread.messages;
|
466
453
|
const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
|
467
|
-
if (messages.length === 0)
|
468
|
-
return null;
|
454
|
+
if (messages.length === 0) return null;
|
469
455
|
return /* @__PURE__ */ jsx7(Fragment2, { children: messages.map((message, idx) => {
|
470
456
|
const parentId = messages[idx - 1]?.id ?? null;
|
471
457
|
return /* @__PURE__ */ jsxs2(
|
@@ -565,8 +551,7 @@ var ComposerRoot = forwardRef6(
|
|
565
551
|
const ref = useComposedRefs2(forwardedRef, formRef);
|
566
552
|
const handleSubmit = (e) => {
|
567
553
|
const composerState = useComposer.getState();
|
568
|
-
if (!composerState.isEditing)
|
569
|
-
return;
|
554
|
+
if (!composerState.isEditing) return;
|
570
555
|
e.preventDefault();
|
571
556
|
composerState.send();
|
572
557
|
useViewport.getState().scrollToBottom();
|
@@ -599,14 +584,12 @@ var ComposerInput = forwardRef7(
|
|
599
584
|
const { useThread, useViewport } = useAssistantContext();
|
600
585
|
const { useComposer, type } = useComposerContext();
|
601
586
|
const value = useComposer((c) => {
|
602
|
-
if (!c.isEditing)
|
603
|
-
return "";
|
587
|
+
if (!c.isEditing) return "";
|
604
588
|
return c.value;
|
605
589
|
});
|
606
590
|
const Component = asChild ? Slot : TextareaAutosize;
|
607
591
|
const handleKeyPress = (e) => {
|
608
|
-
if (disabled)
|
609
|
-
return;
|
592
|
+
if (disabled) return;
|
610
593
|
const composer = useComposer.getState();
|
611
594
|
if (e.key === "Escape") {
|
612
595
|
if (useComposer.getState().cancel()) {
|
@@ -626,8 +609,7 @@ var ComposerInput = forwardRef7(
|
|
626
609
|
const autoFocusEnabled = autoFocus && !disabled;
|
627
610
|
const focus = useCallback(() => {
|
628
611
|
const textarea = textareaRef.current;
|
629
|
-
if (!textarea || !autoFocusEnabled)
|
630
|
-
return;
|
612
|
+
if (!textarea || !autoFocusEnabled) return;
|
631
613
|
textarea.focus();
|
632
614
|
textarea.setSelectionRange(
|
633
615
|
textareaRef.current.value.length,
|
@@ -649,8 +631,7 @@ var ComposerInput = forwardRef7(
|
|
649
631
|
disabled,
|
650
632
|
onChange: composeEventHandlers6(onChange, (e) => {
|
651
633
|
const composerState = useComposer.getState();
|
652
|
-
if (!composerState.isEditing)
|
653
|
-
return;
|
634
|
+
if (!composerState.isEditing) return;
|
654
635
|
return composerState.setValue(e.target.value);
|
655
636
|
}),
|
656
637
|
onKeyDown: composeEventHandlers6(onKeyDown, handleKeyPress)
|
@@ -748,8 +729,7 @@ var useGoToNextBranch = () => {
|
|
748
729
|
[useMessage, useComposer],
|
749
730
|
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
|
750
731
|
);
|
751
|
-
if (disabled)
|
752
|
-
return null;
|
732
|
+
if (disabled) return null;
|
753
733
|
return () => {
|
754
734
|
const { message, branches } = useMessage.getState();
|
755
735
|
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
|
@@ -792,8 +772,7 @@ var useGoToPreviousBranch = () => {
|
|
792
772
|
[useMessage, useComposer],
|
793
773
|
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
|
794
774
|
);
|
795
|
-
if (disabled)
|
796
|
-
return null;
|
775
|
+
if (disabled) return null;
|
797
776
|
return () => {
|
798
777
|
const { message, branches } = useMessage.getState();
|
799
778
|
useThread.getState().switchToBranch(
|
@@ -853,20 +832,16 @@ var ActionBarRoot = forwardRef12(({ hideWhenRunning, autohide, autohideFloat, ..
|
|
853
832
|
const hideAndfloatStatus = useCombinedStore(
|
854
833
|
[useThread, useMessage],
|
855
834
|
(t, m) => {
|
856
|
-
if (hideWhenRunning && t.isRunning)
|
857
|
-
return "hidden" /* Hidden */;
|
835
|
+
if (hideWhenRunning && t.isRunning) return "hidden" /* Hidden */;
|
858
836
|
const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
|
859
|
-
if (!autohideEnabled)
|
860
|
-
|
861
|
-
if (!m.isHovering)
|
862
|
-
return "hidden" /* Hidden */;
|
837
|
+
if (!autohideEnabled) return "normal" /* Normal */;
|
838
|
+
if (!m.isHovering) return "hidden" /* Hidden */;
|
863
839
|
if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branches.length <= 1)
|
864
840
|
return "floating" /* Floating */;
|
865
841
|
return "normal" /* Normal */;
|
866
842
|
}
|
867
843
|
);
|
868
|
-
if (hideAndfloatStatus === "hidden" /* Hidden */)
|
869
|
-
return null;
|
844
|
+
if (hideAndfloatStatus === "hidden" /* Hidden */) return null;
|
870
845
|
return /* @__PURE__ */ jsx18(
|
871
846
|
Primitive11.div,
|
872
847
|
{
|
@@ -880,14 +855,18 @@ var ActionBarRoot = forwardRef12(({ hideWhenRunning, autohide, autohideFloat, ..
|
|
880
855
|
// src/actions/useCopyMessage.tsx
|
881
856
|
var useCopyMessage = ({ copiedDuration = 3e3 }) => {
|
882
857
|
const { useMessage, useComposer } = useMessageContext();
|
883
|
-
const
|
884
|
-
|
885
|
-
|
858
|
+
const hasCopyableContent = useCombinedStore(
|
859
|
+
[useMessage, useComposer],
|
860
|
+
(m, c) => {
|
861
|
+
return c.isEditing || m.message.content.some((c2) => c2.type === "text");
|
862
|
+
}
|
863
|
+
);
|
864
|
+
if (!hasCopyableContent) return null;
|
886
865
|
return () => {
|
866
|
+
const { isEditing, value: composerValue } = useComposer.getState();
|
887
867
|
const { message, setIsCopied } = useMessage.getState();
|
888
|
-
|
889
|
-
|
890
|
-
navigator.clipboard.writeText(message.content[0].text);
|
868
|
+
const valueToCopy = isEditing ? composerValue : getMessageText(message);
|
869
|
+
navigator.clipboard.writeText(valueToCopy);
|
891
870
|
setIsCopied(true);
|
892
871
|
setTimeout(() => setIsCopied(false), copiedDuration);
|
893
872
|
};
|
@@ -904,12 +883,9 @@ var useReloadMessage = () => {
|
|
904
883
|
[useThread, useMessage],
|
905
884
|
(t, m) => t.isRunning || m.message.role !== "assistant"
|
906
885
|
);
|
907
|
-
if (disabled)
|
908
|
-
return null;
|
886
|
+
if (disabled) return null;
|
909
887
|
return () => {
|
910
|
-
const {
|
911
|
-
if (message.role !== "assistant")
|
912
|
-
throw new Error("Reloading is only supported on assistant messages");
|
888
|
+
const { parentId } = useMessage.getState();
|
913
889
|
useThread.getState().startRun(parentId);
|
914
890
|
useViewport.getState().scrollToBottom();
|
915
891
|
};
|
@@ -925,8 +901,7 @@ var useBeginMessageEdit = () => {
|
|
925
901
|
[useMessage, useComposer],
|
926
902
|
(m, c) => m.message.role !== "user" || c.isEditing
|
927
903
|
);
|
928
|
-
if (disabled)
|
929
|
-
return null;
|
904
|
+
if (disabled) return null;
|
930
905
|
return () => {
|
931
906
|
const { edit } = useComposer.getState();
|
932
907
|
edit();
|
@@ -974,13 +949,13 @@ var makeDummyThreadStore = () => {
|
|
974
949
|
switchToBranch: () => {
|
975
950
|
throw new Error("Not implemented");
|
976
951
|
},
|
977
|
-
append:
|
952
|
+
append: () => {
|
978
953
|
throw new Error("Not implemented");
|
979
954
|
},
|
980
|
-
|
955
|
+
startRun: () => {
|
981
956
|
throw new Error("Not implemented");
|
982
957
|
},
|
983
|
-
|
958
|
+
cancelRun: () => {
|
984
959
|
throw new Error("Not implemented");
|
985
960
|
}
|
986
961
|
}));
|
@@ -1008,8 +983,7 @@ var optimisticPrefix = "__optimistic__";
|
|
1008
983
|
var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
|
1009
984
|
var isOptimisticId = (id) => id.startsWith(optimisticPrefix);
|
1010
985
|
var findHead = (message) => {
|
1011
|
-
if (message.next)
|
1012
|
-
return findHead(message.next);
|
986
|
+
if (message.next) return findHead(message.next);
|
1013
987
|
return message;
|
1014
988
|
};
|
1015
989
|
var MessageRepository = class {
|
@@ -1024,28 +998,21 @@ var MessageRepository = class {
|
|
1024
998
|
}
|
1025
999
|
return messages;
|
1026
1000
|
}
|
1027
|
-
|
1028
|
-
// TODO previousId does not fix children
|
1029
|
-
// TODO cut / link operations
|
1030
|
-
addOrUpdateMessage(parentId, message, previousId = message.id) {
|
1001
|
+
addOrUpdateMessage(parentId, message) {
|
1031
1002
|
const item = this.messages.get(message.id);
|
1032
1003
|
if (item) {
|
1033
|
-
if (item.prev?.current.id !== parentId) {
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
if (previousId !== message.id) {
|
1039
|
-
this.messages.delete(previousId);
|
1040
|
-
this.messages.set(message.id, item);
|
1041
|
-
}
|
1042
|
-
return;
|
1043
|
-
}
|
1004
|
+
if ((item.prev?.current.id ?? null) !== parentId) {
|
1005
|
+
this.deleteMessage(message.id);
|
1006
|
+
} else {
|
1007
|
+
item.current = message;
|
1008
|
+
return;
|
1044
1009
|
}
|
1045
1010
|
}
|
1046
1011
|
const prev = parentId ? this.messages.get(parentId) : null;
|
1047
1012
|
if (prev === void 0)
|
1048
|
-
throw new Error(
|
1013
|
+
throw new Error(
|
1014
|
+
"MessageRepository(addOrUpdateMessage): Parent message not found. This is likely an internal bug in assistant-ui."
|
1015
|
+
);
|
1049
1016
|
const newItem = {
|
1050
1017
|
prev,
|
1051
1018
|
current: message,
|
@@ -1067,7 +1034,9 @@ var MessageRepository = class {
|
|
1067
1034
|
deleteMessage(messageId) {
|
1068
1035
|
const message = this.messages.get(messageId);
|
1069
1036
|
if (!message)
|
1070
|
-
throw new Error(
|
1037
|
+
throw new Error(
|
1038
|
+
"MessageRepository(deleteMessage): Message not found. This is likely an internal bug in assistant-ui."
|
1039
|
+
);
|
1071
1040
|
if (message.children.length > 0) {
|
1072
1041
|
for (const child of message.children) {
|
1073
1042
|
this.deleteMessage(child);
|
@@ -1082,7 +1051,9 @@ var MessageRepository = class {
|
|
1082
1051
|
const childId = message.prev.children.at(-1);
|
1083
1052
|
const child = childId ? this.messages.get(childId) : null;
|
1084
1053
|
if (child === void 0)
|
1085
|
-
throw new Error(
|
1054
|
+
throw new Error(
|
1055
|
+
"MessageRepository(deleteMessage): Child message not found. This is likely an internal bug in assistant-ui."
|
1056
|
+
);
|
1086
1057
|
message.prev.next = child;
|
1087
1058
|
}
|
1088
1059
|
} else {
|
@@ -1099,17 +1070,6 @@ var MessageRepository = class {
|
|
1099
1070
|
} while (this.messages.has(optimisticId));
|
1100
1071
|
return optimisticId;
|
1101
1072
|
}
|
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
|
-
}
|
1113
1073
|
commitOptimisticRun(parentId) {
|
1114
1074
|
const optimisticId = this.getOptimisticId();
|
1115
1075
|
this.addOrUpdateMessage(parentId, {
|
@@ -1128,7 +1088,9 @@ var MessageRepository = class {
|
|
1128
1088
|
getBranches(messageId) {
|
1129
1089
|
const message = this.messages.get(messageId);
|
1130
1090
|
if (!message)
|
1131
|
-
throw new Error(
|
1091
|
+
throw new Error(
|
1092
|
+
"MessageRepository(getBranches): Message not found. This is likely an internal bug in assistant-ui."
|
1093
|
+
);
|
1132
1094
|
if (message.prev) {
|
1133
1095
|
return message.prev.children;
|
1134
1096
|
}
|
@@ -1137,7 +1099,9 @@ var MessageRepository = class {
|
|
1137
1099
|
switchToBranch(messageId) {
|
1138
1100
|
const message = this.messages.get(messageId);
|
1139
1101
|
if (!message)
|
1140
|
-
throw new Error(
|
1102
|
+
throw new Error(
|
1103
|
+
"MessageRepository(switchToBranch): Branch not found. This is likely an internal bug in assistant-ui."
|
1104
|
+
);
|
1141
1105
|
if (message.prev) {
|
1142
1106
|
message.prev.next = message;
|
1143
1107
|
}
|
@@ -1147,7 +1111,9 @@ var MessageRepository = class {
|
|
1147
1111
|
if (messageId) {
|
1148
1112
|
const message = this.messages.get(messageId);
|
1149
1113
|
if (!message)
|
1150
|
-
throw new Error(
|
1114
|
+
throw new Error(
|
1115
|
+
"MessageRepository(resetHead): Branch not found. This is likely an internal bug in assistant-ui."
|
1116
|
+
);
|
1151
1117
|
this.head = message;
|
1152
1118
|
for (let current = message; current; current = current.prev) {
|
1153
1119
|
if (current.prev) {
|
@@ -1169,8 +1135,7 @@ var ThreadMessageConverter = class {
|
|
1169
1135
|
convertMessages(messages) {
|
1170
1136
|
return messages.map((m) => {
|
1171
1137
|
const cached = this.cache.get(m);
|
1172
|
-
if (cached)
|
1173
|
-
return cached;
|
1138
|
+
if (cached) return cached;
|
1174
1139
|
const newMessage = this.converter(m);
|
1175
1140
|
this.cache.set(m, newMessage);
|
1176
1141
|
return newMessage;
|
@@ -1181,32 +1146,42 @@ var ThreadMessageConverter = class {
|
|
1181
1146
|
// src/adapters/vercel/useVercelAIThreadState.tsx
|
1182
1147
|
var vercelToThreadMessage = (message) => {
|
1183
1148
|
if (message.role !== "user" && message.role !== "assistant")
|
1184
|
-
throw new Error(
|
1149
|
+
throw new Error(
|
1150
|
+
`You have a message with an unsupported role. The role ${message.role} is not supported.`
|
1151
|
+
);
|
1185
1152
|
return {
|
1186
1153
|
id: message.id,
|
1187
1154
|
role: message.role,
|
1188
|
-
content: [
|
1155
|
+
content: [
|
1156
|
+
...message.content ? [{ type: "text", text: message.content }] : [],
|
1157
|
+
...message.toolInvocations?.map((t) => ({
|
1158
|
+
type: "tool-call",
|
1159
|
+
name: t.toolName,
|
1160
|
+
args: t.args,
|
1161
|
+
result: "result" in t ? t.result : void 0
|
1162
|
+
})) ?? []
|
1163
|
+
],
|
1164
|
+
// ignore type mismatch for now
|
1189
1165
|
createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
|
1190
1166
|
innerMessage: message
|
1191
1167
|
};
|
1192
1168
|
};
|
1193
1169
|
var converter = new ThreadMessageConverter(vercelToThreadMessage);
|
1194
1170
|
var sliceMessagesUntil = (messages, messageId) => {
|
1195
|
-
if (messageId == null)
|
1196
|
-
|
1197
|
-
if (isOptimisticId(messageId))
|
1198
|
-
return messages;
|
1171
|
+
if (messageId == null) return [];
|
1172
|
+
if (isOptimisticId(messageId)) return messages;
|
1199
1173
|
const messageIdx = messages.findIndex((m) => m.id === messageId);
|
1200
1174
|
if (messageIdx === -1)
|
1201
|
-
throw new Error(
|
1175
|
+
throw new Error(
|
1176
|
+
"useVercelAIThreadState: Message not found. This is liekly an internal bug in assistant-ui."
|
1177
|
+
);
|
1202
1178
|
return messages.slice(0, messageIdx + 1);
|
1203
1179
|
};
|
1204
1180
|
var hasUpcomingMessage = (isRunning, messages) => {
|
1205
1181
|
return isRunning && messages[messages.length - 1]?.role !== "assistant";
|
1206
1182
|
};
|
1207
1183
|
var getIsRunning = (vercel) => {
|
1208
|
-
if ("isLoading" in vercel)
|
1209
|
-
return vercel.isLoading;
|
1184
|
+
if ("isLoading" in vercel) return vercel.isLoading;
|
1210
1185
|
return vercel.status === "in_progress";
|
1211
1186
|
};
|
1212
1187
|
var useVercelAIThreadState = (vercel) => {
|
@@ -1234,13 +1209,13 @@ var useVercelAIThreadState = (vercel) => {
|
|
1234
1209
|
data.resetHead(assistantOptimisticIdRef.current ?? vm.at(-1)?.id ?? null);
|
1235
1210
|
return data.getMessages();
|
1236
1211
|
}, [data, isRunning, vercel.messages]);
|
1237
|
-
const
|
1212
|
+
const getBranches2 = useCallback2(
|
1238
1213
|
(messageId) => {
|
1239
1214
|
return data.getBranches(messageId);
|
1240
1215
|
},
|
1241
1216
|
[data]
|
1242
1217
|
);
|
1243
|
-
const
|
1218
|
+
const switchToBranch2 = useCallback2(
|
1244
1219
|
(messageId) => {
|
1245
1220
|
data.switchToBranch(messageId);
|
1246
1221
|
vercelRef.current.setMessages(
|
@@ -1252,7 +1227,9 @@ var useVercelAIThreadState = (vercel) => {
|
|
1252
1227
|
const startRun = useCallback2(async (parentId) => {
|
1253
1228
|
const reloadMaybe = "reload" in vercelRef.current ? vercelRef.current.reload : void 0;
|
1254
1229
|
if (!reloadMaybe)
|
1255
|
-
throw new Error(
|
1230
|
+
throw new Error(
|
1231
|
+
"Reload is not supported by Vercel AI SDK's useAssistant."
|
1232
|
+
);
|
1256
1233
|
const newMessages = sliceMessagesUntil(
|
1257
1234
|
vercelRef.current.messages,
|
1258
1235
|
parentId
|
@@ -1262,7 +1239,7 @@ var useVercelAIThreadState = (vercel) => {
|
|
1262
1239
|
}, []);
|
1263
1240
|
const append = useCallback2(async (message) => {
|
1264
1241
|
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
1265
|
-
throw new Error("Only text content is supported by Vercel AI SDK");
|
1242
|
+
throw new Error("Only text content is supported by Vercel AI SDK.");
|
1266
1243
|
const newMessages = sliceMessagesUntil(
|
1267
1244
|
vercelRef.current.messages,
|
1268
1245
|
message.parentId
|
@@ -1273,7 +1250,7 @@ var useVercelAIThreadState = (vercel) => {
|
|
1273
1250
|
content: message.content[0].text
|
1274
1251
|
});
|
1275
1252
|
}, []);
|
1276
|
-
const
|
1253
|
+
const cancelRun2 = useCallback2(() => {
|
1277
1254
|
const lastMessage = vercelRef.current.messages.at(-1);
|
1278
1255
|
vercelRef.current.stop();
|
1279
1256
|
if (lastMessage?.role === "user") {
|
@@ -1284,20 +1261,20 @@ var useVercelAIThreadState = (vercel) => {
|
|
1284
1261
|
() => ({
|
1285
1262
|
isRunning,
|
1286
1263
|
messages,
|
1287
|
-
getBranches,
|
1288
|
-
switchToBranch,
|
1264
|
+
getBranches: getBranches2,
|
1265
|
+
switchToBranch: switchToBranch2,
|
1289
1266
|
append,
|
1290
1267
|
startRun,
|
1291
|
-
cancelRun
|
1268
|
+
cancelRun: cancelRun2
|
1292
1269
|
}),
|
1293
1270
|
[
|
1294
1271
|
isRunning,
|
1295
1272
|
messages,
|
1296
|
-
|
1297
|
-
|
1273
|
+
getBranches2,
|
1274
|
+
switchToBranch2,
|
1298
1275
|
append,
|
1299
1276
|
startRun,
|
1300
|
-
|
1277
|
+
cancelRun2
|
1301
1278
|
]
|
1302
1279
|
);
|
1303
1280
|
};
|
@@ -1326,12 +1303,11 @@ var VercelAIAssistantProvider = ({
|
|
1326
1303
|
// src/adapters/vercel/VercelRSCAssistantProvider.tsx
|
1327
1304
|
import {
|
1328
1305
|
useCallback as useCallback3,
|
1329
|
-
useMemo as useMemo5
|
1306
|
+
useMemo as useMemo5,
|
1307
|
+
useState as useState4
|
1330
1308
|
} from "react";
|
1331
1309
|
import { jsx as jsx20 } from "react/jsx-runtime";
|
1332
1310
|
var vercelToThreadMessage2 = (message) => {
|
1333
|
-
if (message.role !== "user" && message.role !== "assistant")
|
1334
|
-
throw new Error("Unsupported role");
|
1335
1311
|
return {
|
1336
1312
|
id: message.id,
|
1337
1313
|
role: message.role,
|
@@ -1339,6 +1315,22 @@ var vercelToThreadMessage2 = (message) => {
|
|
1339
1315
|
createdAt: message.createdAt ?? /* @__PURE__ */ new Date()
|
1340
1316
|
};
|
1341
1317
|
};
|
1318
|
+
var EMPTY_BRANCHES = [];
|
1319
|
+
var getBranches = () => {
|
1320
|
+
return EMPTY_BRANCHES;
|
1321
|
+
};
|
1322
|
+
var switchToBranch = () => {
|
1323
|
+
throw new Error(
|
1324
|
+
"Branch switching is not supported by VercelRSCAssistantProvider."
|
1325
|
+
);
|
1326
|
+
};
|
1327
|
+
var cancelRun = () => {
|
1328
|
+
if (process.env["NODE_ENV"] === "development") {
|
1329
|
+
console.warn(
|
1330
|
+
"Run cancellation is not supported by VercelRSCAssistantProvider."
|
1331
|
+
);
|
1332
|
+
}
|
1333
|
+
};
|
1342
1334
|
var VercelRSCAssistantProvider = ({
|
1343
1335
|
children,
|
1344
1336
|
convertMessage,
|
@@ -1348,6 +1340,11 @@ var VercelRSCAssistantProvider = ({
|
|
1348
1340
|
reload
|
1349
1341
|
}) => {
|
1350
1342
|
const context = useDummyAIAssistantContext();
|
1343
|
+
const [isRunning, setIsRunning] = useState4(false);
|
1344
|
+
const withRunning = useCallback3((callback) => {
|
1345
|
+
setIsRunning(true);
|
1346
|
+
return callback.finally(() => setIsRunning(false));
|
1347
|
+
}, []);
|
1351
1348
|
const converter2 = useMemo5(() => {
|
1352
1349
|
const rscConverter = convertMessage ?? ((m) => m);
|
1353
1350
|
return new ThreadMessageConverter((m) => {
|
@@ -1362,32 +1359,39 @@ var VercelRSCAssistantProvider = ({
|
|
1362
1359
|
if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null)) {
|
1363
1360
|
if (!edit)
|
1364
1361
|
throw new Error(
|
1365
|
-
"
|
1362
|
+
"Message editing is not enabled, please provide an edit callback to VercelRSCAssistantProvider."
|
1366
1363
|
);
|
1367
|
-
await edit(message);
|
1364
|
+
await withRunning(edit(message));
|
1368
1365
|
} else {
|
1369
|
-
await appendCallback(message);
|
1366
|
+
await withRunning(appendCallback(message));
|
1370
1367
|
}
|
1371
1368
|
},
|
1372
|
-
[context, appendCallback, edit]
|
1369
|
+
[context, withRunning, appendCallback, edit]
|
1373
1370
|
);
|
1374
1371
|
const startRun = useCallback3(
|
1375
1372
|
async (parentId) => {
|
1376
1373
|
if (!reload)
|
1377
1374
|
throw new Error(
|
1378
|
-
"
|
1375
|
+
"Message reloading is not enabled, please provide a reload callback to VercelRSCAssistantProvider."
|
1379
1376
|
);
|
1380
|
-
await reload(parentId);
|
1377
|
+
await withRunning(reload(parentId));
|
1381
1378
|
},
|
1382
|
-
[reload]
|
1379
|
+
[withRunning, reload]
|
1383
1380
|
);
|
1384
1381
|
useMemo5(() => {
|
1385
|
-
context.useThread.setState(
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1382
|
+
context.useThread.setState(
|
1383
|
+
{
|
1384
|
+
messages,
|
1385
|
+
isRunning,
|
1386
|
+
getBranches,
|
1387
|
+
switchToBranch,
|
1388
|
+
append,
|
1389
|
+
startRun,
|
1390
|
+
cancelRun
|
1391
|
+
},
|
1392
|
+
true
|
1393
|
+
);
|
1394
|
+
}, [context, messages, isRunning, append, startRun]);
|
1391
1395
|
return /* @__PURE__ */ jsx20(AssistantContext.Provider, { value: context, children });
|
1392
1396
|
};
|
1393
1397
|
export {
|