@aomi-labs/react 0.3.20 → 0.3.21

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.js CHANGED
@@ -261,6 +261,8 @@ var ThreadStore = class {
261
261
 
262
262
  // packages/react/src/utils/model-selection.ts
263
263
  var PREFERRED_DEFAULT_MODEL_PATTERNS = [
264
+ /^claude.*opus.*4[.-]?6/i,
265
+ /^claude.*4[.-]?6.*opus/i,
264
266
  /^claude-4\.5-haiku/i,
265
267
  /^claude.*haiku/i,
266
268
  /^gpt-4o-mini/i,
@@ -304,14 +306,17 @@ function getControlSessionId(clientId, fallbackSessionId) {
304
306
 
305
307
  // packages/react/src/contexts/control-context.tsx
306
308
  import { jsx } from "react/jsx-runtime";
307
- var API_KEY_STORAGE_KEY = "aomi_api_key";
308
- var PROVIDER_KEYS_STORAGE_KEY = "aomi_provider_keys";
309
+ var API_KEY_STORAGE_KEY = "aomi_secret_key";
310
+ var BYOK_KEYS_STORAGE_KEY = "aomi_byok_keys";
309
311
  var MODEL_SELECTION_STORAGE_KEY = "aomi_model_selection";
310
- var PROVIDER_KEY_SECRET_PREFIX = "PROVIDER_KEY:";
312
+ var BYOK_SECRET_PREFIX = "PROVIDER_KEY:";
311
313
  function getDefaultApp(apps) {
312
314
  var _a;
313
315
  return apps.includes("default") ? "default" : (_a = apps[0]) != null ? _a : null;
314
316
  }
317
+ function namesFromDescriptors(apps) {
318
+ return apps.map((a) => a.name);
319
+ }
315
320
  function readStoredModelPreference() {
316
321
  var _a;
317
322
  try {
@@ -383,9 +388,10 @@ function ControlContextProvider({
383
388
  clientId: getOrCreateClientId(),
384
389
  availableModels: [],
385
390
  authorizedApps: [],
391
+ appDescriptors: [],
386
392
  defaultModel: null,
387
393
  defaultApp: null,
388
- providerKeys: {}
394
+ byokKeys: {}
389
395
  }));
390
396
  const stateRef = useRef(state);
391
397
  stateRef.current = state;
@@ -428,10 +434,10 @@ function ControlContextProvider({
428
434
  useEffect(() => {
429
435
  var _a2;
430
436
  try {
431
- const raw = (_a2 = globalThis.localStorage) == null ? void 0 : _a2.getItem(PROVIDER_KEYS_STORAGE_KEY);
437
+ const raw = (_a2 = globalThis.localStorage) == null ? void 0 : _a2.getItem(BYOK_KEYS_STORAGE_KEY);
432
438
  if (raw) {
433
439
  const parsed = JSON.parse(raw);
434
- setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), { providerKeys: parsed }));
440
+ setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), { byokKeys: parsed }));
435
441
  }
436
442
  } catch (e) {
437
443
  }
@@ -450,50 +456,53 @@ function ControlContextProvider({
450
456
  useEffect(() => {
451
457
  var _a2, _b2;
452
458
  try {
453
- const keys = state.providerKeys;
459
+ const keys = state.byokKeys;
454
460
  if (Object.keys(keys).length > 0) {
455
461
  (_a2 = globalThis.localStorage) == null ? void 0 : _a2.setItem(
456
- PROVIDER_KEYS_STORAGE_KEY,
462
+ BYOK_KEYS_STORAGE_KEY,
457
463
  JSON.stringify(keys)
458
464
  );
459
465
  } else {
460
- (_b2 = globalThis.localStorage) == null ? void 0 : _b2.removeItem(PROVIDER_KEYS_STORAGE_KEY);
466
+ (_b2 = globalThis.localStorage) == null ? void 0 : _b2.removeItem(BYOK_KEYS_STORAGE_KEY);
461
467
  }
462
468
  } catch (e) {
463
469
  }
464
- }, [state.providerKeys]);
470
+ }, [state.byokKeys]);
465
471
  useEffect(() => {
466
472
  if (!state.clientId) return;
467
- const keys = stateRef.current.providerKeys;
473
+ const keys = stateRef.current.byokKeys;
468
474
  if (Object.keys(keys).length === 0) return;
469
475
  const secrets = {};
470
476
  for (const [provider, entry] of Object.entries(keys)) {
471
- secrets[`${PROVIDER_KEY_SECRET_PREFIX}${provider}`] = entry.apiKey;
477
+ secrets[`${BYOK_SECRET_PREFIX}${provider}`] = entry.apiKey;
472
478
  }
473
479
  void aomiClientRef.current.ingestSecrets(getCurrentControlSessionId(), state.clientId, secrets).catch((err) => {
474
- console.error("Failed to auto-ingest provider keys:", err);
480
+ console.error("Failed to auto-ingest BYOK keys:", err);
475
481
  });
476
- }, [getCurrentControlSessionId, state.clientId, state.providerKeys]);
482
+ }, [getCurrentControlSessionId, state.clientId, state.byokKeys]);
477
483
  useEffect(() => {
478
484
  const fetchApps = async () => {
479
485
  var _a2;
480
486
  try {
481
- const apps = await aomiClientRef.current.getApps(
487
+ const descriptors = await aomiClientRef.current.getApps(
482
488
  getCurrentControlSessionId(),
483
489
  {
484
490
  publicKey: publicKeyRef.current,
485
491
  apiKey: (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
486
492
  }
487
493
  );
488
- const defaultApp = getDefaultApp(apps);
494
+ const names = namesFromDescriptors(descriptors);
495
+ const defaultApp = getDefaultApp(names);
489
496
  setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
490
- authorizedApps: apps,
497
+ authorizedApps: names,
498
+ appDescriptors: descriptors,
491
499
  defaultApp
492
500
  }));
493
501
  } catch (error) {
494
502
  console.error("Failed to fetch apps:", error);
495
503
  setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
496
504
  authorizedApps: ["default"],
505
+ appDescriptors: [{ name: "default" }],
497
506
  defaultApp: "default"
498
507
  }));
499
508
  }
@@ -524,29 +533,53 @@ function ControlContextProvider({
524
533
  });
525
534
  }, []);
526
535
  const ingestSecrets = useCallback(
527
- async (secrets) => {
536
+ async (secrets, app) => {
528
537
  const clientId = stateRef.current.clientId;
529
538
  if (!clientId) throw new Error("clientId not initialized");
530
539
  const { handles } = await aomiClientRef.current.ingestSecrets(
531
540
  getCurrentControlSessionId(),
532
541
  clientId,
533
- secrets
542
+ secrets,
543
+ app
534
544
  );
535
545
  return handles;
536
546
  },
537
547
  [getCurrentControlSessionId]
538
548
  );
539
- const clearSecrets = useCallback(async () => {
540
- var _a2, _b2;
541
- const clientId = stateRef.current.clientId;
542
- if (!clientId) return;
543
- await ((_b2 = (_a2 = aomiClientRef.current).clearSecrets) == null ? void 0 : _b2.call(
544
- _a2,
545
- getCurrentControlSessionId(),
546
- clientId
547
- ));
549
+ const clearSecrets = useCallback(
550
+ async (app) => {
551
+ var _a2, _b2;
552
+ const clientId = stateRef.current.clientId;
553
+ if (!clientId) return;
554
+ await ((_b2 = (_a2 = aomiClientRef.current).clearSecrets) == null ? void 0 : _b2.call(
555
+ _a2,
556
+ getCurrentControlSessionId(),
557
+ clientId,
558
+ app
559
+ ));
560
+ },
561
+ [getCurrentControlSessionId]
562
+ );
563
+ const deleteSecret = useCallback(
564
+ async (name, app) => {
565
+ const clientId = stateRef.current.clientId;
566
+ if (!clientId) return;
567
+ await aomiClientRef.current.deleteSecret(
568
+ getCurrentControlSessionId(),
569
+ clientId,
570
+ name,
571
+ app
572
+ );
573
+ },
574
+ [getCurrentControlSessionId]
575
+ );
576
+ const listSecrets = useCallback(async () => {
577
+ const { by_app } = await aomiClientRef.current.listSecrets(
578
+ getCurrentControlSessionId()
579
+ );
580
+ return by_app;
548
581
  }, [getCurrentControlSessionId]);
549
- const setProviderKey = useCallback(
582
+ const setByok = useCallback(
550
583
  async (provider, apiKey, label) => {
551
584
  const trimmed = apiKey.trim();
552
585
  if (!trimmed) return;
@@ -557,7 +590,7 @@ function ControlContextProvider({
557
590
  };
558
591
  setStateInternal((prev) => {
559
592
  const next = __spreadProps(__spreadValues({}, prev), {
560
- providerKeys: __spreadProps(__spreadValues({}, prev.providerKeys), { [provider]: entry })
593
+ byokKeys: __spreadProps(__spreadValues({}, prev.byokKeys), { [provider]: entry })
561
594
  });
562
595
  callbacks.current.forEach((cb) => cb(next));
563
596
  return next;
@@ -569,41 +602,41 @@ function ControlContextProvider({
569
602
  getCurrentControlSessionId(),
570
603
  clientId,
571
604
  {
572
- [`${PROVIDER_KEY_SECRET_PREFIX}${provider}`]: trimmed
605
+ [`${BYOK_SECRET_PREFIX}${provider}`]: trimmed
573
606
  }
574
607
  );
575
608
  } catch (err) {
576
- console.error("Failed to ingest provider key:", err);
609
+ console.error("Failed to ingest BYOK key:", err);
577
610
  }
578
611
  }
579
612
  },
580
613
  [getCurrentControlSessionId]
581
614
  );
582
- const removeProviderKey = useCallback(
615
+ const removeByok = useCallback(
583
616
  async (provider) => {
584
617
  const clientId = stateRef.current.clientId;
585
618
  if (clientId) {
586
619
  await aomiClientRef.current.deleteSecret(
587
620
  getCurrentControlSessionId(),
588
621
  clientId,
589
- `${PROVIDER_KEY_SECRET_PREFIX}${provider}`
622
+ `${BYOK_SECRET_PREFIX}${provider}`
590
623
  );
591
624
  }
592
625
  setStateInternal((prev) => {
593
- const _a2 = prev.providerKeys, { [provider]: _ } = _a2, rest = __objRest(_a2, [__restKey(provider)]);
594
- const next = __spreadProps(__spreadValues({}, prev), { providerKeys: rest });
626
+ const _a2 = prev.byokKeys, { [provider]: _ } = _a2, rest = __objRest(_a2, [__restKey(provider)]);
627
+ const next = __spreadProps(__spreadValues({}, prev), { byokKeys: rest });
595
628
  callbacks.current.forEach((cb) => cb(next));
596
629
  return next;
597
630
  });
598
631
  },
599
632
  [getCurrentControlSessionId]
600
633
  );
601
- const getProviderKeys = useCallback(
602
- () => stateRef.current.providerKeys,
634
+ const getByokKeys = useCallback(
635
+ () => stateRef.current.byokKeys,
603
636
  []
604
637
  );
605
- const hasProviderKey = useCallback((provider) => {
606
- const keys = stateRef.current.providerKeys;
638
+ const hasByok = useCallback((provider) => {
639
+ const keys = stateRef.current.byokKeys;
607
640
  if (provider) return provider in keys;
608
641
  return Object.keys(keys).length > 0;
609
642
  }, []);
@@ -625,23 +658,26 @@ function ControlContextProvider({
625
658
  const getAuthorizedApps = useCallback(async () => {
626
659
  var _a2;
627
660
  try {
628
- const apps = await aomiClientRef.current.getApps(
661
+ const descriptors = await aomiClientRef.current.getApps(
629
662
  getCurrentControlSessionId(),
630
663
  {
631
664
  publicKey: publicKeyRef.current,
632
665
  apiKey: (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
633
666
  }
634
667
  );
635
- const defaultApp = getDefaultApp(apps);
668
+ const names = namesFromDescriptors(descriptors);
669
+ const defaultApp = getDefaultApp(names);
636
670
  setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
637
- authorizedApps: apps,
671
+ authorizedApps: names,
672
+ appDescriptors: descriptors,
638
673
  defaultApp
639
674
  }));
640
- return apps;
675
+ return names;
641
676
  } catch (error) {
642
677
  console.error("Failed to fetch apps:", error);
643
678
  setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
644
679
  authorizedApps: ["default"],
680
+ appDescriptors: [{ name: "default" }],
645
681
  defaultApp: "default"
646
682
  }));
647
683
  return ["default"];
@@ -896,10 +932,12 @@ function ControlContextProvider({
896
932
  setApiKey,
897
933
  ingestSecrets,
898
934
  clearSecrets,
899
- setProviderKey,
900
- removeProviderKey,
901
- getProviderKeys,
902
- hasProviderKey,
935
+ deleteSecret,
936
+ listSecrets,
937
+ setByok,
938
+ removeByok,
939
+ getByokKeys,
940
+ hasByok,
903
941
  getAvailableModels,
904
942
  getAuthorizedApps,
905
943
  getCurrentThreadControl,
@@ -999,6 +1037,7 @@ import {
999
1037
  createContext as createContext3,
1000
1038
  useCallback as useCallback3,
1001
1039
  useContext as useContext3,
1040
+ useRef as useRef3,
1002
1041
  useState as useState2
1003
1042
  } from "react";
1004
1043
  import { jsx as jsx3 } from "react/jsx-runtime";
@@ -1020,19 +1059,30 @@ function NotificationContextProvider({
1020
1059
  children
1021
1060
  }) {
1022
1061
  const [notifications, setNotifications] = useState2([]);
1062
+ const paymentRequiredIdRef = useRef3(null);
1023
1063
  const showNotification = useCallback3((params) => {
1064
+ if (params.kind === "payment_required" && paymentRequiredIdRef.current) {
1065
+ return paymentRequiredIdRef.current;
1066
+ }
1024
1067
  const id = generateId();
1025
1068
  const notification = __spreadProps(__spreadValues({}, params), {
1026
1069
  id,
1027
1070
  timestamp: Date.now()
1028
1071
  });
1072
+ if (params.kind === "payment_required") {
1073
+ paymentRequiredIdRef.current = id;
1074
+ }
1029
1075
  setNotifications((prev) => [notification, ...prev]);
1030
1076
  return id;
1031
1077
  }, []);
1032
1078
  const dismissNotification = useCallback3((id) => {
1079
+ if (paymentRequiredIdRef.current === id) {
1080
+ paymentRequiredIdRef.current = null;
1081
+ }
1033
1082
  setNotifications((prev) => prev.filter((n) => n.id !== id));
1034
1083
  }, []);
1035
1084
  const clearAll = useCallback3(() => {
1085
+ paymentRequiredIdRef.current = null;
1036
1086
  setNotifications([]);
1037
1087
  }, []);
1038
1088
  const value = {
@@ -1049,7 +1099,7 @@ import {
1049
1099
  createContext as createContext4,
1050
1100
  useContext as useContext4,
1051
1101
  useMemo,
1052
- useRef as useRef3,
1102
+ useRef as useRef4,
1053
1103
  useSyncExternalStore
1054
1104
  } from "react";
1055
1105
  import { jsx as jsx4 } from "react/jsx-runtime";
@@ -1067,7 +1117,7 @@ function ThreadContextProvider({
1067
1117
  children,
1068
1118
  initialThreadId
1069
1119
  }) {
1070
- const storeRef = useRef3(null);
1120
+ const storeRef = useRef4(null);
1071
1121
  if (!storeRef.current) {
1072
1122
  storeRef.current = new ThreadStore({ initialThreadId });
1073
1123
  }
@@ -1094,22 +1144,22 @@ function useCurrentThreadMetadata() {
1094
1144
  );
1095
1145
  }
1096
1146
 
1097
- // packages/react/src/contexts/user-context.tsx
1147
+ // packages/react/src/contexts/ext-user-context.tsx
1098
1148
  import {
1099
1149
  createContext as createContext5,
1100
1150
  useCallback as useCallback4,
1101
1151
  useContext as useContext5,
1102
- useRef as useRef4,
1152
+ useRef as useRef5,
1103
1153
  useState as useState3
1104
1154
  } from "react";
1105
1155
  import { UserState } from "@aomi-labs/client";
1106
1156
  import { UserState as UserState2 } from "@aomi-labs/client";
1107
- import { jsx as jsx5 } from "react/jsx-runtime";
1157
+ import { Fragment, jsx as jsx5 } from "react/jsx-runtime";
1108
1158
  var UserContext = createContext5(void 0);
1109
1159
  function useUser() {
1110
1160
  const context = useContext5(UserContext);
1111
1161
  if (!context) {
1112
- throw new Error("useUser must be used within UserContextProvider");
1162
+ throw new Error("useUser must be used within ExtUserProvider");
1113
1163
  }
1114
1164
  return {
1115
1165
  user: context.user,
@@ -1120,7 +1170,14 @@ function useUser() {
1120
1170
  onUserStateChange: context.onUserStateChange
1121
1171
  };
1122
1172
  }
1123
- function UserContextProvider({ children }) {
1173
+ function ExtUserProvider({ children }) {
1174
+ const parent = useContext5(UserContext);
1175
+ if (parent) {
1176
+ return /* @__PURE__ */ jsx5(Fragment, { children });
1177
+ }
1178
+ return /* @__PURE__ */ jsx5(ExtUserProviderImpl, { children });
1179
+ }
1180
+ function ExtUserProviderImpl({ children }) {
1124
1181
  const [user, setUserState] = useState3({
1125
1182
  address: void 0,
1126
1183
  chain_id: void 0,
@@ -1128,9 +1185,9 @@ function UserContextProvider({ children }) {
1128
1185
  ens_name: void 0,
1129
1186
  ext: void 0
1130
1187
  });
1131
- const userRef = useRef4(user);
1188
+ const userRef = useRef5(user);
1132
1189
  userRef.current = user;
1133
- const StateChangeCallbacks = useRef4(
1190
+ const StateChangeCallbacks = useRef5(
1134
1191
  /* @__PURE__ */ new Set()
1135
1192
  );
1136
1193
  const notifyStateChange = useCallback4((next) => {
@@ -1147,7 +1204,7 @@ function UserContextProvider({ children }) {
1147
1204
  }, []);
1148
1205
  const setUser = useCallback4((data) => {
1149
1206
  setUserState((prev) => {
1150
- var _a, _b, _c;
1207
+ var _a, _b;
1151
1208
  const normalizedData = pruneUndefined((_a = UserState.normalize(data)) != null ? _a : {});
1152
1209
  const nextPartial = __spreadValues({}, normalizedData);
1153
1210
  if (nextPartial.is_connected === true && nextPartial.chain_id === void 0) {
@@ -1157,11 +1214,41 @@ function UserContextProvider({ children }) {
1157
1214
  delete nextPartial.is_connected;
1158
1215
  }
1159
1216
  }
1160
- const next = nextPartial.is_connected === false ? __spreadProps(__spreadValues({}, (_b = UserState.normalize(__spreadValues(__spreadValues({}, prev), nextPartial))) != null ? _b : prev), {
1161
- address: void 0,
1162
- chain_id: void 0,
1163
- ens_name: void 0
1164
- }) : (_c = UserState.normalize(__spreadValues(__spreadValues({}, prev), nextPartial))) != null ? _c : prev;
1217
+ const merged = (_b = UserState.normalize(__spreadValues(__spreadValues({}, prev), nextPartial))) != null ? _b : prev;
1218
+ let next;
1219
+ if (nextPartial.is_connected === false) {
1220
+ next = __spreadProps(__spreadValues({}, merged), {
1221
+ address: void 0,
1222
+ chain_id: void 0,
1223
+ ens_name: void 0,
1224
+ wallet_kind: void 0,
1225
+ aa_mode: void 0,
1226
+ smart_account_4337: void 0,
1227
+ delegation_7702: void 0,
1228
+ svm_address: void 0,
1229
+ wallet_provider: void 0,
1230
+ auth_method: void 0,
1231
+ sponsored: void 0,
1232
+ sponsor_provider: void 0,
1233
+ sponsor_account: void 0,
1234
+ pending_txs: void 0,
1235
+ pending_eip712s: void 0,
1236
+ pending_solana_txs: void 0
1237
+ });
1238
+ } else {
1239
+ const prevAddress = UserState.address(prev);
1240
+ const nextAddress = UserState.address(merged);
1241
+ const addressChanged = prevAddress !== void 0 && nextAddress !== void 0 && prevAddress.toLowerCase() !== nextAddress.toLowerCase();
1242
+ next = addressChanged ? __spreadProps(__spreadValues({}, merged), {
1243
+ aa_mode: void 0,
1244
+ smart_account_4337: void 0,
1245
+ delegation_7702: void 0,
1246
+ ens_name: void 0,
1247
+ pending_txs: void 0,
1248
+ pending_eip712s: void 0,
1249
+ pending_solana_txs: void 0
1250
+ }) : merged;
1251
+ }
1165
1252
  notifyStateChange(next);
1166
1253
  return next;
1167
1254
  });
@@ -1215,7 +1302,7 @@ function UserContextProvider({ children }) {
1215
1302
  }
1216
1303
 
1217
1304
  // packages/react/src/runtime/core.tsx
1218
- import { useCallback as useCallback8, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef8, useState as useState7 } from "react";
1305
+ import { useCallback as useCallback8, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef9, useState as useState7 } from "react";
1219
1306
  import {
1220
1307
  AssistantRuntimeProvider,
1221
1308
  useExternalStoreRuntime
@@ -1223,7 +1310,7 @@ import {
1223
1310
  import { UserState as UserState3 } from "@aomi-labs/client";
1224
1311
 
1225
1312
  // packages/react/src/runtime/orchestrator.ts
1226
- import { useCallback as useCallback5, useEffect as useEffect2, useRef as useRef5, useState as useState4 } from "react";
1313
+ import { useCallback as useCallback5, useEffect as useEffect2, useRef as useRef6, useState as useState4 } from "react";
1227
1314
  import { CLIENT_TYPE_WEB_UI } from "@aomi-labs/client";
1228
1315
 
1229
1316
  // packages/react/src/runtime/session-manager.ts
@@ -1286,6 +1373,9 @@ var SessionManager = class {
1286
1373
  };
1287
1374
 
1288
1375
  // packages/react/src/runtime/utils.ts
1376
+ import {
1377
+ SUPPORTED_CHAINS as CLIENT_SUPPORTED_CHAINS
1378
+ } from "@aomi-labs/client";
1289
1379
  import { clsx } from "clsx";
1290
1380
  import { twMerge } from "tailwind-merge";
1291
1381
  function cn(...inputs) {
@@ -1313,7 +1403,7 @@ function toInboundMessage(msg) {
1313
1403
  if (msg.sender === "system") return null;
1314
1404
  const content = [];
1315
1405
  const role = msg.sender === "user" ? "user" : "assistant";
1316
- if (msg.content) {
1406
+ if (msg.content && msg.content.trim().length > 0) {
1317
1407
  content.push({ type: "text", text: msg.content });
1318
1408
  }
1319
1409
  const [topic, toolContent] = (_a = parseToolPayload(msg)) != null ? _a : [];
@@ -1332,9 +1422,12 @@ function toInboundMessage(msg) {
1332
1422
  })()
1333
1423
  });
1334
1424
  }
1425
+ if (content.length === 0 && role === "assistant" && !msg.is_streaming) {
1426
+ return null;
1427
+ }
1335
1428
  const threadMessage = __spreadValues({
1336
1429
  role,
1337
- content: content.length > 0 ? content : [{ type: "text", text: "" }]
1430
+ content
1338
1431
  }, msg.timestamp && { createdAt: new Date(msg.timestamp) });
1339
1432
  return threadMessage;
1340
1433
  }
@@ -1365,10 +1458,14 @@ var getNetworkName = (chainId) => {
1365
1458
  return "optimism";
1366
1459
  case 11155111:
1367
1460
  return "sepolia";
1461
+ case 143:
1462
+ return "monad";
1463
+ case 10143:
1464
+ return "monad-testnet";
1368
1465
  case 1337:
1369
1466
  case 31337:
1370
1467
  return "testnet";
1371
- case 59140:
1468
+ case 59141:
1372
1469
  return "linea-sepolia";
1373
1470
  case 59144:
1374
1471
  return "linea";
@@ -1377,18 +1474,37 @@ var getNetworkName = (chainId) => {
1377
1474
  }
1378
1475
  };
1379
1476
  var formatAddress = (addr) => addr ? `${addr.slice(0, 6)}...${addr.slice(-4)}` : "Connect Wallet";
1380
- var SUPPORTED_CHAINS = [
1381
- { id: 1, name: "Ethereum", ticker: "ETH" },
1382
- { id: 137, name: "Polygon", ticker: "MATIC" },
1383
- { id: 42161, name: "Arbitrum", ticker: "ARB" },
1384
- { id: 8453, name: "Base", ticker: "BASE" },
1385
- { id: 10, name: "Optimism", ticker: "OP" },
1386
- { id: 11155111, name: "Sepolia", ticker: "SEP" }
1387
- ];
1477
+ var SUPPORTED_CHAINS = [...CLIENT_SUPPORTED_CHAINS];
1388
1478
  var getChainInfo = (chainId) => chainId === void 0 ? void 0 : SUPPORTED_CHAINS.find((c) => c.id === chainId);
1389
1479
 
1390
1480
  // packages/react/src/runtime/orchestrator.ts
1391
1481
  var toErrorMessage = (error) => error instanceof Error ? error.message : "Message failed to send";
1482
+ var getHttpStatus = (error) => {
1483
+ const status = error == null ? void 0 : error.status;
1484
+ if (typeof status === "number") return status;
1485
+ const message = toErrorMessage(error);
1486
+ const match = /\bHTTP\s+(\d{3})\b/i.exec(message);
1487
+ return match ? Number(match[1]) : void 0;
1488
+ };
1489
+ var isPaymentRequiredError = (error) => getHttpStatus(error) === 402;
1490
+ var PAYMENT_REQUIRED_MESSAGE = "You're out of funds, please set up a payment method.";
1491
+ var buildPaymentRequiredMessage = () => ({
1492
+ id: `aomi-payment-required-${Date.now()}`,
1493
+ role: "assistant",
1494
+ content: [
1495
+ {
1496
+ type: "text",
1497
+ text: PAYMENT_REQUIRED_MESSAGE
1498
+ }
1499
+ ],
1500
+ createdAt: /* @__PURE__ */ new Date(),
1501
+ metadata: {
1502
+ custom: {
1503
+ aomiNoticeKind: "payment_required",
1504
+ aomiNoticeTitle: "Credits needed"
1505
+ }
1506
+ }
1507
+ });
1392
1508
  var getOptimisticStatus = (message) => {
1393
1509
  var _a, _b;
1394
1510
  const status = (_b = (_a = message.metadata) == null ? void 0 : _a.custom) == null ? void 0 : _b.aomiSendStatus;
@@ -1426,23 +1542,39 @@ var updateOptimisticMessage = (threadContext, threadId, messageId, status, error
1426
1542
  threadContext.setThreadMessages(threadId, nextMessages);
1427
1543
  }
1428
1544
  };
1545
+ var appendPaymentRequiredMessage = (threadContext, threadId) => {
1546
+ var _a, _b;
1547
+ const messages = threadContext.getThreadMessages(threadId);
1548
+ let hasPaymentNotice = false;
1549
+ for (let i = messages.length - 1; i >= 0; i--) {
1550
+ const message = messages[i];
1551
+ if (message.role !== "assistant") continue;
1552
+ hasPaymentNotice = ((_b = (_a = message.metadata) == null ? void 0 : _a.custom) == null ? void 0 : _b.aomiNoticeKind) === "payment_required";
1553
+ break;
1554
+ }
1555
+ if (hasPaymentNotice) return;
1556
+ threadContext.setThreadMessages(threadId, [
1557
+ ...messages,
1558
+ buildPaymentRequiredMessage()
1559
+ ]);
1560
+ };
1429
1561
  function useRuntimeOrchestrator(aomiClient, options) {
1430
1562
  const threadContext = useThreadContext();
1431
- const threadContextRef = useRef5(threadContext);
1563
+ const threadContextRef = useRef6(threadContext);
1432
1564
  threadContextRef.current = threadContext;
1433
- const aomiClientRef = useRef5(aomiClient);
1565
+ const aomiClientRef = useRef6(aomiClient);
1434
1566
  aomiClientRef.current = aomiClient;
1435
- const optionsRef = useRef5(options);
1567
+ const optionsRef = useRef6(options);
1436
1568
  optionsRef.current = options;
1437
1569
  const [isRunning, setIsRunning] = useState4(false);
1438
- const sessionManagerRef = useRef5(null);
1570
+ const sessionManagerRef = useRef6(null);
1439
1571
  if (!sessionManagerRef.current) {
1440
1572
  sessionManagerRef.current = new SessionManager(() => aomiClientRef.current);
1441
1573
  }
1442
- const pendingFetches = useRef5(/* @__PURE__ */ new Set());
1443
- const initialStatePromises = useRef5(/* @__PURE__ */ new Map());
1444
- const hydratedThreadIds = useRef5(/* @__PURE__ */ new Set());
1445
- const listenerCleanups = useRef5(/* @__PURE__ */ new Map());
1574
+ const pendingFetches = useRef6(/* @__PURE__ */ new Set());
1575
+ const initialStatePromises = useRef6(/* @__PURE__ */ new Map());
1576
+ const hydratedThreadIds = useRef6(/* @__PURE__ */ new Set());
1577
+ const listenerCleanups = useRef6(/* @__PURE__ */ new Map());
1446
1578
  const cleanupSessionListeners = useCallback5((threadId) => {
1447
1579
  var _a;
1448
1580
  (_a = listenerCleanups.current.get(threadId)) == null ? void 0 : _a();
@@ -1633,7 +1765,7 @@ function useRuntimeOrchestrator(aomiClient, options) {
1633
1765
  );
1634
1766
  const sendMessage = useCallback5(
1635
1767
  async (text, threadId) => {
1636
- var _a, _b, _c, _d;
1768
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1637
1769
  const existingMessages = threadContextRef.current.getThreadMessages(threadId);
1638
1770
  const optimisticMessageId = String(existingMessages.length);
1639
1771
  const userMessage = {
@@ -1662,6 +1794,7 @@ function useRuntimeOrchestrator(aomiClient, options) {
1662
1794
  await ((_b = (_a = optionsRef.current).prepareThreadForSend) == null ? void 0 : _b.call(_a, threadId));
1663
1795
  const session = getSession(threadId);
1664
1796
  await session.sendAsync(text);
1797
+ (_d = (_c = optionsRef.current).onSendSuccess) == null ? void 0 : _d.call(_c, threadId);
1665
1798
  if (threadContextRef.current.currentThreadId === threadId) {
1666
1799
  setIsRunning(session.getIsProcessing());
1667
1800
  }
@@ -1671,8 +1804,8 @@ function useRuntimeOrchestrator(aomiClient, options) {
1671
1804
  optimisticMessageId,
1672
1805
  "sent"
1673
1806
  );
1674
- (_d = (_c = optionsRef.current).onPendingRequestsChange) == null ? void 0 : _d.call(
1675
- _c,
1807
+ (_f = (_e = optionsRef.current).onPendingRequestsChange) == null ? void 0 : _f.call(
1808
+ _e,
1676
1809
  session.getPendingRequests()
1677
1810
  );
1678
1811
  } catch (error) {
@@ -1686,6 +1819,10 @@ function useRuntimeOrchestrator(aomiClient, options) {
1686
1819
  "failed",
1687
1820
  error
1688
1821
  );
1822
+ if (isPaymentRequiredError(error)) {
1823
+ appendPaymentRequiredMessage(threadContextRef.current, threadId);
1824
+ }
1825
+ await ((_h = (_g = optionsRef.current).onSendError) == null ? void 0 : _h.call(_g, threadId, error));
1689
1826
  throw error;
1690
1827
  }
1691
1828
  },
@@ -1892,14 +2029,14 @@ function useAomiRuntime() {
1892
2029
  }
1893
2030
 
1894
2031
  // packages/react/src/handlers/wallet-handler.ts
1895
- import { useCallback as useCallback6, useRef as useRef6, useState as useState5 } from "react";
2032
+ import { useCallback as useCallback6, useRef as useRef7, useState as useState5 } from "react";
1896
2033
  function useWalletHandler({
1897
2034
  getSession
1898
2035
  }) {
1899
2036
  const [pendingRequests, setPendingRequests] = useState5([]);
1900
- const requestsRef = useRef6(pendingRequests);
1901
- const inFlightRequestSetRef = useRef6(/* @__PURE__ */ new Set());
1902
- const suppressedRequestSetRef = useRef6(/* @__PURE__ */ new Set());
2037
+ const requestsRef = useRef7(pendingRequests);
2038
+ const inFlightRequestSetRef = useRef7(/* @__PURE__ */ new Set());
2039
+ const suppressedRequestSetRef = useRef7(/* @__PURE__ */ new Set());
1903
2040
  const syncVisibleRequests = useCallback6(() => {
1904
2041
  setPendingRequests(
1905
2042
  requestsRef.current.filter(
@@ -1985,11 +2122,11 @@ function useWalletHandler({
1985
2122
  import {
1986
2123
  useCallback as useCallback7,
1987
2124
  useEffect as useEffect3,
1988
- useRef as useRef7,
2125
+ useRef as useRef8,
1989
2126
  useState as useState6
1990
2127
  } from "react";
1991
2128
  import { UserState as UserStateHelpers } from "@aomi-labs/client";
1992
- import { Fragment, jsx as jsx6 } from "react/jsx-runtime";
2129
+ import { Fragment as Fragment2, jsx as jsx6 } from "react/jsx-runtime";
1993
2130
  var THREAD_PREFETCH_LIMIT = 5;
1994
2131
  var PREFETCH_IDLE_TIMEOUT_MS = 1500;
1995
2132
  function scheduleBackgroundTask(task) {
@@ -2015,17 +2152,24 @@ function useWalletStateSync(context, sessions, remoteThreads) {
2015
2152
  const { remoteThreadIdsRef } = remoteThreads;
2016
2153
  const walletSnapshot = useCallback7(
2017
2154
  (nextUser) => {
2018
- var _a;
2155
+ var _a, _b, _c, _d, _e, _f, _g, _h;
2019
2156
  return {
2020
2157
  address: UserStateHelpers.address(nextUser),
2021
2158
  chain_id: UserStateHelpers.chainId(nextUser),
2022
2159
  is_connected: (_a = UserStateHelpers.isConnected(nextUser)) != null ? _a : false,
2023
- ens_name: typeof nextUser.ens_name === "string" ? nextUser.ens_name : void 0
2160
+ ens_name: typeof nextUser.ens_name === "string" ? nextUser.ens_name : void 0,
2161
+ wallet_provider: (_b = UserStateHelpers.walletProvider(nextUser)) != null ? _b : void 0,
2162
+ auth_method: (_c = UserStateHelpers.authMethod(nextUser)) != null ? _c : void 0,
2163
+ sponsored: (_d = UserStateHelpers.sponsored(nextUser)) != null ? _d : void 0,
2164
+ sponsor_provider: (_e = UserStateHelpers.sponsorProvider(nextUser)) != null ? _e : void 0,
2165
+ sponsor_account: (_f = UserStateHelpers.sponsorAccount(nextUser)) != null ? _f : void 0,
2166
+ smart_account_4337: (_g = UserStateHelpers.SmartAccount4337(nextUser)) != null ? _g : void 0,
2167
+ delegation_7702: (_h = UserStateHelpers.Delegation7702(nextUser)) != null ? _h : void 0
2024
2168
  };
2025
2169
  },
2026
2170
  [getUserState]
2027
2171
  );
2028
- const lastWalletStateRef = useRef7(walletSnapshot(getUserState()));
2172
+ const lastWalletStateRef = useRef8(walletSnapshot(getUserState()));
2029
2173
  useEffect3(() => {
2030
2174
  lastWalletStateRef.current = walletSnapshot(getUserState());
2031
2175
  const unsubscribe = onUserStateChange(async (newUser) => {
@@ -2034,7 +2178,7 @@ function useWalletStateSync(context, sessions, remoteThreads) {
2034
2178
  const prevWalletState = lastWalletStateRef.current;
2035
2179
  const previousAddress = (_a = prevWalletState.address) == null ? void 0 : _a.toLowerCase();
2036
2180
  const nextAddress = (_b = nextWalletState.address) == null ? void 0 : _b.toLowerCase();
2037
- if (prevWalletState.address === nextWalletState.address && prevWalletState.chain_id === nextWalletState.chain_id && prevWalletState.is_connected === nextWalletState.is_connected && prevWalletState.ens_name === nextWalletState.ens_name) {
2181
+ if (prevWalletState.address === nextWalletState.address && prevWalletState.chain_id === nextWalletState.chain_id && prevWalletState.is_connected === nextWalletState.is_connected && prevWalletState.ens_name === nextWalletState.ens_name && prevWalletState.wallet_provider === nextWalletState.wallet_provider && prevWalletState.auth_method === nextWalletState.auth_method && prevWalletState.sponsored === nextWalletState.sponsored && prevWalletState.sponsor_provider === nextWalletState.sponsor_provider && prevWalletState.sponsor_account === nextWalletState.sponsor_account && prevWalletState.smart_account_4337 === nextWalletState.smart_account_4337 && prevWalletState.delegation_7702 === nextWalletState.delegation_7702) {
2038
2182
  return;
2039
2183
  }
2040
2184
  lastWalletStateRef.current = nextWalletState;
@@ -2082,8 +2226,8 @@ function useUserStateRequestResponder(context, sessions) {
2082
2226
  }
2083
2227
  function useRemoteThreadListSync(context, sessions, remoteThreads) {
2084
2228
  const [isThreadListLoading, setIsThreadListLoading] = useState6(true);
2085
- const prefetchCancelRef = useRef7(null);
2086
- const lastConnectedAddressRef = useRef7(void 0);
2229
+ const prefetchCancelRef = useRef8(null);
2230
+ const lastConnectedAddressRef = useRef8(void 0);
2087
2231
  const {
2088
2232
  getControlState,
2089
2233
  threadContextRef,
@@ -2102,6 +2246,7 @@ function useRemoteThreadListSync(context, sessions, remoteThreads) {
2102
2246
  warmedThreadIdsRef,
2103
2247
  warmThread
2104
2248
  } = remoteThreads;
2249
+ const connectedAddress = UserStateHelpers.isConnected(user) ? UserStateHelpers.address(user) : void 0;
2105
2250
  const scheduleThreadPrefetch = useCallback7(
2106
2251
  (threadIds) => {
2107
2252
  var _a;
@@ -2140,7 +2285,7 @@ function useRemoteThreadListSync(context, sessions, remoteThreads) {
2140
2285
  );
2141
2286
  useEffect3(() => {
2142
2287
  var _a, _b;
2143
- const userAddress = UserStateHelpers.isConnected(user) ? UserStateHelpers.address(user) : void 0;
2288
+ const userAddress = connectedAddress;
2144
2289
  const normalizedUserAddress = userAddress == null ? void 0 : userAddress.toLowerCase();
2145
2290
  const previousAddress = lastConnectedAddressRef.current;
2146
2291
  const walletChanged = previousAddress !== void 0 && normalizedUserAddress !== void 0 && previousAddress !== normalizedUserAddress;
@@ -2181,6 +2326,7 @@ function useRemoteThreadListSync(context, sessions, remoteThreads) {
2181
2326
  getControlState().clientId,
2182
2327
  resetThreadId != null ? resetThreadId : currentContext.currentThreadId
2183
2328
  );
2329
+ await aomiClientRef.current.ensureAccount(controlSessionId, userAddress);
2184
2330
  const threadList = await aomiClientRef.current.listThreads(
2185
2331
  controlSessionId,
2186
2332
  userAddress
@@ -2270,7 +2416,7 @@ function useRemoteThreadListSync(context, sessions, remoteThreads) {
2270
2416
  sessionManager,
2271
2417
  setIsThreadLoading,
2272
2418
  threadContextRef,
2273
- user,
2419
+ connectedAddress,
2274
2420
  warmPromisesRef,
2275
2421
  warmedThreadIdsRef,
2276
2422
  warmThread
@@ -2291,7 +2437,7 @@ function useRuntimeUserStateEffects({
2291
2437
  const threadContext = useThreadContext();
2292
2438
  const { user, getUserState, onUserStateChange } = useUser();
2293
2439
  const { getControlState } = useControl();
2294
- const threadContextRef = useRef7(threadContext);
2440
+ const threadContextRef = useRef8(threadContext);
2295
2441
  threadContextRef.current = threadContext;
2296
2442
  const context = {
2297
2443
  getControlState,
@@ -2316,9 +2462,10 @@ function RuntimeUserStateProvider({
2316
2462
  children,
2317
2463
  sessionManager,
2318
2464
  getUserState,
2465
+ setUser,
2319
2466
  onUserStateChange
2320
2467
  }) {
2321
- const lastSerializedStateRef = useRef7("");
2468
+ const lastSerializedStateRef = useRef8("");
2322
2469
  useEffect3(() => {
2323
2470
  const applyToSessions = (next) => {
2324
2471
  const serialized = stableStateString(next);
@@ -2327,20 +2474,40 @@ function RuntimeUserStateProvider({
2327
2474
  }
2328
2475
  lastSerializedStateRef.current = serialized;
2329
2476
  sessionManager.forEach((session) => {
2330
- session.resolveUserState(next);
2477
+ session.resolveUserState(next, { skipEmit: true });
2331
2478
  });
2332
2479
  };
2480
+ const sessionListeners = [];
2481
+ sessionManager.forEach((session) => {
2482
+ const handler = (next) => {
2483
+ setUser(next);
2484
+ };
2485
+ session.on("user_state_updated", handler);
2486
+ sessionListeners.push(
2487
+ () => session.off("user_state_updated", handler)
2488
+ );
2489
+ });
2333
2490
  applyToSessions(getUserState());
2334
2491
  const unsubscribe = onUserStateChange((next) => {
2335
2492
  applyToSessions(next);
2336
2493
  });
2337
- return unsubscribe;
2338
- }, [getUserState, onUserStateChange, sessionManager]);
2339
- return /* @__PURE__ */ jsx6(Fragment, { children });
2494
+ return () => {
2495
+ unsubscribe();
2496
+ sessionListeners.forEach((off) => off());
2497
+ };
2498
+ }, [getUserState, onUserStateChange, sessionManager, setUser]);
2499
+ return /* @__PURE__ */ jsx6(Fragment2, { children });
2340
2500
  }
2341
2501
 
2342
2502
  // packages/react/src/runtime/core.tsx
2343
2503
  import { jsx as jsx7 } from "react/jsx-runtime";
2504
+ var getHttpStatus2 = (error) => {
2505
+ const status = error == null ? void 0 : error.status;
2506
+ if (typeof status === "number") return status;
2507
+ const message = error instanceof Error ? error.message : String(error);
2508
+ const match = /\bHTTP\s+(\d{3})\b/i.exec(message);
2509
+ return match ? Number(match[1]) : void 0;
2510
+ };
2344
2511
  function AomiRuntimeCore({
2345
2512
  children,
2346
2513
  aomiClient
@@ -2355,7 +2522,7 @@ function AomiRuntimeCore({
2355
2522
  getPreferredThreadControl,
2356
2523
  syncCurrentThreadControl
2357
2524
  } = useControl();
2358
- const sessionManagerRef = useRef8(null);
2525
+ const sessionManagerRef = useRef9(null);
2359
2526
  const walletHandler = useWalletHandler({
2360
2527
  getSession: () => {
2361
2528
  var _a;
@@ -2384,19 +2551,68 @@ function AomiRuntimeCore({
2384
2551
  return (_a = getControlState().clientId) != null ? _a : void 0;
2385
2552
  },
2386
2553
  prepareThreadForSend: async (threadId) => {
2387
- await ensureBackendThread(threadId);
2388
2554
  await syncCurrentThreadControl();
2555
+ const wasCreated = await ensureBackendThread(threadId);
2556
+ if (wasCreated) {
2557
+ threadsMaterializedForSendRef.current.add(threadId);
2558
+ }
2559
+ },
2560
+ onSendSuccess: (threadId) => {
2561
+ const wasRemote = remoteThreadIdsRef.current.has(threadId);
2562
+ remoteThreadIdsRef.current.add(threadId);
2563
+ warmedThreadIdsRef.current.add(threadId);
2564
+ threadsMaterializedForSendRef.current.delete(threadId);
2565
+ if (!wasRemote && threadContextRef.current.currentThreadId === threadId) {
2566
+ void syncCurrentThreadControl().catch((error) => {
2567
+ console.error("Failed to sync thread controls:", error);
2568
+ });
2569
+ }
2570
+ },
2571
+ onSendError: async (threadId, error) => {
2572
+ const wasMaterializedForSend = threadsMaterializedForSendRef.current.has(threadId);
2573
+ threadsMaterializedForSendRef.current.delete(threadId);
2574
+ const httpStatus = getHttpStatus2(error);
2575
+ if (httpStatus === 402) {
2576
+ notificationContext.showNotification({
2577
+ type: "error",
2578
+ kind: "payment_required",
2579
+ title: "You're out of funds"
2580
+ });
2581
+ }
2582
+ if (httpStatus !== 402 || !wasMaterializedForSend) {
2583
+ return;
2584
+ }
2585
+ try {
2586
+ await aomiClientRef.current.deleteThread(threadId);
2587
+ remoteThreadIdsRef.current.delete(threadId);
2588
+ warmedThreadIdsRef.current.delete(threadId);
2589
+ } catch (deleteError) {
2590
+ console.error("Failed to delete quota-blocked thread:", deleteError);
2591
+ }
2389
2592
  },
2390
2593
  onPendingRequestsChange: walletHandler.setRequests,
2391
2594
  onEvent: (event) => eventContext.dispatch(event)
2392
2595
  });
2393
2596
  sessionManagerRef.current = sessionManager;
2394
- const threadContextRef = useRef8(threadContext);
2597
+ const threadContextRef = useRef9(threadContext);
2395
2598
  threadContextRef.current = threadContext;
2396
- const remoteThreadIdsRef = useRef8(/* @__PURE__ */ new Set());
2397
- const warmedThreadIdsRef = useRef8(/* @__PURE__ */ new Set());
2398
- const warmPromisesRef = useRef8(/* @__PURE__ */ new Map());
2599
+ const remoteThreadIdsRef = useRef9(/* @__PURE__ */ new Set());
2600
+ const warmedThreadIdsRef = useRef9(/* @__PURE__ */ new Set());
2601
+ const warmPromisesRef = useRef9(/* @__PURE__ */ new Map());
2602
+ const threadsMaterializedForSendRef = useRef9(/* @__PURE__ */ new Set());
2603
+ const ensuredAccountPublicKeysRef = useRef9(/* @__PURE__ */ new Set());
2399
2604
  const [isThreadLoading, setIsThreadLoading] = useState7(false);
2605
+ const ensureAccountForPublicKey = useCallback8(
2606
+ async (sessionId, publicKey) => {
2607
+ const normalizedPublicKey = publicKey.toLowerCase();
2608
+ if (ensuredAccountPublicKeysRef.current.has(normalizedPublicKey)) {
2609
+ return;
2610
+ }
2611
+ await aomiClientRef.current.ensureAccount(sessionId, publicKey);
2612
+ ensuredAccountPublicKeysRef.current.add(normalizedPublicKey);
2613
+ },
2614
+ [aomiClientRef]
2615
+ );
2400
2616
  const warmThread = useCallback8(
2401
2617
  async (threadId) => {
2402
2618
  if (!remoteThreadIdsRef.current.has(threadId) || warmedThreadIdsRef.current.has(threadId)) {
@@ -2408,6 +2624,12 @@ function AomiRuntimeCore({
2408
2624
  }
2409
2625
  const warmPromise = (async () => {
2410
2626
  const userState = getUserState();
2627
+ if (UserState3.isConnected(userState)) {
2628
+ const publicKey = UserState3.address(userState);
2629
+ if (publicKey) {
2630
+ await ensureAccountForPublicKey(threadId, publicKey);
2631
+ }
2632
+ }
2411
2633
  await aomiClientRef.current.createThread(
2412
2634
  threadId,
2413
2635
  UserState3.isConnected(userState) ? UserState3.address(userState) : void 0
@@ -2421,20 +2643,27 @@ function AomiRuntimeCore({
2421
2643
  warmPromisesRef.current.delete(threadId);
2422
2644
  }
2423
2645
  },
2424
- [aomiClientRef, getUserState]
2646
+ [aomiClientRef, ensureAccountForPublicKey, getUserState]
2425
2647
  );
2426
2648
  const ensureBackendThread = useCallback8(
2427
2649
  async (threadId) => {
2428
- if (remoteThreadIdsRef.current.has(threadId)) return;
2650
+ if (remoteThreadIdsRef.current.has(threadId)) return false;
2429
2651
  const userState = getUserState();
2652
+ if (UserState3.isConnected(userState)) {
2653
+ const publicKey = UserState3.address(userState);
2654
+ if (publicKey) {
2655
+ await ensureAccountForPublicKey(threadId, publicKey);
2656
+ }
2657
+ }
2430
2658
  await aomiClientRef.current.createThread(
2431
2659
  threadId,
2432
2660
  UserState3.isConnected(userState) ? UserState3.address(userState) : void 0
2433
2661
  );
2434
2662
  remoteThreadIdsRef.current.add(threadId);
2435
2663
  warmedThreadIdsRef.current.add(threadId);
2664
+ return true;
2436
2665
  },
2437
- [aomiClientRef, getUserState]
2666
+ [aomiClientRef, ensureAccountForPublicKey, getUserState]
2438
2667
  );
2439
2668
  const getRuntimeSession = useCallback8(
2440
2669
  (threadId) => {
@@ -2532,6 +2761,9 @@ function AomiRuntimeCore({
2532
2761
  const showToolNotification = (eventType) => (event) => {
2533
2762
  const payload = event.payload;
2534
2763
  const toolName = typeof (payload == null ? void 0 : payload.tool_name) === "string" ? payload.tool_name : void 0;
2764
+ if (eventType === "tool_complete" && toolName === "commit_txs") {
2765
+ return;
2766
+ }
2535
2767
  const title = toolName ? `${eventType === "tool_update" ? "Tool update" : "Tool complete"}: ${toolName}` : eventType === "tool_update" ? "Tool update" : "Tool complete";
2536
2768
  const message = typeof (payload == null ? void 0 : payload.message) === "string" ? payload.message : typeof (payload == null ? void 0 : payload.result) === "string" ? payload.result : void 0;
2537
2769
  notificationContext.showNotification({
@@ -2568,7 +2800,11 @@ function AomiRuntimeCore({
2568
2800
  (part) => part.type === "text"
2569
2801
  ).map((part) => part.text).join("\n");
2570
2802
  if (text) {
2571
- await orchestratorSendMessage(text, threadContext.currentThreadId);
2803
+ try {
2804
+ await orchestratorSendMessage(text, threadContext.currentThreadId);
2805
+ } catch (error) {
2806
+ console.error("Failed to send message:", error);
2807
+ }
2572
2808
  }
2573
2809
  },
2574
2810
  onCancel: async () => {
@@ -2714,6 +2950,7 @@ function AomiRuntimeCore({
2714
2950
  {
2715
2951
  sessionManager,
2716
2952
  getUserState: userContext.getUserState,
2953
+ setUser: userContext.setUser,
2717
2954
  onUserStateChange: userContext.onUserStateChange,
2718
2955
  children: /* @__PURE__ */ jsx7(AssistantRuntimeProvider, { runtime, children })
2719
2956
  }
@@ -2731,7 +2968,7 @@ function AomiRuntimeProvider({
2731
2968
  () => new AomiClient(__spreadValues({ baseUrl: backendUrl }, clientOptions)),
2732
2969
  [backendUrl, clientOptions]
2733
2970
  );
2734
- return /* @__PURE__ */ jsx8(ThreadContextProvider, { children: /* @__PURE__ */ jsx8(NotificationContextProvider, { children: /* @__PURE__ */ jsx8(UserContextProvider, { children: /* @__PURE__ */ jsx8(AomiRuntimeInner, { aomiClient, children }) }) }) });
2971
+ return /* @__PURE__ */ jsx8(ThreadContextProvider, { children: /* @__PURE__ */ jsx8(NotificationContextProvider, { children: /* @__PURE__ */ jsx8(ExtUserProvider, { children: /* @__PURE__ */ jsx8(AomiRuntimeInner, { aomiClient, children }) }) }) });
2735
2972
  }
2736
2973
  function AomiRuntimeInner({
2737
2974
  children,
@@ -2807,12 +3044,12 @@ export {
2807
3044
  ControlContextProvider,
2808
3045
  DISABLED_PROVIDER_STATE,
2809
3046
  EventContextProvider,
3047
+ ExtUserProvider,
2810
3048
  MAX_AUTO_FEE_WEI,
2811
3049
  NotificationContextProvider,
2812
3050
  RuntimeUserStateProvider,
2813
3051
  SUPPORTED_CHAINS,
2814
3052
  ThreadContextProvider,
2815
- UserContextProvider,
2816
3053
  UserState2 as UserState,
2817
3054
  aaModeFromExecutionKind,
2818
3055
  appendFeeCallToPayload,