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