@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.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,9 +1087,9 @@ 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
|
-
// src/adapters/
|
1092
|
+
// src/adapters/idUtils.tsx
|
1080
1093
|
import { customAlphabet } from "nanoid/non-secure";
|
1081
1094
|
var generateId = customAlphabet(
|
1082
1095
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
@@ -1084,6 +1097,8 @@ var generateId = customAlphabet(
|
|
1084
1097
|
);
|
1085
1098
|
var optimisticPrefix = "__optimistic__";
|
1086
1099
|
var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
|
1100
|
+
|
1101
|
+
// src/adapters/MessageRepository.tsx
|
1087
1102
|
var findHead = (message) => {
|
1088
1103
|
if (message.next) return findHead(message.next);
|
1089
1104
|
return message;
|
@@ -1095,15 +1110,6 @@ var MessageRepository = class {
|
|
1095
1110
|
root = {
|
1096
1111
|
children: []
|
1097
1112
|
};
|
1098
|
-
getFallbackChild(p) {
|
1099
|
-
const childId = p.children.at(-1);
|
1100
|
-
const child = childId ? this.messages.get(childId) : null;
|
1101
|
-
if (child === void 0)
|
1102
|
-
throw new Error(
|
1103
|
-
"MessageRepository(getFallbackChild): Child message not found. This is likely an internal bug in assistant-ui."
|
1104
|
-
);
|
1105
|
-
return child;
|
1106
|
-
}
|
1107
1113
|
performOp(newParent, child, operation) {
|
1108
1114
|
const parentOrRoot = child.prev ?? this.root;
|
1109
1115
|
const newParentOrRoot = newParent ?? this.root;
|
@@ -1113,7 +1119,14 @@ var MessageRepository = class {
|
|
1113
1119
|
(m) => m !== child.current.id
|
1114
1120
|
);
|
1115
1121
|
if (child.prev?.next === child) {
|
1116
|
-
child.prev.
|
1122
|
+
const fallbackId = child.prev.children.at(-1);
|
1123
|
+
const fallback = fallbackId ? this.messages.get(fallbackId) : null;
|
1124
|
+
if (fallback === void 0) {
|
1125
|
+
throw new Error(
|
1126
|
+
"MessageRepository(performOp/cut): Fallback sibling message not found. This is likely an internal bug in assistant-ui."
|
1127
|
+
);
|
1128
|
+
}
|
1129
|
+
child.prev.next = fallback;
|
1117
1130
|
}
|
1118
1131
|
}
|
1119
1132
|
if (operation !== "cut") {
|
@@ -1172,14 +1185,14 @@ var MessageRepository = class {
|
|
1172
1185
|
});
|
1173
1186
|
return optimisticId;
|
1174
1187
|
}
|
1175
|
-
deleteMessage(messageId,
|
1188
|
+
deleteMessage(messageId, replacementId) {
|
1176
1189
|
const message = this.messages.get(messageId);
|
1177
|
-
const
|
1190
|
+
const replacement = replacementId ? this.messages.get(replacementId) : null;
|
1178
1191
|
if (!message)
|
1179
1192
|
throw new Error(
|
1180
1193
|
"MessageRepository(deleteMessage): Optimistic message not found. This is likely an internal bug in assistant-ui."
|
1181
1194
|
);
|
1182
|
-
if (
|
1195
|
+
if (replacement === void 0)
|
1183
1196
|
throw new Error(
|
1184
1197
|
"MessageRepository(deleteMessage): New message not found. This is likely an internal bug in assistant-ui."
|
1185
1198
|
);
|
@@ -1189,11 +1202,11 @@ var MessageRepository = class {
|
|
1189
1202
|
throw new Error(
|
1190
1203
|
"MessageRepository(deleteMessage): Child message not found. This is likely an internal bug in assistant-ui."
|
1191
1204
|
);
|
1192
|
-
this.performOp(
|
1205
|
+
this.performOp(replacement, childMessage, "relink");
|
1193
1206
|
}
|
1194
1207
|
this.messages.delete(messageId);
|
1195
1208
|
if (this.head === message) {
|
1196
|
-
this.head =
|
1209
|
+
this.head = replacement;
|
1197
1210
|
}
|
1198
1211
|
this.performOp(null, message, "cut");
|
1199
1212
|
}
|
@@ -1236,17 +1249,13 @@ var MessageRepository = class {
|
|
1236
1249
|
}
|
1237
1250
|
};
|
1238
1251
|
|
1239
|
-
// src/adapters/ThreadMessageConverter.
|
1252
|
+
// src/adapters/ThreadMessageConverter.ts
|
1240
1253
|
var ThreadMessageConverter = class {
|
1241
|
-
constructor(converter) {
|
1242
|
-
this.converter = converter;
|
1243
|
-
}
|
1244
1254
|
cache = /* @__PURE__ */ new WeakMap();
|
1245
|
-
convertMessages(messages) {
|
1255
|
+
convertMessages(converter, messages) {
|
1246
1256
|
return messages.map((m) => {
|
1247
1257
|
const cached = this.cache.get(m);
|
1248
|
-
|
1249
|
-
const newMessage = this.converter(m);
|
1258
|
+
const newMessage = converter(m, cached);
|
1250
1259
|
this.cache.set(m, newMessage);
|
1251
1260
|
return newMessage;
|
1252
1261
|
});
|
@@ -1319,16 +1328,17 @@ var getIsRunning = (vercel) => {
|
|
1319
1328
|
var useVercelAIThreadState = (vercel) => {
|
1320
1329
|
const [data] = useState4(() => new MessageRepository());
|
1321
1330
|
const isRunning = getIsRunning(vercel);
|
1322
|
-
const
|
1323
|
-
return vercelToThreadMessage(
|
1324
|
-
message,
|
1325
|
-
vercel.messages.at(-1) === message && isRunning ? "in_progress" : "done"
|
1326
|
-
);
|
1327
|
-
});
|
1328
|
-
const converter = new ThreadMessageConverter(convertCallback);
|
1331
|
+
const converter = useMemo5(() => new ThreadMessageConverter(), []);
|
1329
1332
|
const assistantOptimisticIdRef = useRef4(null);
|
1330
1333
|
const messages = useMemo5(() => {
|
1331
|
-
const
|
1334
|
+
const lastMessageId = vercel.messages.at(-1)?.id;
|
1335
|
+
const convertCallback = (message, cache) => {
|
1336
|
+
const status = lastMessageId === message.id && isRunning ? "in_progress" : "done";
|
1337
|
+
if (cache && (cache.role === "user" || cache.status === status))
|
1338
|
+
return cache;
|
1339
|
+
return vercelToThreadMessage(message, status);
|
1340
|
+
};
|
1341
|
+
const vm = converter.convertMessages(convertCallback, vercel.messages);
|
1332
1342
|
for (let i = 0; i < vm.length; i++) {
|
1333
1343
|
const message = vm[i];
|
1334
1344
|
const parent = vm[i - 1];
|
@@ -1350,7 +1360,7 @@ var useVercelAIThreadState = (vercel) => {
|
|
1350
1360
|
data.resetHead(assistantOptimisticIdRef.current ?? vm.at(-1)?.id ?? null);
|
1351
1361
|
return data.getMessages();
|
1352
1362
|
}, [converter, data, isRunning, vercel.messages]);
|
1353
|
-
const getBranches2 =
|
1363
|
+
const getBranches2 = useCallback7(
|
1354
1364
|
(messageId) => {
|
1355
1365
|
return data.getBranches(messageId);
|
1356
1366
|
},
|
@@ -1434,7 +1444,7 @@ var VercelAIAssistantProvider = ({
|
|
1434
1444
|
|
1435
1445
|
// src/adapters/vercel/VercelRSCAssistantProvider.tsx
|
1436
1446
|
import {
|
1437
|
-
useCallback as
|
1447
|
+
useCallback as useCallback8,
|
1438
1448
|
useMemo as useMemo7,
|
1439
1449
|
useState as useState5
|
1440
1450
|
} from "react";
|
@@ -1476,20 +1486,22 @@ var VercelRSCAssistantProvider = ({
|
|
1476
1486
|
}) => {
|
1477
1487
|
const context = useDummyAIAssistantContext();
|
1478
1488
|
const [isRunning, setIsRunning] = useState5(false);
|
1479
|
-
const withRunning =
|
1489
|
+
const withRunning = useCallback8((callback) => {
|
1480
1490
|
setIsRunning(true);
|
1481
1491
|
return callback.finally(() => setIsRunning(false));
|
1482
1492
|
}, []);
|
1483
|
-
const converter = useMemo7(() => {
|
1493
|
+
const [converter, convertCallback] = useMemo7(() => {
|
1484
1494
|
const rscConverter = convertMessage ?? ((m) => m);
|
1485
|
-
|
1495
|
+
const convertCallback2 = (m, cache) => {
|
1496
|
+
if (cache) return cache;
|
1486
1497
|
return vercelToThreadMessage2(rscConverter, m);
|
1487
|
-
}
|
1498
|
+
};
|
1499
|
+
return [new ThreadMessageConverter(), convertCallback2];
|
1488
1500
|
}, [convertMessage]);
|
1489
1501
|
const messages = useMemo7(() => {
|
1490
|
-
return converter.convertMessages(vercelMessages);
|
1491
|
-
}, [converter, vercelMessages]);
|
1492
|
-
const append =
|
1502
|
+
return converter.convertMessages(convertCallback, vercelMessages);
|
1503
|
+
}, [converter, convertCallback, vercelMessages]);
|
1504
|
+
const append = useCallback8(
|
1493
1505
|
async (message) => {
|
1494
1506
|
if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null)) {
|
1495
1507
|
if (!edit)
|
@@ -1503,7 +1515,7 @@ var VercelRSCAssistantProvider = ({
|
|
1503
1515
|
},
|
1504
1516
|
[context, withRunning, appendCallback, edit]
|
1505
1517
|
);
|
1506
|
-
const startRun =
|
1518
|
+
const startRun = useCallback8(
|
1507
1519
|
async (parentId) => {
|
1508
1520
|
if (!reload)
|
1509
1521
|
throw new Error(
|
@@ -1529,6 +1541,266 @@ var VercelRSCAssistantProvider = ({
|
|
1529
1541
|
}, [context, messages, isRunning, append, startRun]);
|
1530
1542
|
return /* @__PURE__ */ jsx22(AssistantContext.Provider, { value: context, children });
|
1531
1543
|
};
|
1544
|
+
|
1545
|
+
// src/adapters/core/utils/useAssistantContext.tsx
|
1546
|
+
import {
|
1547
|
+
useEffect as useEffect4,
|
1548
|
+
useInsertionEffect,
|
1549
|
+
useRef as useRef5,
|
1550
|
+
useState as useState6
|
1551
|
+
} from "react";
|
1552
|
+
import { create as create6 } from "zustand";
|
1553
|
+
|
1554
|
+
// src/adapters/core/utils/AssistantMessageRepository.tsx
|
1555
|
+
var AssistantMessageRepository = class {
|
1556
|
+
constructor(flushCallback) {
|
1557
|
+
this.flushCallback = flushCallback;
|
1558
|
+
}
|
1559
|
+
repository = new MessageRepository();
|
1560
|
+
getBranches(messageId) {
|
1561
|
+
return this.repository.getBranches(messageId);
|
1562
|
+
}
|
1563
|
+
withModifications(callback) {
|
1564
|
+
const res = callback(this.repository);
|
1565
|
+
this.flushCallback(this.repository.getMessages());
|
1566
|
+
return res;
|
1567
|
+
}
|
1568
|
+
};
|
1569
|
+
|
1570
|
+
// src/adapters/core/utils/useAssistantContext.tsx
|
1571
|
+
var makeThreadStore = (runtimeRef) => {
|
1572
|
+
const repository = new AssistantMessageRepository((messages) => {
|
1573
|
+
useThread.setState({ messages });
|
1574
|
+
});
|
1575
|
+
const useThread = create6(() => ({
|
1576
|
+
messages: [],
|
1577
|
+
isRunning: false,
|
1578
|
+
getBranches: (messageId) => repository.getBranches(messageId),
|
1579
|
+
switchToBranch: (branchId) => {
|
1580
|
+
repository.withModifications((repository2) => {
|
1581
|
+
repository2.switchToBranch(branchId);
|
1582
|
+
});
|
1583
|
+
},
|
1584
|
+
startRun: async (parentId) => {
|
1585
|
+
const optimisticId = repository.withModifications((repository2) => {
|
1586
|
+
const optimisticId2 = repository2.appendOptimisticMessage(parentId, {
|
1587
|
+
role: "assistant",
|
1588
|
+
content: [{ type: "text", text: "" }]
|
1589
|
+
});
|
1590
|
+
repository2.resetHead(optimisticId2);
|
1591
|
+
return optimisticId2;
|
1592
|
+
});
|
1593
|
+
const { id } = await runtimeRef.current.startRun(parentId);
|
1594
|
+
repository.withModifications((repository2) => {
|
1595
|
+
repository2.deleteMessage(optimisticId, id);
|
1596
|
+
});
|
1597
|
+
},
|
1598
|
+
append: async (message) => {
|
1599
|
+
const [parentOptimisticId, optimisticId] = repository.withModifications(
|
1600
|
+
(repository2) => {
|
1601
|
+
const parentOptimisticId2 = repository2.appendOptimisticMessage(
|
1602
|
+
message.parentId,
|
1603
|
+
{
|
1604
|
+
role: "user",
|
1605
|
+
content: message.content
|
1606
|
+
}
|
1607
|
+
);
|
1608
|
+
const optimisticId2 = repository2.appendOptimisticMessage(
|
1609
|
+
parentOptimisticId2,
|
1610
|
+
{
|
1611
|
+
role: "assistant",
|
1612
|
+
content: [{ type: "text", text: "" }]
|
1613
|
+
}
|
1614
|
+
);
|
1615
|
+
repository2.resetHead(optimisticId2);
|
1616
|
+
return [parentOptimisticId2, optimisticId2];
|
1617
|
+
}
|
1618
|
+
);
|
1619
|
+
const { parentId, id } = await runtimeRef.current.append(message);
|
1620
|
+
repository.withModifications((repository2) => {
|
1621
|
+
repository2.deleteMessage(parentOptimisticId, parentId);
|
1622
|
+
repository2.deleteMessage(optimisticId, id);
|
1623
|
+
});
|
1624
|
+
},
|
1625
|
+
cancelRun: () => runtimeRef.current.cancelRun()
|
1626
|
+
}));
|
1627
|
+
const onNewMessage = (parentId, message) => {
|
1628
|
+
repository.withModifications((repository2) => {
|
1629
|
+
repository2.addOrUpdateMessage(parentId, message);
|
1630
|
+
});
|
1631
|
+
};
|
1632
|
+
const onRunningChange = (isRunning) => {
|
1633
|
+
useThread.setState({ isRunning });
|
1634
|
+
};
|
1635
|
+
return {
|
1636
|
+
useThread,
|
1637
|
+
onNewMessage,
|
1638
|
+
onRunningChange
|
1639
|
+
};
|
1640
|
+
};
|
1641
|
+
var useAssistantContext2 = (runtime) => {
|
1642
|
+
const runtimeRef = useRef5(runtime);
|
1643
|
+
useInsertionEffect(() => {
|
1644
|
+
runtimeRef.current = runtime;
|
1645
|
+
});
|
1646
|
+
const [{ context, onNewMessage, onRunningChange }] = useState6(() => {
|
1647
|
+
const { useThread, onNewMessage: onNewMessage2, onRunningChange: onRunningChange2 } = makeThreadStore(runtimeRef);
|
1648
|
+
const useViewport = makeViewportStore();
|
1649
|
+
const useComposer = makeThreadComposerStore(useThread);
|
1650
|
+
return {
|
1651
|
+
context: { useViewport, useThread, useComposer },
|
1652
|
+
onNewMessage: onNewMessage2,
|
1653
|
+
onRunningChange: onRunningChange2
|
1654
|
+
};
|
1655
|
+
});
|
1656
|
+
useEffect4(() => {
|
1657
|
+
return runtime.subscribeToMessageUpdates(onNewMessage);
|
1658
|
+
}, [runtime, onNewMessage]);
|
1659
|
+
useEffect4(() => {
|
1660
|
+
return runtime.subscribeToStatusUpdates(onRunningChange);
|
1661
|
+
}, [runtime, onRunningChange]);
|
1662
|
+
return context;
|
1663
|
+
};
|
1664
|
+
|
1665
|
+
// src/adapters/core/AssistantProvider.tsx
|
1666
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
1667
|
+
var AssistantProvider = ({ children, runtime }) => {
|
1668
|
+
const context = useAssistantContext2(runtime);
|
1669
|
+
return /* @__PURE__ */ jsx23(AssistantContext.Provider, { value: context, children });
|
1670
|
+
};
|
1671
|
+
|
1672
|
+
// src/adapters/core/local/useLocalRuntime.tsx
|
1673
|
+
import { useState as useState7 } from "react";
|
1674
|
+
|
1675
|
+
// src/adapters/core/local/LocalRuntime.tsx
|
1676
|
+
var LocalRuntime = class {
|
1677
|
+
constructor(adapter) {
|
1678
|
+
this.adapter = adapter;
|
1679
|
+
}
|
1680
|
+
_messageUpdateCallbacks = /* @__PURE__ */ new Set();
|
1681
|
+
_statusUpdateCallbacks = /* @__PURE__ */ new Set();
|
1682
|
+
abortController = null;
|
1683
|
+
repository = new MessageRepository();
|
1684
|
+
async append(message) {
|
1685
|
+
const userMessageId = generateId();
|
1686
|
+
const userMessage = {
|
1687
|
+
id: userMessageId,
|
1688
|
+
role: "user",
|
1689
|
+
content: message.content,
|
1690
|
+
createdAt: /* @__PURE__ */ new Date()
|
1691
|
+
};
|
1692
|
+
this.addOrUpdateMessage(message.parentId, userMessage);
|
1693
|
+
const { id } = await this.startRun(userMessageId);
|
1694
|
+
return { parentId: userMessageId, id };
|
1695
|
+
}
|
1696
|
+
async startRun(parentId) {
|
1697
|
+
const id = generateId();
|
1698
|
+
this.repository.resetHead(parentId);
|
1699
|
+
const messages = this.repository.getMessages();
|
1700
|
+
const message = {
|
1701
|
+
id,
|
1702
|
+
role: "assistant",
|
1703
|
+
status: "in_progress",
|
1704
|
+
content: [{ type: "text", text: "" }],
|
1705
|
+
createdAt: /* @__PURE__ */ new Date()
|
1706
|
+
};
|
1707
|
+
this.addOrUpdateMessage(parentId, message);
|
1708
|
+
void this.run(parentId, messages, message);
|
1709
|
+
return { id };
|
1710
|
+
}
|
1711
|
+
addOrUpdateMessage(parentId, message) {
|
1712
|
+
const clone = { ...message };
|
1713
|
+
this.repository.addOrUpdateMessage(parentId, clone);
|
1714
|
+
for (const callback of this._messageUpdateCallbacks)
|
1715
|
+
callback(parentId, clone);
|
1716
|
+
}
|
1717
|
+
async run(parentId, messages, message) {
|
1718
|
+
this.cancelRun();
|
1719
|
+
for (const callback of this._statusUpdateCallbacks) callback(true);
|
1720
|
+
this.abortController = new AbortController();
|
1721
|
+
try {
|
1722
|
+
await this.adapter.run({
|
1723
|
+
messages,
|
1724
|
+
abortSignal: this.abortController.signal,
|
1725
|
+
onUpdate: ({ content }) => {
|
1726
|
+
message.content = content;
|
1727
|
+
this.addOrUpdateMessage(parentId, message);
|
1728
|
+
}
|
1729
|
+
});
|
1730
|
+
message.status = "done";
|
1731
|
+
this.addOrUpdateMessage(parentId, message);
|
1732
|
+
} catch (e) {
|
1733
|
+
message.status = "error";
|
1734
|
+
this.addOrUpdateMessage(parentId, message);
|
1735
|
+
console.error(e);
|
1736
|
+
} finally {
|
1737
|
+
this.cancelRun();
|
1738
|
+
}
|
1739
|
+
}
|
1740
|
+
cancelRun() {
|
1741
|
+
if (!this.abortController) return;
|
1742
|
+
this.abortController.abort();
|
1743
|
+
this.abortController = null;
|
1744
|
+
for (const callback of this._statusUpdateCallbacks) callback(false);
|
1745
|
+
}
|
1746
|
+
subscribeToMessageUpdates(callback) {
|
1747
|
+
this._messageUpdateCallbacks.add(callback);
|
1748
|
+
return () => this._messageUpdateCallbacks.delete(callback);
|
1749
|
+
}
|
1750
|
+
subscribeToStatusUpdates(callback) {
|
1751
|
+
this._statusUpdateCallbacks.add(callback);
|
1752
|
+
return () => this._statusUpdateCallbacks.delete(callback);
|
1753
|
+
}
|
1754
|
+
};
|
1755
|
+
|
1756
|
+
// src/adapters/core/local/useLocalRuntime.tsx
|
1757
|
+
var useLocalRuntime = (adapter) => {
|
1758
|
+
const [runtime] = useState7(() => new LocalRuntime(adapter));
|
1759
|
+
runtime.adapter = adapter;
|
1760
|
+
return runtime;
|
1761
|
+
};
|
1762
|
+
|
1763
|
+
// src/adapters/core/local/vercel/VercelModelAdapter.tsx
|
1764
|
+
import { streamText } from "ai";
|
1765
|
+
var VercelModelAdapter = class {
|
1766
|
+
constructor(model) {
|
1767
|
+
this.model = model;
|
1768
|
+
}
|
1769
|
+
async run({ messages, abortSignal, onUpdate }) {
|
1770
|
+
const { fullStream } = await streamText({
|
1771
|
+
model: this.model,
|
1772
|
+
abortSignal,
|
1773
|
+
messages: messages.map((m) => ({
|
1774
|
+
role: m.role,
|
1775
|
+
content: m.content.filter((c) => c.type !== "ui")
|
1776
|
+
}))
|
1777
|
+
});
|
1778
|
+
const content = [];
|
1779
|
+
for await (const aiPart of fullStream) {
|
1780
|
+
switch (aiPart.type) {
|
1781
|
+
case "text-delta": {
|
1782
|
+
let part = content.at(-1);
|
1783
|
+
if (!part || part.type !== "text") {
|
1784
|
+
part = { type: "text", text: "" };
|
1785
|
+
content.push(part);
|
1786
|
+
}
|
1787
|
+
part.text += aiPart.textDelta;
|
1788
|
+
break;
|
1789
|
+
}
|
1790
|
+
case "tool-call": {
|
1791
|
+
content.push({
|
1792
|
+
type: "tool-call",
|
1793
|
+
name: aiPart.toolName,
|
1794
|
+
args: aiPart.args
|
1795
|
+
});
|
1796
|
+
break;
|
1797
|
+
}
|
1798
|
+
}
|
1799
|
+
onUpdate({ content });
|
1800
|
+
}
|
1801
|
+
return { content };
|
1802
|
+
}
|
1803
|
+
};
|
1532
1804
|
export {
|
1533
1805
|
actionBar_exports as ActionBarPrimitive,
|
1534
1806
|
branchPicker_exports as BranchPickerPrimitive,
|
@@ -1538,8 +1810,11 @@ export {
|
|
1538
1810
|
thread_exports as ThreadPrimitive,
|
1539
1811
|
VercelAIAssistantProvider,
|
1540
1812
|
VercelRSCAssistantProvider,
|
1813
|
+
AssistantProvider as unstable_AssistantProvider,
|
1814
|
+
VercelModelAdapter as unstable_VercelModelAdapter,
|
1541
1815
|
getVercelMessage as unstable_getVercelMessage,
|
1542
1816
|
getVercelRSCMessage as unstable_getVercelRSCMessage,
|
1817
|
+
useLocalRuntime as unstable_useLocalRuntime,
|
1543
1818
|
useMessageContext as unstable_useMessageContext,
|
1544
1819
|
useBeginMessageEdit,
|
1545
1820
|
useCopyMessage,
|