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