@assistant-ui/react 0.0.18 → 0.0.20
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 +41 -45
- package/dist/index.d.ts +41 -45
- package/dist/index.js +348 -415
- package/dist/index.mjs +345 -411
- package/package.json +1 -1
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
|
-
// src/adapters/
|
1037
|
-
var
|
1049
|
+
// src/adapters/core/AssistantProvider.tsx
|
1050
|
+
var import_react29 = require("react");
|
1038
1051
|
var import_zustand5 = require("zustand");
|
1039
1052
|
|
1040
1053
|
// src/utils/context/stores/ViewportStore.tsx
|
@@ -1057,41 +1070,79 @@ var makeViewportStore = () => {
|
|
1057
1070
|
}));
|
1058
1071
|
};
|
1059
1072
|
|
1060
|
-
// src/adapters/
|
1061
|
-
var
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
append: () => {
|
1072
|
-
throw new Error("Not implemented");
|
1073
|
-
},
|
1074
|
-
startRun: () => {
|
1075
|
-
throw new Error("Not implemented");
|
1076
|
-
},
|
1077
|
-
cancelRun: () => {
|
1078
|
-
throw new Error("Not implemented");
|
1079
|
-
}
|
1073
|
+
// src/adapters/core/AssistantProvider.tsx
|
1074
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
1075
|
+
var makeThreadStore = (runtimeRef) => {
|
1076
|
+
const useThread = (0, import_zustand5.create)(() => ({
|
1077
|
+
messages: runtimeRef.current.messages,
|
1078
|
+
isRunning: runtimeRef.current.isRunning,
|
1079
|
+
getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
|
1080
|
+
switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
|
1081
|
+
startRun: (parentId) => runtimeRef.current.startRun(parentId),
|
1082
|
+
append: (message) => runtimeRef.current.append(message),
|
1083
|
+
cancelRun: () => runtimeRef.current.cancelRun()
|
1080
1084
|
}));
|
1085
|
+
const onRuntimeUpdate = () => {
|
1086
|
+
useThread.setState({
|
1087
|
+
messages: runtimeRef.current.messages,
|
1088
|
+
isRunning: runtimeRef.current.isRunning
|
1089
|
+
});
|
1090
|
+
};
|
1091
|
+
return {
|
1092
|
+
useThread,
|
1093
|
+
onRuntimeUpdate
|
1094
|
+
};
|
1081
1095
|
};
|
1082
|
-
var
|
1083
|
-
const
|
1084
|
-
|
1096
|
+
var AssistantProvider = ({ children, runtime }) => {
|
1097
|
+
const runtimeRef = (0, import_react29.useRef)(runtime);
|
1098
|
+
(0, import_react29.useInsertionEffect)(() => {
|
1099
|
+
runtimeRef.current = runtime;
|
1100
|
+
});
|
1101
|
+
const [{ context, onRuntimeUpdate }] = (0, import_react29.useState)(() => {
|
1102
|
+
const { useThread, onRuntimeUpdate: onRuntimeUpdate2 } = makeThreadStore(runtimeRef);
|
1085
1103
|
const useViewport = makeViewportStore();
|
1086
1104
|
const useComposer = makeThreadComposerStore(useThread);
|
1087
|
-
return {
|
1105
|
+
return {
|
1106
|
+
context: {
|
1107
|
+
useViewport,
|
1108
|
+
useThread,
|
1109
|
+
useComposer
|
1110
|
+
},
|
1111
|
+
onRuntimeUpdate: onRuntimeUpdate2
|
1112
|
+
};
|
1088
1113
|
});
|
1089
|
-
|
1114
|
+
(0, import_react29.useEffect)(() => {
|
1115
|
+
onRuntimeUpdate();
|
1116
|
+
return runtime.subscribe(onRuntimeUpdate);
|
1117
|
+
}, [onRuntimeUpdate, runtime]);
|
1118
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AssistantContext.Provider, { value: context, children });
|
1090
1119
|
};
|
1091
1120
|
|
1092
|
-
// src/adapters/vercel/
|
1093
|
-
var
|
1094
|
-
|
1121
|
+
// src/adapters/core/vercel-use-chat/useVercelUseChatRuntime.tsx
|
1122
|
+
var import_react30 = require("react");
|
1123
|
+
|
1124
|
+
// src/adapters/ThreadMessageConverter.ts
|
1125
|
+
var ThreadMessageConverter = class {
|
1126
|
+
cache = /* @__PURE__ */ new WeakMap();
|
1127
|
+
convertMessages(converter, messages) {
|
1128
|
+
return messages.map((m) => {
|
1129
|
+
const cached = this.cache.get(m);
|
1130
|
+
const newMessage = converter(m, cached);
|
1131
|
+
this.cache.set(m, newMessage);
|
1132
|
+
return newMessage;
|
1133
|
+
});
|
1134
|
+
}
|
1135
|
+
};
|
1136
|
+
|
1137
|
+
// src/adapters/vercel/VercelThreadMessage.tsx
|
1138
|
+
var symbolInnerMessage = Symbol("innerMessage");
|
1139
|
+
var symbolInnerRSCMessage = Symbol("innerRSCMessage");
|
1140
|
+
var getVercelMessage = (message) => {
|
1141
|
+
return message[symbolInnerMessage];
|
1142
|
+
};
|
1143
|
+
var getVercelRSCMessage = (message) => {
|
1144
|
+
return message[symbolInnerRSCMessage];
|
1145
|
+
};
|
1095
1146
|
|
1096
1147
|
// src/adapters/idUtils.tsx
|
1097
1148
|
var import_non_secure = require("nanoid/non-secure");
|
@@ -1253,30 +1304,104 @@ var MessageRepository = class {
|
|
1253
1304
|
}
|
1254
1305
|
};
|
1255
1306
|
|
1256
|
-
// src/adapters/
|
1257
|
-
var
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1307
|
+
// src/adapters/core/vercel-use-chat/VercelUseChatRuntime.tsx
|
1308
|
+
var sliceMessagesUntil = (messages, messageId) => {
|
1309
|
+
if (messageId == null) return [];
|
1310
|
+
const messageIdx = messages.findIndex((m) => m.id === messageId);
|
1311
|
+
if (messageIdx === -1)
|
1312
|
+
throw new Error(
|
1313
|
+
"useVercelAIThreadState: Message not found. This is liekly an internal bug in assistant-ui."
|
1314
|
+
);
|
1315
|
+
return messages.slice(0, messageIdx + 1);
|
1316
|
+
};
|
1317
|
+
var hasUpcomingMessage = (isRunning, messages) => {
|
1318
|
+
return isRunning && messages[messages.length - 1]?.role !== "assistant";
|
1319
|
+
};
|
1320
|
+
var VercelUseChatRuntime = class {
|
1321
|
+
constructor(vercel) {
|
1322
|
+
this.vercel = vercel;
|
1323
|
+
}
|
1324
|
+
_subscriptions = /* @__PURE__ */ new Set();
|
1325
|
+
repository = new MessageRepository();
|
1326
|
+
assistantOptimisticId = null;
|
1327
|
+
messages = [];
|
1328
|
+
isRunning = false;
|
1329
|
+
getBranches(messageId) {
|
1330
|
+
return this.repository.getBranches(messageId);
|
1331
|
+
}
|
1332
|
+
switchToBranch(branchId) {
|
1333
|
+
this.repository.switchToBranch(branchId);
|
1334
|
+
this.vercel.setMessages(
|
1335
|
+
this.repository.getMessages().map(getVercelMessage).filter((m) => m != null)
|
1336
|
+
);
|
1337
|
+
}
|
1338
|
+
async append(message) {
|
1339
|
+
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
1340
|
+
throw new Error("Only text content is supported by Vercel AI SDK.");
|
1341
|
+
const newMessages = sliceMessagesUntil(
|
1342
|
+
this.vercel.messages,
|
1343
|
+
message.parentId
|
1344
|
+
);
|
1345
|
+
this.vercel.setMessages(newMessages);
|
1346
|
+
await this.vercel.append({
|
1347
|
+
role: "user",
|
1348
|
+
content: message.content[0].text
|
1265
1349
|
});
|
1266
1350
|
}
|
1351
|
+
async startRun(parentId) {
|
1352
|
+
const reloadMaybe = "reload" in this.vercel ? this.vercel.reload : void 0;
|
1353
|
+
if (!reloadMaybe)
|
1354
|
+
throw new Error(
|
1355
|
+
"Reload is not supported by Vercel AI SDK's useAssistant."
|
1356
|
+
);
|
1357
|
+
const newMessages = sliceMessagesUntil(this.vercel.messages, parentId);
|
1358
|
+
this.vercel.setMessages(newMessages);
|
1359
|
+
await reloadMaybe();
|
1360
|
+
}
|
1361
|
+
cancelRun() {
|
1362
|
+
const lastMessage = this.vercel.messages.at(-1);
|
1363
|
+
this.vercel.stop();
|
1364
|
+
if (lastMessage?.role === "user") {
|
1365
|
+
this.vercel.setInput(lastMessage.content);
|
1366
|
+
}
|
1367
|
+
}
|
1368
|
+
updateData(isRunning, vm) {
|
1369
|
+
for (let i = 0; i < vm.length; i++) {
|
1370
|
+
const message = vm[i];
|
1371
|
+
const parent = vm[i - 1];
|
1372
|
+
this.repository.addOrUpdateMessage(parent?.id ?? null, message);
|
1373
|
+
}
|
1374
|
+
if (this.assistantOptimisticId) {
|
1375
|
+
this.repository.deleteMessage(this.assistantOptimisticId, null);
|
1376
|
+
this.assistantOptimisticId = null;
|
1377
|
+
}
|
1378
|
+
if (hasUpcomingMessage(isRunning, vm)) {
|
1379
|
+
this.assistantOptimisticId = this.repository.appendOptimisticMessage(
|
1380
|
+
vm.at(-1)?.id ?? null,
|
1381
|
+
{
|
1382
|
+
role: "assistant",
|
1383
|
+
content: [{ type: "text", text: "" }]
|
1384
|
+
}
|
1385
|
+
);
|
1386
|
+
}
|
1387
|
+
this.repository.resetHead(
|
1388
|
+
this.assistantOptimisticId ?? vm.at(-1)?.id ?? null
|
1389
|
+
);
|
1390
|
+
this.messages = this.repository.getMessages();
|
1391
|
+
this.isRunning = isRunning;
|
1392
|
+
for (const callback of this._subscriptions) callback();
|
1393
|
+
}
|
1394
|
+
subscribe(callback) {
|
1395
|
+
this._subscriptions.add(callback);
|
1396
|
+
return () => this._subscriptions.delete(callback);
|
1397
|
+
}
|
1267
1398
|
};
|
1268
1399
|
|
1269
|
-
// src/adapters/vercel/
|
1270
|
-
var
|
1271
|
-
|
1272
|
-
|
1273
|
-
return message[symbolInnerMessage];
|
1274
|
-
};
|
1275
|
-
var getVercelRSCMessage = (message) => {
|
1276
|
-
return message[symbolInnerRSCMessage];
|
1400
|
+
// src/adapters/core/vercel-use-chat/useVercelUseChatRuntime.tsx
|
1401
|
+
var getIsRunning = (vercel) => {
|
1402
|
+
if ("isLoading" in vercel) return vercel.isLoading;
|
1403
|
+
return vercel.status === "in_progress";
|
1277
1404
|
};
|
1278
|
-
|
1279
|
-
// src/adapters/vercel/useVercelAIThreadState.tsx
|
1280
1405
|
var vercelToThreadMessage = (message, status) => {
|
1281
1406
|
const common = {
|
1282
1407
|
id: message.id,
|
@@ -1313,28 +1438,14 @@ var vercelToThreadMessage = (message, status) => {
|
|
1313
1438
|
);
|
1314
1439
|
}
|
1315
1440
|
};
|
1316
|
-
var
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
"useVercelAIThreadState: Message not found. This is liekly an internal bug in assistant-ui."
|
1322
|
-
);
|
1323
|
-
return messages.slice(0, messageIdx + 1);
|
1324
|
-
};
|
1325
|
-
var hasUpcomingMessage = (isRunning, messages) => {
|
1326
|
-
return isRunning && messages[messages.length - 1]?.role !== "assistant";
|
1327
|
-
};
|
1328
|
-
var getIsRunning = (vercel) => {
|
1329
|
-
if ("isLoading" in vercel) return vercel.isLoading;
|
1330
|
-
return vercel.status === "in_progress";
|
1331
|
-
};
|
1332
|
-
var useVercelAIThreadState = (vercel) => {
|
1333
|
-
const [data] = (0, import_react25.useState)(() => new MessageRepository());
|
1441
|
+
var useVercelUseChatRuntime = (vercel) => {
|
1442
|
+
const [runtime] = (0, import_react30.useState)(() => new VercelUseChatRuntime(vercel));
|
1443
|
+
(0, import_react30.useInsertionEffect)(() => {
|
1444
|
+
runtime.vercel = vercel;
|
1445
|
+
});
|
1334
1446
|
const isRunning = getIsRunning(vercel);
|
1335
|
-
const converter = (0,
|
1336
|
-
const
|
1337
|
-
const messages = (0, import_react25.useMemo)(() => {
|
1447
|
+
const converter = (0, import_react30.useMemo)(() => new ThreadMessageConverter(), []);
|
1448
|
+
const messages = (0, import_react30.useMemo)(() => {
|
1338
1449
|
const lastMessageId = vercel.messages.at(-1)?.id;
|
1339
1450
|
const convertCallback = (message, cache) => {
|
1340
1451
|
const status = lastMessageId === message.id && isRunning ? "in_progress" : "done";
|
@@ -1342,113 +1453,102 @@ var useVercelAIThreadState = (vercel) => {
|
|
1342
1453
|
return cache;
|
1343
1454
|
return vercelToThreadMessage(message, status);
|
1344
1455
|
};
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
if (assistantOptimisticIdRef.current) {
|
1352
|
-
data.deleteMessage(assistantOptimisticIdRef.current, null);
|
1353
|
-
assistantOptimisticIdRef.current = null;
|
1354
|
-
}
|
1355
|
-
if (hasUpcomingMessage(isRunning, vm)) {
|
1356
|
-
assistantOptimisticIdRef.current = data.appendOptimisticMessage(
|
1357
|
-
vm.at(-1)?.id ?? null,
|
1358
|
-
{
|
1359
|
-
role: "assistant",
|
1360
|
-
content: [{ type: "text", text: "" }]
|
1361
|
-
}
|
1362
|
-
);
|
1363
|
-
}
|
1364
|
-
data.resetHead(assistantOptimisticIdRef.current ?? vm.at(-1)?.id ?? null);
|
1365
|
-
return data.getMessages();
|
1366
|
-
}, [converter, data, isRunning, vercel.messages]);
|
1367
|
-
const getBranches2 = (0, import_react25.useCallback)(
|
1368
|
-
(messageId) => {
|
1369
|
-
return data.getBranches(messageId);
|
1370
|
-
},
|
1371
|
-
[data]
|
1372
|
-
);
|
1373
|
-
const switchToBranch2 = (0, import_react_use_callback_ref3.useCallbackRef)((messageId) => {
|
1374
|
-
data.switchToBranch(messageId);
|
1375
|
-
vercel.setMessages(
|
1376
|
-
data.getMessages().map(getVercelMessage).filter((m) => m != null)
|
1377
|
-
);
|
1378
|
-
});
|
1379
|
-
const startRun = (0, import_react_use_callback_ref3.useCallbackRef)(async (parentId) => {
|
1380
|
-
const reloadMaybe = "reload" in vercel ? vercel.reload : void 0;
|
1381
|
-
if (!reloadMaybe)
|
1382
|
-
throw new Error(
|
1383
|
-
"Reload is not supported by Vercel AI SDK's useAssistant."
|
1384
|
-
);
|
1385
|
-
const newMessages = sliceMessagesUntil(vercel.messages, parentId);
|
1386
|
-
vercel.setMessages(newMessages);
|
1387
|
-
await reloadMaybe();
|
1388
|
-
});
|
1389
|
-
const append = (0, import_react_use_callback_ref3.useCallbackRef)(async (message) => {
|
1390
|
-
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
1391
|
-
throw new Error("Only text content is supported by Vercel AI SDK.");
|
1392
|
-
const newMessages = sliceMessagesUntil(vercel.messages, message.parentId);
|
1393
|
-
vercel.setMessages(newMessages);
|
1394
|
-
await vercel.append({
|
1395
|
-
role: "user",
|
1396
|
-
content: message.content[0].text
|
1397
|
-
});
|
1398
|
-
});
|
1399
|
-
const cancelRun2 = (0, import_react_use_callback_ref3.useCallbackRef)(() => {
|
1400
|
-
const lastMessage = vercel.messages.at(-1);
|
1401
|
-
vercel.stop();
|
1402
|
-
if (lastMessage?.role === "user") {
|
1403
|
-
vercel.setInput(lastMessage.content);
|
1404
|
-
}
|
1405
|
-
});
|
1406
|
-
return (0, import_react25.useMemo)(
|
1407
|
-
() => ({
|
1408
|
-
isRunning,
|
1409
|
-
messages,
|
1410
|
-
getBranches: getBranches2,
|
1411
|
-
switchToBranch: switchToBranch2,
|
1412
|
-
append,
|
1413
|
-
startRun,
|
1414
|
-
cancelRun: cancelRun2
|
1415
|
-
}),
|
1416
|
-
[
|
1417
|
-
isRunning,
|
1418
|
-
messages,
|
1419
|
-
getBranches2,
|
1420
|
-
switchToBranch2,
|
1421
|
-
append,
|
1422
|
-
startRun,
|
1423
|
-
cancelRun2
|
1424
|
-
]
|
1425
|
-
);
|
1456
|
+
return converter.convertMessages(convertCallback, vercel.messages);
|
1457
|
+
}, [isRunning, vercel.messages, converter]);
|
1458
|
+
(0, import_react30.useEffect)(() => {
|
1459
|
+
runtime.updateData(isRunning, messages);
|
1460
|
+
}, [runtime, isRunning, messages]);
|
1461
|
+
return runtime;
|
1426
1462
|
};
|
1427
1463
|
|
1428
1464
|
// src/adapters/vercel/VercelAIAssistantProvider.tsx
|
1429
|
-
var
|
1465
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
1430
1466
|
var VercelAIAssistantProvider = ({
|
1431
1467
|
children,
|
1432
1468
|
...rest
|
1433
1469
|
}) => {
|
1434
|
-
const context = useDummyAIAssistantContext();
|
1435
1470
|
const vercel = "chat" in rest ? rest.chat : rest.assistant;
|
1436
|
-
const
|
1437
|
-
(0,
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1471
|
+
const runtime = useVercelUseChatRuntime(vercel);
|
1472
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(AssistantProvider, { runtime, children: [
|
1473
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ComposerSync, { vercel }),
|
1474
|
+
children
|
1475
|
+
] });
|
1476
|
+
};
|
1477
|
+
var ComposerSync = ({
|
1478
|
+
vercel
|
1479
|
+
}) => {
|
1480
|
+
const { useComposer } = useAssistantContext();
|
1481
|
+
(0, import_react31.useEffect)(() => {
|
1482
|
+
useComposer.setState({
|
1442
1483
|
value: vercel.input,
|
1443
1484
|
setValue: vercel.setInput
|
1444
1485
|
});
|
1445
|
-
}, [
|
1446
|
-
return
|
1486
|
+
}, [useComposer, vercel.input, vercel.setInput]);
|
1487
|
+
return null;
|
1447
1488
|
};
|
1448
1489
|
|
1449
|
-
// src/adapters/vercel/
|
1450
|
-
var
|
1451
|
-
|
1490
|
+
// src/adapters/core/vercel-rsc/useVercelRSCRuntime.tsx
|
1491
|
+
var import_react32 = require("react");
|
1492
|
+
|
1493
|
+
// src/adapters/core/vercel-rsc/VercelRSCRuntime.tsx
|
1494
|
+
var EMPTY_BRANCHES = Object.freeze([]);
|
1495
|
+
var VercelRSCRuntime = class {
|
1496
|
+
constructor(adapter) {
|
1497
|
+
this.adapter = adapter;
|
1498
|
+
}
|
1499
|
+
_subscriptions = /* @__PURE__ */ new Set();
|
1500
|
+
isRunning = false;
|
1501
|
+
messages = [];
|
1502
|
+
withRunning = (callback) => {
|
1503
|
+
this.isRunning = true;
|
1504
|
+
return callback.finally(() => {
|
1505
|
+
this.isRunning = false;
|
1506
|
+
});
|
1507
|
+
};
|
1508
|
+
getBranches() {
|
1509
|
+
return EMPTY_BRANCHES;
|
1510
|
+
}
|
1511
|
+
switchToBranch() {
|
1512
|
+
throw new Error(
|
1513
|
+
"Branch switching is not supported by VercelRSCAssistantProvider."
|
1514
|
+
);
|
1515
|
+
}
|
1516
|
+
async append(message) {
|
1517
|
+
if (message.parentId !== (this.messages.at(-1)?.id ?? null)) {
|
1518
|
+
if (!this.adapter.edit)
|
1519
|
+
throw new Error(
|
1520
|
+
"Message editing is not enabled, please provide an edit callback to VercelRSCAssistantProvider."
|
1521
|
+
);
|
1522
|
+
await this.withRunning(this.adapter.edit(message));
|
1523
|
+
} else {
|
1524
|
+
await this.withRunning(this.adapter.append(message));
|
1525
|
+
}
|
1526
|
+
}
|
1527
|
+
async startRun(parentId) {
|
1528
|
+
if (!this.adapter.reload)
|
1529
|
+
throw new Error(
|
1530
|
+
"Message reloading is not enabled, please provide a reload callback to VercelRSCAssistantProvider."
|
1531
|
+
);
|
1532
|
+
await this.withRunning(this.adapter.reload(parentId));
|
1533
|
+
}
|
1534
|
+
cancelRun() {
|
1535
|
+
if (process.env["NODE_ENV"] === "development") {
|
1536
|
+
console.warn(
|
1537
|
+
"Run cancellation is not supported by VercelRSCAssistantProvider."
|
1538
|
+
);
|
1539
|
+
}
|
1540
|
+
}
|
1541
|
+
updateData(messages) {
|
1542
|
+
this.messages = messages;
|
1543
|
+
for (const callback of this._subscriptions) callback();
|
1544
|
+
}
|
1545
|
+
subscribe(callback) {
|
1546
|
+
this._subscriptions.add(callback);
|
1547
|
+
return () => this._subscriptions.delete(callback);
|
1548
|
+
}
|
1549
|
+
};
|
1550
|
+
|
1551
|
+
// src/adapters/core/vercel-rsc/useVercelRSCRuntime.tsx
|
1452
1552
|
var vercelToThreadMessage2 = (converter, rawMessage) => {
|
1453
1553
|
const message = converter(rawMessage);
|
1454
1554
|
return {
|
@@ -1460,220 +1560,61 @@ var vercelToThreadMessage2 = (converter, rawMessage) => {
|
|
1460
1560
|
[symbolInnerRSCMessage]: rawMessage
|
1461
1561
|
};
|
1462
1562
|
};
|
1463
|
-
var
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
);
|
1471
|
-
};
|
1472
|
-
var cancelRun = () => {
|
1473
|
-
if (process.env["NODE_ENV"] === "development") {
|
1474
|
-
console.warn(
|
1475
|
-
"Run cancellation is not supported by VercelRSCAssistantProvider."
|
1476
|
-
);
|
1477
|
-
}
|
1478
|
-
};
|
1479
|
-
var VercelRSCAssistantProvider = ({
|
1480
|
-
children,
|
1481
|
-
convertMessage,
|
1482
|
-
messages: vercelMessages,
|
1483
|
-
append: appendCallback,
|
1484
|
-
edit,
|
1485
|
-
reload
|
1486
|
-
}) => {
|
1487
|
-
const context = useDummyAIAssistantContext();
|
1488
|
-
const [isRunning, setIsRunning] = (0, import_react27.useState)(false);
|
1489
|
-
const withRunning = (0, import_react27.useCallback)((callback) => {
|
1490
|
-
setIsRunning(true);
|
1491
|
-
return callback.finally(() => setIsRunning(false));
|
1492
|
-
}, []);
|
1493
|
-
const [converter, convertCallback] = (0, import_react27.useMemo)(() => {
|
1494
|
-
const rscConverter = convertMessage ?? ((m) => m);
|
1563
|
+
var useVercelRSCRuntime = (adapter) => {
|
1564
|
+
const [runtime] = (0, import_react32.useState)(() => new VercelRSCRuntime(adapter));
|
1565
|
+
(0, import_react32.useInsertionEffect)(() => {
|
1566
|
+
runtime.adapter = adapter;
|
1567
|
+
});
|
1568
|
+
const [converter, convertCallback] = (0, import_react32.useMemo)(() => {
|
1569
|
+
const rscConverter = adapter.convertMessage ?? ((m) => m);
|
1495
1570
|
const convertCallback2 = (m, cache) => {
|
1496
1571
|
if (cache) return cache;
|
1497
1572
|
return vercelToThreadMessage2(rscConverter, m);
|
1498
1573
|
};
|
1499
1574
|
return [new ThreadMessageConverter(), convertCallback2];
|
1500
|
-
}, [convertMessage]);
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
const append = (0, import_react27.useCallback)(
|
1505
|
-
async (message) => {
|
1506
|
-
if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null)) {
|
1507
|
-
if (!edit)
|
1508
|
-
throw new Error(
|
1509
|
-
"Message editing is not enabled, please provide an edit callback to VercelRSCAssistantProvider."
|
1510
|
-
);
|
1511
|
-
await withRunning(edit(message));
|
1512
|
-
} else {
|
1513
|
-
await withRunning(appendCallback(message));
|
1514
|
-
}
|
1515
|
-
},
|
1516
|
-
[context, withRunning, appendCallback, edit]
|
1517
|
-
);
|
1518
|
-
const startRun = (0, import_react27.useCallback)(
|
1519
|
-
async (parentId) => {
|
1520
|
-
if (!reload)
|
1521
|
-
throw new Error(
|
1522
|
-
"Message reloading is not enabled, please provide a reload callback to VercelRSCAssistantProvider."
|
1523
|
-
);
|
1524
|
-
await withRunning(reload(parentId));
|
1525
|
-
},
|
1526
|
-
[withRunning, reload]
|
1527
|
-
);
|
1528
|
-
(0, import_react27.useMemo)(() => {
|
1529
|
-
context.useThread.setState(
|
1530
|
-
{
|
1531
|
-
messages,
|
1532
|
-
isRunning,
|
1533
|
-
getBranches,
|
1534
|
-
switchToBranch,
|
1535
|
-
append,
|
1536
|
-
startRun,
|
1537
|
-
cancelRun
|
1538
|
-
},
|
1539
|
-
true
|
1575
|
+
}, [adapter.convertMessage]);
|
1576
|
+
(0, import_react32.useEffect)(() => {
|
1577
|
+
runtime.updateData(
|
1578
|
+
converter.convertMessages(convertCallback, adapter.messages)
|
1540
1579
|
);
|
1541
|
-
}, [
|
1542
|
-
return
|
1543
|
-
};
|
1544
|
-
|
1545
|
-
// src/adapters/core/utils/useAssistantContext.tsx
|
1546
|
-
var import_react28 = require("react");
|
1547
|
-
var import_zustand6 = require("zustand");
|
1548
|
-
|
1549
|
-
// src/adapters/core/utils/AssistantMessageRepository.tsx
|
1550
|
-
var AssistantMessageRepository = class {
|
1551
|
-
constructor(flushCallback) {
|
1552
|
-
this.flushCallback = flushCallback;
|
1553
|
-
}
|
1554
|
-
repository = new MessageRepository();
|
1555
|
-
getBranches(messageId) {
|
1556
|
-
return this.repository.getBranches(messageId);
|
1557
|
-
}
|
1558
|
-
withModifications(callback) {
|
1559
|
-
const res = callback(this.repository);
|
1560
|
-
this.flushCallback(this.repository.getMessages());
|
1561
|
-
return res;
|
1562
|
-
}
|
1563
|
-
};
|
1564
|
-
|
1565
|
-
// src/adapters/core/utils/useAssistantContext.tsx
|
1566
|
-
var makeThreadStore = (runtimeRef) => {
|
1567
|
-
const repository = new AssistantMessageRepository((messages) => {
|
1568
|
-
useThread.setState({ messages });
|
1569
|
-
});
|
1570
|
-
const useThread = (0, import_zustand6.create)(() => ({
|
1571
|
-
messages: [],
|
1572
|
-
isRunning: false,
|
1573
|
-
getBranches: (messageId) => repository.getBranches(messageId),
|
1574
|
-
switchToBranch: (branchId) => {
|
1575
|
-
repository.withModifications((repository2) => {
|
1576
|
-
repository2.switchToBranch(branchId);
|
1577
|
-
});
|
1578
|
-
},
|
1579
|
-
startRun: async (parentId) => {
|
1580
|
-
const optimisticId = repository.withModifications((repository2) => {
|
1581
|
-
const optimisticId2 = repository2.appendOptimisticMessage(parentId, {
|
1582
|
-
role: "assistant",
|
1583
|
-
content: [{ type: "text", text: "" }]
|
1584
|
-
});
|
1585
|
-
repository2.resetHead(optimisticId2);
|
1586
|
-
return optimisticId2;
|
1587
|
-
});
|
1588
|
-
const { id } = await runtimeRef.current.startRun(parentId);
|
1589
|
-
repository.withModifications((repository2) => {
|
1590
|
-
repository2.deleteMessage(optimisticId, id);
|
1591
|
-
});
|
1592
|
-
},
|
1593
|
-
append: async (message) => {
|
1594
|
-
const [parentOptimisticId, optimisticId] = repository.withModifications(
|
1595
|
-
(repository2) => {
|
1596
|
-
const parentOptimisticId2 = repository2.appendOptimisticMessage(
|
1597
|
-
message.parentId,
|
1598
|
-
{
|
1599
|
-
role: "user",
|
1600
|
-
content: message.content
|
1601
|
-
}
|
1602
|
-
);
|
1603
|
-
const optimisticId2 = repository2.appendOptimisticMessage(
|
1604
|
-
parentOptimisticId2,
|
1605
|
-
{
|
1606
|
-
role: "assistant",
|
1607
|
-
content: [{ type: "text", text: "" }]
|
1608
|
-
}
|
1609
|
-
);
|
1610
|
-
repository2.resetHead(optimisticId2);
|
1611
|
-
return [parentOptimisticId2, optimisticId2];
|
1612
|
-
}
|
1613
|
-
);
|
1614
|
-
const { parentId, id } = await runtimeRef.current.append(message);
|
1615
|
-
repository.withModifications((repository2) => {
|
1616
|
-
repository2.deleteMessage(parentOptimisticId, parentId);
|
1617
|
-
repository2.deleteMessage(optimisticId, id);
|
1618
|
-
});
|
1619
|
-
},
|
1620
|
-
cancelRun: () => runtimeRef.current.cancelRun()
|
1621
|
-
}));
|
1622
|
-
const onNewMessage = (parentId, message) => {
|
1623
|
-
repository.withModifications((repository2) => {
|
1624
|
-
repository2.addOrUpdateMessage(parentId, message);
|
1625
|
-
});
|
1626
|
-
};
|
1627
|
-
const onRunningChange = (isRunning) => {
|
1628
|
-
useThread.setState({ isRunning });
|
1629
|
-
};
|
1630
|
-
return {
|
1631
|
-
useThread,
|
1632
|
-
onNewMessage,
|
1633
|
-
onRunningChange
|
1634
|
-
};
|
1635
|
-
};
|
1636
|
-
var useAssistantContext2 = (runtime) => {
|
1637
|
-
const runtimeRef = (0, import_react28.useRef)(runtime);
|
1638
|
-
runtimeRef.current = runtime;
|
1639
|
-
const [{ context, onNewMessage, onRunningChange }] = (0, import_react28.useState)(() => {
|
1640
|
-
const { useThread, onNewMessage: onNewMessage2, onRunningChange: onRunningChange2 } = makeThreadStore(runtimeRef);
|
1641
|
-
const useViewport = makeViewportStore();
|
1642
|
-
const useComposer = makeThreadComposerStore(useThread);
|
1643
|
-
return {
|
1644
|
-
context: { useViewport, useThread, useComposer },
|
1645
|
-
onNewMessage: onNewMessage2,
|
1646
|
-
onRunningChange: onRunningChange2
|
1647
|
-
};
|
1648
|
-
});
|
1649
|
-
(0, import_react28.useEffect)(() => {
|
1650
|
-
return runtime.subscribeToMessageUpdates(onNewMessage);
|
1651
|
-
}, [runtime, onNewMessage]);
|
1652
|
-
(0, import_react28.useEffect)(() => {
|
1653
|
-
return runtime.subscribeToStatusUpdates(onRunningChange);
|
1654
|
-
}, [runtime, onRunningChange]);
|
1655
|
-
return context;
|
1580
|
+
}, [runtime, converter, convertCallback, adapter.messages]);
|
1581
|
+
return runtime;
|
1656
1582
|
};
|
1657
1583
|
|
1658
|
-
// src/adapters/
|
1584
|
+
// src/adapters/vercel/VercelRSCAssistantProvider.tsx
|
1659
1585
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
1660
|
-
var
|
1661
|
-
|
1662
|
-
|
1586
|
+
var VercelRSCAssistantProvider = ({
|
1587
|
+
children,
|
1588
|
+
...adapter
|
1589
|
+
}) => {
|
1590
|
+
const runtime = useVercelRSCRuntime(adapter);
|
1591
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AssistantProvider, { runtime, children });
|
1663
1592
|
};
|
1664
1593
|
|
1665
1594
|
// src/adapters/core/local/useLocalRuntime.tsx
|
1666
|
-
var
|
1595
|
+
var import_react33 = require("react");
|
1667
1596
|
|
1668
1597
|
// src/adapters/core/local/LocalRuntime.tsx
|
1669
1598
|
var LocalRuntime = class {
|
1670
1599
|
constructor(adapter) {
|
1671
1600
|
this.adapter = adapter;
|
1672
1601
|
}
|
1673
|
-
|
1674
|
-
_statusUpdateCallbacks = /* @__PURE__ */ new Set();
|
1602
|
+
_subscriptions = /* @__PURE__ */ new Set();
|
1675
1603
|
abortController = null;
|
1676
1604
|
repository = new MessageRepository();
|
1605
|
+
get messages() {
|
1606
|
+
return this.repository.getMessages();
|
1607
|
+
}
|
1608
|
+
get isRunning() {
|
1609
|
+
return this.abortController != null;
|
1610
|
+
}
|
1611
|
+
getBranches(messageId) {
|
1612
|
+
return this.repository.getBranches(messageId);
|
1613
|
+
}
|
1614
|
+
switchToBranch(branchId) {
|
1615
|
+
this.repository.switchToBranch(branchId);
|
1616
|
+
this.notifySubscribers();
|
1617
|
+
}
|
1677
1618
|
async append(message) {
|
1678
1619
|
const userMessageId = generateId();
|
1679
1620
|
const userMessage = {
|
@@ -1682,9 +1623,8 @@ var LocalRuntime = class {
|
|
1682
1623
|
content: message.content,
|
1683
1624
|
createdAt: /* @__PURE__ */ new Date()
|
1684
1625
|
};
|
1685
|
-
this.addOrUpdateMessage(message.parentId, userMessage);
|
1686
|
-
|
1687
|
-
return { parentId: userMessageId, id };
|
1626
|
+
this.repository.addOrUpdateMessage(message.parentId, userMessage);
|
1627
|
+
await this.startRun(userMessageId);
|
1688
1628
|
}
|
1689
1629
|
async startRun(parentId) {
|
1690
1630
|
const id = generateId();
|
@@ -1697,59 +1637,52 @@ var LocalRuntime = class {
|
|
1697
1637
|
content: [{ type: "text", text: "" }],
|
1698
1638
|
createdAt: /* @__PURE__ */ new Date()
|
1699
1639
|
};
|
1700
|
-
this.addOrUpdateMessage(parentId, message);
|
1701
|
-
|
1702
|
-
return { id };
|
1703
|
-
}
|
1704
|
-
addOrUpdateMessage(parentId, message) {
|
1705
|
-
const clone = { ...message };
|
1706
|
-
this.repository.addOrUpdateMessage(parentId, clone);
|
1707
|
-
for (const callback of this._messageUpdateCallbacks)
|
1708
|
-
callback(parentId, clone);
|
1709
|
-
}
|
1710
|
-
async run(parentId, messages, message) {
|
1711
|
-
this.cancelRun();
|
1712
|
-
for (const callback of this._statusUpdateCallbacks) callback(true);
|
1640
|
+
this.repository.addOrUpdateMessage(parentId, { ...message });
|
1641
|
+
this.abortController?.abort();
|
1713
1642
|
this.abortController = new AbortController();
|
1643
|
+
this.notifySubscribers();
|
1714
1644
|
try {
|
1715
1645
|
await this.adapter.run({
|
1716
1646
|
messages,
|
1717
1647
|
abortSignal: this.abortController.signal,
|
1718
1648
|
onUpdate: ({ content }) => {
|
1719
1649
|
message.content = content;
|
1720
|
-
this.addOrUpdateMessage(parentId, message);
|
1650
|
+
this.repository.addOrUpdateMessage(parentId, { ...message });
|
1651
|
+
this.notifySubscribers();
|
1721
1652
|
}
|
1722
1653
|
});
|
1723
1654
|
message.status = "done";
|
1724
|
-
this.addOrUpdateMessage(parentId, message);
|
1655
|
+
this.repository.addOrUpdateMessage(parentId, { ...message });
|
1725
1656
|
} catch (e) {
|
1726
1657
|
message.status = "error";
|
1727
|
-
this.addOrUpdateMessage(parentId, message);
|
1658
|
+
this.repository.addOrUpdateMessage(parentId, { ...message });
|
1728
1659
|
console.error(e);
|
1729
1660
|
} finally {
|
1730
|
-
this.
|
1661
|
+
this.abortController = null;
|
1662
|
+
this.notifySubscribers();
|
1731
1663
|
}
|
1732
1664
|
}
|
1733
1665
|
cancelRun() {
|
1734
1666
|
if (!this.abortController) return;
|
1735
1667
|
this.abortController.abort();
|
1736
1668
|
this.abortController = null;
|
1737
|
-
|
1669
|
+
this.notifySubscribers();
|
1738
1670
|
}
|
1739
|
-
|
1740
|
-
this.
|
1741
|
-
return () => this._messageUpdateCallbacks.delete(callback);
|
1671
|
+
notifySubscribers() {
|
1672
|
+
for (const callback of this._subscriptions) callback();
|
1742
1673
|
}
|
1743
|
-
|
1744
|
-
this.
|
1745
|
-
return () => this.
|
1674
|
+
subscribe(callback) {
|
1675
|
+
this._subscriptions.add(callback);
|
1676
|
+
return () => this._subscriptions.delete(callback);
|
1746
1677
|
}
|
1747
1678
|
};
|
1748
1679
|
|
1749
1680
|
// src/adapters/core/local/useLocalRuntime.tsx
|
1750
1681
|
var useLocalRuntime = (adapter) => {
|
1751
|
-
const [runtime] = (0,
|
1752
|
-
|
1682
|
+
const [runtime] = (0, import_react33.useState)(() => new LocalRuntime(adapter));
|
1683
|
+
(0, import_react33.useInsertionEffect)(() => {
|
1684
|
+
runtime.adapter = adapter;
|
1685
|
+
});
|
1753
1686
|
return runtime;
|
1754
1687
|
};
|
1755
1688
|
|