@aomi-labs/react 0.3.2 → 0.3.4
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/README.md +6 -2
- package/dist/index.cjs +115 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +115 -22
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -10,12 +10,16 @@ npm install @aomi-labs/react @assistant-ui/react react react-dom
|
|
|
10
10
|
pnpm add @aomi-labs/react @assistant-ui/react react react-dom
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Optional
|
|
13
|
+
Optional dependencies for advanced custom wallet adapters:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
pnpm add wagmi viem
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
If you use the registry-installed `AomiFrame`, the default Para-backed
|
|
20
|
+
`AomiAdapterProvider` is already wired for you. Add `wagmi` only when you want
|
|
21
|
+
to bring your own adapter implementation.
|
|
22
|
+
|
|
19
23
|
## Quick Start
|
|
20
24
|
|
|
21
25
|
Wrap your app with `AomiRuntimeProvider`, then use `useAomiRuntime()` anywhere inside:
|
|
@@ -117,7 +121,7 @@ Returns an `AomiRuntimeApi` object with:
|
|
|
117
121
|
| `useControl()` | Model/namespace/API key state |
|
|
118
122
|
| `useNotification()` | Toast notification context |
|
|
119
123
|
| `useEventContext()` | Raw event system access |
|
|
120
|
-
| `useWalletHandler()` | Wallet request handler
|
|
124
|
+
| `useWalletHandler()` | Wallet request handler for custom adapter implementations |
|
|
121
125
|
| `useNotificationHandler()` | Notification event handler |
|
|
122
126
|
|
|
123
127
|
## Utilities
|
package/dist/index.cjs
CHANGED
|
@@ -276,6 +276,7 @@ function ControlContextProvider({
|
|
|
276
276
|
var _a, _b;
|
|
277
277
|
const [state, setStateInternal] = (0, import_react.useState)(() => ({
|
|
278
278
|
apiKey: null,
|
|
279
|
+
clientId: null,
|
|
279
280
|
availableModels: [],
|
|
280
281
|
authorizedApps: [],
|
|
281
282
|
defaultModel: null,
|
|
@@ -296,6 +297,11 @@ function ControlContextProvider({
|
|
|
296
297
|
const callbacks = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
297
298
|
const currentThreadMetadata = getThreadMetadata(sessionId);
|
|
298
299
|
const isProcessing = (_b = (_a = currentThreadMetadata == null ? void 0 : currentThreadMetadata.control) == null ? void 0 : _a.isProcessing) != null ? _b : false;
|
|
300
|
+
(0, import_react.useEffect)(() => {
|
|
301
|
+
var _a2, _b2, _c;
|
|
302
|
+
const clientId = (_c = (_b2 = (_a2 = globalThis.crypto) == null ? void 0 : _a2.randomUUID) == null ? void 0 : _b2.call(_a2)) != null ? _c : `client-${Date.now()}`;
|
|
303
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), { clientId }));
|
|
304
|
+
}, []);
|
|
299
305
|
(0, import_react.useEffect)(() => {
|
|
300
306
|
var _a2, _b2;
|
|
301
307
|
try {
|
|
@@ -369,6 +375,24 @@ function ControlContextProvider({
|
|
|
369
375
|
return next;
|
|
370
376
|
});
|
|
371
377
|
}, []);
|
|
378
|
+
const ingestSecrets = (0, import_react.useCallback)(
|
|
379
|
+
async (secrets) => {
|
|
380
|
+
const clientId = stateRef.current.clientId;
|
|
381
|
+
if (!clientId) throw new Error("clientId not initialized");
|
|
382
|
+
const { handles } = await aomiClientRef.current.ingestSecrets(
|
|
383
|
+
clientId,
|
|
384
|
+
secrets
|
|
385
|
+
);
|
|
386
|
+
return handles;
|
|
387
|
+
},
|
|
388
|
+
[]
|
|
389
|
+
);
|
|
390
|
+
const clearSecrets = (0, import_react.useCallback)(async () => {
|
|
391
|
+
var _a2, _b2;
|
|
392
|
+
const clientId = stateRef.current.clientId;
|
|
393
|
+
if (!clientId) return;
|
|
394
|
+
await ((_b2 = (_a2 = aomiClientRef.current).clearSecrets) == null ? void 0 : _b2.call(_a2, clientId));
|
|
395
|
+
}, []);
|
|
372
396
|
const getAvailableModels = (0, import_react.useCallback)(async () => {
|
|
373
397
|
try {
|
|
374
398
|
const models = await aomiClientRef.current.getModels(
|
|
@@ -549,6 +573,8 @@ function ControlContextProvider({
|
|
|
549
573
|
value: {
|
|
550
574
|
state,
|
|
551
575
|
setApiKey,
|
|
576
|
+
ingestSecrets,
|
|
577
|
+
clearSecrets,
|
|
552
578
|
getAvailableModels,
|
|
553
579
|
getAuthorizedApps,
|
|
554
580
|
getCurrentThreadControl,
|
|
@@ -840,6 +866,8 @@ function useUser() {
|
|
|
840
866
|
return {
|
|
841
867
|
user: context.user,
|
|
842
868
|
setUser: context.setUser,
|
|
869
|
+
addExtValue: context.addExtValue,
|
|
870
|
+
removeExtValue: context.removeExtValue,
|
|
843
871
|
getUserState: context.getUserState,
|
|
844
872
|
onUserStateChange: context.onUserStateChange
|
|
845
873
|
};
|
|
@@ -849,7 +877,8 @@ function UserContextProvider({ children }) {
|
|
|
849
877
|
isConnected: false,
|
|
850
878
|
address: void 0,
|
|
851
879
|
chainId: void 0,
|
|
852
|
-
ensName: void 0
|
|
880
|
+
ensName: void 0,
|
|
881
|
+
ext: void 0
|
|
853
882
|
});
|
|
854
883
|
const userRef = (0, import_react5.useRef)(user);
|
|
855
884
|
userRef.current = user;
|
|
@@ -865,6 +894,36 @@ function UserContextProvider({ children }) {
|
|
|
865
894
|
return next;
|
|
866
895
|
});
|
|
867
896
|
}, []);
|
|
897
|
+
const addExtValue = (0, import_react5.useCallback)((key, value) => {
|
|
898
|
+
setUserState((prev) => {
|
|
899
|
+
var _a;
|
|
900
|
+
const next = __spreadProps(__spreadValues({}, prev), {
|
|
901
|
+
ext: __spreadProps(__spreadValues({}, (_a = prev.ext) != null ? _a : {}), {
|
|
902
|
+
[key]: value
|
|
903
|
+
})
|
|
904
|
+
});
|
|
905
|
+
StateChangeCallbacks.current.forEach((callback) => {
|
|
906
|
+
callback(next);
|
|
907
|
+
});
|
|
908
|
+
return next;
|
|
909
|
+
});
|
|
910
|
+
}, []);
|
|
911
|
+
const removeExtValue = (0, import_react5.useCallback)((key) => {
|
|
912
|
+
setUserState((prev) => {
|
|
913
|
+
if (!prev.ext || !(key in prev.ext)) {
|
|
914
|
+
return prev;
|
|
915
|
+
}
|
|
916
|
+
const nextExt = __spreadValues({}, prev.ext);
|
|
917
|
+
delete nextExt[key];
|
|
918
|
+
const next = __spreadProps(__spreadValues({}, prev), {
|
|
919
|
+
ext: Object.keys(nextExt).length > 0 ? nextExt : void 0
|
|
920
|
+
});
|
|
921
|
+
StateChangeCallbacks.current.forEach((callback) => {
|
|
922
|
+
callback(next);
|
|
923
|
+
});
|
|
924
|
+
return next;
|
|
925
|
+
});
|
|
926
|
+
}, []);
|
|
868
927
|
const getUserState = (0, import_react5.useCallback)(() => userRef.current, []);
|
|
869
928
|
const onUserStateChange = (0, import_react5.useCallback)(
|
|
870
929
|
(callback) => {
|
|
@@ -881,6 +940,8 @@ function UserContextProvider({ children }) {
|
|
|
881
940
|
value: {
|
|
882
941
|
user,
|
|
883
942
|
setUser,
|
|
943
|
+
addExtValue,
|
|
944
|
+
removeExtValue,
|
|
884
945
|
getUserState,
|
|
885
946
|
onUserStateChange
|
|
886
947
|
},
|
|
@@ -1035,7 +1096,7 @@ var MessageController = class {
|
|
|
1035
1096
|
this.getThreadContextApi().setThreadMessages(threadId, threadMessages);
|
|
1036
1097
|
}
|
|
1037
1098
|
async outbound(message, threadId) {
|
|
1038
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1099
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
1039
1100
|
const backendState = this.config.backendStateRef.current;
|
|
1040
1101
|
const text = message.content.filter(
|
|
1041
1102
|
(part) => part.type === "text"
|
|
@@ -1058,18 +1119,19 @@ var MessageController = class {
|
|
|
1058
1119
|
const app = this.config.getApp();
|
|
1059
1120
|
const publicKey = (_b = (_a = this.config).getPublicKey) == null ? void 0 : _b.call(_a);
|
|
1060
1121
|
const apiKey = (_e = (_d = (_c = this.config).getApiKey) == null ? void 0 : _d.call(_c)) != null ? _e : void 0;
|
|
1061
|
-
const
|
|
1122
|
+
const clientId = (_g = (_f = this.config).getClientId) == null ? void 0 : _g.call(_f);
|
|
1123
|
+
const userState = (_i = (_h = this.config).getUserState) == null ? void 0 : _i.call(_h);
|
|
1062
1124
|
try {
|
|
1063
1125
|
this.markRunning(threadId, true);
|
|
1064
1126
|
const response = await this.config.aomiClientRef.current.sendMessage(
|
|
1065
1127
|
backendThreadId,
|
|
1066
1128
|
text,
|
|
1067
|
-
{ app, publicKey, apiKey, userState }
|
|
1129
|
+
{ app, publicKey, apiKey, userState, clientId }
|
|
1068
1130
|
);
|
|
1069
1131
|
if (response == null ? void 0 : response.messages) {
|
|
1070
1132
|
this.inbound(threadId, response.messages);
|
|
1071
1133
|
}
|
|
1072
|
-
if (((
|
|
1134
|
+
if (((_j = response == null ? void 0 : response.system_events) == null ? void 0 : _j.length) && this.config.onSyncEvents) {
|
|
1073
1135
|
this.config.onSyncEvents(backendThreadId, response.system_events);
|
|
1074
1136
|
}
|
|
1075
1137
|
if (response == null ? void 0 : response.is_processing) {
|
|
@@ -1128,7 +1190,7 @@ var PollingController = class {
|
|
|
1128
1190
|
const backendThreadId = resolveThreadId(backendState, threadId);
|
|
1129
1191
|
setThreadRunning(backendState, threadId, true);
|
|
1130
1192
|
const tick = async () => {
|
|
1131
|
-
var _a2, _b2;
|
|
1193
|
+
var _a2, _b2, _c, _d;
|
|
1132
1194
|
if (!this.intervals.has(threadId)) return;
|
|
1133
1195
|
try {
|
|
1134
1196
|
console.log(
|
|
@@ -1136,9 +1198,11 @@ var PollingController = class {
|
|
|
1136
1198
|
threadId
|
|
1137
1199
|
);
|
|
1138
1200
|
const userState = (_b2 = (_a2 = this.config).getUserState) == null ? void 0 : _b2.call(_a2);
|
|
1201
|
+
const clientId = (_d = (_c = this.config).getClientId) == null ? void 0 : _d.call(_c);
|
|
1139
1202
|
const state = await this.config.aomiClientRef.current.fetchState(
|
|
1140
1203
|
backendThreadId,
|
|
1141
|
-
userState
|
|
1204
|
+
userState,
|
|
1205
|
+
clientId
|
|
1142
1206
|
);
|
|
1143
1207
|
if (!this.intervals.has(threadId)) return;
|
|
1144
1208
|
this.handleState(threadId, state);
|
|
@@ -1205,6 +1269,7 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1205
1269
|
},
|
|
1206
1270
|
onSyncEvents: options.onSyncEvents,
|
|
1207
1271
|
getUserState: options.getUserState,
|
|
1272
|
+
getClientId: options.getClientId,
|
|
1208
1273
|
onStart: (threadId) => {
|
|
1209
1274
|
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1210
1275
|
setIsRunning(true);
|
|
@@ -1227,29 +1292,32 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1227
1292
|
getPublicKey: options.getPublicKey,
|
|
1228
1293
|
getApp: options.getApp,
|
|
1229
1294
|
getApiKey: options.getApiKey,
|
|
1295
|
+
getClientId: options.getClientId,
|
|
1230
1296
|
getUserState: options.getUserState,
|
|
1231
1297
|
onSyncEvents: options.onSyncEvents
|
|
1232
1298
|
});
|
|
1233
1299
|
}
|
|
1234
1300
|
const ensureInitialState = (0, import_react6.useCallback)(async (threadId) => {
|
|
1235
|
-
var _a, _b, _c, _d;
|
|
1301
|
+
var _a, _b, _c, _d, _e;
|
|
1236
1302
|
if (pendingFetches.current.has(threadId)) return;
|
|
1237
1303
|
const backendThreadId = resolveThreadId(backendStateRef.current, threadId);
|
|
1238
1304
|
pendingFetches.current.add(threadId);
|
|
1239
1305
|
try {
|
|
1240
1306
|
const userState = (_a = options.getUserState) == null ? void 0 : _a.call(options);
|
|
1307
|
+
const clientId = (_b = options.getClientId) == null ? void 0 : _b.call(options);
|
|
1241
1308
|
const state = await aomiClientRef.current.fetchState(
|
|
1242
1309
|
backendThreadId,
|
|
1243
|
-
userState
|
|
1310
|
+
userState,
|
|
1311
|
+
clientId
|
|
1244
1312
|
);
|
|
1245
|
-
(
|
|
1246
|
-
if (((
|
|
1313
|
+
(_c = messageControllerRef.current) == null ? void 0 : _c.inbound(threadId, state.messages);
|
|
1314
|
+
if (((_d = state.system_events) == null ? void 0 : _d.length) && options.onSyncEvents) {
|
|
1247
1315
|
options.onSyncEvents(backendThreadId, state.system_events);
|
|
1248
1316
|
}
|
|
1249
1317
|
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1250
1318
|
if (state.is_processing) {
|
|
1251
1319
|
setIsRunning(true);
|
|
1252
|
-
(
|
|
1320
|
+
(_e = pollingRef.current) == null ? void 0 : _e.start(threadId);
|
|
1253
1321
|
} else {
|
|
1254
1322
|
setIsRunning(false);
|
|
1255
1323
|
}
|
|
@@ -1582,7 +1650,7 @@ function AomiRuntimeCore({
|
|
|
1582
1650
|
const notificationContext = useNotification();
|
|
1583
1651
|
const { dispatchInboundSystem: dispatchSystemEvents } = eventContext;
|
|
1584
1652
|
const { user, onUserStateChange, getUserState } = useUser();
|
|
1585
|
-
const { getControlState, getCurrentThreadApp } = useControl();
|
|
1653
|
+
const { getControlState, getCurrentThreadApp, clearSecrets } = useControl();
|
|
1586
1654
|
const {
|
|
1587
1655
|
backendStateRef,
|
|
1588
1656
|
polling,
|
|
@@ -1596,24 +1664,46 @@ function AomiRuntimeCore({
|
|
|
1596
1664
|
getPublicKey: () => getUserState().address,
|
|
1597
1665
|
getUserState,
|
|
1598
1666
|
getApp: getCurrentThreadApp,
|
|
1599
|
-
getApiKey: () => getControlState().apiKey
|
|
1667
|
+
getApiKey: () => getControlState().apiKey,
|
|
1668
|
+
getClientId: () => {
|
|
1669
|
+
var _a;
|
|
1670
|
+
return (_a = getControlState().clientId) != null ? _a : void 0;
|
|
1671
|
+
}
|
|
1600
1672
|
});
|
|
1673
|
+
const walletSnapshot = (0, import_react9.useCallback)(
|
|
1674
|
+
(nextUser) => ({
|
|
1675
|
+
address: nextUser.address,
|
|
1676
|
+
chainId: nextUser.chainId,
|
|
1677
|
+
isConnected: nextUser.isConnected,
|
|
1678
|
+
ensName: nextUser.ensName
|
|
1679
|
+
}),
|
|
1680
|
+
[getUserState]
|
|
1681
|
+
);
|
|
1682
|
+
const lastWalletStateRef = (0, import_react9.useRef)(walletSnapshot(getUserState()));
|
|
1601
1683
|
(0, import_react9.useEffect)(() => {
|
|
1684
|
+
lastWalletStateRef.current = walletSnapshot(getUserState());
|
|
1602
1685
|
const unsubscribe = onUserStateChange(async (newUser) => {
|
|
1686
|
+
const nextWalletState = walletSnapshot(newUser);
|
|
1687
|
+
const prevWalletState = lastWalletStateRef.current;
|
|
1688
|
+
if (prevWalletState.address === nextWalletState.address && prevWalletState.chainId === nextWalletState.chainId && prevWalletState.isConnected === nextWalletState.isConnected && prevWalletState.ensName === nextWalletState.ensName) {
|
|
1689
|
+
return;
|
|
1690
|
+
}
|
|
1691
|
+
lastWalletStateRef.current = nextWalletState;
|
|
1603
1692
|
const sessionId = threadContext.currentThreadId;
|
|
1604
1693
|
const message = JSON.stringify({
|
|
1605
1694
|
type: "wallet:state_changed",
|
|
1606
|
-
payload:
|
|
1607
|
-
address: newUser.address,
|
|
1608
|
-
chainId: newUser.chainId,
|
|
1609
|
-
isConnected: newUser.isConnected,
|
|
1610
|
-
ensName: newUser.ensName
|
|
1611
|
-
}
|
|
1695
|
+
payload: nextWalletState
|
|
1612
1696
|
});
|
|
1613
1697
|
await aomiClientRef.current.sendSystemMessage(sessionId, message);
|
|
1614
1698
|
});
|
|
1615
1699
|
return unsubscribe;
|
|
1616
|
-
}, [
|
|
1700
|
+
}, [
|
|
1701
|
+
onUserStateChange,
|
|
1702
|
+
aomiClientRef,
|
|
1703
|
+
threadContext.currentThreadId,
|
|
1704
|
+
getUserState,
|
|
1705
|
+
walletSnapshot
|
|
1706
|
+
]);
|
|
1617
1707
|
const threadContextRef = (0, import_react9.useRef)(threadContext);
|
|
1618
1708
|
threadContextRef.current = threadContext;
|
|
1619
1709
|
const currentThreadIdRef = (0, import_react9.useRef)(threadContext.currentThreadId);
|
|
@@ -1805,8 +1895,9 @@ function AomiRuntimeCore({
|
|
|
1805
1895
|
(0, import_react9.useEffect)(() => {
|
|
1806
1896
|
return () => {
|
|
1807
1897
|
polling.stopAll();
|
|
1898
|
+
void clearSecrets();
|
|
1808
1899
|
};
|
|
1809
|
-
}, [polling]);
|
|
1900
|
+
}, [polling, clearSecrets]);
|
|
1810
1901
|
const userContext = useUser();
|
|
1811
1902
|
const sendMessage = (0, import_react9.useCallback)(
|
|
1812
1903
|
async (text) => {
|
|
@@ -1869,6 +1960,8 @@ function AomiRuntimeCore({
|
|
|
1869
1960
|
user: userContext.user,
|
|
1870
1961
|
getUserState: userContext.getUserState,
|
|
1871
1962
|
setUser: userContext.setUser,
|
|
1963
|
+
addExtValue: userContext.addExtValue,
|
|
1964
|
+
removeExtValue: userContext.removeExtValue,
|
|
1872
1965
|
onUserStateChange: userContext.onUserStateChange,
|
|
1873
1966
|
// Thread API
|
|
1874
1967
|
currentThreadId: threadContext.currentThreadId,
|