@aomi-labs/react 0.3.9 → 0.3.10

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 CHANGED
@@ -50,7 +50,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
50
50
  // packages/react/src/index.ts
51
51
  var index_exports = {};
52
52
  __export(index_exports, {
53
- AomiClient: () => import_client3.AomiClient,
53
+ AomiClient: () => import_client6.AomiClient,
54
54
  AomiRuntimeProvider: () => AomiRuntimeProvider,
55
55
  ControlContextProvider: () => ControlContextProvider,
56
56
  EventContextProvider: () => EventContextProvider,
@@ -63,7 +63,7 @@ __export(index_exports, {
63
63
  getChainInfo: () => getChainInfo,
64
64
  getNetworkName: () => getNetworkName,
65
65
  initThreadControl: () => initThreadControl,
66
- toViemSignTypedDataArgs: () => import_client4.toViemSignTypedDataArgs,
66
+ toViemSignTypedDataArgs: () => import_client7.toViemSignTypedDataArgs,
67
67
  useAomiRuntime: () => useAomiRuntime,
68
68
  useControl: () => useControl,
69
69
  useCurrentThreadMessages: () => useCurrentThreadMessages,
@@ -76,12 +76,12 @@ __export(index_exports, {
76
76
  useWalletHandler: () => useWalletHandler
77
77
  });
78
78
  module.exports = __toCommonJS(index_exports);
79
- var import_client3 = require("@aomi-labs/client");
80
- var import_client4 = require("@aomi-labs/client");
79
+ var import_client6 = require("@aomi-labs/client");
80
+ var import_client7 = require("@aomi-labs/client");
81
81
 
82
82
  // packages/react/src/runtime/aomi-runtime.tsx
83
83
  var import_react11 = require("react");
84
- var import_client2 = require("@aomi-labs/client");
84
+ var import_client5 = require("@aomi-labs/client");
85
85
 
86
86
  // packages/react/src/contexts/control-context.tsx
87
87
  var import_react = require("react");
@@ -895,18 +895,10 @@ function useCurrentThreadMetadata() {
895
895
 
896
896
  // packages/react/src/contexts/user-context.tsx
897
897
  var import_react5 = require("react");
898
+ var import_client = require("@aomi-labs/client");
899
+ var import_client2 = require("@aomi-labs/client");
898
900
  var import_jsx_runtime5 = require("react/jsx-runtime");
899
901
  var UserContext = (0, import_react5.createContext)(void 0);
900
- function normalizeUserState(next, data) {
901
- if (data.isConnected === false) {
902
- return __spreadProps(__spreadValues({}, next), {
903
- address: void 0,
904
- chainId: void 0,
905
- ensName: void 0
906
- });
907
- }
908
- return next;
909
- }
910
902
  function useUser() {
911
903
  const context = (0, import_react5.useContext)(UserContext);
912
904
  if (!context) {
@@ -923,10 +915,10 @@ function useUser() {
923
915
  }
924
916
  function UserContextProvider({ children }) {
925
917
  const [user, setUserState] = (0, import_react5.useState)({
926
- isConnected: false,
927
918
  address: void 0,
928
- chainId: void 0,
929
- ensName: void 0,
919
+ chain_id: void 0,
920
+ is_connected: false,
921
+ ens_name: void 0,
930
922
  ext: void 0
931
923
  });
932
924
  const userRef = (0, import_react5.useRef)(user);
@@ -936,7 +928,13 @@ function UserContextProvider({ children }) {
936
928
  );
937
929
  const setUser = (0, import_react5.useCallback)((data) => {
938
930
  setUserState((prev) => {
939
- const next = normalizeUserState(__spreadValues(__spreadValues({}, prev), data), data);
931
+ var _a, _b, _c;
932
+ const normalizedData = (_a = import_client.UserState.normalize(data)) != null ? _a : {};
933
+ const next = normalizedData.is_connected === false ? __spreadProps(__spreadValues({}, (_b = import_client.UserState.normalize(__spreadValues(__spreadValues({}, prev), normalizedData))) != null ? _b : prev), {
934
+ address: void 0,
935
+ chain_id: void 0,
936
+ ens_name: void 0
937
+ }) : (_c = import_client.UserState.normalize(__spreadValues(__spreadValues({}, prev), normalizedData))) != null ? _c : prev;
940
938
  StateChangeCallbacks.current.forEach((callback) => {
941
939
  callback(next);
942
940
  });
@@ -945,12 +943,7 @@ function UserContextProvider({ children }) {
945
943
  }, []);
946
944
  const addExtValue = (0, import_react5.useCallback)((key, value) => {
947
945
  setUserState((prev) => {
948
- var _a;
949
- const next = __spreadProps(__spreadValues({}, prev), {
950
- ext: __spreadProps(__spreadValues({}, (_a = prev.ext) != null ? _a : {}), {
951
- [key]: value
952
- })
953
- });
946
+ const next = import_client.UserState.withExt(prev, key, value);
954
947
  StateChangeCallbacks.current.forEach((callback) => {
955
948
  callback(next);
956
949
  });
@@ -959,10 +952,11 @@ function UserContextProvider({ children }) {
959
952
  }, []);
960
953
  const removeExtValue = (0, import_react5.useCallback)((key) => {
961
954
  setUserState((prev) => {
962
- if (!prev.ext || !(key in prev.ext)) {
955
+ const ext = prev.ext;
956
+ if (typeof ext !== "object" || ext === null || Array.isArray(ext) || !(key in ext)) {
963
957
  return prev;
964
958
  }
965
- const nextExt = __spreadValues({}, prev.ext);
959
+ const nextExt = __spreadValues({}, ext);
966
960
  delete nextExt[key];
967
961
  const next = __spreadProps(__spreadValues({}, prev), {
968
962
  ext: Object.keys(nextExt).length > 0 ? nextExt : void 0
@@ -1002,12 +996,13 @@ function UserContextProvider({ children }) {
1002
996
  // packages/react/src/runtime/core.tsx
1003
997
  var import_react9 = require("react");
1004
998
  var import_react10 = require("@assistant-ui/react");
999
+ var import_client4 = require("@aomi-labs/client");
1005
1000
 
1006
1001
  // packages/react/src/runtime/orchestrator.ts
1007
1002
  var import_react6 = require("react");
1008
1003
 
1009
1004
  // packages/react/src/runtime/session-manager.ts
1010
- var import_client = require("@aomi-labs/client");
1005
+ var import_client3 = require("@aomi-labs/client");
1011
1006
  var SessionManager = class {
1012
1007
  constructor(clientFactory) {
1013
1008
  this.clientFactory = clientFactory;
@@ -1016,7 +1011,7 @@ var SessionManager = class {
1016
1011
  getOrCreate(threadId, opts) {
1017
1012
  let session = this.sessions.get(threadId);
1018
1013
  if (session) return session;
1019
- session = new import_client.Session(this.clientFactory(), __spreadProps(__spreadValues({}, opts), {
1014
+ session = new import_client3.Session(this.clientFactory(), __spreadProps(__spreadValues({}, opts), {
1020
1015
  sessionId: threadId
1021
1016
  }));
1022
1017
  this.sessions.set(threadId, session);
@@ -1195,16 +1190,13 @@ function useRuntimeOrchestrator(aomiClient, options) {
1195
1190
  })
1196
1191
  );
1197
1192
  cleanups.push(
1198
- session.on("wallet_tx_request", (req) => {
1199
- var _a2;
1200
- return (_a2 = options.onWalletRequest) == null ? void 0 : _a2.call(options, req);
1201
- })
1202
- );
1203
- cleanups.push(
1204
- session.on("wallet_eip712_request", (req) => {
1205
- var _a2;
1206
- return (_a2 = options.onWalletRequest) == null ? void 0 : _a2.call(options, req);
1207
- })
1193
+ session.on(
1194
+ "wallet_requests_changed",
1195
+ (requests) => {
1196
+ var _a2;
1197
+ return (_a2 = options.onPendingRequestsChange) == null ? void 0 : _a2.call(options, requests);
1198
+ }
1199
+ )
1208
1200
  );
1209
1201
  cleanups.push(
1210
1202
  session.on("title_changed", ({ title }) => {
@@ -1230,7 +1222,7 @@ function useRuntimeOrchestrator(aomiClient, options) {
1230
1222
  );
1231
1223
  const ensureInitialState = (0, import_react6.useCallback)(
1232
1224
  async (threadId) => {
1233
- var _a;
1225
+ var _a, _b;
1234
1226
  if (pendingFetches.current.has(threadId)) return;
1235
1227
  pendingFetches.current.add(threadId);
1236
1228
  try {
@@ -1238,6 +1230,7 @@ function useRuntimeOrchestrator(aomiClient, options) {
1238
1230
  const userState = (_a = options.getUserState) == null ? void 0 : _a.call(options);
1239
1231
  if (userState) session.resolveUserState(userState);
1240
1232
  await session.fetchCurrentState();
1233
+ (_b = options.onPendingRequestsChange) == null ? void 0 : _b.call(options, session.getPendingRequests());
1241
1234
  if (threadContextRef.current.currentThreadId === threadId) {
1242
1235
  setIsRunning(session.getIsProcessing());
1243
1236
  }
@@ -1254,7 +1247,7 @@ function useRuntimeOrchestrator(aomiClient, options) {
1254
1247
  );
1255
1248
  const sendMessage = (0, import_react6.useCallback)(
1256
1249
  async (text, threadId) => {
1257
- var _a;
1250
+ var _a, _b;
1258
1251
  const session = getSession(threadId);
1259
1252
  const userState = (_a = options.getUserState) == null ? void 0 : _a.call(options);
1260
1253
  if (userState) session.resolveUserState(userState);
@@ -1272,6 +1265,7 @@ function useRuntimeOrchestrator(aomiClient, options) {
1272
1265
  lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
1273
1266
  });
1274
1267
  await session.sendAsync(text);
1268
+ (_b = options.onPendingRequestsChange) == null ? void 0 : _b.call(options, session.getPendingRequests());
1275
1269
  },
1276
1270
  [getSession]
1277
1271
  );
@@ -1459,9 +1453,9 @@ function useWalletHandler({
1459
1453
  getSession
1460
1454
  }) {
1461
1455
  const [pendingRequests, setPendingRequests] = (0, import_react8.useState)([]);
1462
- const requestsRef = (0, import_react8.useRef)([]);
1463
- const enqueueRequest = (0, import_react8.useCallback)((request) => {
1464
- requestsRef.current = [...requestsRef.current, request];
1456
+ const requestsRef = (0, import_react8.useRef)(pendingRequests);
1457
+ const setRequests = (0, import_react8.useCallback)((requests) => {
1458
+ requestsRef.current = [...requests];
1465
1459
  setPendingRequests(requestsRef.current);
1466
1460
  }, []);
1467
1461
  const resolveRequest = (0, import_react8.useCallback)(
@@ -1471,13 +1465,12 @@ function useWalletHandler({
1471
1465
  console.error("[wallet-handler] No session available to resolve request");
1472
1466
  return;
1473
1467
  }
1474
- requestsRef.current = requestsRef.current.filter((r) => r.id !== id);
1475
- setPendingRequests(requestsRef.current);
1468
+ setRequests(requestsRef.current.filter((request) => request.id !== id));
1476
1469
  void session.resolve(id, result).catch((err) => {
1477
1470
  console.error("[wallet-handler] Failed to resolve request:", err);
1478
1471
  });
1479
1472
  },
1480
- [getSession]
1473
+ [getSession, setRequests]
1481
1474
  );
1482
1475
  const rejectRequest = (0, import_react8.useCallback)(
1483
1476
  (id, error) => {
@@ -1486,17 +1479,16 @@ function useWalletHandler({
1486
1479
  console.error("[wallet-handler] No session available to reject request");
1487
1480
  return;
1488
1481
  }
1489
- requestsRef.current = requestsRef.current.filter((r) => r.id !== id);
1490
- setPendingRequests(requestsRef.current);
1482
+ setRequests(requestsRef.current.filter((request) => request.id !== id));
1491
1483
  void session.reject(id, error).catch((err) => {
1492
1484
  console.error("[wallet-handler] Failed to reject request:", err);
1493
1485
  });
1494
1486
  },
1495
- [getSession]
1487
+ [getSession, setRequests]
1496
1488
  );
1497
1489
  return {
1498
1490
  pendingRequests,
1499
- enqueueRequest,
1491
+ setRequests,
1500
1492
  resolveRequest,
1501
1493
  rejectRequest
1502
1494
  };
@@ -1530,11 +1522,7 @@ function AomiRuntimeCore({
1530
1522
  cancelGeneration: orchestratorCancel,
1531
1523
  aomiClientRef
1532
1524
  } = useRuntimeOrchestrator(aomiClient, {
1533
- getPublicKey: () => {
1534
- var _a;
1535
- const userState = getUserState();
1536
- return userState.isConnected ? (_a = userState.address) != null ? _a : void 0 : void 0;
1537
- },
1525
+ getPublicKey: () => import_client4.UserState.isConnected(getUserState()) ? import_client4.UserState.address(getUserState()) : void 0,
1538
1526
  getUserState,
1539
1527
  getApp: getCurrentThreadApp,
1540
1528
  getApiKey: () => getControlState().apiKey,
@@ -1542,17 +1530,20 @@ function AomiRuntimeCore({
1542
1530
  var _a;
1543
1531
  return (_a = getControlState().clientId) != null ? _a : void 0;
1544
1532
  },
1545
- onWalletRequest: (request) => walletHandler.enqueueRequest(request),
1533
+ onPendingRequestsChange: walletHandler.setRequests,
1546
1534
  onEvent: (event) => eventContext.dispatch(event)
1547
1535
  });
1548
1536
  sessionManagerRef.current = sessionManager;
1549
1537
  const walletSnapshot = (0, import_react9.useCallback)(
1550
- (nextUser) => ({
1551
- address: nextUser.address,
1552
- chainId: nextUser.chainId,
1553
- isConnected: nextUser.isConnected,
1554
- ensName: nextUser.ensName
1555
- }),
1538
+ (nextUser) => {
1539
+ var _a;
1540
+ return {
1541
+ address: import_client4.UserState.address(nextUser),
1542
+ chain_id: import_client4.UserState.chainId(nextUser),
1543
+ is_connected: (_a = import_client4.UserState.isConnected(nextUser)) != null ? _a : false,
1544
+ ens_name: typeof nextUser.ens_name === "string" ? nextUser.ens_name : void 0
1545
+ };
1546
+ },
1556
1547
  [getUserState]
1557
1548
  );
1558
1549
  const lastWalletStateRef = (0, import_react9.useRef)(walletSnapshot(getUserState()));
@@ -1561,7 +1552,7 @@ function AomiRuntimeCore({
1561
1552
  const unsubscribe = onUserStateChange(async (newUser) => {
1562
1553
  const nextWalletState = walletSnapshot(newUser);
1563
1554
  const prevWalletState = lastWalletStateRef.current;
1564
- if (prevWalletState.address === nextWalletState.address && prevWalletState.chainId === nextWalletState.chainId && prevWalletState.isConnected === nextWalletState.isConnected && prevWalletState.ensName === nextWalletState.ensName) {
1555
+ if (prevWalletState.address === nextWalletState.address && prevWalletState.chain_id === nextWalletState.chain_id && prevWalletState.is_connected === nextWalletState.is_connected && prevWalletState.ens_name === nextWalletState.ens_name) {
1565
1556
  return;
1566
1557
  }
1567
1558
  lastWalletStateRef.current = nextWalletState;
@@ -1582,26 +1573,50 @@ function AomiRuntimeCore({
1582
1573
  ]);
1583
1574
  const threadContextRef = (0, import_react9.useRef)(threadContext);
1584
1575
  threadContextRef.current = threadContext;
1585
- const currentThreadIdRef = (0, import_react9.useRef)(threadContext.currentThreadId);
1586
- (0, import_react9.useEffect)(() => {
1587
- currentThreadIdRef.current = threadContext.currentThreadId;
1588
- }, [threadContext.currentThreadId]);
1576
+ const remoteThreadIdsRef = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
1577
+ const warmedThreadIdsRef = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
1578
+ const warmThread = (0, import_react9.useCallback)(
1579
+ async (threadId) => {
1580
+ if (!remoteThreadIdsRef.current.has(threadId) || warmedThreadIdsRef.current.has(threadId)) {
1581
+ return;
1582
+ }
1583
+ const userState = getUserState();
1584
+ await aomiClientRef.current.createThread(
1585
+ threadId,
1586
+ import_client4.UserState.isConnected(userState) ? import_client4.UserState.address(userState) : void 0
1587
+ );
1588
+ warmedThreadIdsRef.current.add(threadId);
1589
+ },
1590
+ [aomiClientRef, getUserState]
1591
+ );
1589
1592
  (0, import_react9.useEffect)(() => {
1590
1593
  const unsubscribe = eventContext.subscribe(
1591
1594
  "user_state_request",
1592
1595
  () => {
1596
+ var _a, _b, _c;
1597
+ const session = (_b = (_a = sessionManagerRef.current) == null ? void 0 : _a.get(threadContext.currentThreadId)) != null ? _b : getSession(threadContext.currentThreadId);
1593
1598
  eventContext.sendOutboundSystem({
1594
1599
  type: "user_state_response",
1595
1600
  sessionId: threadContext.currentThreadId,
1596
- payload: getUserState()
1601
+ payload: (_c = session.getUserState()) != null ? _c : getUserState()
1597
1602
  });
1598
1603
  }
1599
1604
  );
1600
1605
  return unsubscribe;
1601
- }, [eventContext, threadContext.currentThreadId, getUserState]);
1606
+ }, [eventContext, threadContext.currentThreadId, getSession, getUserState]);
1602
1607
  (0, import_react9.useEffect)(() => {
1603
- void ensureInitialState(threadContext.currentThreadId);
1604
- }, [ensureInitialState, threadContext.currentThreadId]);
1608
+ const threadId = threadContext.currentThreadId;
1609
+ let cancelled = false;
1610
+ void (async () => {
1611
+ await warmThread(threadId);
1612
+ if (!cancelled) {
1613
+ await ensureInitialState(threadId);
1614
+ }
1615
+ })();
1616
+ return () => {
1617
+ cancelled = true;
1618
+ };
1619
+ }, [ensureInitialState, threadContext.currentThreadId, warmThread]);
1605
1620
  (0, import_react9.useEffect)(() => {
1606
1621
  const threadId = threadContext.currentThreadId;
1607
1622
  const currentMeta = threadContext.getThreadMetadata(threadId);
@@ -1617,16 +1632,22 @@ function AomiRuntimeCore({
1617
1632
  threadContext.currentThreadId
1618
1633
  );
1619
1634
  (0, import_react9.useEffect)(() => {
1620
- const userAddress = user.isConnected ? user.address : void 0;
1621
- if (!userAddress) return;
1635
+ const userAddress = import_client4.UserState.isConnected(user) ? import_client4.UserState.address(user) : void 0;
1636
+ if (!userAddress) {
1637
+ remoteThreadIdsRef.current.clear();
1638
+ warmedThreadIdsRef.current.clear();
1639
+ return;
1640
+ }
1622
1641
  const fetchThreadList = async () => {
1623
1642
  var _a, _b, _c;
1624
1643
  try {
1625
1644
  const threadList = await aomiClientRef.current.listThreads(userAddress);
1626
1645
  const currentContext = threadContextRef.current;
1646
+ const remoteThreadIds = /* @__PURE__ */ new Set();
1627
1647
  const newMetadata = new Map(currentContext.allThreadsMetadata);
1628
1648
  let maxChatNum = currentContext.threadCnt;
1629
1649
  for (const thread of threadList) {
1650
+ remoteThreadIds.add(thread.session_id);
1630
1651
  const rawTitle = (_a = thread.title) != null ? _a : "";
1631
1652
  const title = isPlaceholderTitle(rawTitle) ? "" : rawTitle;
1632
1653
  const lastActive = ((_b = newMetadata.get(thread.session_id)) == null ? void 0 : _b.lastActiveAt) || (/* @__PURE__ */ new Date()).toISOString();
@@ -1645,16 +1666,26 @@ function AomiRuntimeCore({
1645
1666
  }
1646
1667
  }
1647
1668
  }
1669
+ remoteThreadIdsRef.current = remoteThreadIds;
1670
+ warmedThreadIdsRef.current = new Set(
1671
+ Array.from(warmedThreadIdsRef.current).filter(
1672
+ (threadId) => remoteThreadIds.has(threadId)
1673
+ )
1674
+ );
1648
1675
  currentContext.setThreadMetadata(newMetadata);
1649
1676
  if (maxChatNum > currentContext.threadCnt) {
1650
1677
  currentContext.setThreadCnt(maxChatNum);
1651
1678
  }
1679
+ if (remoteThreadIds.has(currentContext.currentThreadId)) {
1680
+ await warmThread(currentContext.currentThreadId);
1681
+ await ensureInitialState(currentContext.currentThreadId);
1682
+ }
1652
1683
  } catch (error) {
1653
1684
  console.error("Failed to fetch thread list:", error);
1654
1685
  }
1655
1686
  };
1656
1687
  void fetchThreadList();
1657
- }, [user.address, user.isConnected, aomiClientRef]);
1688
+ }, [user, aomiClientRef, ensureInitialState, warmThread]);
1658
1689
  const threadListAdapter = (0, import_react9.useMemo)(
1659
1690
  () => buildThreadListAdapter({
1660
1691
  aomiClientRef,
@@ -1842,7 +1873,7 @@ function AomiRuntimeProvider({
1842
1873
  children,
1843
1874
  backendUrl = "http://localhost:8080"
1844
1875
  }) {
1845
- const aomiClient = (0, import_react11.useMemo)(() => new import_client2.AomiClient({ baseUrl: backendUrl }), [backendUrl]);
1876
+ const aomiClient = (0, import_react11.useMemo)(() => new import_client5.AomiClient({ baseUrl: backendUrl }), [backendUrl]);
1846
1877
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThreadContextProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(NotificationContextProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(UserContextProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AomiRuntimeInner, { aomiClient, children }) }) }) });
1847
1878
  }
1848
1879
  function AomiRuntimeInner({
@@ -1857,7 +1888,7 @@ function AomiRuntimeInner({
1857
1888
  {
1858
1889
  aomiClient,
1859
1890
  sessionId: threadContext.currentThreadId,
1860
- publicKey: user.isConnected ? (_a = user.address) != null ? _a : void 0 : void 0,
1891
+ publicKey: import_client5.UserState.isConnected(user) ? (_a = import_client5.UserState.address(user)) != null ? _a : void 0 : void 0,
1861
1892
  getThreadMetadata: threadContext.getThreadMetadata,
1862
1893
  updateThreadMetadata: threadContext.updateThreadMetadata,
1863
1894
  children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(