@aomi-labs/react 0.3.16 → 0.3.17
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.cjs +475 -88
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +480 -92
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -61,6 +61,7 @@ __export(index_exports, {
|
|
|
61
61
|
SUPPORTED_CHAINS: () => SUPPORTED_CHAINS,
|
|
62
62
|
ThreadContextProvider: () => ThreadContextProvider,
|
|
63
63
|
UserContextProvider: () => UserContextProvider,
|
|
64
|
+
UserState: () => import_client2.UserState,
|
|
64
65
|
aaModeFromExecutionKind: () => import_client8.aaModeFromExecutionKind,
|
|
65
66
|
appendFeeCallToPayload: () => import_client8.appendFeeCallToPayload,
|
|
66
67
|
buildFeeAAWalletCall: () => import_client8.buildFeeAAWalletCall,
|
|
@@ -189,6 +190,29 @@ var ThreadStore = class {
|
|
|
189
190
|
this.getThreadMetadata = (threadId) => {
|
|
190
191
|
return this.state.threadMetadata.get(threadId);
|
|
191
192
|
};
|
|
193
|
+
/** Reset store to a single empty "New Chat" thread (e.g. on wallet disconnect). */
|
|
194
|
+
this.resetToDefault = () => {
|
|
195
|
+
const threadId = generateUUID();
|
|
196
|
+
this.state = {
|
|
197
|
+
currentThreadId: threadId,
|
|
198
|
+
threadViewKey: this.state.threadViewKey + 1,
|
|
199
|
+
threadCnt: 1,
|
|
200
|
+
threads: /* @__PURE__ */ new Map([[threadId, []]]),
|
|
201
|
+
threadMetadata: /* @__PURE__ */ new Map([
|
|
202
|
+
[
|
|
203
|
+
threadId,
|
|
204
|
+
{
|
|
205
|
+
title: "New Chat",
|
|
206
|
+
status: "regular",
|
|
207
|
+
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
208
|
+
control: initThreadControl()
|
|
209
|
+
}
|
|
210
|
+
]
|
|
211
|
+
])
|
|
212
|
+
};
|
|
213
|
+
this.snapshot = this.buildSnapshot();
|
|
214
|
+
this.emit();
|
|
215
|
+
};
|
|
192
216
|
this.updateThreadMetadata = (threadId, updates) => {
|
|
193
217
|
const existing = this.state.threadMetadata.get(threadId);
|
|
194
218
|
if (!existing) {
|
|
@@ -266,7 +290,8 @@ var ThreadStore = class {
|
|
|
266
290
|
getThreadMessages: this.getThreadMessages,
|
|
267
291
|
setThreadMessages: this.setThreadMessages,
|
|
268
292
|
getThreadMetadata: this.getThreadMetadata,
|
|
269
|
-
updateThreadMetadata: this.updateThreadMetadata
|
|
293
|
+
updateThreadMetadata: this.updateThreadMetadata,
|
|
294
|
+
resetToDefault: this.resetToDefault
|
|
270
295
|
};
|
|
271
296
|
}
|
|
272
297
|
};
|
|
@@ -497,7 +522,7 @@ function ControlContextProvider({
|
|
|
497
522
|
}
|
|
498
523
|
};
|
|
499
524
|
void fetchApps();
|
|
500
|
-
}, [state.apiKey, publicKey
|
|
525
|
+
}, [state.apiKey, publicKey]);
|
|
501
526
|
(0, import_react.useEffect)(() => {
|
|
502
527
|
const fetchModels = async () => {
|
|
503
528
|
try {
|
|
@@ -1205,6 +1230,9 @@ var SessionManager = class {
|
|
|
1205
1230
|
get(threadId) {
|
|
1206
1231
|
return this.sessions.get(threadId);
|
|
1207
1232
|
}
|
|
1233
|
+
get size() {
|
|
1234
|
+
return this.sessions.size;
|
|
1235
|
+
}
|
|
1208
1236
|
forEach(callback) {
|
|
1209
1237
|
for (const [threadId, session] of this.sessions) {
|
|
1210
1238
|
callback(session, threadId);
|
|
@@ -1217,6 +1245,21 @@ var SessionManager = class {
|
|
|
1217
1245
|
this.sessions.delete(threadId);
|
|
1218
1246
|
}
|
|
1219
1247
|
}
|
|
1248
|
+
closeIdleExcept(activeThreadId, onBeforeClose) {
|
|
1249
|
+
const closedThreadIds = [];
|
|
1250
|
+
for (const [threadId, session] of this.sessions) {
|
|
1251
|
+
if (threadId === activeThreadId) continue;
|
|
1252
|
+
if (session.getIsProcessing()) continue;
|
|
1253
|
+
if (session.getIsPolling()) continue;
|
|
1254
|
+
if (session.getPendingRequests().length > 0) continue;
|
|
1255
|
+
closedThreadIds.push(threadId);
|
|
1256
|
+
}
|
|
1257
|
+
for (const threadId of closedThreadIds) {
|
|
1258
|
+
onBeforeClose == null ? void 0 : onBeforeClose(threadId);
|
|
1259
|
+
this.close(threadId);
|
|
1260
|
+
}
|
|
1261
|
+
return closedThreadIds;
|
|
1262
|
+
}
|
|
1220
1263
|
closeAll() {
|
|
1221
1264
|
for (const [threadId, session] of this.sessions) {
|
|
1222
1265
|
session.close();
|
|
@@ -1328,28 +1371,113 @@ var SUPPORTED_CHAINS = [
|
|
|
1328
1371
|
var getChainInfo = (chainId) => chainId === void 0 ? void 0 : SUPPORTED_CHAINS.find((c) => c.id === chainId);
|
|
1329
1372
|
|
|
1330
1373
|
// packages/react/src/runtime/orchestrator.ts
|
|
1374
|
+
var toErrorMessage = (error) => error instanceof Error ? error.message : "Message failed to send";
|
|
1375
|
+
var getOptimisticStatus = (message) => {
|
|
1376
|
+
var _a, _b;
|
|
1377
|
+
const status = (_b = (_a = message.metadata) == null ? void 0 : _a.custom) == null ? void 0 : _b.aomiSendStatus;
|
|
1378
|
+
return status === "sending" || status === "sent" || status === "failed" ? status : void 0;
|
|
1379
|
+
};
|
|
1380
|
+
var hasUnhydratedOptimisticMessage = (messages) => messages.some((message) => {
|
|
1381
|
+
const status = getOptimisticStatus(message);
|
|
1382
|
+
return status === "sending" || status === "sent";
|
|
1383
|
+
});
|
|
1384
|
+
var withOptimisticStatus = (message, status, error) => {
|
|
1385
|
+
var _a, _b;
|
|
1386
|
+
const custom = __spreadProps(__spreadValues({}, (_b = (_a = message.metadata) == null ? void 0 : _a.custom) != null ? _b : {}), {
|
|
1387
|
+
aomiSendStatus: status
|
|
1388
|
+
});
|
|
1389
|
+
if (error) {
|
|
1390
|
+
custom.aomiSendError = toErrorMessage(error);
|
|
1391
|
+
} else {
|
|
1392
|
+
delete custom.aomiSendError;
|
|
1393
|
+
}
|
|
1394
|
+
return __spreadProps(__spreadValues({}, message), {
|
|
1395
|
+
metadata: __spreadProps(__spreadValues({}, message.metadata), {
|
|
1396
|
+
custom
|
|
1397
|
+
})
|
|
1398
|
+
});
|
|
1399
|
+
};
|
|
1400
|
+
var updateOptimisticMessage = (threadContext, threadId, messageId, status, error) => {
|
|
1401
|
+
const messages = threadContext.getThreadMessages(threadId);
|
|
1402
|
+
let changed = false;
|
|
1403
|
+
const nextMessages = messages.map((message) => {
|
|
1404
|
+
if (message.id !== messageId) return message;
|
|
1405
|
+
changed = true;
|
|
1406
|
+
return withOptimisticStatus(message, status, error);
|
|
1407
|
+
});
|
|
1408
|
+
if (changed) {
|
|
1409
|
+
threadContext.setThreadMessages(threadId, nextMessages);
|
|
1410
|
+
}
|
|
1411
|
+
};
|
|
1331
1412
|
function useRuntimeOrchestrator(aomiClient, options) {
|
|
1332
1413
|
const threadContext = useThreadContext();
|
|
1333
1414
|
const threadContextRef = (0, import_react6.useRef)(threadContext);
|
|
1334
1415
|
threadContextRef.current = threadContext;
|
|
1335
1416
|
const aomiClientRef = (0, import_react6.useRef)(aomiClient);
|
|
1336
1417
|
aomiClientRef.current = aomiClient;
|
|
1418
|
+
const optionsRef = (0, import_react6.useRef)(options);
|
|
1419
|
+
optionsRef.current = options;
|
|
1337
1420
|
const [isRunning, setIsRunning] = (0, import_react6.useState)(false);
|
|
1338
1421
|
const sessionManagerRef = (0, import_react6.useRef)(null);
|
|
1339
1422
|
if (!sessionManagerRef.current) {
|
|
1340
1423
|
sessionManagerRef.current = new SessionManager(() => aomiClientRef.current);
|
|
1341
1424
|
}
|
|
1342
1425
|
const pendingFetches = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
|
|
1426
|
+
const initialStatePromises = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
|
|
1427
|
+
const hydratedThreadIds = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
|
|
1343
1428
|
const listenerCleanups = (0, import_react6.useRef)(/* @__PURE__ */ new Map());
|
|
1429
|
+
const cleanupSessionListeners = (0, import_react6.useCallback)((threadId) => {
|
|
1430
|
+
var _a;
|
|
1431
|
+
(_a = listenerCleanups.current.get(threadId)) == null ? void 0 : _a();
|
|
1432
|
+
listenerCleanups.current.delete(threadId);
|
|
1433
|
+
}, []);
|
|
1434
|
+
const closeSession = (0, import_react6.useCallback)(
|
|
1435
|
+
(threadId) => {
|
|
1436
|
+
var _a;
|
|
1437
|
+
cleanupSessionListeners(threadId);
|
|
1438
|
+
pendingFetches.current.delete(threadId);
|
|
1439
|
+
initialStatePromises.current.delete(threadId);
|
|
1440
|
+
hydratedThreadIds.current.delete(threadId);
|
|
1441
|
+
(_a = sessionManagerRef.current) == null ? void 0 : _a.close(threadId);
|
|
1442
|
+
},
|
|
1443
|
+
[cleanupSessionListeners]
|
|
1444
|
+
);
|
|
1445
|
+
const closeIdleSessionsExcept = (0, import_react6.useCallback)(
|
|
1446
|
+
(activeThreadId) => {
|
|
1447
|
+
var _a, _b;
|
|
1448
|
+
const closedThreadIds = (_b = (_a = sessionManagerRef.current) == null ? void 0 : _a.closeIdleExcept(
|
|
1449
|
+
activeThreadId,
|
|
1450
|
+
cleanupSessionListeners
|
|
1451
|
+
)) != null ? _b : [];
|
|
1452
|
+
for (const threadId of closedThreadIds) {
|
|
1453
|
+
pendingFetches.current.delete(threadId);
|
|
1454
|
+
initialStatePromises.current.delete(threadId);
|
|
1455
|
+
hydratedThreadIds.current.delete(threadId);
|
|
1456
|
+
}
|
|
1457
|
+
return closedThreadIds;
|
|
1458
|
+
},
|
|
1459
|
+
[cleanupSessionListeners]
|
|
1460
|
+
);
|
|
1461
|
+
const closeAllSessions = (0, import_react6.useCallback)(() => {
|
|
1462
|
+
var _a;
|
|
1463
|
+
pendingFetches.current.clear();
|
|
1464
|
+
initialStatePromises.current.clear();
|
|
1465
|
+
hydratedThreadIds.current.clear();
|
|
1466
|
+
for (const threadId of Array.from(listenerCleanups.current.keys())) {
|
|
1467
|
+
cleanupSessionListeners(threadId);
|
|
1468
|
+
}
|
|
1469
|
+
(_a = sessionManagerRef.current) == null ? void 0 : _a.closeAll();
|
|
1470
|
+
}, [cleanupSessionListeners]);
|
|
1344
1471
|
const getSession = (0, import_react6.useCallback)(
|
|
1345
1472
|
(threadId) => {
|
|
1346
1473
|
var _a, _b, _c, _d, _e;
|
|
1347
1474
|
const manager = sessionManagerRef.current;
|
|
1348
|
-
const
|
|
1349
|
-
const
|
|
1350
|
-
const
|
|
1351
|
-
const
|
|
1352
|
-
const
|
|
1475
|
+
const nextOptions = optionsRef.current;
|
|
1476
|
+
const nextApp = nextOptions.getApp();
|
|
1477
|
+
const nextPublicKey = (_a = nextOptions.getPublicKey) == null ? void 0 : _a.call(nextOptions);
|
|
1478
|
+
const nextApiKey = (_c = (_b = nextOptions.getApiKey) == null ? void 0 : _b.call(nextOptions)) != null ? _c : void 0;
|
|
1479
|
+
const nextClientId = (_d = nextOptions.getClientId) == null ? void 0 : _d.call(nextOptions);
|
|
1480
|
+
const nextUserState = (_e = nextOptions.getUserState) == null ? void 0 : _e.call(nextOptions);
|
|
1353
1481
|
const existing = manager.get(threadId);
|
|
1354
1482
|
if (existing) {
|
|
1355
1483
|
existing.syncRuntimeOptions({
|
|
@@ -1378,6 +1506,10 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1378
1506
|
const converted = toInboundMessage(msg);
|
|
1379
1507
|
if (converted) threadMessages.push(converted);
|
|
1380
1508
|
}
|
|
1509
|
+
const existingMessages = threadContextRef.current.getThreadMessages(threadId);
|
|
1510
|
+
if (threadMessages.length === 0 && hasUnhydratedOptimisticMessage(existingMessages)) {
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1381
1513
|
threadContextRef.current.setThreadMessages(threadId, threadMessages);
|
|
1382
1514
|
})
|
|
1383
1515
|
);
|
|
@@ -1399,8 +1531,8 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1399
1531
|
session.on(
|
|
1400
1532
|
"wallet_requests_changed",
|
|
1401
1533
|
(requests) => {
|
|
1402
|
-
var _a2;
|
|
1403
|
-
return (_a2 =
|
|
1534
|
+
var _a2, _b2;
|
|
1535
|
+
return (_b2 = (_a2 = optionsRef.current).onPendingRequestsChange) == null ? void 0 : _b2.call(_a2, requests);
|
|
1404
1536
|
}
|
|
1405
1537
|
)
|
|
1406
1538
|
);
|
|
@@ -1409,10 +1541,17 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1409
1541
|
threadContextRef.current.updateThreadMetadata(threadId, { title });
|
|
1410
1542
|
})
|
|
1411
1543
|
);
|
|
1412
|
-
const forwardEvent = (type) => session.on(
|
|
1413
|
-
|
|
1414
|
-
(
|
|
1415
|
-
|
|
1544
|
+
const forwardEvent = (type) => session.on(
|
|
1545
|
+
type,
|
|
1546
|
+
(payload) => {
|
|
1547
|
+
var _a2, _b2;
|
|
1548
|
+
(_b2 = (_a2 = optionsRef.current).onEvent) == null ? void 0 : _b2.call(_a2, {
|
|
1549
|
+
type,
|
|
1550
|
+
payload,
|
|
1551
|
+
sessionId: threadId
|
|
1552
|
+
});
|
|
1553
|
+
}
|
|
1554
|
+
);
|
|
1416
1555
|
cleanups.push(forwardEvent("tool_update"));
|
|
1417
1556
|
cleanups.push(forwardEvent("tool_complete"));
|
|
1418
1557
|
cleanups.push(forwardEvent("system_notice"));
|
|
@@ -1428,36 +1567,68 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1428
1567
|
);
|
|
1429
1568
|
const ensureInitialState = (0, import_react6.useCallback)(
|
|
1430
1569
|
async (threadId) => {
|
|
1431
|
-
var _a;
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1570
|
+
var _a, _b, _c;
|
|
1571
|
+
const existingPromise = initialStatePromises.current.get(threadId);
|
|
1572
|
+
if (existingPromise) {
|
|
1573
|
+
return existingPromise;
|
|
1574
|
+
}
|
|
1575
|
+
const cachedMessages = threadContextRef.current.getThreadMessages(threadId);
|
|
1576
|
+
const existingSession = (_a = sessionManagerRef.current) == null ? void 0 : _a.get(threadId);
|
|
1577
|
+
if (existingSession && (hydratedThreadIds.current.has(threadId) || cachedMessages.length > 0)) {
|
|
1578
|
+
(_c = (_b = optionsRef.current).onPendingRequestsChange) == null ? void 0 : _c.call(
|
|
1579
|
+
_b,
|
|
1580
|
+
existingSession.getPendingRequests()
|
|
1581
|
+
);
|
|
1443
1582
|
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1444
|
-
setIsRunning(
|
|
1583
|
+
setIsRunning(existingSession.getIsProcessing());
|
|
1445
1584
|
}
|
|
1446
|
-
|
|
1447
|
-
pendingFetches.current.delete(threadId);
|
|
1585
|
+
return;
|
|
1448
1586
|
}
|
|
1587
|
+
const fetchPromise = (async () => {
|
|
1588
|
+
var _a2, _b2;
|
|
1589
|
+
pendingFetches.current.add(threadId);
|
|
1590
|
+
try {
|
|
1591
|
+
const session = getSession(threadId);
|
|
1592
|
+
await session.fetchCurrentState();
|
|
1593
|
+
hydratedThreadIds.current.add(threadId);
|
|
1594
|
+
(_b2 = (_a2 = optionsRef.current).onPendingRequestsChange) == null ? void 0 : _b2.call(
|
|
1595
|
+
_a2,
|
|
1596
|
+
session.getPendingRequests()
|
|
1597
|
+
);
|
|
1598
|
+
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1599
|
+
setIsRunning(session.getIsProcessing());
|
|
1600
|
+
}
|
|
1601
|
+
} catch (error) {
|
|
1602
|
+
console.error("Failed to fetch initial state:", error);
|
|
1603
|
+
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1604
|
+
setIsRunning(false);
|
|
1605
|
+
}
|
|
1606
|
+
} finally {
|
|
1607
|
+
pendingFetches.current.delete(threadId);
|
|
1608
|
+
initialStatePromises.current.delete(threadId);
|
|
1609
|
+
}
|
|
1610
|
+
})();
|
|
1611
|
+
initialStatePromises.current.set(threadId, fetchPromise);
|
|
1612
|
+
return fetchPromise;
|
|
1449
1613
|
},
|
|
1450
1614
|
[getSession]
|
|
1451
1615
|
);
|
|
1452
1616
|
const sendMessage = (0, import_react6.useCallback)(
|
|
1453
1617
|
async (text, threadId) => {
|
|
1454
|
-
var _a;
|
|
1455
|
-
const session = getSession(threadId);
|
|
1618
|
+
var _a, _b, _c, _d;
|
|
1456
1619
|
const existingMessages = threadContextRef.current.getThreadMessages(threadId);
|
|
1620
|
+
const optimisticMessageId = String(existingMessages.length);
|
|
1457
1621
|
const userMessage = {
|
|
1622
|
+
id: optimisticMessageId,
|
|
1458
1623
|
role: "user",
|
|
1459
1624
|
content: [{ type: "text", text }],
|
|
1460
|
-
createdAt: /* @__PURE__ */ new Date()
|
|
1625
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
1626
|
+
metadata: {
|
|
1627
|
+
custom: {
|
|
1628
|
+
aomiOriginalText: text,
|
|
1629
|
+
aomiSendStatus: "sending"
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1461
1632
|
};
|
|
1462
1633
|
threadContextRef.current.setThreadMessages(threadId, [
|
|
1463
1634
|
...existingMessages,
|
|
@@ -1466,31 +1637,54 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1466
1637
|
threadContextRef.current.updateThreadMetadata(threadId, {
|
|
1467
1638
|
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1468
1639
|
});
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1640
|
+
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1641
|
+
setIsRunning(true);
|
|
1642
|
+
}
|
|
1643
|
+
try {
|
|
1644
|
+
await ((_b = (_a = optionsRef.current).prepareThreadForSend) == null ? void 0 : _b.call(_a, threadId));
|
|
1645
|
+
const session = getSession(threadId);
|
|
1646
|
+
await session.sendAsync(text);
|
|
1647
|
+
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1648
|
+
setIsRunning(session.getIsProcessing());
|
|
1649
|
+
}
|
|
1650
|
+
updateOptimisticMessage(
|
|
1651
|
+
threadContextRef.current,
|
|
1652
|
+
threadId,
|
|
1653
|
+
optimisticMessageId,
|
|
1654
|
+
"sent"
|
|
1655
|
+
);
|
|
1656
|
+
(_d = (_c = optionsRef.current).onPendingRequestsChange) == null ? void 0 : _d.call(
|
|
1657
|
+
_c,
|
|
1658
|
+
session.getPendingRequests()
|
|
1659
|
+
);
|
|
1660
|
+
} catch (error) {
|
|
1661
|
+
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1662
|
+
setIsRunning(false);
|
|
1663
|
+
}
|
|
1664
|
+
updateOptimisticMessage(
|
|
1665
|
+
threadContextRef.current,
|
|
1666
|
+
threadId,
|
|
1667
|
+
optimisticMessageId,
|
|
1668
|
+
"failed",
|
|
1669
|
+
error
|
|
1670
|
+
);
|
|
1671
|
+
throw error;
|
|
1480
1672
|
}
|
|
1481
1673
|
},
|
|
1482
|
-
[]
|
|
1674
|
+
[getSession]
|
|
1483
1675
|
);
|
|
1676
|
+
const cancelGeneration = (0, import_react6.useCallback)(async (threadId) => {
|
|
1677
|
+
var _a;
|
|
1678
|
+
const session = (_a = sessionManagerRef.current) == null ? void 0 : _a.get(threadId);
|
|
1679
|
+
if (session) {
|
|
1680
|
+
await session.interrupt();
|
|
1681
|
+
}
|
|
1682
|
+
}, []);
|
|
1484
1683
|
(0, import_react6.useEffect)(() => {
|
|
1485
1684
|
return () => {
|
|
1486
|
-
|
|
1487
|
-
(_a = sessionManagerRef.current) == null ? void 0 : _a.closeAll();
|
|
1488
|
-
for (const cleanup of listenerCleanups.current.values()) {
|
|
1489
|
-
cleanup();
|
|
1490
|
-
}
|
|
1491
|
-
listenerCleanups.current.clear();
|
|
1685
|
+
closeAllSessions();
|
|
1492
1686
|
};
|
|
1493
|
-
}, []);
|
|
1687
|
+
}, [closeAllSessions]);
|
|
1494
1688
|
return {
|
|
1495
1689
|
sessionManager: sessionManagerRef.current,
|
|
1496
1690
|
getSession,
|
|
@@ -1499,6 +1693,9 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1499
1693
|
ensureInitialState,
|
|
1500
1694
|
sendMessage,
|
|
1501
1695
|
cancelGeneration,
|
|
1696
|
+
closeSession,
|
|
1697
|
+
closeAllSessions,
|
|
1698
|
+
closeIdleSessionsExcept,
|
|
1502
1699
|
aomiClientRef
|
|
1503
1700
|
};
|
|
1504
1701
|
}
|
|
@@ -1509,9 +1706,9 @@ var sortByLastActiveDesc = ([, metaA], [, metaB]) => {
|
|
|
1509
1706
|
const tsB = parseTimestamp(metaB.lastActiveAt);
|
|
1510
1707
|
return tsB - tsA;
|
|
1511
1708
|
};
|
|
1512
|
-
function buildThreadLists(threadMetadata) {
|
|
1709
|
+
function buildThreadLists(threadMetadata, shouldShowThread) {
|
|
1513
1710
|
const entries = Array.from(threadMetadata.entries()).filter(
|
|
1514
|
-
([, meta]) => !isPlaceholderTitle(meta.title)
|
|
1711
|
+
([threadId, meta]) => !isPlaceholderTitle(meta.title) && shouldShowThread(threadId)
|
|
1515
1712
|
);
|
|
1516
1713
|
const regularThreads = entries.filter(([, meta]) => meta.status !== "archived").sort(sortByLastActiveDesc).map(
|
|
1517
1714
|
([id, meta]) => ({
|
|
@@ -1533,16 +1730,41 @@ function buildThreadListAdapter({
|
|
|
1533
1730
|
aomiClientRef,
|
|
1534
1731
|
threadContext,
|
|
1535
1732
|
setIsRunning,
|
|
1536
|
-
|
|
1733
|
+
isLoading = false,
|
|
1734
|
+
getInitialControl = initThreadControl,
|
|
1735
|
+
isRemoteThread = () => true
|
|
1537
1736
|
}) {
|
|
1737
|
+
const shouldShowThread = (threadId) => {
|
|
1738
|
+
if (isRemoteThread(threadId)) return true;
|
|
1739
|
+
return threadContext.getThreadMessages(threadId).some((message) => message.role === "user");
|
|
1740
|
+
};
|
|
1538
1741
|
const { regularThreads, archivedThreads } = buildThreadLists(
|
|
1539
|
-
threadContext.allThreadsMetadata
|
|
1742
|
+
threadContext.allThreadsMetadata,
|
|
1743
|
+
shouldShowThread
|
|
1540
1744
|
);
|
|
1745
|
+
const cleanupEmptyLocalThread = () => {
|
|
1746
|
+
const prevId = threadContext.currentThreadId;
|
|
1747
|
+
if (isRemoteThread(prevId)) return;
|
|
1748
|
+
const msgs = threadContext.getThreadMessages(prevId);
|
|
1749
|
+
if (msgs.length > 0) return;
|
|
1750
|
+
threadContext.setThreadMetadata((prev) => {
|
|
1751
|
+
const next = new Map(prev);
|
|
1752
|
+
next.delete(prevId);
|
|
1753
|
+
return next;
|
|
1754
|
+
});
|
|
1755
|
+
threadContext.setThreads((prev) => {
|
|
1756
|
+
const next = new Map(prev);
|
|
1757
|
+
next.delete(prevId);
|
|
1758
|
+
return next;
|
|
1759
|
+
});
|
|
1760
|
+
};
|
|
1541
1761
|
return {
|
|
1542
1762
|
threadId: threadContext.currentThreadId,
|
|
1763
|
+
isLoading,
|
|
1543
1764
|
threads: regularThreads,
|
|
1544
1765
|
archivedThreads,
|
|
1545
1766
|
onSwitchToNewThread: () => {
|
|
1767
|
+
cleanupEmptyLocalThread();
|
|
1546
1768
|
const threadId = generateUUID();
|
|
1547
1769
|
threadContext.setThreadMetadata(
|
|
1548
1770
|
(prev) => new Map(prev).set(threadId, {
|
|
@@ -1558,6 +1780,7 @@ function buildThreadListAdapter({
|
|
|
1558
1780
|
threadContext.bumpThreadViewKey();
|
|
1559
1781
|
},
|
|
1560
1782
|
onSwitchToThread: (threadId) => {
|
|
1783
|
+
cleanupEmptyLocalThread();
|
|
1561
1784
|
threadContext.setCurrentThreadId(threadId);
|
|
1562
1785
|
threadContext.bumpThreadViewKey();
|
|
1563
1786
|
},
|
|
@@ -1775,6 +1998,22 @@ function RuntimeUserStateProvider({
|
|
|
1775
1998
|
|
|
1776
1999
|
// packages/react/src/runtime/core.tsx
|
|
1777
2000
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
2001
|
+
var THREAD_PREFETCH_LIMIT = 5;
|
|
2002
|
+
var PREFETCH_IDLE_TIMEOUT_MS = 1500;
|
|
2003
|
+
function scheduleBackgroundTask(task) {
|
|
2004
|
+
const runtimeGlobal = globalThis;
|
|
2005
|
+
if (typeof runtimeGlobal.requestIdleCallback === "function") {
|
|
2006
|
+
const idleId = runtimeGlobal.requestIdleCallback(task, {
|
|
2007
|
+
timeout: PREFETCH_IDLE_TIMEOUT_MS
|
|
2008
|
+
});
|
|
2009
|
+
return () => {
|
|
2010
|
+
var _a;
|
|
2011
|
+
return (_a = runtimeGlobal.cancelIdleCallback) == null ? void 0 : _a.call(runtimeGlobal, idleId);
|
|
2012
|
+
};
|
|
2013
|
+
}
|
|
2014
|
+
const timeoutId = runtimeGlobal.setTimeout(task, 0);
|
|
2015
|
+
return () => runtimeGlobal.clearTimeout(timeoutId);
|
|
2016
|
+
}
|
|
1778
2017
|
function AomiRuntimeCore({
|
|
1779
2018
|
children,
|
|
1780
2019
|
aomiClient
|
|
@@ -1804,6 +2043,9 @@ function AomiRuntimeCore({
|
|
|
1804
2043
|
ensureInitialState,
|
|
1805
2044
|
sendMessage: orchestratorSendMessage,
|
|
1806
2045
|
cancelGeneration: orchestratorCancel,
|
|
2046
|
+
closeSession,
|
|
2047
|
+
closeIdleSessionsExcept,
|
|
2048
|
+
closeAllSessions,
|
|
1807
2049
|
aomiClientRef
|
|
1808
2050
|
} = useRuntimeOrchestrator(aomiClient, {
|
|
1809
2051
|
getPublicKey: () => import_client5.UserState.isConnected(getUserState()) ? import_client5.UserState.address(getUserState()) : void 0,
|
|
@@ -1814,10 +2056,22 @@ function AomiRuntimeCore({
|
|
|
1814
2056
|
var _a;
|
|
1815
2057
|
return (_a = getControlState().clientId) != null ? _a : void 0;
|
|
1816
2058
|
},
|
|
2059
|
+
prepareThreadForSend: async (threadId) => {
|
|
2060
|
+
await ensureBackendThread(threadId);
|
|
2061
|
+
await syncCurrentThreadControl();
|
|
2062
|
+
},
|
|
1817
2063
|
onPendingRequestsChange: walletHandler.setRequests,
|
|
1818
2064
|
onEvent: (event) => eventContext.dispatch(event)
|
|
1819
2065
|
});
|
|
1820
2066
|
sessionManagerRef.current = sessionManager;
|
|
2067
|
+
const threadContextRef = (0, import_react10.useRef)(threadContext);
|
|
2068
|
+
threadContextRef.current = threadContext;
|
|
2069
|
+
const remoteThreadIdsRef = (0, import_react10.useRef)(/* @__PURE__ */ new Set());
|
|
2070
|
+
const warmedThreadIdsRef = (0, import_react10.useRef)(/* @__PURE__ */ new Set());
|
|
2071
|
+
const warmPromisesRef = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
|
|
2072
|
+
const prefetchCancelRef = (0, import_react10.useRef)(null);
|
|
2073
|
+
const [isThreadLoading, setIsThreadLoading] = (0, import_react10.useState)(false);
|
|
2074
|
+
const [isThreadListLoading, setIsThreadListLoading] = (0, import_react10.useState)(true);
|
|
1821
2075
|
const walletSnapshot = (0, import_react10.useCallback)(
|
|
1822
2076
|
(nextUser) => {
|
|
1823
2077
|
var _a;
|
|
@@ -1841,6 +2095,9 @@ function AomiRuntimeCore({
|
|
|
1841
2095
|
}
|
|
1842
2096
|
lastWalletStateRef.current = nextWalletState;
|
|
1843
2097
|
const sessionId = threadContext.currentThreadId;
|
|
2098
|
+
if (!remoteThreadIdsRef.current.has(sessionId)) {
|
|
2099
|
+
return;
|
|
2100
|
+
}
|
|
1844
2101
|
const message = JSON.stringify({
|
|
1845
2102
|
type: "wallet:state_changed",
|
|
1846
2103
|
payload: nextWalletState
|
|
@@ -1855,24 +2112,67 @@ function AomiRuntimeCore({
|
|
|
1855
2112
|
getUserState,
|
|
1856
2113
|
walletSnapshot
|
|
1857
2114
|
]);
|
|
1858
|
-
const threadContextRef = (0, import_react10.useRef)(threadContext);
|
|
1859
|
-
threadContextRef.current = threadContext;
|
|
1860
|
-
const remoteThreadIdsRef = (0, import_react10.useRef)(/* @__PURE__ */ new Set());
|
|
1861
|
-
const warmedThreadIdsRef = (0, import_react10.useRef)(/* @__PURE__ */ new Set());
|
|
1862
2115
|
const warmThread = (0, import_react10.useCallback)(
|
|
1863
2116
|
async (threadId) => {
|
|
1864
2117
|
if (!remoteThreadIdsRef.current.has(threadId) || warmedThreadIdsRef.current.has(threadId)) {
|
|
1865
2118
|
return;
|
|
1866
2119
|
}
|
|
1867
|
-
const
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
)
|
|
1872
|
-
|
|
2120
|
+
const existingPromise = warmPromisesRef.current.get(threadId);
|
|
2121
|
+
if (existingPromise) {
|
|
2122
|
+
return existingPromise;
|
|
2123
|
+
}
|
|
2124
|
+
const warmPromise = (async () => {
|
|
2125
|
+
const userState = getUserState();
|
|
2126
|
+
await aomiClientRef.current.createThread(
|
|
2127
|
+
threadId,
|
|
2128
|
+
import_client5.UserState.isConnected(userState) ? import_client5.UserState.address(userState) : void 0
|
|
2129
|
+
);
|
|
2130
|
+
warmedThreadIdsRef.current.add(threadId);
|
|
2131
|
+
})();
|
|
2132
|
+
warmPromisesRef.current.set(threadId, warmPromise);
|
|
2133
|
+
try {
|
|
2134
|
+
await warmPromise;
|
|
2135
|
+
} finally {
|
|
2136
|
+
warmPromisesRef.current.delete(threadId);
|
|
2137
|
+
}
|
|
1873
2138
|
},
|
|
1874
2139
|
[aomiClientRef, getUserState]
|
|
1875
2140
|
);
|
|
2141
|
+
const scheduleThreadPrefetch = (0, import_react10.useCallback)(
|
|
2142
|
+
(threadIds) => {
|
|
2143
|
+
var _a;
|
|
2144
|
+
(_a = prefetchCancelRef.current) == null ? void 0 : _a.call(prefetchCancelRef);
|
|
2145
|
+
const prefetchThreadIds = Array.from(new Set(threadIds)).filter((threadId) => remoteThreadIdsRef.current.has(threadId)).slice(0, THREAD_PREFETCH_LIMIT);
|
|
2146
|
+
if (prefetchThreadIds.length === 0) {
|
|
2147
|
+
prefetchCancelRef.current = null;
|
|
2148
|
+
return;
|
|
2149
|
+
}
|
|
2150
|
+
let cancelled = false;
|
|
2151
|
+
const cancelScheduledTask = scheduleBackgroundTask(() => {
|
|
2152
|
+
void Promise.all(
|
|
2153
|
+
prefetchThreadIds.map(async (threadId) => {
|
|
2154
|
+
if (cancelled || !remoteThreadIdsRef.current.has(threadId)) return;
|
|
2155
|
+
if (threadContextRef.current.getThreadMessages(threadId).length > 0) {
|
|
2156
|
+
return;
|
|
2157
|
+
}
|
|
2158
|
+
try {
|
|
2159
|
+
await warmThread(threadId);
|
|
2160
|
+
if (cancelled || !remoteThreadIdsRef.current.has(threadId))
|
|
2161
|
+
return;
|
|
2162
|
+
await ensureInitialState(threadId);
|
|
2163
|
+
} catch (error) {
|
|
2164
|
+
console.debug("Failed to prefetch thread:", threadId, error);
|
|
2165
|
+
}
|
|
2166
|
+
})
|
|
2167
|
+
);
|
|
2168
|
+
});
|
|
2169
|
+
prefetchCancelRef.current = () => {
|
|
2170
|
+
cancelled = true;
|
|
2171
|
+
cancelScheduledTask();
|
|
2172
|
+
};
|
|
2173
|
+
},
|
|
2174
|
+
[ensureInitialState, warmThread]
|
|
2175
|
+
);
|
|
1876
2176
|
(0, import_react10.useEffect)(() => {
|
|
1877
2177
|
const unsubscribe = eventContext.subscribe("user_state_request", () => {
|
|
1878
2178
|
var _a, _b, _c;
|
|
@@ -1885,19 +2185,49 @@ function AomiRuntimeCore({
|
|
|
1885
2185
|
});
|
|
1886
2186
|
return unsubscribe;
|
|
1887
2187
|
}, [eventContext, threadContext.currentThreadId, getSession, getUserState]);
|
|
2188
|
+
const ensureBackendThread = (0, import_react10.useCallback)(
|
|
2189
|
+
async (threadId) => {
|
|
2190
|
+
if (remoteThreadIdsRef.current.has(threadId)) return;
|
|
2191
|
+
const userState = getUserState();
|
|
2192
|
+
await aomiClientRef.current.createThread(
|
|
2193
|
+
threadId,
|
|
2194
|
+
import_client5.UserState.isConnected(userState) ? import_client5.UserState.address(userState) : void 0
|
|
2195
|
+
);
|
|
2196
|
+
remoteThreadIdsRef.current.add(threadId);
|
|
2197
|
+
warmedThreadIdsRef.current.add(threadId);
|
|
2198
|
+
},
|
|
2199
|
+
[aomiClientRef, getUserState]
|
|
2200
|
+
);
|
|
1888
2201
|
(0, import_react10.useEffect)(() => {
|
|
1889
2202
|
const threadId = threadContext.currentThreadId;
|
|
2203
|
+
closeIdleSessionsExcept(threadId);
|
|
2204
|
+
if (!remoteThreadIdsRef.current.has(threadId)) {
|
|
2205
|
+
setIsThreadLoading(false);
|
|
2206
|
+
return;
|
|
2207
|
+
}
|
|
1890
2208
|
let cancelled = false;
|
|
2209
|
+
setIsThreadLoading(true);
|
|
1891
2210
|
void (async () => {
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
2211
|
+
try {
|
|
2212
|
+
await warmThread(threadId);
|
|
2213
|
+
if (!cancelled) {
|
|
2214
|
+
await ensureInitialState(threadId);
|
|
2215
|
+
}
|
|
2216
|
+
} finally {
|
|
2217
|
+
if (!cancelled) {
|
|
2218
|
+
setIsThreadLoading(false);
|
|
2219
|
+
}
|
|
1895
2220
|
}
|
|
1896
2221
|
})();
|
|
1897
2222
|
return () => {
|
|
1898
2223
|
cancelled = true;
|
|
1899
2224
|
};
|
|
1900
|
-
}, [
|
|
2225
|
+
}, [
|
|
2226
|
+
closeIdleSessionsExcept,
|
|
2227
|
+
ensureInitialState,
|
|
2228
|
+
threadContext.currentThreadId,
|
|
2229
|
+
warmThread
|
|
2230
|
+
]);
|
|
1901
2231
|
(0, import_react10.useEffect)(() => {
|
|
1902
2232
|
const threadId = threadContext.currentThreadId;
|
|
1903
2233
|
const currentMeta = threadContext.getThreadMetadata(threadId);
|
|
@@ -1913,23 +2243,38 @@ function AomiRuntimeCore({
|
|
|
1913
2243
|
threadContext.currentThreadId
|
|
1914
2244
|
);
|
|
1915
2245
|
(0, import_react10.useEffect)(() => {
|
|
2246
|
+
var _a;
|
|
1916
2247
|
const userAddress = import_client5.UserState.isConnected(user) ? import_client5.UserState.address(user) : void 0;
|
|
1917
2248
|
if (!userAddress) {
|
|
2249
|
+
const hadRemoteThreads = remoteThreadIdsRef.current.size > 0;
|
|
2250
|
+
const hadSessions = sessionManager.size > 0;
|
|
2251
|
+
setIsThreadListLoading(false);
|
|
2252
|
+
(_a = prefetchCancelRef.current) == null ? void 0 : _a.call(prefetchCancelRef);
|
|
2253
|
+
prefetchCancelRef.current = null;
|
|
1918
2254
|
remoteThreadIdsRef.current.clear();
|
|
1919
2255
|
warmedThreadIdsRef.current.clear();
|
|
2256
|
+
warmPromisesRef.current.clear();
|
|
2257
|
+
closeAllSessions();
|
|
2258
|
+
if (hadRemoteThreads || hadSessions) {
|
|
2259
|
+
threadContextRef.current.resetToDefault();
|
|
2260
|
+
}
|
|
1920
2261
|
return;
|
|
1921
2262
|
}
|
|
2263
|
+
let cancelled = false;
|
|
2264
|
+
setIsThreadListLoading(true);
|
|
1922
2265
|
const fetchThreadList = async () => {
|
|
1923
|
-
var
|
|
2266
|
+
var _a2, _b, _c;
|
|
1924
2267
|
try {
|
|
2268
|
+
const remoteThreadIdsAtFetchStart = new Set(remoteThreadIdsRef.current);
|
|
1925
2269
|
const threadList = await aomiClientRef.current.listThreads(userAddress);
|
|
2270
|
+
if (cancelled) return;
|
|
1926
2271
|
const currentContext = threadContextRef.current;
|
|
1927
2272
|
const remoteThreadIds = /* @__PURE__ */ new Set();
|
|
1928
2273
|
const newMetadata = new Map(currentContext.allThreadsMetadata);
|
|
1929
2274
|
let maxChatNum = currentContext.threadCnt;
|
|
1930
2275
|
for (const thread of threadList) {
|
|
1931
2276
|
remoteThreadIds.add(thread.session_id);
|
|
1932
|
-
const rawTitle = (
|
|
2277
|
+
const rawTitle = (_a2 = thread.title) != null ? _a2 : "";
|
|
1933
2278
|
const title = isPlaceholderTitle(rawTitle) ? "" : rawTitle;
|
|
1934
2279
|
const lastActive = ((_b = newMetadata.get(thread.session_id)) == null ? void 0 : _b.lastActiveAt) || (/* @__PURE__ */ new Date()).toISOString();
|
|
1935
2280
|
const existingControl = (_c = newMetadata.get(thread.session_id)) == null ? void 0 : _c.control;
|
|
@@ -1947,6 +2292,11 @@ function AomiRuntimeCore({
|
|
|
1947
2292
|
}
|
|
1948
2293
|
}
|
|
1949
2294
|
}
|
|
2295
|
+
for (const threadId of remoteThreadIdsRef.current) {
|
|
2296
|
+
if (!remoteThreadIdsAtFetchStart.has(threadId)) {
|
|
2297
|
+
remoteThreadIds.add(threadId);
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
1950
2300
|
remoteThreadIdsRef.current = remoteThreadIds;
|
|
1951
2301
|
warmedThreadIdsRef.current = new Set(
|
|
1952
2302
|
Array.from(warmedThreadIdsRef.current).filter(
|
|
@@ -1957,30 +2307,65 @@ function AomiRuntimeCore({
|
|
|
1957
2307
|
if (maxChatNum > currentContext.threadCnt) {
|
|
1958
2308
|
currentContext.setThreadCnt(maxChatNum);
|
|
1959
2309
|
}
|
|
2310
|
+
scheduleThreadPrefetch(threadList.map((thread) => thread.session_id));
|
|
1960
2311
|
if (remoteThreadIds.has(currentContext.currentThreadId)) {
|
|
1961
|
-
|
|
1962
|
-
|
|
2312
|
+
setIsThreadLoading(true);
|
|
2313
|
+
try {
|
|
2314
|
+
await warmThread(currentContext.currentThreadId);
|
|
2315
|
+
if (!cancelled) {
|
|
2316
|
+
await ensureInitialState(currentContext.currentThreadId);
|
|
2317
|
+
}
|
|
2318
|
+
} finally {
|
|
2319
|
+
if (!cancelled) {
|
|
2320
|
+
setIsThreadLoading(false);
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
1963
2323
|
}
|
|
1964
2324
|
} catch (error) {
|
|
1965
2325
|
console.error("Failed to fetch thread list:", error);
|
|
2326
|
+
} finally {
|
|
2327
|
+
if (!cancelled) {
|
|
2328
|
+
setIsThreadListLoading(false);
|
|
2329
|
+
}
|
|
1966
2330
|
}
|
|
1967
2331
|
};
|
|
1968
2332
|
void fetchThreadList();
|
|
1969
|
-
|
|
2333
|
+
return () => {
|
|
2334
|
+
var _a2;
|
|
2335
|
+
cancelled = true;
|
|
2336
|
+
(_a2 = prefetchCancelRef.current) == null ? void 0 : _a2.call(prefetchCancelRef);
|
|
2337
|
+
prefetchCancelRef.current = null;
|
|
2338
|
+
};
|
|
2339
|
+
}, [
|
|
2340
|
+
user,
|
|
2341
|
+
aomiClientRef,
|
|
2342
|
+
ensureInitialState,
|
|
2343
|
+
scheduleThreadPrefetch,
|
|
2344
|
+
warmThread
|
|
2345
|
+
]);
|
|
2346
|
+
const isRemoteThread = (0, import_react10.useCallback)(
|
|
2347
|
+
(threadId) => remoteThreadIdsRef.current.has(threadId),
|
|
2348
|
+
[]
|
|
2349
|
+
);
|
|
1970
2350
|
const threadListAdapter = (0, import_react10.useMemo)(
|
|
1971
2351
|
() => buildThreadListAdapter({
|
|
1972
2352
|
aomiClientRef,
|
|
1973
2353
|
threadContext,
|
|
1974
2354
|
setIsRunning,
|
|
1975
|
-
|
|
2355
|
+
isLoading: isThreadListLoading,
|
|
2356
|
+
getInitialControl: getPreferredThreadControl,
|
|
2357
|
+
isRemoteThread
|
|
1976
2358
|
}),
|
|
1977
2359
|
[
|
|
1978
2360
|
aomiClientRef,
|
|
1979
2361
|
getPreferredThreadControl,
|
|
2362
|
+
isRemoteThread,
|
|
2363
|
+
isThreadListLoading,
|
|
1980
2364
|
setIsRunning,
|
|
1981
2365
|
threadContext,
|
|
1982
2366
|
threadContext.currentThreadId,
|
|
1983
|
-
threadContext.allThreadsMetadata
|
|
2367
|
+
threadContext.allThreadsMetadata,
|
|
2368
|
+
currentMessages
|
|
1984
2369
|
]
|
|
1985
2370
|
);
|
|
1986
2371
|
(0, import_react10.useEffect)(() => {
|
|
@@ -2015,6 +2400,7 @@ function AomiRuntimeCore({
|
|
|
2015
2400
|
}, [eventContext, notificationContext]);
|
|
2016
2401
|
const runtime = (0, import_react11.useExternalStoreRuntime)({
|
|
2017
2402
|
messages: currentMessages,
|
|
2403
|
+
isLoading: isThreadLoading,
|
|
2018
2404
|
setMessages: (msgs) => threadContext.setThreadMessages(threadContext.currentThreadId, [...msgs]),
|
|
2019
2405
|
isRunning,
|
|
2020
2406
|
onNew: async (message) => {
|
|
@@ -2022,7 +2408,6 @@ function AomiRuntimeCore({
|
|
|
2022
2408
|
(part) => part.type === "text"
|
|
2023
2409
|
).map((part) => part.text).join("\n");
|
|
2024
2410
|
if (text) {
|
|
2025
|
-
await syncCurrentThreadControl();
|
|
2026
2411
|
await orchestratorSendMessage(text, threadContext.currentThreadId);
|
|
2027
2412
|
}
|
|
2028
2413
|
},
|
|
@@ -2034,20 +2419,17 @@ function AomiRuntimeCore({
|
|
|
2034
2419
|
});
|
|
2035
2420
|
(0, import_react10.useEffect)(() => {
|
|
2036
2421
|
return () => {
|
|
2037
|
-
|
|
2422
|
+
var _a;
|
|
2423
|
+
(_a = prefetchCancelRef.current) == null ? void 0 : _a.call(prefetchCancelRef);
|
|
2424
|
+
closeAllSessions();
|
|
2038
2425
|
};
|
|
2039
|
-
}, [
|
|
2426
|
+
}, [closeAllSessions]);
|
|
2040
2427
|
const userContext = useUser();
|
|
2041
2428
|
const sendMessage = (0, import_react10.useCallback)(
|
|
2042
2429
|
async (text) => {
|
|
2043
|
-
await syncCurrentThreadControl();
|
|
2044
2430
|
await orchestratorSendMessage(text, threadContext.currentThreadId);
|
|
2045
2431
|
},
|
|
2046
|
-
[
|
|
2047
|
-
orchestratorSendMessage,
|
|
2048
|
-
syncCurrentThreadControl,
|
|
2049
|
-
threadContext.currentThreadId
|
|
2050
|
-
]
|
|
2432
|
+
[orchestratorSendMessage, threadContext.currentThreadId]
|
|
2051
2433
|
);
|
|
2052
2434
|
const cancelGeneration = (0, import_react10.useCallback)(() => {
|
|
2053
2435
|
void orchestratorCancel(threadContext.currentThreadId);
|
|
@@ -2065,10 +2447,10 @@ function AomiRuntimeCore({
|
|
|
2065
2447
|
}, [threadListAdapter]);
|
|
2066
2448
|
const deleteThread = (0, import_react10.useCallback)(
|
|
2067
2449
|
async (threadId) => {
|
|
2068
|
-
|
|
2450
|
+
closeSession(threadId);
|
|
2069
2451
|
await threadListAdapter.onDelete(threadId);
|
|
2070
2452
|
},
|
|
2071
|
-
[
|
|
2453
|
+
[closeSession, threadListAdapter]
|
|
2072
2454
|
);
|
|
2073
2455
|
const renameThread = (0, import_react10.useCallback)(
|
|
2074
2456
|
async (threadId, title) => {
|
|
@@ -2184,9 +2566,13 @@ function AomiRuntimeCore({
|
|
|
2184
2566
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2185
2567
|
function AomiRuntimeProvider({
|
|
2186
2568
|
children,
|
|
2187
|
-
backendUrl = "http://localhost:8080"
|
|
2569
|
+
backendUrl = "http://localhost:8080",
|
|
2570
|
+
clientOptions
|
|
2188
2571
|
}) {
|
|
2189
|
-
const aomiClient = (0, import_react12.useMemo)(
|
|
2572
|
+
const aomiClient = (0, import_react12.useMemo)(
|
|
2573
|
+
() => new import_client6.AomiClient(__spreadValues({ baseUrl: backendUrl }, clientOptions)),
|
|
2574
|
+
[backendUrl, clientOptions]
|
|
2575
|
+
);
|
|
2190
2576
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ThreadContextProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NotificationContextProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(UserContextProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(AomiRuntimeInner, { aomiClient, children }) }) }) });
|
|
2191
2577
|
}
|
|
2192
2578
|
function AomiRuntimeInner({
|
|
@@ -2270,6 +2656,7 @@ function useNotificationHandler({
|
|
|
2270
2656
|
SUPPORTED_CHAINS,
|
|
2271
2657
|
ThreadContextProvider,
|
|
2272
2658
|
UserContextProvider,
|
|
2659
|
+
UserState,
|
|
2273
2660
|
aaModeFromExecutionKind,
|
|
2274
2661
|
appendFeeCallToPayload,
|
|
2275
2662
|
buildFeeAAWalletCall,
|