@aomi-labs/react 0.3.19 → 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.cjs +349 -115
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -31
- package/dist/index.d.ts +65 -31
- package/dist/index.js +356 -119
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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 = "
|
|
308
|
-
var
|
|
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
|
|
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
|
-
|
|
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(
|
|
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), {
|
|
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.
|
|
459
|
+
const keys = state.byokKeys;
|
|
454
460
|
if (Object.keys(keys).length > 0) {
|
|
455
461
|
(_a2 = globalThis.localStorage) == null ? void 0 : _a2.setItem(
|
|
456
|
-
|
|
462
|
+
BYOK_KEYS_STORAGE_KEY,
|
|
457
463
|
JSON.stringify(keys)
|
|
458
464
|
);
|
|
459
465
|
} else {
|
|
460
|
-
(_b2 = globalThis.localStorage) == null ? void 0 : _b2.removeItem(
|
|
466
|
+
(_b2 = globalThis.localStorage) == null ? void 0 : _b2.removeItem(BYOK_KEYS_STORAGE_KEY);
|
|
461
467
|
}
|
|
462
468
|
} catch (e) {
|
|
463
469
|
}
|
|
464
|
-
}, [state.
|
|
470
|
+
}, [state.byokKeys]);
|
|
465
471
|
useEffect(() => {
|
|
466
472
|
if (!state.clientId) return;
|
|
467
|
-
const keys = stateRef.current.
|
|
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[`${
|
|
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
|
|
480
|
+
console.error("Failed to auto-ingest BYOK keys:", err);
|
|
475
481
|
});
|
|
476
|
-
}, [getCurrentControlSessionId, state.clientId, state.
|
|
482
|
+
}, [getCurrentControlSessionId, state.clientId, state.byokKeys]);
|
|
477
483
|
useEffect(() => {
|
|
478
484
|
const fetchApps = async () => {
|
|
479
485
|
var _a2;
|
|
480
486
|
try {
|
|
481
|
-
const
|
|
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
|
|
494
|
+
const names = namesFromDescriptors(descriptors);
|
|
495
|
+
const defaultApp = getDefaultApp(names);
|
|
489
496
|
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
490
|
-
authorizedApps:
|
|
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(
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
_a2
|
|
545
|
-
|
|
546
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
[`${
|
|
605
|
+
[`${BYOK_SECRET_PREFIX}${provider}`]: trimmed
|
|
573
606
|
}
|
|
574
607
|
);
|
|
575
608
|
} catch (err) {
|
|
576
|
-
console.error("Failed to ingest
|
|
609
|
+
console.error("Failed to ingest BYOK key:", err);
|
|
577
610
|
}
|
|
578
611
|
}
|
|
579
612
|
},
|
|
580
613
|
[getCurrentControlSessionId]
|
|
581
614
|
);
|
|
582
|
-
const
|
|
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
|
-
`${
|
|
622
|
+
`${BYOK_SECRET_PREFIX}${provider}`
|
|
590
623
|
);
|
|
591
624
|
}
|
|
592
625
|
setStateInternal((prev) => {
|
|
593
|
-
const _a2 = prev.
|
|
594
|
-
const next = __spreadProps(__spreadValues({}, prev), {
|
|
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
|
|
602
|
-
() => stateRef.current.
|
|
634
|
+
const getByokKeys = useCallback(
|
|
635
|
+
() => stateRef.current.byokKeys,
|
|
603
636
|
[]
|
|
604
637
|
);
|
|
605
|
-
const
|
|
606
|
-
const keys = stateRef.current.
|
|
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
|
|
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
|
|
668
|
+
const names = namesFromDescriptors(descriptors);
|
|
669
|
+
const defaultApp = getDefaultApp(names);
|
|
636
670
|
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
637
|
-
authorizedApps:
|
|
671
|
+
authorizedApps: names,
|
|
672
|
+
appDescriptors: descriptors,
|
|
638
673
|
defaultApp
|
|
639
674
|
}));
|
|
640
|
-
return
|
|
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
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
1188
|
+
const userRef = useRef5(user);
|
|
1132
1189
|
userRef.current = user;
|
|
1133
|
-
const StateChangeCallbacks =
|
|
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
|
|
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
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
1563
|
+
const threadContextRef = useRef6(threadContext);
|
|
1432
1564
|
threadContextRef.current = threadContext;
|
|
1433
|
-
const aomiClientRef =
|
|
1565
|
+
const aomiClientRef = useRef6(aomiClient);
|
|
1434
1566
|
aomiClientRef.current = aomiClient;
|
|
1435
|
-
const optionsRef =
|
|
1567
|
+
const optionsRef = useRef6(options);
|
|
1436
1568
|
optionsRef.current = options;
|
|
1437
1569
|
const [isRunning, setIsRunning] = useState4(false);
|
|
1438
|
-
const sessionManagerRef =
|
|
1570
|
+
const sessionManagerRef = useRef6(null);
|
|
1439
1571
|
if (!sessionManagerRef.current) {
|
|
1440
1572
|
sessionManagerRef.current = new SessionManager(() => aomiClientRef.current);
|
|
1441
1573
|
}
|
|
1442
|
-
const pendingFetches =
|
|
1443
|
-
const initialStatePromises =
|
|
1444
|
-
const hydratedThreadIds =
|
|
1445
|
-
const listenerCleanups =
|
|
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
|
-
(
|
|
1675
|
-
|
|
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
|
|
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 =
|
|
1901
|
-
const inFlightRequestSetRef =
|
|
1902
|
-
const suppressedRequestSetRef =
|
|
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
|
|
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 =
|
|
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 =
|
|
2086
|
-
const lastConnectedAddressRef =
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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
|
|
2338
|
-
|
|
2339
|
-
|
|
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 =
|
|
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 =
|
|
2597
|
+
const threadContextRef = useRef9(threadContext);
|
|
2395
2598
|
threadContextRef.current = threadContext;
|
|
2396
|
-
const remoteThreadIdsRef =
|
|
2397
|
-
const warmedThreadIdsRef =
|
|
2398
|
-
const warmPromisesRef =
|
|
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
|
-
|
|
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(
|
|
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,
|