@assistant-ui/react 0.0.18 → 0.0.19
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 +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +70 -55
- package/dist/index.mjs +49 -29
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
@@ -103,16 +103,16 @@ declare namespace index$4 {
|
|
103
103
|
export { ComposerCancel as Cancel, ComposerIf as If, ComposerInput as Input, ComposerRoot as Root, ComposerSend as Send };
|
104
104
|
}
|
105
105
|
|
106
|
-
type BaseComposerState = {
|
106
|
+
type BaseComposerState = Readonly<{
|
107
107
|
value: string;
|
108
108
|
setValue: (value: string) => void;
|
109
|
-
}
|
110
|
-
type MessageComposerState = BaseComposerState & {
|
109
|
+
}>;
|
110
|
+
type MessageComposerState = BaseComposerState & Readonly<{
|
111
111
|
isEditing: boolean;
|
112
112
|
edit: () => void;
|
113
113
|
send: () => void;
|
114
114
|
cancel: () => boolean;
|
115
|
-
}
|
115
|
+
}>;
|
116
116
|
|
117
117
|
type TextContentPart = {
|
118
118
|
type: "text";
|
@@ -379,10 +379,10 @@ declare class VercelModelAdapter implements ChatModelAdapter {
|
|
379
379
|
declare const getVercelMessage: (message: ThreadMessage) => Message | undefined;
|
380
380
|
declare const getVercelRSCMessage: <T>(message: ThreadMessage) => T | undefined;
|
381
381
|
|
382
|
-
type MessageState = {
|
383
|
-
message: ThreadMessage
|
382
|
+
type MessageState = Readonly<{
|
383
|
+
message: Readonly<ThreadMessage>;
|
384
384
|
parentId: string | null;
|
385
|
-
branches: string[];
|
385
|
+
branches: readonly string[];
|
386
386
|
isLast: boolean;
|
387
387
|
inProgressIndicator: ReactNode | null;
|
388
388
|
setInProgressIndicator: (value: ReactNode | null) => void;
|
@@ -390,7 +390,7 @@ type MessageState = {
|
|
390
390
|
setIsCopied: (value: boolean) => void;
|
391
391
|
isHovering: boolean;
|
392
392
|
setIsHovering: (value: boolean) => void;
|
393
|
-
}
|
393
|
+
}>;
|
394
394
|
type MessageStore = {
|
395
395
|
useMessage: UseBoundStore<StoreApi<MessageState>>;
|
396
396
|
useComposer: UseBoundStore<StoreApi<MessageComposerState>>;
|
package/dist/index.d.ts
CHANGED
@@ -103,16 +103,16 @@ declare namespace index$4 {
|
|
103
103
|
export { ComposerCancel as Cancel, ComposerIf as If, ComposerInput as Input, ComposerRoot as Root, ComposerSend as Send };
|
104
104
|
}
|
105
105
|
|
106
|
-
type BaseComposerState = {
|
106
|
+
type BaseComposerState = Readonly<{
|
107
107
|
value: string;
|
108
108
|
setValue: (value: string) => void;
|
109
|
-
}
|
110
|
-
type MessageComposerState = BaseComposerState & {
|
109
|
+
}>;
|
110
|
+
type MessageComposerState = BaseComposerState & Readonly<{
|
111
111
|
isEditing: boolean;
|
112
112
|
edit: () => void;
|
113
113
|
send: () => void;
|
114
114
|
cancel: () => boolean;
|
115
|
-
}
|
115
|
+
}>;
|
116
116
|
|
117
117
|
type TextContentPart = {
|
118
118
|
type: "text";
|
@@ -379,10 +379,10 @@ declare class VercelModelAdapter implements ChatModelAdapter {
|
|
379
379
|
declare const getVercelMessage: (message: ThreadMessage) => Message | undefined;
|
380
380
|
declare const getVercelRSCMessage: <T>(message: ThreadMessage) => T | undefined;
|
381
381
|
|
382
|
-
type MessageState = {
|
383
|
-
message: ThreadMessage
|
382
|
+
type MessageState = Readonly<{
|
383
|
+
message: Readonly<ThreadMessage>;
|
384
384
|
parentId: string | null;
|
385
|
-
branches: string[];
|
385
|
+
branches: readonly string[];
|
386
386
|
isLast: boolean;
|
387
387
|
inProgressIndicator: ReactNode | null;
|
388
388
|
setInProgressIndicator: (value: ReactNode | null) => void;
|
@@ -390,7 +390,7 @@ type MessageState = {
|
|
390
390
|
setIsCopied: (value: boolean) => void;
|
391
391
|
isHovering: boolean;
|
392
392
|
setIsHovering: (value: boolean) => void;
|
393
|
-
}
|
393
|
+
}>;
|
394
394
|
type MessageStore = {
|
395
395
|
useMessage: UseBoundStore<StoreApi<MessageState>>;
|
396
396
|
useComposer: UseBoundStore<StoreApi<MessageComposerState>>;
|
package/dist/index.js
CHANGED
@@ -173,18 +173,22 @@ var ThreadViewport = (0, import_react5.forwardRef)(({ autoScroll = true, onScrol
|
|
173
173
|
const ref = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, divRef);
|
174
174
|
const { useViewport } = useAssistantContext();
|
175
175
|
const firstRenderRef = (0, import_react5.useRef)(true);
|
176
|
+
const isScrollingToBottomRef = (0, import_react5.useRef)(false);
|
176
177
|
const lastScrollTop = (0, import_react5.useRef)(0);
|
177
178
|
const scrollToBottom = () => {
|
178
179
|
const div = messagesEndRef.current;
|
179
180
|
if (!div || !autoScroll) return;
|
180
181
|
const behavior = firstRenderRef.current ? "instant" : "auto";
|
181
182
|
firstRenderRef.current = false;
|
182
|
-
|
183
|
+
isScrollingToBottomRef.current = true;
|
183
184
|
div.scrollIntoView({ behavior });
|
184
185
|
};
|
185
186
|
useOnResizeContent(divRef, () => {
|
186
|
-
if (!useViewport.getState().isAtBottom)
|
187
|
-
|
187
|
+
if (!isScrollingToBottomRef.current && !useViewport.getState().isAtBottom) {
|
188
|
+
handleScroll();
|
189
|
+
} else {
|
190
|
+
scrollToBottom();
|
191
|
+
}
|
188
192
|
});
|
189
193
|
useOnScrollToBottom(() => {
|
190
194
|
scrollToBottom();
|
@@ -196,6 +200,7 @@ var ThreadViewport = (0, import_react5.forwardRef)(({ autoScroll = true, onScrol
|
|
196
200
|
const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
|
197
201
|
if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
|
198
202
|
} else if (newIsAtBottom !== isAtBottom) {
|
203
|
+
isScrollingToBottomRef.current = false;
|
199
204
|
useViewport.setState({ isAtBottom: newIsAtBottom });
|
200
205
|
}
|
201
206
|
lastScrollTop.current = div.scrollTop;
|
@@ -841,6 +846,7 @@ __export(branchPicker_exports, {
|
|
841
846
|
});
|
842
847
|
|
843
848
|
// src/actions/useGoToNextBranch.tsx
|
849
|
+
var import_react21 = require("react");
|
844
850
|
var useGoToNextBranch = () => {
|
845
851
|
const { useThread } = useAssistantContext();
|
846
852
|
const { useMessage, useComposer } = useMessageContext();
|
@@ -848,20 +854,21 @@ var useGoToNextBranch = () => {
|
|
848
854
|
[useMessage, useComposer],
|
849
855
|
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
|
850
856
|
);
|
851
|
-
|
852
|
-
return () => {
|
857
|
+
const callback = (0, import_react21.useCallback)(() => {
|
853
858
|
const { message, branches } = useMessage.getState();
|
854
859
|
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
|
855
|
-
};
|
860
|
+
}, [useMessage, useThread]);
|
861
|
+
if (disabled) return null;
|
862
|
+
return callback;
|
856
863
|
};
|
857
864
|
|
858
865
|
// src/utils/createActionButton.tsx
|
859
866
|
var import_primitive8 = require("@radix-ui/primitive");
|
860
867
|
var import_react_primitive10 = require("@radix-ui/react-primitive");
|
861
|
-
var
|
868
|
+
var import_react22 = require("react");
|
862
869
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
863
870
|
var createActionButton = (useActionButton) => {
|
864
|
-
return (0,
|
871
|
+
return (0, import_react22.forwardRef)(
|
865
872
|
(props, forwardedRef) => {
|
866
873
|
const onClick = useActionButton(props);
|
867
874
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
@@ -882,6 +889,7 @@ var createActionButton = (useActionButton) => {
|
|
882
889
|
var BranchPickerNext = createActionButton(useGoToNextBranch);
|
883
890
|
|
884
891
|
// src/actions/useGoToPreviousBranch.tsx
|
892
|
+
var import_react23 = require("react");
|
885
893
|
var useGoToPreviousBranch = () => {
|
886
894
|
const { useThread } = useAssistantContext();
|
887
895
|
const { useMessage, useComposer } = useMessageContext();
|
@@ -889,13 +897,12 @@ var useGoToPreviousBranch = () => {
|
|
889
897
|
[useMessage, useComposer],
|
890
898
|
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
|
891
899
|
);
|
892
|
-
|
893
|
-
return () => {
|
900
|
+
const callback = (0, import_react23.useCallback)(() => {
|
894
901
|
const { message, branches } = useMessage.getState();
|
895
|
-
useThread.getState().switchToBranch(
|
896
|
-
|
897
|
-
|
898
|
-
|
902
|
+
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
|
903
|
+
}, [useMessage, useThread]);
|
904
|
+
if (disabled) return null;
|
905
|
+
return callback;
|
899
906
|
};
|
900
907
|
|
901
908
|
// src/primitives/branchPicker/BranchPickerPrevious.tsx
|
@@ -919,9 +926,9 @@ var BranchPickerNumber = () => {
|
|
919
926
|
|
920
927
|
// src/primitives/branchPicker/BranchPickerRoot.tsx
|
921
928
|
var import_react_primitive11 = require("@radix-ui/react-primitive");
|
922
|
-
var
|
929
|
+
var import_react24 = require("react");
|
923
930
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
924
|
-
var BranchPickerRoot = (0,
|
931
|
+
var BranchPickerRoot = (0, import_react24.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
|
925
932
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_primitive11.Primitive.div, { ...rest, ref }) });
|
926
933
|
});
|
927
934
|
|
@@ -936,9 +943,9 @@ __export(actionBar_exports, {
|
|
936
943
|
|
937
944
|
// src/primitives/actionBar/ActionBarRoot.tsx
|
938
945
|
var import_react_primitive12 = require("@radix-ui/react-primitive");
|
939
|
-
var
|
946
|
+
var import_react25 = require("react");
|
940
947
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
941
|
-
var ActionBarRoot = (0,
|
948
|
+
var ActionBarRoot = (0, import_react25.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
|
942
949
|
const { useThread } = useAssistantContext();
|
943
950
|
const { useMessage } = useMessageContext();
|
944
951
|
const hideAndfloatStatus = useCombinedStore(
|
@@ -965,6 +972,7 @@ var ActionBarRoot = (0, import_react23.forwardRef)(({ hideWhenRunning, autohide,
|
|
965
972
|
});
|
966
973
|
|
967
974
|
// src/actions/useCopyMessage.tsx
|
975
|
+
var import_react26 = require("react");
|
968
976
|
var useCopyMessage = ({ copiedDuration = 3e3 }) => {
|
969
977
|
const { useMessage, useComposer } = useMessageContext();
|
970
978
|
const hasCopyableContent = useCombinedStore(
|
@@ -973,21 +981,23 @@ var useCopyMessage = ({ copiedDuration = 3e3 }) => {
|
|
973
981
|
return c.isEditing || m.message.content.some((c2) => c2.type === "text");
|
974
982
|
}
|
975
983
|
);
|
976
|
-
|
977
|
-
return () => {
|
984
|
+
const callback = (0, import_react26.useCallback)(() => {
|
978
985
|
const { isEditing, value: composerValue } = useComposer.getState();
|
979
986
|
const { message, setIsCopied } = useMessage.getState();
|
980
987
|
const valueToCopy = isEditing ? composerValue : getMessageText(message);
|
981
988
|
navigator.clipboard.writeText(valueToCopy);
|
982
989
|
setIsCopied(true);
|
983
990
|
setTimeout(() => setIsCopied(false), copiedDuration);
|
984
|
-
};
|
991
|
+
}, [useComposer, useMessage, copiedDuration]);
|
992
|
+
if (!hasCopyableContent) return null;
|
993
|
+
return callback;
|
985
994
|
};
|
986
995
|
|
987
996
|
// src/primitives/actionBar/ActionBarCopy.tsx
|
988
997
|
var ActionBarCopy = createActionButton(useCopyMessage);
|
989
998
|
|
990
999
|
// src/actions/useReloadMessage.tsx
|
1000
|
+
var import_react27 = require("react");
|
991
1001
|
var useReloadMessage = () => {
|
992
1002
|
const { useThread, useViewport } = useAssistantContext();
|
993
1003
|
const { useMessage } = useMessageContext();
|
@@ -995,29 +1005,32 @@ var useReloadMessage = () => {
|
|
995
1005
|
[useThread, useMessage],
|
996
1006
|
(t, m) => t.isRunning || m.message.role !== "assistant"
|
997
1007
|
);
|
998
|
-
|
999
|
-
return () => {
|
1008
|
+
const callback = (0, import_react27.useCallback)(() => {
|
1000
1009
|
const { parentId } = useMessage.getState();
|
1001
1010
|
useThread.getState().startRun(parentId);
|
1002
1011
|
useViewport.getState().scrollToBottom();
|
1003
|
-
};
|
1012
|
+
}, [useMessage, useThread, useViewport]);
|
1013
|
+
if (disabled) return null;
|
1014
|
+
return callback;
|
1004
1015
|
};
|
1005
1016
|
|
1006
1017
|
// src/primitives/actionBar/ActionBarReload.tsx
|
1007
1018
|
var ActionBarReload = createActionButton(useReloadMessage);
|
1008
1019
|
|
1009
1020
|
// src/actions/useBeginMessageEdit.tsx
|
1021
|
+
var import_react28 = require("react");
|
1010
1022
|
var useBeginMessageEdit = () => {
|
1011
1023
|
const { useMessage, useComposer } = useMessageContext();
|
1012
1024
|
const disabled = useCombinedStore(
|
1013
1025
|
[useMessage, useComposer],
|
1014
1026
|
(m, c) => m.message.role !== "user" || c.isEditing
|
1015
1027
|
);
|
1016
|
-
|
1017
|
-
return () => {
|
1028
|
+
const callback = (0, import_react28.useCallback)(() => {
|
1018
1029
|
const { edit } = useComposer.getState();
|
1019
1030
|
edit();
|
1020
|
-
};
|
1031
|
+
}, [useComposer]);
|
1032
|
+
if (disabled) return null;
|
1033
|
+
return callback;
|
1021
1034
|
};
|
1022
1035
|
|
1023
1036
|
// src/primitives/actionBar/ActionBarEdit.tsx
|
@@ -1031,10 +1044,10 @@ __export(contentPart_exports, {
|
|
1031
1044
|
});
|
1032
1045
|
|
1033
1046
|
// src/adapters/vercel/VercelAIAssistantProvider.tsx
|
1034
|
-
var
|
1047
|
+
var import_react31 = require("react");
|
1035
1048
|
|
1036
1049
|
// src/adapters/vercel/useDummyAIAssistantContext.tsx
|
1037
|
-
var
|
1050
|
+
var import_react29 = require("react");
|
1038
1051
|
var import_zustand5 = require("zustand");
|
1039
1052
|
|
1040
1053
|
// src/utils/context/stores/ViewportStore.tsx
|
@@ -1080,7 +1093,7 @@ var makeDummyThreadStore = () => {
|
|
1080
1093
|
}));
|
1081
1094
|
};
|
1082
1095
|
var useDummyAIAssistantContext = () => {
|
1083
|
-
const [context] = (0,
|
1096
|
+
const [context] = (0, import_react29.useState)(() => {
|
1084
1097
|
const useThread = makeDummyThreadStore();
|
1085
1098
|
const useViewport = makeViewportStore();
|
1086
1099
|
const useComposer = makeThreadComposerStore(useThread);
|
@@ -1091,7 +1104,7 @@ var useDummyAIAssistantContext = () => {
|
|
1091
1104
|
|
1092
1105
|
// src/adapters/vercel/useVercelAIThreadState.tsx
|
1093
1106
|
var import_react_use_callback_ref3 = require("@radix-ui/react-use-callback-ref");
|
1094
|
-
var
|
1107
|
+
var import_react30 = require("react");
|
1095
1108
|
|
1096
1109
|
// src/adapters/idUtils.tsx
|
1097
1110
|
var import_non_secure = require("nanoid/non-secure");
|
@@ -1330,11 +1343,11 @@ var getIsRunning = (vercel) => {
|
|
1330
1343
|
return vercel.status === "in_progress";
|
1331
1344
|
};
|
1332
1345
|
var useVercelAIThreadState = (vercel) => {
|
1333
|
-
const [data] = (0,
|
1346
|
+
const [data] = (0, import_react30.useState)(() => new MessageRepository());
|
1334
1347
|
const isRunning = getIsRunning(vercel);
|
1335
|
-
const converter = (0,
|
1336
|
-
const assistantOptimisticIdRef = (0,
|
1337
|
-
const messages = (0,
|
1348
|
+
const converter = (0, import_react30.useMemo)(() => new ThreadMessageConverter(), []);
|
1349
|
+
const assistantOptimisticIdRef = (0, import_react30.useRef)(null);
|
1350
|
+
const messages = (0, import_react30.useMemo)(() => {
|
1338
1351
|
const lastMessageId = vercel.messages.at(-1)?.id;
|
1339
1352
|
const convertCallback = (message, cache) => {
|
1340
1353
|
const status = lastMessageId === message.id && isRunning ? "in_progress" : "done";
|
@@ -1364,7 +1377,7 @@ var useVercelAIThreadState = (vercel) => {
|
|
1364
1377
|
data.resetHead(assistantOptimisticIdRef.current ?? vm.at(-1)?.id ?? null);
|
1365
1378
|
return data.getMessages();
|
1366
1379
|
}, [converter, data, isRunning, vercel.messages]);
|
1367
|
-
const getBranches2 = (0,
|
1380
|
+
const getBranches2 = (0, import_react30.useCallback)(
|
1368
1381
|
(messageId) => {
|
1369
1382
|
return data.getBranches(messageId);
|
1370
1383
|
},
|
@@ -1403,7 +1416,7 @@ var useVercelAIThreadState = (vercel) => {
|
|
1403
1416
|
vercel.setInput(lastMessage.content);
|
1404
1417
|
}
|
1405
1418
|
});
|
1406
|
-
return (0,
|
1419
|
+
return (0, import_react30.useMemo)(
|
1407
1420
|
() => ({
|
1408
1421
|
isRunning,
|
1409
1422
|
messages,
|
@@ -1434,10 +1447,10 @@ var VercelAIAssistantProvider = ({
|
|
1434
1447
|
const context = useDummyAIAssistantContext();
|
1435
1448
|
const vercel = "chat" in rest ? rest.chat : rest.assistant;
|
1436
1449
|
const threadState = useVercelAIThreadState(vercel);
|
1437
|
-
(0,
|
1450
|
+
(0, import_react31.useMemo)(() => {
|
1438
1451
|
context.useThread.setState(threadState, true);
|
1439
1452
|
}, [context, threadState]);
|
1440
|
-
(0,
|
1453
|
+
(0, import_react31.useMemo)(() => {
|
1441
1454
|
context.useComposer.setState({
|
1442
1455
|
value: vercel.input,
|
1443
1456
|
setValue: vercel.setInput
|
@@ -1447,7 +1460,7 @@ var VercelAIAssistantProvider = ({
|
|
1447
1460
|
};
|
1448
1461
|
|
1449
1462
|
// src/adapters/vercel/VercelRSCAssistantProvider.tsx
|
1450
|
-
var
|
1463
|
+
var import_react32 = require("react");
|
1451
1464
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
1452
1465
|
var vercelToThreadMessage2 = (converter, rawMessage) => {
|
1453
1466
|
const message = converter(rawMessage);
|
@@ -1485,12 +1498,12 @@ var VercelRSCAssistantProvider = ({
|
|
1485
1498
|
reload
|
1486
1499
|
}) => {
|
1487
1500
|
const context = useDummyAIAssistantContext();
|
1488
|
-
const [isRunning, setIsRunning] = (0,
|
1489
|
-
const withRunning = (0,
|
1501
|
+
const [isRunning, setIsRunning] = (0, import_react32.useState)(false);
|
1502
|
+
const withRunning = (0, import_react32.useCallback)((callback) => {
|
1490
1503
|
setIsRunning(true);
|
1491
1504
|
return callback.finally(() => setIsRunning(false));
|
1492
1505
|
}, []);
|
1493
|
-
const [converter, convertCallback] = (0,
|
1506
|
+
const [converter, convertCallback] = (0, import_react32.useMemo)(() => {
|
1494
1507
|
const rscConverter = convertMessage ?? ((m) => m);
|
1495
1508
|
const convertCallback2 = (m, cache) => {
|
1496
1509
|
if (cache) return cache;
|
@@ -1498,10 +1511,10 @@ var VercelRSCAssistantProvider = ({
|
|
1498
1511
|
};
|
1499
1512
|
return [new ThreadMessageConverter(), convertCallback2];
|
1500
1513
|
}, [convertMessage]);
|
1501
|
-
const messages = (0,
|
1514
|
+
const messages = (0, import_react32.useMemo)(() => {
|
1502
1515
|
return converter.convertMessages(convertCallback, vercelMessages);
|
1503
1516
|
}, [converter, convertCallback, vercelMessages]);
|
1504
|
-
const append = (0,
|
1517
|
+
const append = (0, import_react32.useCallback)(
|
1505
1518
|
async (message) => {
|
1506
1519
|
if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null)) {
|
1507
1520
|
if (!edit)
|
@@ -1515,7 +1528,7 @@ var VercelRSCAssistantProvider = ({
|
|
1515
1528
|
},
|
1516
1529
|
[context, withRunning, appendCallback, edit]
|
1517
1530
|
);
|
1518
|
-
const startRun = (0,
|
1531
|
+
const startRun = (0, import_react32.useCallback)(
|
1519
1532
|
async (parentId) => {
|
1520
1533
|
if (!reload)
|
1521
1534
|
throw new Error(
|
@@ -1525,7 +1538,7 @@ var VercelRSCAssistantProvider = ({
|
|
1525
1538
|
},
|
1526
1539
|
[withRunning, reload]
|
1527
1540
|
);
|
1528
|
-
(0,
|
1541
|
+
(0, import_react32.useMemo)(() => {
|
1529
1542
|
context.useThread.setState(
|
1530
1543
|
{
|
1531
1544
|
messages,
|
@@ -1543,7 +1556,7 @@ var VercelRSCAssistantProvider = ({
|
|
1543
1556
|
};
|
1544
1557
|
|
1545
1558
|
// src/adapters/core/utils/useAssistantContext.tsx
|
1546
|
-
var
|
1559
|
+
var import_react33 = require("react");
|
1547
1560
|
var import_zustand6 = require("zustand");
|
1548
1561
|
|
1549
1562
|
// src/adapters/core/utils/AssistantMessageRepository.tsx
|
@@ -1634,9 +1647,11 @@ var makeThreadStore = (runtimeRef) => {
|
|
1634
1647
|
};
|
1635
1648
|
};
|
1636
1649
|
var useAssistantContext2 = (runtime) => {
|
1637
|
-
const runtimeRef = (0,
|
1638
|
-
|
1639
|
-
|
1650
|
+
const runtimeRef = (0, import_react33.useRef)(runtime);
|
1651
|
+
(0, import_react33.useInsertionEffect)(() => {
|
1652
|
+
runtimeRef.current = runtime;
|
1653
|
+
});
|
1654
|
+
const [{ context, onNewMessage, onRunningChange }] = (0, import_react33.useState)(() => {
|
1640
1655
|
const { useThread, onNewMessage: onNewMessage2, onRunningChange: onRunningChange2 } = makeThreadStore(runtimeRef);
|
1641
1656
|
const useViewport = makeViewportStore();
|
1642
1657
|
const useComposer = makeThreadComposerStore(useThread);
|
@@ -1646,10 +1661,10 @@ var useAssistantContext2 = (runtime) => {
|
|
1646
1661
|
onRunningChange: onRunningChange2
|
1647
1662
|
};
|
1648
1663
|
});
|
1649
|
-
(0,
|
1664
|
+
(0, import_react33.useEffect)(() => {
|
1650
1665
|
return runtime.subscribeToMessageUpdates(onNewMessage);
|
1651
1666
|
}, [runtime, onNewMessage]);
|
1652
|
-
(0,
|
1667
|
+
(0, import_react33.useEffect)(() => {
|
1653
1668
|
return runtime.subscribeToStatusUpdates(onRunningChange);
|
1654
1669
|
}, [runtime, onRunningChange]);
|
1655
1670
|
return context;
|
@@ -1663,7 +1678,7 @@ var AssistantProvider = ({ children, runtime }) => {
|
|
1663
1678
|
};
|
1664
1679
|
|
1665
1680
|
// src/adapters/core/local/useLocalRuntime.tsx
|
1666
|
-
var
|
1681
|
+
var import_react34 = require("react");
|
1667
1682
|
|
1668
1683
|
// src/adapters/core/local/LocalRuntime.tsx
|
1669
1684
|
var LocalRuntime = class {
|
@@ -1748,7 +1763,7 @@ var LocalRuntime = class {
|
|
1748
1763
|
|
1749
1764
|
// src/adapters/core/local/useLocalRuntime.tsx
|
1750
1765
|
var useLocalRuntime = (adapter) => {
|
1751
|
-
const [runtime] = (0,
|
1766
|
+
const [runtime] = (0, import_react34.useState)(() => new LocalRuntime(adapter));
|
1752
1767
|
runtime.adapter = adapter;
|
1753
1768
|
return runtime;
|
1754
1769
|
};
|
package/dist/index.mjs
CHANGED
@@ -129,18 +129,22 @@ var ThreadViewport = forwardRef2(({ autoScroll = true, onScroll, children, ...re
|
|
129
129
|
const ref = useComposedRefs(forwardedRef, divRef);
|
130
130
|
const { useViewport } = useAssistantContext();
|
131
131
|
const firstRenderRef = useRef(true);
|
132
|
+
const isScrollingToBottomRef = useRef(false);
|
132
133
|
const lastScrollTop = useRef(0);
|
133
134
|
const scrollToBottom = () => {
|
134
135
|
const div = messagesEndRef.current;
|
135
136
|
if (!div || !autoScroll) return;
|
136
137
|
const behavior = firstRenderRef.current ? "instant" : "auto";
|
137
138
|
firstRenderRef.current = false;
|
138
|
-
|
139
|
+
isScrollingToBottomRef.current = true;
|
139
140
|
div.scrollIntoView({ behavior });
|
140
141
|
};
|
141
142
|
useOnResizeContent(divRef, () => {
|
142
|
-
if (!useViewport.getState().isAtBottom)
|
143
|
-
|
143
|
+
if (!isScrollingToBottomRef.current && !useViewport.getState().isAtBottom) {
|
144
|
+
handleScroll();
|
145
|
+
} else {
|
146
|
+
scrollToBottom();
|
147
|
+
}
|
144
148
|
});
|
145
149
|
useOnScrollToBottom(() => {
|
146
150
|
scrollToBottom();
|
@@ -152,6 +156,7 @@ var ThreadViewport = forwardRef2(({ autoScroll = true, onScroll, children, ...re
|
|
152
156
|
const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
|
153
157
|
if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
|
154
158
|
} else if (newIsAtBottom !== isAtBottom) {
|
159
|
+
isScrollingToBottomRef.current = false;
|
155
160
|
useViewport.setState({ isAtBottom: newIsAtBottom });
|
156
161
|
}
|
157
162
|
lastScrollTop.current = div.scrollTop;
|
@@ -818,6 +823,7 @@ __export(branchPicker_exports, {
|
|
818
823
|
});
|
819
824
|
|
820
825
|
// src/actions/useGoToNextBranch.tsx
|
826
|
+
import { useCallback as useCallback2 } from "react";
|
821
827
|
var useGoToNextBranch = () => {
|
822
828
|
const { useThread } = useAssistantContext();
|
823
829
|
const { useMessage, useComposer } = useMessageContext();
|
@@ -825,11 +831,12 @@ var useGoToNextBranch = () => {
|
|
825
831
|
[useMessage, useComposer],
|
826
832
|
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
|
827
833
|
);
|
828
|
-
|
829
|
-
return () => {
|
834
|
+
const callback = useCallback2(() => {
|
830
835
|
const { message, branches } = useMessage.getState();
|
831
836
|
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
|
832
|
-
};
|
837
|
+
}, [useMessage, useThread]);
|
838
|
+
if (disabled) return null;
|
839
|
+
return callback;
|
833
840
|
};
|
834
841
|
|
835
842
|
// src/utils/createActionButton.tsx
|
@@ -861,6 +868,7 @@ var createActionButton = (useActionButton) => {
|
|
861
868
|
var BranchPickerNext = createActionButton(useGoToNextBranch);
|
862
869
|
|
863
870
|
// src/actions/useGoToPreviousBranch.tsx
|
871
|
+
import { useCallback as useCallback3 } from "react";
|
864
872
|
var useGoToPreviousBranch = () => {
|
865
873
|
const { useThread } = useAssistantContext();
|
866
874
|
const { useMessage, useComposer } = useMessageContext();
|
@@ -868,13 +876,12 @@ var useGoToPreviousBranch = () => {
|
|
868
876
|
[useMessage, useComposer],
|
869
877
|
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
|
870
878
|
);
|
871
|
-
|
872
|
-
return () => {
|
879
|
+
const callback = useCallback3(() => {
|
873
880
|
const { message, branches } = useMessage.getState();
|
874
|
-
useThread.getState().switchToBranch(
|
875
|
-
|
876
|
-
|
877
|
-
|
881
|
+
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
|
882
|
+
}, [useMessage, useThread]);
|
883
|
+
if (disabled) return null;
|
884
|
+
return callback;
|
878
885
|
};
|
879
886
|
|
880
887
|
// src/primitives/branchPicker/BranchPickerPrevious.tsx
|
@@ -948,6 +955,7 @@ var ActionBarRoot = forwardRef13(({ hideWhenRunning, autohide, autohideFloat, ..
|
|
948
955
|
});
|
949
956
|
|
950
957
|
// src/actions/useCopyMessage.tsx
|
958
|
+
import { useCallback as useCallback4 } from "react";
|
951
959
|
var useCopyMessage = ({ copiedDuration = 3e3 }) => {
|
952
960
|
const { useMessage, useComposer } = useMessageContext();
|
953
961
|
const hasCopyableContent = useCombinedStore(
|
@@ -956,21 +964,23 @@ var useCopyMessage = ({ copiedDuration = 3e3 }) => {
|
|
956
964
|
return c.isEditing || m.message.content.some((c2) => c2.type === "text");
|
957
965
|
}
|
958
966
|
);
|
959
|
-
|
960
|
-
return () => {
|
967
|
+
const callback = useCallback4(() => {
|
961
968
|
const { isEditing, value: composerValue } = useComposer.getState();
|
962
969
|
const { message, setIsCopied } = useMessage.getState();
|
963
970
|
const valueToCopy = isEditing ? composerValue : getMessageText(message);
|
964
971
|
navigator.clipboard.writeText(valueToCopy);
|
965
972
|
setIsCopied(true);
|
966
973
|
setTimeout(() => setIsCopied(false), copiedDuration);
|
967
|
-
};
|
974
|
+
}, [useComposer, useMessage, copiedDuration]);
|
975
|
+
if (!hasCopyableContent) return null;
|
976
|
+
return callback;
|
968
977
|
};
|
969
978
|
|
970
979
|
// src/primitives/actionBar/ActionBarCopy.tsx
|
971
980
|
var ActionBarCopy = createActionButton(useCopyMessage);
|
972
981
|
|
973
982
|
// src/actions/useReloadMessage.tsx
|
983
|
+
import { useCallback as useCallback5 } from "react";
|
974
984
|
var useReloadMessage = () => {
|
975
985
|
const { useThread, useViewport } = useAssistantContext();
|
976
986
|
const { useMessage } = useMessageContext();
|
@@ -978,29 +988,32 @@ var useReloadMessage = () => {
|
|
978
988
|
[useThread, useMessage],
|
979
989
|
(t, m) => t.isRunning || m.message.role !== "assistant"
|
980
990
|
);
|
981
|
-
|
982
|
-
return () => {
|
991
|
+
const callback = useCallback5(() => {
|
983
992
|
const { parentId } = useMessage.getState();
|
984
993
|
useThread.getState().startRun(parentId);
|
985
994
|
useViewport.getState().scrollToBottom();
|
986
|
-
};
|
995
|
+
}, [useMessage, useThread, useViewport]);
|
996
|
+
if (disabled) return null;
|
997
|
+
return callback;
|
987
998
|
};
|
988
999
|
|
989
1000
|
// src/primitives/actionBar/ActionBarReload.tsx
|
990
1001
|
var ActionBarReload = createActionButton(useReloadMessage);
|
991
1002
|
|
992
1003
|
// src/actions/useBeginMessageEdit.tsx
|
1004
|
+
import { useCallback as useCallback6 } from "react";
|
993
1005
|
var useBeginMessageEdit = () => {
|
994
1006
|
const { useMessage, useComposer } = useMessageContext();
|
995
1007
|
const disabled = useCombinedStore(
|
996
1008
|
[useMessage, useComposer],
|
997
1009
|
(m, c) => m.message.role !== "user" || c.isEditing
|
998
1010
|
);
|
999
|
-
|
1000
|
-
return () => {
|
1011
|
+
const callback = useCallback6(() => {
|
1001
1012
|
const { edit } = useComposer.getState();
|
1002
1013
|
edit();
|
1003
|
-
};
|
1014
|
+
}, [useComposer]);
|
1015
|
+
if (disabled) return null;
|
1016
|
+
return callback;
|
1004
1017
|
};
|
1005
1018
|
|
1006
1019
|
// src/primitives/actionBar/ActionBarEdit.tsx
|
@@ -1074,7 +1087,7 @@ var useDummyAIAssistantContext = () => {
|
|
1074
1087
|
|
1075
1088
|
// src/adapters/vercel/useVercelAIThreadState.tsx
|
1076
1089
|
import { useCallbackRef as useCallbackRef3 } from "@radix-ui/react-use-callback-ref";
|
1077
|
-
import { useCallback as
|
1090
|
+
import { useCallback as useCallback7, useMemo as useMemo5, useRef as useRef4, useState as useState4 } from "react";
|
1078
1091
|
|
1079
1092
|
// src/adapters/idUtils.tsx
|
1080
1093
|
import { customAlphabet } from "nanoid/non-secure";
|
@@ -1347,7 +1360,7 @@ var useVercelAIThreadState = (vercel) => {
|
|
1347
1360
|
data.resetHead(assistantOptimisticIdRef.current ?? vm.at(-1)?.id ?? null);
|
1348
1361
|
return data.getMessages();
|
1349
1362
|
}, [converter, data, isRunning, vercel.messages]);
|
1350
|
-
const getBranches2 =
|
1363
|
+
const getBranches2 = useCallback7(
|
1351
1364
|
(messageId) => {
|
1352
1365
|
return data.getBranches(messageId);
|
1353
1366
|
},
|
@@ -1431,7 +1444,7 @@ var VercelAIAssistantProvider = ({
|
|
1431
1444
|
|
1432
1445
|
// src/adapters/vercel/VercelRSCAssistantProvider.tsx
|
1433
1446
|
import {
|
1434
|
-
useCallback as
|
1447
|
+
useCallback as useCallback8,
|
1435
1448
|
useMemo as useMemo7,
|
1436
1449
|
useState as useState5
|
1437
1450
|
} from "react";
|
@@ -1473,7 +1486,7 @@ var VercelRSCAssistantProvider = ({
|
|
1473
1486
|
}) => {
|
1474
1487
|
const context = useDummyAIAssistantContext();
|
1475
1488
|
const [isRunning, setIsRunning] = useState5(false);
|
1476
|
-
const withRunning =
|
1489
|
+
const withRunning = useCallback8((callback) => {
|
1477
1490
|
setIsRunning(true);
|
1478
1491
|
return callback.finally(() => setIsRunning(false));
|
1479
1492
|
}, []);
|
@@ -1488,7 +1501,7 @@ var VercelRSCAssistantProvider = ({
|
|
1488
1501
|
const messages = useMemo7(() => {
|
1489
1502
|
return converter.convertMessages(convertCallback, vercelMessages);
|
1490
1503
|
}, [converter, convertCallback, vercelMessages]);
|
1491
|
-
const append =
|
1504
|
+
const append = useCallback8(
|
1492
1505
|
async (message) => {
|
1493
1506
|
if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null)) {
|
1494
1507
|
if (!edit)
|
@@ -1502,7 +1515,7 @@ var VercelRSCAssistantProvider = ({
|
|
1502
1515
|
},
|
1503
1516
|
[context, withRunning, appendCallback, edit]
|
1504
1517
|
);
|
1505
|
-
const startRun =
|
1518
|
+
const startRun = useCallback8(
|
1506
1519
|
async (parentId) => {
|
1507
1520
|
if (!reload)
|
1508
1521
|
throw new Error(
|
@@ -1530,7 +1543,12 @@ var VercelRSCAssistantProvider = ({
|
|
1530
1543
|
};
|
1531
1544
|
|
1532
1545
|
// src/adapters/core/utils/useAssistantContext.tsx
|
1533
|
-
import {
|
1546
|
+
import {
|
1547
|
+
useEffect as useEffect4,
|
1548
|
+
useInsertionEffect,
|
1549
|
+
useRef as useRef5,
|
1550
|
+
useState as useState6
|
1551
|
+
} from "react";
|
1534
1552
|
import { create as create6 } from "zustand";
|
1535
1553
|
|
1536
1554
|
// src/adapters/core/utils/AssistantMessageRepository.tsx
|
@@ -1622,7 +1640,9 @@ var makeThreadStore = (runtimeRef) => {
|
|
1622
1640
|
};
|
1623
1641
|
var useAssistantContext2 = (runtime) => {
|
1624
1642
|
const runtimeRef = useRef5(runtime);
|
1625
|
-
|
1643
|
+
useInsertionEffect(() => {
|
1644
|
+
runtimeRef.current = runtime;
|
1645
|
+
});
|
1626
1646
|
const [{ context, onNewMessage, onRunningChange }] = useState6(() => {
|
1627
1647
|
const { useThread, onNewMessage: onNewMessage2, onRunningChange: onRunningChange2 } = makeThreadStore(runtimeRef);
|
1628
1648
|
const useViewport = makeViewportStore();
|