@assistant-ui/react 0.0.17 → 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 +75 -11
- package/dist/index.d.ts +75 -11
- package/dist/index.js +354 -81
- package/dist/index.mjs +338 -63
- package/package.json +1 -1
package/dist/index.js
CHANGED
@@ -38,8 +38,11 @@ __export(src_exports, {
|
|
38
38
|
ThreadPrimitive: () => thread_exports,
|
39
39
|
VercelAIAssistantProvider: () => VercelAIAssistantProvider,
|
40
40
|
VercelRSCAssistantProvider: () => VercelRSCAssistantProvider,
|
41
|
+
unstable_AssistantProvider: () => AssistantProvider,
|
42
|
+
unstable_VercelModelAdapter: () => VercelModelAdapter,
|
41
43
|
unstable_getVercelMessage: () => getVercelMessage,
|
42
44
|
unstable_getVercelRSCMessage: () => getVercelRSCMessage,
|
45
|
+
unstable_useLocalRuntime: () => useLocalRuntime,
|
43
46
|
unstable_useMessageContext: () => useMessageContext,
|
44
47
|
useBeginMessageEdit: () => useBeginMessageEdit,
|
45
48
|
useCopyMessage: () => useCopyMessage,
|
@@ -170,18 +173,22 @@ var ThreadViewport = (0, import_react5.forwardRef)(({ autoScroll = true, onScrol
|
|
170
173
|
const ref = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, divRef);
|
171
174
|
const { useViewport } = useAssistantContext();
|
172
175
|
const firstRenderRef = (0, import_react5.useRef)(true);
|
176
|
+
const isScrollingToBottomRef = (0, import_react5.useRef)(false);
|
173
177
|
const lastScrollTop = (0, import_react5.useRef)(0);
|
174
178
|
const scrollToBottom = () => {
|
175
179
|
const div = messagesEndRef.current;
|
176
180
|
if (!div || !autoScroll) return;
|
177
181
|
const behavior = firstRenderRef.current ? "instant" : "auto";
|
178
182
|
firstRenderRef.current = false;
|
179
|
-
|
183
|
+
isScrollingToBottomRef.current = true;
|
180
184
|
div.scrollIntoView({ behavior });
|
181
185
|
};
|
182
186
|
useOnResizeContent(divRef, () => {
|
183
|
-
if (!useViewport.getState().isAtBottom)
|
184
|
-
|
187
|
+
if (!isScrollingToBottomRef.current && !useViewport.getState().isAtBottom) {
|
188
|
+
handleScroll();
|
189
|
+
} else {
|
190
|
+
scrollToBottom();
|
191
|
+
}
|
185
192
|
});
|
186
193
|
useOnScrollToBottom(() => {
|
187
194
|
scrollToBottom();
|
@@ -193,6 +200,7 @@ var ThreadViewport = (0, import_react5.forwardRef)(({ autoScroll = true, onScrol
|
|
193
200
|
const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
|
194
201
|
if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
|
195
202
|
} else if (newIsAtBottom !== isAtBottom) {
|
203
|
+
isScrollingToBottomRef.current = false;
|
196
204
|
useViewport.setState({ isAtBottom: newIsAtBottom });
|
197
205
|
}
|
198
206
|
lastScrollTop.current = div.scrollTop;
|
@@ -838,6 +846,7 @@ __export(branchPicker_exports, {
|
|
838
846
|
});
|
839
847
|
|
840
848
|
// src/actions/useGoToNextBranch.tsx
|
849
|
+
var import_react21 = require("react");
|
841
850
|
var useGoToNextBranch = () => {
|
842
851
|
const { useThread } = useAssistantContext();
|
843
852
|
const { useMessage, useComposer } = useMessageContext();
|
@@ -845,20 +854,21 @@ var useGoToNextBranch = () => {
|
|
845
854
|
[useMessage, useComposer],
|
846
855
|
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
|
847
856
|
);
|
848
|
-
|
849
|
-
return () => {
|
857
|
+
const callback = (0, import_react21.useCallback)(() => {
|
850
858
|
const { message, branches } = useMessage.getState();
|
851
859
|
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
|
852
|
-
};
|
860
|
+
}, [useMessage, useThread]);
|
861
|
+
if (disabled) return null;
|
862
|
+
return callback;
|
853
863
|
};
|
854
864
|
|
855
865
|
// src/utils/createActionButton.tsx
|
856
866
|
var import_primitive8 = require("@radix-ui/primitive");
|
857
867
|
var import_react_primitive10 = require("@radix-ui/react-primitive");
|
858
|
-
var
|
868
|
+
var import_react22 = require("react");
|
859
869
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
860
870
|
var createActionButton = (useActionButton) => {
|
861
|
-
return (0,
|
871
|
+
return (0, import_react22.forwardRef)(
|
862
872
|
(props, forwardedRef) => {
|
863
873
|
const onClick = useActionButton(props);
|
864
874
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
@@ -879,6 +889,7 @@ var createActionButton = (useActionButton) => {
|
|
879
889
|
var BranchPickerNext = createActionButton(useGoToNextBranch);
|
880
890
|
|
881
891
|
// src/actions/useGoToPreviousBranch.tsx
|
892
|
+
var import_react23 = require("react");
|
882
893
|
var useGoToPreviousBranch = () => {
|
883
894
|
const { useThread } = useAssistantContext();
|
884
895
|
const { useMessage, useComposer } = useMessageContext();
|
@@ -886,13 +897,12 @@ var useGoToPreviousBranch = () => {
|
|
886
897
|
[useMessage, useComposer],
|
887
898
|
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
|
888
899
|
);
|
889
|
-
|
890
|
-
return () => {
|
900
|
+
const callback = (0, import_react23.useCallback)(() => {
|
891
901
|
const { message, branches } = useMessage.getState();
|
892
|
-
useThread.getState().switchToBranch(
|
893
|
-
|
894
|
-
|
895
|
-
|
902
|
+
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
|
903
|
+
}, [useMessage, useThread]);
|
904
|
+
if (disabled) return null;
|
905
|
+
return callback;
|
896
906
|
};
|
897
907
|
|
898
908
|
// src/primitives/branchPicker/BranchPickerPrevious.tsx
|
@@ -916,9 +926,9 @@ var BranchPickerNumber = () => {
|
|
916
926
|
|
917
927
|
// src/primitives/branchPicker/BranchPickerRoot.tsx
|
918
928
|
var import_react_primitive11 = require("@radix-ui/react-primitive");
|
919
|
-
var
|
929
|
+
var import_react24 = require("react");
|
920
930
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
921
|
-
var BranchPickerRoot = (0,
|
931
|
+
var BranchPickerRoot = (0, import_react24.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
|
922
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 }) });
|
923
933
|
});
|
924
934
|
|
@@ -933,9 +943,9 @@ __export(actionBar_exports, {
|
|
933
943
|
|
934
944
|
// src/primitives/actionBar/ActionBarRoot.tsx
|
935
945
|
var import_react_primitive12 = require("@radix-ui/react-primitive");
|
936
|
-
var
|
946
|
+
var import_react25 = require("react");
|
937
947
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
938
|
-
var ActionBarRoot = (0,
|
948
|
+
var ActionBarRoot = (0, import_react25.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
|
939
949
|
const { useThread } = useAssistantContext();
|
940
950
|
const { useMessage } = useMessageContext();
|
941
951
|
const hideAndfloatStatus = useCombinedStore(
|
@@ -962,6 +972,7 @@ var ActionBarRoot = (0, import_react23.forwardRef)(({ hideWhenRunning, autohide,
|
|
962
972
|
});
|
963
973
|
|
964
974
|
// src/actions/useCopyMessage.tsx
|
975
|
+
var import_react26 = require("react");
|
965
976
|
var useCopyMessage = ({ copiedDuration = 3e3 }) => {
|
966
977
|
const { useMessage, useComposer } = useMessageContext();
|
967
978
|
const hasCopyableContent = useCombinedStore(
|
@@ -970,21 +981,23 @@ var useCopyMessage = ({ copiedDuration = 3e3 }) => {
|
|
970
981
|
return c.isEditing || m.message.content.some((c2) => c2.type === "text");
|
971
982
|
}
|
972
983
|
);
|
973
|
-
|
974
|
-
return () => {
|
984
|
+
const callback = (0, import_react26.useCallback)(() => {
|
975
985
|
const { isEditing, value: composerValue } = useComposer.getState();
|
976
986
|
const { message, setIsCopied } = useMessage.getState();
|
977
987
|
const valueToCopy = isEditing ? composerValue : getMessageText(message);
|
978
988
|
navigator.clipboard.writeText(valueToCopy);
|
979
989
|
setIsCopied(true);
|
980
990
|
setTimeout(() => setIsCopied(false), copiedDuration);
|
981
|
-
};
|
991
|
+
}, [useComposer, useMessage, copiedDuration]);
|
992
|
+
if (!hasCopyableContent) return null;
|
993
|
+
return callback;
|
982
994
|
};
|
983
995
|
|
984
996
|
// src/primitives/actionBar/ActionBarCopy.tsx
|
985
997
|
var ActionBarCopy = createActionButton(useCopyMessage);
|
986
998
|
|
987
999
|
// src/actions/useReloadMessage.tsx
|
1000
|
+
var import_react27 = require("react");
|
988
1001
|
var useReloadMessage = () => {
|
989
1002
|
const { useThread, useViewport } = useAssistantContext();
|
990
1003
|
const { useMessage } = useMessageContext();
|
@@ -992,29 +1005,32 @@ var useReloadMessage = () => {
|
|
992
1005
|
[useThread, useMessage],
|
993
1006
|
(t, m) => t.isRunning || m.message.role !== "assistant"
|
994
1007
|
);
|
995
|
-
|
996
|
-
return () => {
|
1008
|
+
const callback = (0, import_react27.useCallback)(() => {
|
997
1009
|
const { parentId } = useMessage.getState();
|
998
1010
|
useThread.getState().startRun(parentId);
|
999
1011
|
useViewport.getState().scrollToBottom();
|
1000
|
-
};
|
1012
|
+
}, [useMessage, useThread, useViewport]);
|
1013
|
+
if (disabled) return null;
|
1014
|
+
return callback;
|
1001
1015
|
};
|
1002
1016
|
|
1003
1017
|
// src/primitives/actionBar/ActionBarReload.tsx
|
1004
1018
|
var ActionBarReload = createActionButton(useReloadMessage);
|
1005
1019
|
|
1006
1020
|
// src/actions/useBeginMessageEdit.tsx
|
1021
|
+
var import_react28 = require("react");
|
1007
1022
|
var useBeginMessageEdit = () => {
|
1008
1023
|
const { useMessage, useComposer } = useMessageContext();
|
1009
1024
|
const disabled = useCombinedStore(
|
1010
1025
|
[useMessage, useComposer],
|
1011
1026
|
(m, c) => m.message.role !== "user" || c.isEditing
|
1012
1027
|
);
|
1013
|
-
|
1014
|
-
return () => {
|
1028
|
+
const callback = (0, import_react28.useCallback)(() => {
|
1015
1029
|
const { edit } = useComposer.getState();
|
1016
1030
|
edit();
|
1017
|
-
};
|
1031
|
+
}, [useComposer]);
|
1032
|
+
if (disabled) return null;
|
1033
|
+
return callback;
|
1018
1034
|
};
|
1019
1035
|
|
1020
1036
|
// src/primitives/actionBar/ActionBarEdit.tsx
|
@@ -1028,10 +1044,10 @@ __export(contentPart_exports, {
|
|
1028
1044
|
});
|
1029
1045
|
|
1030
1046
|
// src/adapters/vercel/VercelAIAssistantProvider.tsx
|
1031
|
-
var
|
1047
|
+
var import_react31 = require("react");
|
1032
1048
|
|
1033
1049
|
// src/adapters/vercel/useDummyAIAssistantContext.tsx
|
1034
|
-
var
|
1050
|
+
var import_react29 = require("react");
|
1035
1051
|
var import_zustand5 = require("zustand");
|
1036
1052
|
|
1037
1053
|
// src/utils/context/stores/ViewportStore.tsx
|
@@ -1077,7 +1093,7 @@ var makeDummyThreadStore = () => {
|
|
1077
1093
|
}));
|
1078
1094
|
};
|
1079
1095
|
var useDummyAIAssistantContext = () => {
|
1080
|
-
const [context] = (0,
|
1096
|
+
const [context] = (0, import_react29.useState)(() => {
|
1081
1097
|
const useThread = makeDummyThreadStore();
|
1082
1098
|
const useViewport = makeViewportStore();
|
1083
1099
|
const useComposer = makeThreadComposerStore(useThread);
|
@@ -1088,9 +1104,9 @@ var useDummyAIAssistantContext = () => {
|
|
1088
1104
|
|
1089
1105
|
// src/adapters/vercel/useVercelAIThreadState.tsx
|
1090
1106
|
var import_react_use_callback_ref3 = require("@radix-ui/react-use-callback-ref");
|
1091
|
-
var
|
1107
|
+
var import_react30 = require("react");
|
1092
1108
|
|
1093
|
-
// src/adapters/
|
1109
|
+
// src/adapters/idUtils.tsx
|
1094
1110
|
var import_non_secure = require("nanoid/non-secure");
|
1095
1111
|
var generateId = (0, import_non_secure.customAlphabet)(
|
1096
1112
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
@@ -1098,6 +1114,8 @@ var generateId = (0, import_non_secure.customAlphabet)(
|
|
1098
1114
|
);
|
1099
1115
|
var optimisticPrefix = "__optimistic__";
|
1100
1116
|
var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
|
1117
|
+
|
1118
|
+
// src/adapters/MessageRepository.tsx
|
1101
1119
|
var findHead = (message) => {
|
1102
1120
|
if (message.next) return findHead(message.next);
|
1103
1121
|
return message;
|
@@ -1109,15 +1127,6 @@ var MessageRepository = class {
|
|
1109
1127
|
root = {
|
1110
1128
|
children: []
|
1111
1129
|
};
|
1112
|
-
getFallbackChild(p) {
|
1113
|
-
const childId = p.children.at(-1);
|
1114
|
-
const child = childId ? this.messages.get(childId) : null;
|
1115
|
-
if (child === void 0)
|
1116
|
-
throw new Error(
|
1117
|
-
"MessageRepository(getFallbackChild): Child message not found. This is likely an internal bug in assistant-ui."
|
1118
|
-
);
|
1119
|
-
return child;
|
1120
|
-
}
|
1121
1130
|
performOp(newParent, child, operation) {
|
1122
1131
|
const parentOrRoot = child.prev ?? this.root;
|
1123
1132
|
const newParentOrRoot = newParent ?? this.root;
|
@@ -1127,7 +1136,14 @@ var MessageRepository = class {
|
|
1127
1136
|
(m) => m !== child.current.id
|
1128
1137
|
);
|
1129
1138
|
if (child.prev?.next === child) {
|
1130
|
-
child.prev.
|
1139
|
+
const fallbackId = child.prev.children.at(-1);
|
1140
|
+
const fallback = fallbackId ? this.messages.get(fallbackId) : null;
|
1141
|
+
if (fallback === void 0) {
|
1142
|
+
throw new Error(
|
1143
|
+
"MessageRepository(performOp/cut): Fallback sibling message not found. This is likely an internal bug in assistant-ui."
|
1144
|
+
);
|
1145
|
+
}
|
1146
|
+
child.prev.next = fallback;
|
1131
1147
|
}
|
1132
1148
|
}
|
1133
1149
|
if (operation !== "cut") {
|
@@ -1186,14 +1202,14 @@ var MessageRepository = class {
|
|
1186
1202
|
});
|
1187
1203
|
return optimisticId;
|
1188
1204
|
}
|
1189
|
-
deleteMessage(messageId,
|
1205
|
+
deleteMessage(messageId, replacementId) {
|
1190
1206
|
const message = this.messages.get(messageId);
|
1191
|
-
const
|
1207
|
+
const replacement = replacementId ? this.messages.get(replacementId) : null;
|
1192
1208
|
if (!message)
|
1193
1209
|
throw new Error(
|
1194
1210
|
"MessageRepository(deleteMessage): Optimistic message not found. This is likely an internal bug in assistant-ui."
|
1195
1211
|
);
|
1196
|
-
if (
|
1212
|
+
if (replacement === void 0)
|
1197
1213
|
throw new Error(
|
1198
1214
|
"MessageRepository(deleteMessage): New message not found. This is likely an internal bug in assistant-ui."
|
1199
1215
|
);
|
@@ -1203,11 +1219,11 @@ var MessageRepository = class {
|
|
1203
1219
|
throw new Error(
|
1204
1220
|
"MessageRepository(deleteMessage): Child message not found. This is likely an internal bug in assistant-ui."
|
1205
1221
|
);
|
1206
|
-
this.performOp(
|
1222
|
+
this.performOp(replacement, childMessage, "relink");
|
1207
1223
|
}
|
1208
1224
|
this.messages.delete(messageId);
|
1209
1225
|
if (this.head === message) {
|
1210
|
-
this.head =
|
1226
|
+
this.head = replacement;
|
1211
1227
|
}
|
1212
1228
|
this.performOp(null, message, "cut");
|
1213
1229
|
}
|
@@ -1250,17 +1266,13 @@ var MessageRepository = class {
|
|
1250
1266
|
}
|
1251
1267
|
};
|
1252
1268
|
|
1253
|
-
// src/adapters/ThreadMessageConverter.
|
1269
|
+
// src/adapters/ThreadMessageConverter.ts
|
1254
1270
|
var ThreadMessageConverter = class {
|
1255
|
-
constructor(converter) {
|
1256
|
-
this.converter = converter;
|
1257
|
-
}
|
1258
1271
|
cache = /* @__PURE__ */ new WeakMap();
|
1259
|
-
convertMessages(messages) {
|
1272
|
+
convertMessages(converter, messages) {
|
1260
1273
|
return messages.map((m) => {
|
1261
1274
|
const cached = this.cache.get(m);
|
1262
|
-
|
1263
|
-
const newMessage = this.converter(m);
|
1275
|
+
const newMessage = converter(m, cached);
|
1264
1276
|
this.cache.set(m, newMessage);
|
1265
1277
|
return newMessage;
|
1266
1278
|
});
|
@@ -1331,18 +1343,19 @@ var getIsRunning = (vercel) => {
|
|
1331
1343
|
return vercel.status === "in_progress";
|
1332
1344
|
};
|
1333
1345
|
var useVercelAIThreadState = (vercel) => {
|
1334
|
-
const [data] = (0,
|
1346
|
+
const [data] = (0, import_react30.useState)(() => new MessageRepository());
|
1335
1347
|
const isRunning = getIsRunning(vercel);
|
1336
|
-
const
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
)
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1348
|
+
const converter = (0, import_react30.useMemo)(() => new ThreadMessageConverter(), []);
|
1349
|
+
const assistantOptimisticIdRef = (0, import_react30.useRef)(null);
|
1350
|
+
const messages = (0, import_react30.useMemo)(() => {
|
1351
|
+
const lastMessageId = vercel.messages.at(-1)?.id;
|
1352
|
+
const convertCallback = (message, cache) => {
|
1353
|
+
const status = lastMessageId === message.id && isRunning ? "in_progress" : "done";
|
1354
|
+
if (cache && (cache.role === "user" || cache.status === status))
|
1355
|
+
return cache;
|
1356
|
+
return vercelToThreadMessage(message, status);
|
1357
|
+
};
|
1358
|
+
const vm = converter.convertMessages(convertCallback, vercel.messages);
|
1346
1359
|
for (let i = 0; i < vm.length; i++) {
|
1347
1360
|
const message = vm[i];
|
1348
1361
|
const parent = vm[i - 1];
|
@@ -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,21 +1498,23 @@ 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 = (0,
|
1506
|
+
const [converter, convertCallback] = (0, import_react32.useMemo)(() => {
|
1494
1507
|
const rscConverter = convertMessage ?? ((m) => m);
|
1495
|
-
|
1508
|
+
const convertCallback2 = (m, cache) => {
|
1509
|
+
if (cache) return cache;
|
1496
1510
|
return vercelToThreadMessage2(rscConverter, m);
|
1497
|
-
}
|
1511
|
+
};
|
1512
|
+
return [new ThreadMessageConverter(), convertCallback2];
|
1498
1513
|
}, [convertMessage]);
|
1499
|
-
const messages = (0,
|
1500
|
-
return converter.convertMessages(vercelMessages);
|
1501
|
-
}, [converter, vercelMessages]);
|
1502
|
-
const append = (0,
|
1514
|
+
const messages = (0, import_react32.useMemo)(() => {
|
1515
|
+
return converter.convertMessages(convertCallback, vercelMessages);
|
1516
|
+
}, [converter, convertCallback, vercelMessages]);
|
1517
|
+
const append = (0, import_react32.useCallback)(
|
1503
1518
|
async (message) => {
|
1504
1519
|
if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null)) {
|
1505
1520
|
if (!edit)
|
@@ -1513,7 +1528,7 @@ var VercelRSCAssistantProvider = ({
|
|
1513
1528
|
},
|
1514
1529
|
[context, withRunning, appendCallback, edit]
|
1515
1530
|
);
|
1516
|
-
const startRun = (0,
|
1531
|
+
const startRun = (0, import_react32.useCallback)(
|
1517
1532
|
async (parentId) => {
|
1518
1533
|
if (!reload)
|
1519
1534
|
throw new Error(
|
@@ -1523,7 +1538,7 @@ var VercelRSCAssistantProvider = ({
|
|
1523
1538
|
},
|
1524
1539
|
[withRunning, reload]
|
1525
1540
|
);
|
1526
|
-
(0,
|
1541
|
+
(0, import_react32.useMemo)(() => {
|
1527
1542
|
context.useThread.setState(
|
1528
1543
|
{
|
1529
1544
|
messages,
|
@@ -1539,6 +1554,261 @@ var VercelRSCAssistantProvider = ({
|
|
1539
1554
|
}, [context, messages, isRunning, append, startRun]);
|
1540
1555
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AssistantContext.Provider, { value: context, children });
|
1541
1556
|
};
|
1557
|
+
|
1558
|
+
// src/adapters/core/utils/useAssistantContext.tsx
|
1559
|
+
var import_react33 = require("react");
|
1560
|
+
var import_zustand6 = require("zustand");
|
1561
|
+
|
1562
|
+
// src/adapters/core/utils/AssistantMessageRepository.tsx
|
1563
|
+
var AssistantMessageRepository = class {
|
1564
|
+
constructor(flushCallback) {
|
1565
|
+
this.flushCallback = flushCallback;
|
1566
|
+
}
|
1567
|
+
repository = new MessageRepository();
|
1568
|
+
getBranches(messageId) {
|
1569
|
+
return this.repository.getBranches(messageId);
|
1570
|
+
}
|
1571
|
+
withModifications(callback) {
|
1572
|
+
const res = callback(this.repository);
|
1573
|
+
this.flushCallback(this.repository.getMessages());
|
1574
|
+
return res;
|
1575
|
+
}
|
1576
|
+
};
|
1577
|
+
|
1578
|
+
// src/adapters/core/utils/useAssistantContext.tsx
|
1579
|
+
var makeThreadStore = (runtimeRef) => {
|
1580
|
+
const repository = new AssistantMessageRepository((messages) => {
|
1581
|
+
useThread.setState({ messages });
|
1582
|
+
});
|
1583
|
+
const useThread = (0, import_zustand6.create)(() => ({
|
1584
|
+
messages: [],
|
1585
|
+
isRunning: false,
|
1586
|
+
getBranches: (messageId) => repository.getBranches(messageId),
|
1587
|
+
switchToBranch: (branchId) => {
|
1588
|
+
repository.withModifications((repository2) => {
|
1589
|
+
repository2.switchToBranch(branchId);
|
1590
|
+
});
|
1591
|
+
},
|
1592
|
+
startRun: async (parentId) => {
|
1593
|
+
const optimisticId = repository.withModifications((repository2) => {
|
1594
|
+
const optimisticId2 = repository2.appendOptimisticMessage(parentId, {
|
1595
|
+
role: "assistant",
|
1596
|
+
content: [{ type: "text", text: "" }]
|
1597
|
+
});
|
1598
|
+
repository2.resetHead(optimisticId2);
|
1599
|
+
return optimisticId2;
|
1600
|
+
});
|
1601
|
+
const { id } = await runtimeRef.current.startRun(parentId);
|
1602
|
+
repository.withModifications((repository2) => {
|
1603
|
+
repository2.deleteMessage(optimisticId, id);
|
1604
|
+
});
|
1605
|
+
},
|
1606
|
+
append: async (message) => {
|
1607
|
+
const [parentOptimisticId, optimisticId] = repository.withModifications(
|
1608
|
+
(repository2) => {
|
1609
|
+
const parentOptimisticId2 = repository2.appendOptimisticMessage(
|
1610
|
+
message.parentId,
|
1611
|
+
{
|
1612
|
+
role: "user",
|
1613
|
+
content: message.content
|
1614
|
+
}
|
1615
|
+
);
|
1616
|
+
const optimisticId2 = repository2.appendOptimisticMessage(
|
1617
|
+
parentOptimisticId2,
|
1618
|
+
{
|
1619
|
+
role: "assistant",
|
1620
|
+
content: [{ type: "text", text: "" }]
|
1621
|
+
}
|
1622
|
+
);
|
1623
|
+
repository2.resetHead(optimisticId2);
|
1624
|
+
return [parentOptimisticId2, optimisticId2];
|
1625
|
+
}
|
1626
|
+
);
|
1627
|
+
const { parentId, id } = await runtimeRef.current.append(message);
|
1628
|
+
repository.withModifications((repository2) => {
|
1629
|
+
repository2.deleteMessage(parentOptimisticId, parentId);
|
1630
|
+
repository2.deleteMessage(optimisticId, id);
|
1631
|
+
});
|
1632
|
+
},
|
1633
|
+
cancelRun: () => runtimeRef.current.cancelRun()
|
1634
|
+
}));
|
1635
|
+
const onNewMessage = (parentId, message) => {
|
1636
|
+
repository.withModifications((repository2) => {
|
1637
|
+
repository2.addOrUpdateMessage(parentId, message);
|
1638
|
+
});
|
1639
|
+
};
|
1640
|
+
const onRunningChange = (isRunning) => {
|
1641
|
+
useThread.setState({ isRunning });
|
1642
|
+
};
|
1643
|
+
return {
|
1644
|
+
useThread,
|
1645
|
+
onNewMessage,
|
1646
|
+
onRunningChange
|
1647
|
+
};
|
1648
|
+
};
|
1649
|
+
var useAssistantContext2 = (runtime) => {
|
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)(() => {
|
1655
|
+
const { useThread, onNewMessage: onNewMessage2, onRunningChange: onRunningChange2 } = makeThreadStore(runtimeRef);
|
1656
|
+
const useViewport = makeViewportStore();
|
1657
|
+
const useComposer = makeThreadComposerStore(useThread);
|
1658
|
+
return {
|
1659
|
+
context: { useViewport, useThread, useComposer },
|
1660
|
+
onNewMessage: onNewMessage2,
|
1661
|
+
onRunningChange: onRunningChange2
|
1662
|
+
};
|
1663
|
+
});
|
1664
|
+
(0, import_react33.useEffect)(() => {
|
1665
|
+
return runtime.subscribeToMessageUpdates(onNewMessage);
|
1666
|
+
}, [runtime, onNewMessage]);
|
1667
|
+
(0, import_react33.useEffect)(() => {
|
1668
|
+
return runtime.subscribeToStatusUpdates(onRunningChange);
|
1669
|
+
}, [runtime, onRunningChange]);
|
1670
|
+
return context;
|
1671
|
+
};
|
1672
|
+
|
1673
|
+
// src/adapters/core/AssistantProvider.tsx
|
1674
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
1675
|
+
var AssistantProvider = ({ children, runtime }) => {
|
1676
|
+
const context = useAssistantContext2(runtime);
|
1677
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AssistantContext.Provider, { value: context, children });
|
1678
|
+
};
|
1679
|
+
|
1680
|
+
// src/adapters/core/local/useLocalRuntime.tsx
|
1681
|
+
var import_react34 = require("react");
|
1682
|
+
|
1683
|
+
// src/adapters/core/local/LocalRuntime.tsx
|
1684
|
+
var LocalRuntime = class {
|
1685
|
+
constructor(adapter) {
|
1686
|
+
this.adapter = adapter;
|
1687
|
+
}
|
1688
|
+
_messageUpdateCallbacks = /* @__PURE__ */ new Set();
|
1689
|
+
_statusUpdateCallbacks = /* @__PURE__ */ new Set();
|
1690
|
+
abortController = null;
|
1691
|
+
repository = new MessageRepository();
|
1692
|
+
async append(message) {
|
1693
|
+
const userMessageId = generateId();
|
1694
|
+
const userMessage = {
|
1695
|
+
id: userMessageId,
|
1696
|
+
role: "user",
|
1697
|
+
content: message.content,
|
1698
|
+
createdAt: /* @__PURE__ */ new Date()
|
1699
|
+
};
|
1700
|
+
this.addOrUpdateMessage(message.parentId, userMessage);
|
1701
|
+
const { id } = await this.startRun(userMessageId);
|
1702
|
+
return { parentId: userMessageId, id };
|
1703
|
+
}
|
1704
|
+
async startRun(parentId) {
|
1705
|
+
const id = generateId();
|
1706
|
+
this.repository.resetHead(parentId);
|
1707
|
+
const messages = this.repository.getMessages();
|
1708
|
+
const message = {
|
1709
|
+
id,
|
1710
|
+
role: "assistant",
|
1711
|
+
status: "in_progress",
|
1712
|
+
content: [{ type: "text", text: "" }],
|
1713
|
+
createdAt: /* @__PURE__ */ new Date()
|
1714
|
+
};
|
1715
|
+
this.addOrUpdateMessage(parentId, message);
|
1716
|
+
void this.run(parentId, messages, message);
|
1717
|
+
return { id };
|
1718
|
+
}
|
1719
|
+
addOrUpdateMessage(parentId, message) {
|
1720
|
+
const clone = { ...message };
|
1721
|
+
this.repository.addOrUpdateMessage(parentId, clone);
|
1722
|
+
for (const callback of this._messageUpdateCallbacks)
|
1723
|
+
callback(parentId, clone);
|
1724
|
+
}
|
1725
|
+
async run(parentId, messages, message) {
|
1726
|
+
this.cancelRun();
|
1727
|
+
for (const callback of this._statusUpdateCallbacks) callback(true);
|
1728
|
+
this.abortController = new AbortController();
|
1729
|
+
try {
|
1730
|
+
await this.adapter.run({
|
1731
|
+
messages,
|
1732
|
+
abortSignal: this.abortController.signal,
|
1733
|
+
onUpdate: ({ content }) => {
|
1734
|
+
message.content = content;
|
1735
|
+
this.addOrUpdateMessage(parentId, message);
|
1736
|
+
}
|
1737
|
+
});
|
1738
|
+
message.status = "done";
|
1739
|
+
this.addOrUpdateMessage(parentId, message);
|
1740
|
+
} catch (e) {
|
1741
|
+
message.status = "error";
|
1742
|
+
this.addOrUpdateMessage(parentId, message);
|
1743
|
+
console.error(e);
|
1744
|
+
} finally {
|
1745
|
+
this.cancelRun();
|
1746
|
+
}
|
1747
|
+
}
|
1748
|
+
cancelRun() {
|
1749
|
+
if (!this.abortController) return;
|
1750
|
+
this.abortController.abort();
|
1751
|
+
this.abortController = null;
|
1752
|
+
for (const callback of this._statusUpdateCallbacks) callback(false);
|
1753
|
+
}
|
1754
|
+
subscribeToMessageUpdates(callback) {
|
1755
|
+
this._messageUpdateCallbacks.add(callback);
|
1756
|
+
return () => this._messageUpdateCallbacks.delete(callback);
|
1757
|
+
}
|
1758
|
+
subscribeToStatusUpdates(callback) {
|
1759
|
+
this._statusUpdateCallbacks.add(callback);
|
1760
|
+
return () => this._statusUpdateCallbacks.delete(callback);
|
1761
|
+
}
|
1762
|
+
};
|
1763
|
+
|
1764
|
+
// src/adapters/core/local/useLocalRuntime.tsx
|
1765
|
+
var useLocalRuntime = (adapter) => {
|
1766
|
+
const [runtime] = (0, import_react34.useState)(() => new LocalRuntime(adapter));
|
1767
|
+
runtime.adapter = adapter;
|
1768
|
+
return runtime;
|
1769
|
+
};
|
1770
|
+
|
1771
|
+
// src/adapters/core/local/vercel/VercelModelAdapter.tsx
|
1772
|
+
var import_ai = require("ai");
|
1773
|
+
var VercelModelAdapter = class {
|
1774
|
+
constructor(model) {
|
1775
|
+
this.model = model;
|
1776
|
+
}
|
1777
|
+
async run({ messages, abortSignal, onUpdate }) {
|
1778
|
+
const { fullStream } = await (0, import_ai.streamText)({
|
1779
|
+
model: this.model,
|
1780
|
+
abortSignal,
|
1781
|
+
messages: messages.map((m) => ({
|
1782
|
+
role: m.role,
|
1783
|
+
content: m.content.filter((c) => c.type !== "ui")
|
1784
|
+
}))
|
1785
|
+
});
|
1786
|
+
const content = [];
|
1787
|
+
for await (const aiPart of fullStream) {
|
1788
|
+
switch (aiPart.type) {
|
1789
|
+
case "text-delta": {
|
1790
|
+
let part = content.at(-1);
|
1791
|
+
if (!part || part.type !== "text") {
|
1792
|
+
part = { type: "text", text: "" };
|
1793
|
+
content.push(part);
|
1794
|
+
}
|
1795
|
+
part.text += aiPart.textDelta;
|
1796
|
+
break;
|
1797
|
+
}
|
1798
|
+
case "tool-call": {
|
1799
|
+
content.push({
|
1800
|
+
type: "tool-call",
|
1801
|
+
name: aiPart.toolName,
|
1802
|
+
args: aiPart.args
|
1803
|
+
});
|
1804
|
+
break;
|
1805
|
+
}
|
1806
|
+
}
|
1807
|
+
onUpdate({ content });
|
1808
|
+
}
|
1809
|
+
return { content };
|
1810
|
+
}
|
1811
|
+
};
|
1542
1812
|
// Annotate the CommonJS export names for ESM import in node:
|
1543
1813
|
0 && (module.exports = {
|
1544
1814
|
ActionBarPrimitive,
|
@@ -1549,8 +1819,11 @@ var VercelRSCAssistantProvider = ({
|
|
1549
1819
|
ThreadPrimitive,
|
1550
1820
|
VercelAIAssistantProvider,
|
1551
1821
|
VercelRSCAssistantProvider,
|
1822
|
+
unstable_AssistantProvider,
|
1823
|
+
unstable_VercelModelAdapter,
|
1552
1824
|
unstable_getVercelMessage,
|
1553
1825
|
unstable_getVercelRSCMessage,
|
1826
|
+
unstable_useLocalRuntime,
|
1554
1827
|
unstable_useMessageContext,
|
1555
1828
|
useBeginMessageEdit,
|
1556
1829
|
useCopyMessage,
|