@aomi-labs/react 0.3.15 → 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 +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +480 -92
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -152,6 +152,29 @@ var ThreadStore = class {
|
|
|
152
152
|
this.getThreadMetadata = (threadId) => {
|
|
153
153
|
return this.state.threadMetadata.get(threadId);
|
|
154
154
|
};
|
|
155
|
+
/** Reset store to a single empty "New Chat" thread (e.g. on wallet disconnect). */
|
|
156
|
+
this.resetToDefault = () => {
|
|
157
|
+
const threadId = generateUUID();
|
|
158
|
+
this.state = {
|
|
159
|
+
currentThreadId: threadId,
|
|
160
|
+
threadViewKey: this.state.threadViewKey + 1,
|
|
161
|
+
threadCnt: 1,
|
|
162
|
+
threads: /* @__PURE__ */ new Map([[threadId, []]]),
|
|
163
|
+
threadMetadata: /* @__PURE__ */ new Map([
|
|
164
|
+
[
|
|
165
|
+
threadId,
|
|
166
|
+
{
|
|
167
|
+
title: "New Chat",
|
|
168
|
+
status: "regular",
|
|
169
|
+
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
170
|
+
control: initThreadControl()
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
])
|
|
174
|
+
};
|
|
175
|
+
this.snapshot = this.buildSnapshot();
|
|
176
|
+
this.emit();
|
|
177
|
+
};
|
|
155
178
|
this.updateThreadMetadata = (threadId, updates) => {
|
|
156
179
|
const existing = this.state.threadMetadata.get(threadId);
|
|
157
180
|
if (!existing) {
|
|
@@ -229,7 +252,8 @@ var ThreadStore = class {
|
|
|
229
252
|
getThreadMessages: this.getThreadMessages,
|
|
230
253
|
setThreadMessages: this.setThreadMessages,
|
|
231
254
|
getThreadMetadata: this.getThreadMetadata,
|
|
232
|
-
updateThreadMetadata: this.updateThreadMetadata
|
|
255
|
+
updateThreadMetadata: this.updateThreadMetadata,
|
|
256
|
+
resetToDefault: this.resetToDefault
|
|
233
257
|
};
|
|
234
258
|
}
|
|
235
259
|
};
|
|
@@ -460,7 +484,7 @@ function ControlContextProvider({
|
|
|
460
484
|
}
|
|
461
485
|
};
|
|
462
486
|
void fetchApps();
|
|
463
|
-
}, [state.apiKey, publicKey
|
|
487
|
+
}, [state.apiKey, publicKey]);
|
|
464
488
|
useEffect(() => {
|
|
465
489
|
const fetchModels = async () => {
|
|
466
490
|
try {
|
|
@@ -1163,7 +1187,7 @@ function UserContextProvider({ children }) {
|
|
|
1163
1187
|
}
|
|
1164
1188
|
|
|
1165
1189
|
// packages/react/src/runtime/core.tsx
|
|
1166
|
-
import { useCallback as useCallback7, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef8 } from "react";
|
|
1190
|
+
import { useCallback as useCallback7, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef8, useState as useState6 } from "react";
|
|
1167
1191
|
import {
|
|
1168
1192
|
AssistantRuntimeProvider,
|
|
1169
1193
|
useExternalStoreRuntime
|
|
@@ -1175,7 +1199,9 @@ import { useCallback as useCallback5, useEffect as useEffect2, useRef as useRef5
|
|
|
1175
1199
|
import { CLIENT_TYPE_WEB_UI } from "@aomi-labs/client";
|
|
1176
1200
|
|
|
1177
1201
|
// packages/react/src/runtime/session-manager.ts
|
|
1178
|
-
import {
|
|
1202
|
+
import {
|
|
1203
|
+
Session as ClientSession
|
|
1204
|
+
} from "@aomi-labs/client";
|
|
1179
1205
|
var SessionManager = class {
|
|
1180
1206
|
constructor(clientFactory) {
|
|
1181
1207
|
this.clientFactory = clientFactory;
|
|
@@ -1193,6 +1219,9 @@ var SessionManager = class {
|
|
|
1193
1219
|
get(threadId) {
|
|
1194
1220
|
return this.sessions.get(threadId);
|
|
1195
1221
|
}
|
|
1222
|
+
get size() {
|
|
1223
|
+
return this.sessions.size;
|
|
1224
|
+
}
|
|
1196
1225
|
forEach(callback) {
|
|
1197
1226
|
for (const [threadId, session] of this.sessions) {
|
|
1198
1227
|
callback(session, threadId);
|
|
@@ -1205,6 +1234,21 @@ var SessionManager = class {
|
|
|
1205
1234
|
this.sessions.delete(threadId);
|
|
1206
1235
|
}
|
|
1207
1236
|
}
|
|
1237
|
+
closeIdleExcept(activeThreadId, onBeforeClose) {
|
|
1238
|
+
const closedThreadIds = [];
|
|
1239
|
+
for (const [threadId, session] of this.sessions) {
|
|
1240
|
+
if (threadId === activeThreadId) continue;
|
|
1241
|
+
if (session.getIsProcessing()) continue;
|
|
1242
|
+
if (session.getIsPolling()) continue;
|
|
1243
|
+
if (session.getPendingRequests().length > 0) continue;
|
|
1244
|
+
closedThreadIds.push(threadId);
|
|
1245
|
+
}
|
|
1246
|
+
for (const threadId of closedThreadIds) {
|
|
1247
|
+
onBeforeClose == null ? void 0 : onBeforeClose(threadId);
|
|
1248
|
+
this.close(threadId);
|
|
1249
|
+
}
|
|
1250
|
+
return closedThreadIds;
|
|
1251
|
+
}
|
|
1208
1252
|
closeAll() {
|
|
1209
1253
|
for (const [threadId, session] of this.sessions) {
|
|
1210
1254
|
session.close();
|
|
@@ -1316,28 +1360,113 @@ var SUPPORTED_CHAINS = [
|
|
|
1316
1360
|
var getChainInfo = (chainId) => chainId === void 0 ? void 0 : SUPPORTED_CHAINS.find((c) => c.id === chainId);
|
|
1317
1361
|
|
|
1318
1362
|
// packages/react/src/runtime/orchestrator.ts
|
|
1363
|
+
var toErrorMessage = (error) => error instanceof Error ? error.message : "Message failed to send";
|
|
1364
|
+
var getOptimisticStatus = (message) => {
|
|
1365
|
+
var _a, _b;
|
|
1366
|
+
const status = (_b = (_a = message.metadata) == null ? void 0 : _a.custom) == null ? void 0 : _b.aomiSendStatus;
|
|
1367
|
+
return status === "sending" || status === "sent" || status === "failed" ? status : void 0;
|
|
1368
|
+
};
|
|
1369
|
+
var hasUnhydratedOptimisticMessage = (messages) => messages.some((message) => {
|
|
1370
|
+
const status = getOptimisticStatus(message);
|
|
1371
|
+
return status === "sending" || status === "sent";
|
|
1372
|
+
});
|
|
1373
|
+
var withOptimisticStatus = (message, status, error) => {
|
|
1374
|
+
var _a, _b;
|
|
1375
|
+
const custom = __spreadProps(__spreadValues({}, (_b = (_a = message.metadata) == null ? void 0 : _a.custom) != null ? _b : {}), {
|
|
1376
|
+
aomiSendStatus: status
|
|
1377
|
+
});
|
|
1378
|
+
if (error) {
|
|
1379
|
+
custom.aomiSendError = toErrorMessage(error);
|
|
1380
|
+
} else {
|
|
1381
|
+
delete custom.aomiSendError;
|
|
1382
|
+
}
|
|
1383
|
+
return __spreadProps(__spreadValues({}, message), {
|
|
1384
|
+
metadata: __spreadProps(__spreadValues({}, message.metadata), {
|
|
1385
|
+
custom
|
|
1386
|
+
})
|
|
1387
|
+
});
|
|
1388
|
+
};
|
|
1389
|
+
var updateOptimisticMessage = (threadContext, threadId, messageId, status, error) => {
|
|
1390
|
+
const messages = threadContext.getThreadMessages(threadId);
|
|
1391
|
+
let changed = false;
|
|
1392
|
+
const nextMessages = messages.map((message) => {
|
|
1393
|
+
if (message.id !== messageId) return message;
|
|
1394
|
+
changed = true;
|
|
1395
|
+
return withOptimisticStatus(message, status, error);
|
|
1396
|
+
});
|
|
1397
|
+
if (changed) {
|
|
1398
|
+
threadContext.setThreadMessages(threadId, nextMessages);
|
|
1399
|
+
}
|
|
1400
|
+
};
|
|
1319
1401
|
function useRuntimeOrchestrator(aomiClient, options) {
|
|
1320
1402
|
const threadContext = useThreadContext();
|
|
1321
1403
|
const threadContextRef = useRef5(threadContext);
|
|
1322
1404
|
threadContextRef.current = threadContext;
|
|
1323
1405
|
const aomiClientRef = useRef5(aomiClient);
|
|
1324
1406
|
aomiClientRef.current = aomiClient;
|
|
1407
|
+
const optionsRef = useRef5(options);
|
|
1408
|
+
optionsRef.current = options;
|
|
1325
1409
|
const [isRunning, setIsRunning] = useState4(false);
|
|
1326
1410
|
const sessionManagerRef = useRef5(null);
|
|
1327
1411
|
if (!sessionManagerRef.current) {
|
|
1328
1412
|
sessionManagerRef.current = new SessionManager(() => aomiClientRef.current);
|
|
1329
1413
|
}
|
|
1330
1414
|
const pendingFetches = useRef5(/* @__PURE__ */ new Set());
|
|
1415
|
+
const initialStatePromises = useRef5(/* @__PURE__ */ new Map());
|
|
1416
|
+
const hydratedThreadIds = useRef5(/* @__PURE__ */ new Set());
|
|
1331
1417
|
const listenerCleanups = useRef5(/* @__PURE__ */ new Map());
|
|
1418
|
+
const cleanupSessionListeners = useCallback5((threadId) => {
|
|
1419
|
+
var _a;
|
|
1420
|
+
(_a = listenerCleanups.current.get(threadId)) == null ? void 0 : _a();
|
|
1421
|
+
listenerCleanups.current.delete(threadId);
|
|
1422
|
+
}, []);
|
|
1423
|
+
const closeSession = useCallback5(
|
|
1424
|
+
(threadId) => {
|
|
1425
|
+
var _a;
|
|
1426
|
+
cleanupSessionListeners(threadId);
|
|
1427
|
+
pendingFetches.current.delete(threadId);
|
|
1428
|
+
initialStatePromises.current.delete(threadId);
|
|
1429
|
+
hydratedThreadIds.current.delete(threadId);
|
|
1430
|
+
(_a = sessionManagerRef.current) == null ? void 0 : _a.close(threadId);
|
|
1431
|
+
},
|
|
1432
|
+
[cleanupSessionListeners]
|
|
1433
|
+
);
|
|
1434
|
+
const closeIdleSessionsExcept = useCallback5(
|
|
1435
|
+
(activeThreadId) => {
|
|
1436
|
+
var _a, _b;
|
|
1437
|
+
const closedThreadIds = (_b = (_a = sessionManagerRef.current) == null ? void 0 : _a.closeIdleExcept(
|
|
1438
|
+
activeThreadId,
|
|
1439
|
+
cleanupSessionListeners
|
|
1440
|
+
)) != null ? _b : [];
|
|
1441
|
+
for (const threadId of closedThreadIds) {
|
|
1442
|
+
pendingFetches.current.delete(threadId);
|
|
1443
|
+
initialStatePromises.current.delete(threadId);
|
|
1444
|
+
hydratedThreadIds.current.delete(threadId);
|
|
1445
|
+
}
|
|
1446
|
+
return closedThreadIds;
|
|
1447
|
+
},
|
|
1448
|
+
[cleanupSessionListeners]
|
|
1449
|
+
);
|
|
1450
|
+
const closeAllSessions = useCallback5(() => {
|
|
1451
|
+
var _a;
|
|
1452
|
+
pendingFetches.current.clear();
|
|
1453
|
+
initialStatePromises.current.clear();
|
|
1454
|
+
hydratedThreadIds.current.clear();
|
|
1455
|
+
for (const threadId of Array.from(listenerCleanups.current.keys())) {
|
|
1456
|
+
cleanupSessionListeners(threadId);
|
|
1457
|
+
}
|
|
1458
|
+
(_a = sessionManagerRef.current) == null ? void 0 : _a.closeAll();
|
|
1459
|
+
}, [cleanupSessionListeners]);
|
|
1332
1460
|
const getSession = useCallback5(
|
|
1333
1461
|
(threadId) => {
|
|
1334
1462
|
var _a, _b, _c, _d, _e;
|
|
1335
1463
|
const manager = sessionManagerRef.current;
|
|
1336
|
-
const
|
|
1337
|
-
const
|
|
1338
|
-
const
|
|
1339
|
-
const
|
|
1340
|
-
const
|
|
1464
|
+
const nextOptions = optionsRef.current;
|
|
1465
|
+
const nextApp = nextOptions.getApp();
|
|
1466
|
+
const nextPublicKey = (_a = nextOptions.getPublicKey) == null ? void 0 : _a.call(nextOptions);
|
|
1467
|
+
const nextApiKey = (_c = (_b = nextOptions.getApiKey) == null ? void 0 : _b.call(nextOptions)) != null ? _c : void 0;
|
|
1468
|
+
const nextClientId = (_d = nextOptions.getClientId) == null ? void 0 : _d.call(nextOptions);
|
|
1469
|
+
const nextUserState = (_e = nextOptions.getUserState) == null ? void 0 : _e.call(nextOptions);
|
|
1341
1470
|
const existing = manager.get(threadId);
|
|
1342
1471
|
if (existing) {
|
|
1343
1472
|
existing.syncRuntimeOptions({
|
|
@@ -1366,6 +1495,10 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1366
1495
|
const converted = toInboundMessage(msg);
|
|
1367
1496
|
if (converted) threadMessages.push(converted);
|
|
1368
1497
|
}
|
|
1498
|
+
const existingMessages = threadContextRef.current.getThreadMessages(threadId);
|
|
1499
|
+
if (threadMessages.length === 0 && hasUnhydratedOptimisticMessage(existingMessages)) {
|
|
1500
|
+
return;
|
|
1501
|
+
}
|
|
1369
1502
|
threadContextRef.current.setThreadMessages(threadId, threadMessages);
|
|
1370
1503
|
})
|
|
1371
1504
|
);
|
|
@@ -1387,8 +1520,8 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1387
1520
|
session.on(
|
|
1388
1521
|
"wallet_requests_changed",
|
|
1389
1522
|
(requests) => {
|
|
1390
|
-
var _a2;
|
|
1391
|
-
return (_a2 =
|
|
1523
|
+
var _a2, _b2;
|
|
1524
|
+
return (_b2 = (_a2 = optionsRef.current).onPendingRequestsChange) == null ? void 0 : _b2.call(_a2, requests);
|
|
1392
1525
|
}
|
|
1393
1526
|
)
|
|
1394
1527
|
);
|
|
@@ -1397,10 +1530,17 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1397
1530
|
threadContextRef.current.updateThreadMetadata(threadId, { title });
|
|
1398
1531
|
})
|
|
1399
1532
|
);
|
|
1400
|
-
const forwardEvent = (type) => session.on(
|
|
1401
|
-
|
|
1402
|
-
(
|
|
1403
|
-
|
|
1533
|
+
const forwardEvent = (type) => session.on(
|
|
1534
|
+
type,
|
|
1535
|
+
(payload) => {
|
|
1536
|
+
var _a2, _b2;
|
|
1537
|
+
(_b2 = (_a2 = optionsRef.current).onEvent) == null ? void 0 : _b2.call(_a2, {
|
|
1538
|
+
type,
|
|
1539
|
+
payload,
|
|
1540
|
+
sessionId: threadId
|
|
1541
|
+
});
|
|
1542
|
+
}
|
|
1543
|
+
);
|
|
1404
1544
|
cleanups.push(forwardEvent("tool_update"));
|
|
1405
1545
|
cleanups.push(forwardEvent("tool_complete"));
|
|
1406
1546
|
cleanups.push(forwardEvent("system_notice"));
|
|
@@ -1416,36 +1556,68 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1416
1556
|
);
|
|
1417
1557
|
const ensureInitialState = useCallback5(
|
|
1418
1558
|
async (threadId) => {
|
|
1419
|
-
var _a;
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1559
|
+
var _a, _b, _c;
|
|
1560
|
+
const existingPromise = initialStatePromises.current.get(threadId);
|
|
1561
|
+
if (existingPromise) {
|
|
1562
|
+
return existingPromise;
|
|
1563
|
+
}
|
|
1564
|
+
const cachedMessages = threadContextRef.current.getThreadMessages(threadId);
|
|
1565
|
+
const existingSession = (_a = sessionManagerRef.current) == null ? void 0 : _a.get(threadId);
|
|
1566
|
+
if (existingSession && (hydratedThreadIds.current.has(threadId) || cachedMessages.length > 0)) {
|
|
1567
|
+
(_c = (_b = optionsRef.current).onPendingRequestsChange) == null ? void 0 : _c.call(
|
|
1568
|
+
_b,
|
|
1569
|
+
existingSession.getPendingRequests()
|
|
1570
|
+
);
|
|
1431
1571
|
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1432
|
-
setIsRunning(
|
|
1572
|
+
setIsRunning(existingSession.getIsProcessing());
|
|
1433
1573
|
}
|
|
1434
|
-
|
|
1435
|
-
pendingFetches.current.delete(threadId);
|
|
1574
|
+
return;
|
|
1436
1575
|
}
|
|
1576
|
+
const fetchPromise = (async () => {
|
|
1577
|
+
var _a2, _b2;
|
|
1578
|
+
pendingFetches.current.add(threadId);
|
|
1579
|
+
try {
|
|
1580
|
+
const session = getSession(threadId);
|
|
1581
|
+
await session.fetchCurrentState();
|
|
1582
|
+
hydratedThreadIds.current.add(threadId);
|
|
1583
|
+
(_b2 = (_a2 = optionsRef.current).onPendingRequestsChange) == null ? void 0 : _b2.call(
|
|
1584
|
+
_a2,
|
|
1585
|
+
session.getPendingRequests()
|
|
1586
|
+
);
|
|
1587
|
+
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1588
|
+
setIsRunning(session.getIsProcessing());
|
|
1589
|
+
}
|
|
1590
|
+
} catch (error) {
|
|
1591
|
+
console.error("Failed to fetch initial state:", error);
|
|
1592
|
+
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1593
|
+
setIsRunning(false);
|
|
1594
|
+
}
|
|
1595
|
+
} finally {
|
|
1596
|
+
pendingFetches.current.delete(threadId);
|
|
1597
|
+
initialStatePromises.current.delete(threadId);
|
|
1598
|
+
}
|
|
1599
|
+
})();
|
|
1600
|
+
initialStatePromises.current.set(threadId, fetchPromise);
|
|
1601
|
+
return fetchPromise;
|
|
1437
1602
|
},
|
|
1438
1603
|
[getSession]
|
|
1439
1604
|
);
|
|
1440
1605
|
const sendMessage = useCallback5(
|
|
1441
1606
|
async (text, threadId) => {
|
|
1442
|
-
var _a;
|
|
1443
|
-
const session = getSession(threadId);
|
|
1607
|
+
var _a, _b, _c, _d;
|
|
1444
1608
|
const existingMessages = threadContextRef.current.getThreadMessages(threadId);
|
|
1609
|
+
const optimisticMessageId = String(existingMessages.length);
|
|
1445
1610
|
const userMessage = {
|
|
1611
|
+
id: optimisticMessageId,
|
|
1446
1612
|
role: "user",
|
|
1447
1613
|
content: [{ type: "text", text }],
|
|
1448
|
-
createdAt: /* @__PURE__ */ new Date()
|
|
1614
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
1615
|
+
metadata: {
|
|
1616
|
+
custom: {
|
|
1617
|
+
aomiOriginalText: text,
|
|
1618
|
+
aomiSendStatus: "sending"
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1449
1621
|
};
|
|
1450
1622
|
threadContextRef.current.setThreadMessages(threadId, [
|
|
1451
1623
|
...existingMessages,
|
|
@@ -1454,31 +1626,54 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1454
1626
|
threadContextRef.current.updateThreadMetadata(threadId, {
|
|
1455
1627
|
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1456
1628
|
});
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1629
|
+
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1630
|
+
setIsRunning(true);
|
|
1631
|
+
}
|
|
1632
|
+
try {
|
|
1633
|
+
await ((_b = (_a = optionsRef.current).prepareThreadForSend) == null ? void 0 : _b.call(_a, threadId));
|
|
1634
|
+
const session = getSession(threadId);
|
|
1635
|
+
await session.sendAsync(text);
|
|
1636
|
+
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1637
|
+
setIsRunning(session.getIsProcessing());
|
|
1638
|
+
}
|
|
1639
|
+
updateOptimisticMessage(
|
|
1640
|
+
threadContextRef.current,
|
|
1641
|
+
threadId,
|
|
1642
|
+
optimisticMessageId,
|
|
1643
|
+
"sent"
|
|
1644
|
+
);
|
|
1645
|
+
(_d = (_c = optionsRef.current).onPendingRequestsChange) == null ? void 0 : _d.call(
|
|
1646
|
+
_c,
|
|
1647
|
+
session.getPendingRequests()
|
|
1648
|
+
);
|
|
1649
|
+
} catch (error) {
|
|
1650
|
+
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1651
|
+
setIsRunning(false);
|
|
1652
|
+
}
|
|
1653
|
+
updateOptimisticMessage(
|
|
1654
|
+
threadContextRef.current,
|
|
1655
|
+
threadId,
|
|
1656
|
+
optimisticMessageId,
|
|
1657
|
+
"failed",
|
|
1658
|
+
error
|
|
1659
|
+
);
|
|
1660
|
+
throw error;
|
|
1468
1661
|
}
|
|
1469
1662
|
},
|
|
1470
|
-
[]
|
|
1663
|
+
[getSession]
|
|
1471
1664
|
);
|
|
1665
|
+
const cancelGeneration = useCallback5(async (threadId) => {
|
|
1666
|
+
var _a;
|
|
1667
|
+
const session = (_a = sessionManagerRef.current) == null ? void 0 : _a.get(threadId);
|
|
1668
|
+
if (session) {
|
|
1669
|
+
await session.interrupt();
|
|
1670
|
+
}
|
|
1671
|
+
}, []);
|
|
1472
1672
|
useEffect2(() => {
|
|
1473
1673
|
return () => {
|
|
1474
|
-
|
|
1475
|
-
(_a = sessionManagerRef.current) == null ? void 0 : _a.closeAll();
|
|
1476
|
-
for (const cleanup of listenerCleanups.current.values()) {
|
|
1477
|
-
cleanup();
|
|
1478
|
-
}
|
|
1479
|
-
listenerCleanups.current.clear();
|
|
1674
|
+
closeAllSessions();
|
|
1480
1675
|
};
|
|
1481
|
-
}, []);
|
|
1676
|
+
}, [closeAllSessions]);
|
|
1482
1677
|
return {
|
|
1483
1678
|
sessionManager: sessionManagerRef.current,
|
|
1484
1679
|
getSession,
|
|
@@ -1487,6 +1682,9 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1487
1682
|
ensureInitialState,
|
|
1488
1683
|
sendMessage,
|
|
1489
1684
|
cancelGeneration,
|
|
1685
|
+
closeSession,
|
|
1686
|
+
closeAllSessions,
|
|
1687
|
+
closeIdleSessionsExcept,
|
|
1490
1688
|
aomiClientRef
|
|
1491
1689
|
};
|
|
1492
1690
|
}
|
|
@@ -1497,9 +1695,9 @@ var sortByLastActiveDesc = ([, metaA], [, metaB]) => {
|
|
|
1497
1695
|
const tsB = parseTimestamp(metaB.lastActiveAt);
|
|
1498
1696
|
return tsB - tsA;
|
|
1499
1697
|
};
|
|
1500
|
-
function buildThreadLists(threadMetadata) {
|
|
1698
|
+
function buildThreadLists(threadMetadata, shouldShowThread) {
|
|
1501
1699
|
const entries = Array.from(threadMetadata.entries()).filter(
|
|
1502
|
-
([, meta]) => !isPlaceholderTitle(meta.title)
|
|
1700
|
+
([threadId, meta]) => !isPlaceholderTitle(meta.title) && shouldShowThread(threadId)
|
|
1503
1701
|
);
|
|
1504
1702
|
const regularThreads = entries.filter(([, meta]) => meta.status !== "archived").sort(sortByLastActiveDesc).map(
|
|
1505
1703
|
([id, meta]) => ({
|
|
@@ -1521,16 +1719,41 @@ function buildThreadListAdapter({
|
|
|
1521
1719
|
aomiClientRef,
|
|
1522
1720
|
threadContext,
|
|
1523
1721
|
setIsRunning,
|
|
1524
|
-
|
|
1722
|
+
isLoading = false,
|
|
1723
|
+
getInitialControl = initThreadControl,
|
|
1724
|
+
isRemoteThread = () => true
|
|
1525
1725
|
}) {
|
|
1726
|
+
const shouldShowThread = (threadId) => {
|
|
1727
|
+
if (isRemoteThread(threadId)) return true;
|
|
1728
|
+
return threadContext.getThreadMessages(threadId).some((message) => message.role === "user");
|
|
1729
|
+
};
|
|
1526
1730
|
const { regularThreads, archivedThreads } = buildThreadLists(
|
|
1527
|
-
threadContext.allThreadsMetadata
|
|
1731
|
+
threadContext.allThreadsMetadata,
|
|
1732
|
+
shouldShowThread
|
|
1528
1733
|
);
|
|
1734
|
+
const cleanupEmptyLocalThread = () => {
|
|
1735
|
+
const prevId = threadContext.currentThreadId;
|
|
1736
|
+
if (isRemoteThread(prevId)) return;
|
|
1737
|
+
const msgs = threadContext.getThreadMessages(prevId);
|
|
1738
|
+
if (msgs.length > 0) return;
|
|
1739
|
+
threadContext.setThreadMetadata((prev) => {
|
|
1740
|
+
const next = new Map(prev);
|
|
1741
|
+
next.delete(prevId);
|
|
1742
|
+
return next;
|
|
1743
|
+
});
|
|
1744
|
+
threadContext.setThreads((prev) => {
|
|
1745
|
+
const next = new Map(prev);
|
|
1746
|
+
next.delete(prevId);
|
|
1747
|
+
return next;
|
|
1748
|
+
});
|
|
1749
|
+
};
|
|
1529
1750
|
return {
|
|
1530
1751
|
threadId: threadContext.currentThreadId,
|
|
1752
|
+
isLoading,
|
|
1531
1753
|
threads: regularThreads,
|
|
1532
1754
|
archivedThreads,
|
|
1533
1755
|
onSwitchToNewThread: () => {
|
|
1756
|
+
cleanupEmptyLocalThread();
|
|
1534
1757
|
const threadId = generateUUID();
|
|
1535
1758
|
threadContext.setThreadMetadata(
|
|
1536
1759
|
(prev) => new Map(prev).set(threadId, {
|
|
@@ -1546,6 +1769,7 @@ function buildThreadListAdapter({
|
|
|
1546
1769
|
threadContext.bumpThreadViewKey();
|
|
1547
1770
|
},
|
|
1548
1771
|
onSwitchToThread: (threadId) => {
|
|
1772
|
+
cleanupEmptyLocalThread();
|
|
1549
1773
|
threadContext.setCurrentThreadId(threadId);
|
|
1550
1774
|
threadContext.bumpThreadViewKey();
|
|
1551
1775
|
},
|
|
@@ -1763,6 +1987,22 @@ function RuntimeUserStateProvider({
|
|
|
1763
1987
|
|
|
1764
1988
|
// packages/react/src/runtime/core.tsx
|
|
1765
1989
|
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1990
|
+
var THREAD_PREFETCH_LIMIT = 5;
|
|
1991
|
+
var PREFETCH_IDLE_TIMEOUT_MS = 1500;
|
|
1992
|
+
function scheduleBackgroundTask(task) {
|
|
1993
|
+
const runtimeGlobal = globalThis;
|
|
1994
|
+
if (typeof runtimeGlobal.requestIdleCallback === "function") {
|
|
1995
|
+
const idleId = runtimeGlobal.requestIdleCallback(task, {
|
|
1996
|
+
timeout: PREFETCH_IDLE_TIMEOUT_MS
|
|
1997
|
+
});
|
|
1998
|
+
return () => {
|
|
1999
|
+
var _a;
|
|
2000
|
+
return (_a = runtimeGlobal.cancelIdleCallback) == null ? void 0 : _a.call(runtimeGlobal, idleId);
|
|
2001
|
+
};
|
|
2002
|
+
}
|
|
2003
|
+
const timeoutId = runtimeGlobal.setTimeout(task, 0);
|
|
2004
|
+
return () => runtimeGlobal.clearTimeout(timeoutId);
|
|
2005
|
+
}
|
|
1766
2006
|
function AomiRuntimeCore({
|
|
1767
2007
|
children,
|
|
1768
2008
|
aomiClient
|
|
@@ -1792,6 +2032,9 @@ function AomiRuntimeCore({
|
|
|
1792
2032
|
ensureInitialState,
|
|
1793
2033
|
sendMessage: orchestratorSendMessage,
|
|
1794
2034
|
cancelGeneration: orchestratorCancel,
|
|
2035
|
+
closeSession,
|
|
2036
|
+
closeIdleSessionsExcept,
|
|
2037
|
+
closeAllSessions,
|
|
1795
2038
|
aomiClientRef
|
|
1796
2039
|
} = useRuntimeOrchestrator(aomiClient, {
|
|
1797
2040
|
getPublicKey: () => UserState3.isConnected(getUserState()) ? UserState3.address(getUserState()) : void 0,
|
|
@@ -1802,10 +2045,22 @@ function AomiRuntimeCore({
|
|
|
1802
2045
|
var _a;
|
|
1803
2046
|
return (_a = getControlState().clientId) != null ? _a : void 0;
|
|
1804
2047
|
},
|
|
2048
|
+
prepareThreadForSend: async (threadId) => {
|
|
2049
|
+
await ensureBackendThread(threadId);
|
|
2050
|
+
await syncCurrentThreadControl();
|
|
2051
|
+
},
|
|
1805
2052
|
onPendingRequestsChange: walletHandler.setRequests,
|
|
1806
2053
|
onEvent: (event) => eventContext.dispatch(event)
|
|
1807
2054
|
});
|
|
1808
2055
|
sessionManagerRef.current = sessionManager;
|
|
2056
|
+
const threadContextRef = useRef8(threadContext);
|
|
2057
|
+
threadContextRef.current = threadContext;
|
|
2058
|
+
const remoteThreadIdsRef = useRef8(/* @__PURE__ */ new Set());
|
|
2059
|
+
const warmedThreadIdsRef = useRef8(/* @__PURE__ */ new Set());
|
|
2060
|
+
const warmPromisesRef = useRef8(/* @__PURE__ */ new Map());
|
|
2061
|
+
const prefetchCancelRef = useRef8(null);
|
|
2062
|
+
const [isThreadLoading, setIsThreadLoading] = useState6(false);
|
|
2063
|
+
const [isThreadListLoading, setIsThreadListLoading] = useState6(true);
|
|
1809
2064
|
const walletSnapshot = useCallback7(
|
|
1810
2065
|
(nextUser) => {
|
|
1811
2066
|
var _a;
|
|
@@ -1829,6 +2084,9 @@ function AomiRuntimeCore({
|
|
|
1829
2084
|
}
|
|
1830
2085
|
lastWalletStateRef.current = nextWalletState;
|
|
1831
2086
|
const sessionId = threadContext.currentThreadId;
|
|
2087
|
+
if (!remoteThreadIdsRef.current.has(sessionId)) {
|
|
2088
|
+
return;
|
|
2089
|
+
}
|
|
1832
2090
|
const message = JSON.stringify({
|
|
1833
2091
|
type: "wallet:state_changed",
|
|
1834
2092
|
payload: nextWalletState
|
|
@@ -1843,24 +2101,67 @@ function AomiRuntimeCore({
|
|
|
1843
2101
|
getUserState,
|
|
1844
2102
|
walletSnapshot
|
|
1845
2103
|
]);
|
|
1846
|
-
const threadContextRef = useRef8(threadContext);
|
|
1847
|
-
threadContextRef.current = threadContext;
|
|
1848
|
-
const remoteThreadIdsRef = useRef8(/* @__PURE__ */ new Set());
|
|
1849
|
-
const warmedThreadIdsRef = useRef8(/* @__PURE__ */ new Set());
|
|
1850
2104
|
const warmThread = useCallback7(
|
|
1851
2105
|
async (threadId) => {
|
|
1852
2106
|
if (!remoteThreadIdsRef.current.has(threadId) || warmedThreadIdsRef.current.has(threadId)) {
|
|
1853
2107
|
return;
|
|
1854
2108
|
}
|
|
1855
|
-
const
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
)
|
|
1860
|
-
|
|
2109
|
+
const existingPromise = warmPromisesRef.current.get(threadId);
|
|
2110
|
+
if (existingPromise) {
|
|
2111
|
+
return existingPromise;
|
|
2112
|
+
}
|
|
2113
|
+
const warmPromise = (async () => {
|
|
2114
|
+
const userState = getUserState();
|
|
2115
|
+
await aomiClientRef.current.createThread(
|
|
2116
|
+
threadId,
|
|
2117
|
+
UserState3.isConnected(userState) ? UserState3.address(userState) : void 0
|
|
2118
|
+
);
|
|
2119
|
+
warmedThreadIdsRef.current.add(threadId);
|
|
2120
|
+
})();
|
|
2121
|
+
warmPromisesRef.current.set(threadId, warmPromise);
|
|
2122
|
+
try {
|
|
2123
|
+
await warmPromise;
|
|
2124
|
+
} finally {
|
|
2125
|
+
warmPromisesRef.current.delete(threadId);
|
|
2126
|
+
}
|
|
1861
2127
|
},
|
|
1862
2128
|
[aomiClientRef, getUserState]
|
|
1863
2129
|
);
|
|
2130
|
+
const scheduleThreadPrefetch = useCallback7(
|
|
2131
|
+
(threadIds) => {
|
|
2132
|
+
var _a;
|
|
2133
|
+
(_a = prefetchCancelRef.current) == null ? void 0 : _a.call(prefetchCancelRef);
|
|
2134
|
+
const prefetchThreadIds = Array.from(new Set(threadIds)).filter((threadId) => remoteThreadIdsRef.current.has(threadId)).slice(0, THREAD_PREFETCH_LIMIT);
|
|
2135
|
+
if (prefetchThreadIds.length === 0) {
|
|
2136
|
+
prefetchCancelRef.current = null;
|
|
2137
|
+
return;
|
|
2138
|
+
}
|
|
2139
|
+
let cancelled = false;
|
|
2140
|
+
const cancelScheduledTask = scheduleBackgroundTask(() => {
|
|
2141
|
+
void Promise.all(
|
|
2142
|
+
prefetchThreadIds.map(async (threadId) => {
|
|
2143
|
+
if (cancelled || !remoteThreadIdsRef.current.has(threadId)) return;
|
|
2144
|
+
if (threadContextRef.current.getThreadMessages(threadId).length > 0) {
|
|
2145
|
+
return;
|
|
2146
|
+
}
|
|
2147
|
+
try {
|
|
2148
|
+
await warmThread(threadId);
|
|
2149
|
+
if (cancelled || !remoteThreadIdsRef.current.has(threadId))
|
|
2150
|
+
return;
|
|
2151
|
+
await ensureInitialState(threadId);
|
|
2152
|
+
} catch (error) {
|
|
2153
|
+
console.debug("Failed to prefetch thread:", threadId, error);
|
|
2154
|
+
}
|
|
2155
|
+
})
|
|
2156
|
+
);
|
|
2157
|
+
});
|
|
2158
|
+
prefetchCancelRef.current = () => {
|
|
2159
|
+
cancelled = true;
|
|
2160
|
+
cancelScheduledTask();
|
|
2161
|
+
};
|
|
2162
|
+
},
|
|
2163
|
+
[ensureInitialState, warmThread]
|
|
2164
|
+
);
|
|
1864
2165
|
useEffect4(() => {
|
|
1865
2166
|
const unsubscribe = eventContext.subscribe("user_state_request", () => {
|
|
1866
2167
|
var _a, _b, _c;
|
|
@@ -1873,19 +2174,49 @@ function AomiRuntimeCore({
|
|
|
1873
2174
|
});
|
|
1874
2175
|
return unsubscribe;
|
|
1875
2176
|
}, [eventContext, threadContext.currentThreadId, getSession, getUserState]);
|
|
2177
|
+
const ensureBackendThread = useCallback7(
|
|
2178
|
+
async (threadId) => {
|
|
2179
|
+
if (remoteThreadIdsRef.current.has(threadId)) return;
|
|
2180
|
+
const userState = getUserState();
|
|
2181
|
+
await aomiClientRef.current.createThread(
|
|
2182
|
+
threadId,
|
|
2183
|
+
UserState3.isConnected(userState) ? UserState3.address(userState) : void 0
|
|
2184
|
+
);
|
|
2185
|
+
remoteThreadIdsRef.current.add(threadId);
|
|
2186
|
+
warmedThreadIdsRef.current.add(threadId);
|
|
2187
|
+
},
|
|
2188
|
+
[aomiClientRef, getUserState]
|
|
2189
|
+
);
|
|
1876
2190
|
useEffect4(() => {
|
|
1877
2191
|
const threadId = threadContext.currentThreadId;
|
|
2192
|
+
closeIdleSessionsExcept(threadId);
|
|
2193
|
+
if (!remoteThreadIdsRef.current.has(threadId)) {
|
|
2194
|
+
setIsThreadLoading(false);
|
|
2195
|
+
return;
|
|
2196
|
+
}
|
|
1878
2197
|
let cancelled = false;
|
|
2198
|
+
setIsThreadLoading(true);
|
|
1879
2199
|
void (async () => {
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
2200
|
+
try {
|
|
2201
|
+
await warmThread(threadId);
|
|
2202
|
+
if (!cancelled) {
|
|
2203
|
+
await ensureInitialState(threadId);
|
|
2204
|
+
}
|
|
2205
|
+
} finally {
|
|
2206
|
+
if (!cancelled) {
|
|
2207
|
+
setIsThreadLoading(false);
|
|
2208
|
+
}
|
|
1883
2209
|
}
|
|
1884
2210
|
})();
|
|
1885
2211
|
return () => {
|
|
1886
2212
|
cancelled = true;
|
|
1887
2213
|
};
|
|
1888
|
-
}, [
|
|
2214
|
+
}, [
|
|
2215
|
+
closeIdleSessionsExcept,
|
|
2216
|
+
ensureInitialState,
|
|
2217
|
+
threadContext.currentThreadId,
|
|
2218
|
+
warmThread
|
|
2219
|
+
]);
|
|
1889
2220
|
useEffect4(() => {
|
|
1890
2221
|
const threadId = threadContext.currentThreadId;
|
|
1891
2222
|
const currentMeta = threadContext.getThreadMetadata(threadId);
|
|
@@ -1901,23 +2232,38 @@ function AomiRuntimeCore({
|
|
|
1901
2232
|
threadContext.currentThreadId
|
|
1902
2233
|
);
|
|
1903
2234
|
useEffect4(() => {
|
|
2235
|
+
var _a;
|
|
1904
2236
|
const userAddress = UserState3.isConnected(user) ? UserState3.address(user) : void 0;
|
|
1905
2237
|
if (!userAddress) {
|
|
2238
|
+
const hadRemoteThreads = remoteThreadIdsRef.current.size > 0;
|
|
2239
|
+
const hadSessions = sessionManager.size > 0;
|
|
2240
|
+
setIsThreadListLoading(false);
|
|
2241
|
+
(_a = prefetchCancelRef.current) == null ? void 0 : _a.call(prefetchCancelRef);
|
|
2242
|
+
prefetchCancelRef.current = null;
|
|
1906
2243
|
remoteThreadIdsRef.current.clear();
|
|
1907
2244
|
warmedThreadIdsRef.current.clear();
|
|
2245
|
+
warmPromisesRef.current.clear();
|
|
2246
|
+
closeAllSessions();
|
|
2247
|
+
if (hadRemoteThreads || hadSessions) {
|
|
2248
|
+
threadContextRef.current.resetToDefault();
|
|
2249
|
+
}
|
|
1908
2250
|
return;
|
|
1909
2251
|
}
|
|
2252
|
+
let cancelled = false;
|
|
2253
|
+
setIsThreadListLoading(true);
|
|
1910
2254
|
const fetchThreadList = async () => {
|
|
1911
|
-
var
|
|
2255
|
+
var _a2, _b, _c;
|
|
1912
2256
|
try {
|
|
2257
|
+
const remoteThreadIdsAtFetchStart = new Set(remoteThreadIdsRef.current);
|
|
1913
2258
|
const threadList = await aomiClientRef.current.listThreads(userAddress);
|
|
2259
|
+
if (cancelled) return;
|
|
1914
2260
|
const currentContext = threadContextRef.current;
|
|
1915
2261
|
const remoteThreadIds = /* @__PURE__ */ new Set();
|
|
1916
2262
|
const newMetadata = new Map(currentContext.allThreadsMetadata);
|
|
1917
2263
|
let maxChatNum = currentContext.threadCnt;
|
|
1918
2264
|
for (const thread of threadList) {
|
|
1919
2265
|
remoteThreadIds.add(thread.session_id);
|
|
1920
|
-
const rawTitle = (
|
|
2266
|
+
const rawTitle = (_a2 = thread.title) != null ? _a2 : "";
|
|
1921
2267
|
const title = isPlaceholderTitle(rawTitle) ? "" : rawTitle;
|
|
1922
2268
|
const lastActive = ((_b = newMetadata.get(thread.session_id)) == null ? void 0 : _b.lastActiveAt) || (/* @__PURE__ */ new Date()).toISOString();
|
|
1923
2269
|
const existingControl = (_c = newMetadata.get(thread.session_id)) == null ? void 0 : _c.control;
|
|
@@ -1935,6 +2281,11 @@ function AomiRuntimeCore({
|
|
|
1935
2281
|
}
|
|
1936
2282
|
}
|
|
1937
2283
|
}
|
|
2284
|
+
for (const threadId of remoteThreadIdsRef.current) {
|
|
2285
|
+
if (!remoteThreadIdsAtFetchStart.has(threadId)) {
|
|
2286
|
+
remoteThreadIds.add(threadId);
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
1938
2289
|
remoteThreadIdsRef.current = remoteThreadIds;
|
|
1939
2290
|
warmedThreadIdsRef.current = new Set(
|
|
1940
2291
|
Array.from(warmedThreadIdsRef.current).filter(
|
|
@@ -1945,30 +2296,65 @@ function AomiRuntimeCore({
|
|
|
1945
2296
|
if (maxChatNum > currentContext.threadCnt) {
|
|
1946
2297
|
currentContext.setThreadCnt(maxChatNum);
|
|
1947
2298
|
}
|
|
2299
|
+
scheduleThreadPrefetch(threadList.map((thread) => thread.session_id));
|
|
1948
2300
|
if (remoteThreadIds.has(currentContext.currentThreadId)) {
|
|
1949
|
-
|
|
1950
|
-
|
|
2301
|
+
setIsThreadLoading(true);
|
|
2302
|
+
try {
|
|
2303
|
+
await warmThread(currentContext.currentThreadId);
|
|
2304
|
+
if (!cancelled) {
|
|
2305
|
+
await ensureInitialState(currentContext.currentThreadId);
|
|
2306
|
+
}
|
|
2307
|
+
} finally {
|
|
2308
|
+
if (!cancelled) {
|
|
2309
|
+
setIsThreadLoading(false);
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
1951
2312
|
}
|
|
1952
2313
|
} catch (error) {
|
|
1953
2314
|
console.error("Failed to fetch thread list:", error);
|
|
2315
|
+
} finally {
|
|
2316
|
+
if (!cancelled) {
|
|
2317
|
+
setIsThreadListLoading(false);
|
|
2318
|
+
}
|
|
1954
2319
|
}
|
|
1955
2320
|
};
|
|
1956
2321
|
void fetchThreadList();
|
|
1957
|
-
|
|
2322
|
+
return () => {
|
|
2323
|
+
var _a2;
|
|
2324
|
+
cancelled = true;
|
|
2325
|
+
(_a2 = prefetchCancelRef.current) == null ? void 0 : _a2.call(prefetchCancelRef);
|
|
2326
|
+
prefetchCancelRef.current = null;
|
|
2327
|
+
};
|
|
2328
|
+
}, [
|
|
2329
|
+
user,
|
|
2330
|
+
aomiClientRef,
|
|
2331
|
+
ensureInitialState,
|
|
2332
|
+
scheduleThreadPrefetch,
|
|
2333
|
+
warmThread
|
|
2334
|
+
]);
|
|
2335
|
+
const isRemoteThread = useCallback7(
|
|
2336
|
+
(threadId) => remoteThreadIdsRef.current.has(threadId),
|
|
2337
|
+
[]
|
|
2338
|
+
);
|
|
1958
2339
|
const threadListAdapter = useMemo2(
|
|
1959
2340
|
() => buildThreadListAdapter({
|
|
1960
2341
|
aomiClientRef,
|
|
1961
2342
|
threadContext,
|
|
1962
2343
|
setIsRunning,
|
|
1963
|
-
|
|
2344
|
+
isLoading: isThreadListLoading,
|
|
2345
|
+
getInitialControl: getPreferredThreadControl,
|
|
2346
|
+
isRemoteThread
|
|
1964
2347
|
}),
|
|
1965
2348
|
[
|
|
1966
2349
|
aomiClientRef,
|
|
1967
2350
|
getPreferredThreadControl,
|
|
2351
|
+
isRemoteThread,
|
|
2352
|
+
isThreadListLoading,
|
|
1968
2353
|
setIsRunning,
|
|
1969
2354
|
threadContext,
|
|
1970
2355
|
threadContext.currentThreadId,
|
|
1971
|
-
threadContext.allThreadsMetadata
|
|
2356
|
+
threadContext.allThreadsMetadata,
|
|
2357
|
+
currentMessages
|
|
1972
2358
|
]
|
|
1973
2359
|
);
|
|
1974
2360
|
useEffect4(() => {
|
|
@@ -2003,6 +2389,7 @@ function AomiRuntimeCore({
|
|
|
2003
2389
|
}, [eventContext, notificationContext]);
|
|
2004
2390
|
const runtime = useExternalStoreRuntime({
|
|
2005
2391
|
messages: currentMessages,
|
|
2392
|
+
isLoading: isThreadLoading,
|
|
2006
2393
|
setMessages: (msgs) => threadContext.setThreadMessages(threadContext.currentThreadId, [...msgs]),
|
|
2007
2394
|
isRunning,
|
|
2008
2395
|
onNew: async (message) => {
|
|
@@ -2010,7 +2397,6 @@ function AomiRuntimeCore({
|
|
|
2010
2397
|
(part) => part.type === "text"
|
|
2011
2398
|
).map((part) => part.text).join("\n");
|
|
2012
2399
|
if (text) {
|
|
2013
|
-
await syncCurrentThreadControl();
|
|
2014
2400
|
await orchestratorSendMessage(text, threadContext.currentThreadId);
|
|
2015
2401
|
}
|
|
2016
2402
|
},
|
|
@@ -2022,20 +2408,17 @@ function AomiRuntimeCore({
|
|
|
2022
2408
|
});
|
|
2023
2409
|
useEffect4(() => {
|
|
2024
2410
|
return () => {
|
|
2025
|
-
|
|
2411
|
+
var _a;
|
|
2412
|
+
(_a = prefetchCancelRef.current) == null ? void 0 : _a.call(prefetchCancelRef);
|
|
2413
|
+
closeAllSessions();
|
|
2026
2414
|
};
|
|
2027
|
-
}, [
|
|
2415
|
+
}, [closeAllSessions]);
|
|
2028
2416
|
const userContext = useUser();
|
|
2029
2417
|
const sendMessage = useCallback7(
|
|
2030
2418
|
async (text) => {
|
|
2031
|
-
await syncCurrentThreadControl();
|
|
2032
2419
|
await orchestratorSendMessage(text, threadContext.currentThreadId);
|
|
2033
2420
|
},
|
|
2034
|
-
[
|
|
2035
|
-
orchestratorSendMessage,
|
|
2036
|
-
syncCurrentThreadControl,
|
|
2037
|
-
threadContext.currentThreadId
|
|
2038
|
-
]
|
|
2421
|
+
[orchestratorSendMessage, threadContext.currentThreadId]
|
|
2039
2422
|
);
|
|
2040
2423
|
const cancelGeneration = useCallback7(() => {
|
|
2041
2424
|
void orchestratorCancel(threadContext.currentThreadId);
|
|
@@ -2053,10 +2436,10 @@ function AomiRuntimeCore({
|
|
|
2053
2436
|
}, [threadListAdapter]);
|
|
2054
2437
|
const deleteThread = useCallback7(
|
|
2055
2438
|
async (threadId) => {
|
|
2056
|
-
|
|
2439
|
+
closeSession(threadId);
|
|
2057
2440
|
await threadListAdapter.onDelete(threadId);
|
|
2058
2441
|
},
|
|
2059
|
-
[
|
|
2442
|
+
[closeSession, threadListAdapter]
|
|
2060
2443
|
);
|
|
2061
2444
|
const renameThread = useCallback7(
|
|
2062
2445
|
async (threadId, title) => {
|
|
@@ -2172,9 +2555,13 @@ function AomiRuntimeCore({
|
|
|
2172
2555
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
2173
2556
|
function AomiRuntimeProvider({
|
|
2174
2557
|
children,
|
|
2175
|
-
backendUrl = "http://localhost:8080"
|
|
2558
|
+
backendUrl = "http://localhost:8080",
|
|
2559
|
+
clientOptions
|
|
2176
2560
|
}) {
|
|
2177
|
-
const aomiClient = useMemo3(
|
|
2561
|
+
const aomiClient = useMemo3(
|
|
2562
|
+
() => new AomiClient(__spreadValues({ baseUrl: backendUrl }, clientOptions)),
|
|
2563
|
+
[backendUrl, clientOptions]
|
|
2564
|
+
);
|
|
2178
2565
|
return /* @__PURE__ */ jsx8(ThreadContextProvider, { children: /* @__PURE__ */ jsx8(NotificationContextProvider, { children: /* @__PURE__ */ jsx8(UserContextProvider, { children: /* @__PURE__ */ jsx8(AomiRuntimeInner, { aomiClient, children }) }) }) });
|
|
2179
2566
|
}
|
|
2180
2567
|
function AomiRuntimeInner({
|
|
@@ -2205,7 +2592,7 @@ function AomiRuntimeInner({
|
|
|
2205
2592
|
}
|
|
2206
2593
|
|
|
2207
2594
|
// packages/react/src/handlers/notification-handler.ts
|
|
2208
|
-
import { useCallback as useCallback8, useEffect as useEffect5, useState as
|
|
2595
|
+
import { useCallback as useCallback8, useEffect as useEffect5, useState as useState7 } from "react";
|
|
2209
2596
|
var notificationIdCounter2 = 0;
|
|
2210
2597
|
function generateNotificationId() {
|
|
2211
2598
|
return `notif-${Date.now()}-${++notificationIdCounter2}`;
|
|
@@ -2214,7 +2601,7 @@ function useNotificationHandler({
|
|
|
2214
2601
|
onNotification
|
|
2215
2602
|
} = {}) {
|
|
2216
2603
|
const { subscribe } = useEventContext();
|
|
2217
|
-
const [notifications, setNotifications] =
|
|
2604
|
+
const [notifications, setNotifications] = useState7([]);
|
|
2218
2605
|
useEffect5(() => {
|
|
2219
2606
|
const unsubscribe = subscribe("notification", (event) => {
|
|
2220
2607
|
var _a, _b;
|
|
@@ -2257,6 +2644,7 @@ export {
|
|
|
2257
2644
|
SUPPORTED_CHAINS,
|
|
2258
2645
|
ThreadContextProvider,
|
|
2259
2646
|
UserContextProvider,
|
|
2647
|
+
UserState2 as UserState,
|
|
2260
2648
|
aaModeFromExecutionKind,
|
|
2261
2649
|
appendFeeCallToPayload,
|
|
2262
2650
|
buildFeeAAWalletCall,
|