@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/dist/index.d.cts
CHANGED
|
@@ -16,10 +16,13 @@ type UserState = {
|
|
|
16
16
|
chainId?: number;
|
|
17
17
|
isConnected: boolean;
|
|
18
18
|
ensName?: string;
|
|
19
|
+
ext?: Record<string, unknown>;
|
|
19
20
|
};
|
|
20
21
|
declare function useUser(): {
|
|
21
22
|
user: UserState;
|
|
22
23
|
setUser: (data: Partial<UserState>) => void;
|
|
24
|
+
addExtValue: (key: string, value: unknown) => void;
|
|
25
|
+
removeExtValue: (key: string) => void;
|
|
23
26
|
getUserState: () => UserState;
|
|
24
27
|
onUserStateChange: (callback: (user: UserState) => void) => () => void;
|
|
25
28
|
};
|
|
@@ -166,6 +169,10 @@ type AomiRuntimeApi = {
|
|
|
166
169
|
getUserState: () => UserState;
|
|
167
170
|
/** Update user state (partial updates merged with existing state) */
|
|
168
171
|
setUser: (data: Partial<UserState>) => void;
|
|
172
|
+
/** Add or overwrite a value in user_state.ext */
|
|
173
|
+
addExtValue: (key: string, value: unknown) => void;
|
|
174
|
+
/** Remove a value from user_state.ext */
|
|
175
|
+
removeExtValue: (key: string) => void;
|
|
169
176
|
/** Subscribe to user state changes. Returns unsubscribe function. */
|
|
170
177
|
onUserStateChange: (callback: (user: UserState) => void) => () => void;
|
|
171
178
|
/** ID of the currently active thread */
|
|
@@ -318,6 +325,8 @@ declare const getChainInfo: (chainId: number | undefined) => ChainInfo | undefin
|
|
|
318
325
|
type ControlState = {
|
|
319
326
|
/** API key for authenticated requests */
|
|
320
327
|
apiKey: string | null;
|
|
328
|
+
/** Stable client identifier for this browser tab (associates sessions with secrets) */
|
|
329
|
+
clientId: string | null;
|
|
321
330
|
/** Available models fetched from backend */
|
|
322
331
|
availableModels: string[];
|
|
323
332
|
/** Authorized apps fetched from backend */
|
|
@@ -328,10 +337,14 @@ type ControlState = {
|
|
|
328
337
|
defaultApp: string | null;
|
|
329
338
|
};
|
|
330
339
|
type ControlContextApi = {
|
|
331
|
-
/** Global state (apiKey, available models/apps) */
|
|
340
|
+
/** Global state (apiKey, clientId, available models/apps) */
|
|
332
341
|
state: ControlState;
|
|
333
342
|
/** Update global state (apiKey only) */
|
|
334
343
|
setApiKey: (apiKey: string | null) => void;
|
|
344
|
+
/** Ingest secrets into the backend vault, returns opaque handles */
|
|
345
|
+
ingestSecrets: (secrets: Record<string, string>) => Promise<Record<string, string>>;
|
|
346
|
+
/** Clear all secrets from the backend vault */
|
|
347
|
+
clearSecrets: () => Promise<void>;
|
|
335
348
|
/** Fetch available models from backend */
|
|
336
349
|
getAvailableModels: () => Promise<string[]>;
|
|
337
350
|
/** Fetch authorized apps from backend */
|
package/dist/index.d.ts
CHANGED
|
@@ -16,10 +16,13 @@ type UserState = {
|
|
|
16
16
|
chainId?: number;
|
|
17
17
|
isConnected: boolean;
|
|
18
18
|
ensName?: string;
|
|
19
|
+
ext?: Record<string, unknown>;
|
|
19
20
|
};
|
|
20
21
|
declare function useUser(): {
|
|
21
22
|
user: UserState;
|
|
22
23
|
setUser: (data: Partial<UserState>) => void;
|
|
24
|
+
addExtValue: (key: string, value: unknown) => void;
|
|
25
|
+
removeExtValue: (key: string) => void;
|
|
23
26
|
getUserState: () => UserState;
|
|
24
27
|
onUserStateChange: (callback: (user: UserState) => void) => () => void;
|
|
25
28
|
};
|
|
@@ -166,6 +169,10 @@ type AomiRuntimeApi = {
|
|
|
166
169
|
getUserState: () => UserState;
|
|
167
170
|
/** Update user state (partial updates merged with existing state) */
|
|
168
171
|
setUser: (data: Partial<UserState>) => void;
|
|
172
|
+
/** Add or overwrite a value in user_state.ext */
|
|
173
|
+
addExtValue: (key: string, value: unknown) => void;
|
|
174
|
+
/** Remove a value from user_state.ext */
|
|
175
|
+
removeExtValue: (key: string) => void;
|
|
169
176
|
/** Subscribe to user state changes. Returns unsubscribe function. */
|
|
170
177
|
onUserStateChange: (callback: (user: UserState) => void) => () => void;
|
|
171
178
|
/** ID of the currently active thread */
|
|
@@ -318,6 +325,8 @@ declare const getChainInfo: (chainId: number | undefined) => ChainInfo | undefin
|
|
|
318
325
|
type ControlState = {
|
|
319
326
|
/** API key for authenticated requests */
|
|
320
327
|
apiKey: string | null;
|
|
328
|
+
/** Stable client identifier for this browser tab (associates sessions with secrets) */
|
|
329
|
+
clientId: string | null;
|
|
321
330
|
/** Available models fetched from backend */
|
|
322
331
|
availableModels: string[];
|
|
323
332
|
/** Authorized apps fetched from backend */
|
|
@@ -328,10 +337,14 @@ type ControlState = {
|
|
|
328
337
|
defaultApp: string | null;
|
|
329
338
|
};
|
|
330
339
|
type ControlContextApi = {
|
|
331
|
-
/** Global state (apiKey, available models/apps) */
|
|
340
|
+
/** Global state (apiKey, clientId, available models/apps) */
|
|
332
341
|
state: ControlState;
|
|
333
342
|
/** Update global state (apiKey only) */
|
|
334
343
|
setApiKey: (apiKey: string | null) => void;
|
|
344
|
+
/** Ingest secrets into the backend vault, returns opaque handles */
|
|
345
|
+
ingestSecrets: (secrets: Record<string, string>) => Promise<Record<string, string>>;
|
|
346
|
+
/** Clear all secrets from the backend vault */
|
|
347
|
+
clearSecrets: () => Promise<void>;
|
|
335
348
|
/** Fetch available models from backend */
|
|
336
349
|
getAvailableModels: () => Promise<string[]>;
|
|
337
350
|
/** Fetch authorized apps from backend */
|
package/dist/index.js
CHANGED
|
@@ -239,6 +239,7 @@ function ControlContextProvider({
|
|
|
239
239
|
var _a, _b;
|
|
240
240
|
const [state, setStateInternal] = useState(() => ({
|
|
241
241
|
apiKey: null,
|
|
242
|
+
clientId: null,
|
|
242
243
|
availableModels: [],
|
|
243
244
|
authorizedApps: [],
|
|
244
245
|
defaultModel: null,
|
|
@@ -259,6 +260,11 @@ function ControlContextProvider({
|
|
|
259
260
|
const callbacks = useRef(/* @__PURE__ */ new Set());
|
|
260
261
|
const currentThreadMetadata = getThreadMetadata(sessionId);
|
|
261
262
|
const isProcessing = (_b = (_a = currentThreadMetadata == null ? void 0 : currentThreadMetadata.control) == null ? void 0 : _a.isProcessing) != null ? _b : false;
|
|
263
|
+
useEffect(() => {
|
|
264
|
+
var _a2, _b2, _c;
|
|
265
|
+
const clientId = (_c = (_b2 = (_a2 = globalThis.crypto) == null ? void 0 : _a2.randomUUID) == null ? void 0 : _b2.call(_a2)) != null ? _c : `client-${Date.now()}`;
|
|
266
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), { clientId }));
|
|
267
|
+
}, []);
|
|
262
268
|
useEffect(() => {
|
|
263
269
|
var _a2, _b2;
|
|
264
270
|
try {
|
|
@@ -332,6 +338,24 @@ function ControlContextProvider({
|
|
|
332
338
|
return next;
|
|
333
339
|
});
|
|
334
340
|
}, []);
|
|
341
|
+
const ingestSecrets = useCallback(
|
|
342
|
+
async (secrets) => {
|
|
343
|
+
const clientId = stateRef.current.clientId;
|
|
344
|
+
if (!clientId) throw new Error("clientId not initialized");
|
|
345
|
+
const { handles } = await aomiClientRef.current.ingestSecrets(
|
|
346
|
+
clientId,
|
|
347
|
+
secrets
|
|
348
|
+
);
|
|
349
|
+
return handles;
|
|
350
|
+
},
|
|
351
|
+
[]
|
|
352
|
+
);
|
|
353
|
+
const clearSecrets = useCallback(async () => {
|
|
354
|
+
var _a2, _b2;
|
|
355
|
+
const clientId = stateRef.current.clientId;
|
|
356
|
+
if (!clientId) return;
|
|
357
|
+
await ((_b2 = (_a2 = aomiClientRef.current).clearSecrets) == null ? void 0 : _b2.call(_a2, clientId));
|
|
358
|
+
}, []);
|
|
335
359
|
const getAvailableModels = useCallback(async () => {
|
|
336
360
|
try {
|
|
337
361
|
const models = await aomiClientRef.current.getModels(
|
|
@@ -512,6 +536,8 @@ function ControlContextProvider({
|
|
|
512
536
|
value: {
|
|
513
537
|
state,
|
|
514
538
|
setApiKey,
|
|
539
|
+
ingestSecrets,
|
|
540
|
+
clearSecrets,
|
|
515
541
|
getAvailableModels,
|
|
516
542
|
getAuthorizedApps,
|
|
517
543
|
getCurrentThreadControl,
|
|
@@ -832,6 +858,8 @@ function useUser() {
|
|
|
832
858
|
return {
|
|
833
859
|
user: context.user,
|
|
834
860
|
setUser: context.setUser,
|
|
861
|
+
addExtValue: context.addExtValue,
|
|
862
|
+
removeExtValue: context.removeExtValue,
|
|
835
863
|
getUserState: context.getUserState,
|
|
836
864
|
onUserStateChange: context.onUserStateChange
|
|
837
865
|
};
|
|
@@ -841,7 +869,8 @@ function UserContextProvider({ children }) {
|
|
|
841
869
|
isConnected: false,
|
|
842
870
|
address: void 0,
|
|
843
871
|
chainId: void 0,
|
|
844
|
-
ensName: void 0
|
|
872
|
+
ensName: void 0,
|
|
873
|
+
ext: void 0
|
|
845
874
|
});
|
|
846
875
|
const userRef = useRef4(user);
|
|
847
876
|
userRef.current = user;
|
|
@@ -857,6 +886,36 @@ function UserContextProvider({ children }) {
|
|
|
857
886
|
return next;
|
|
858
887
|
});
|
|
859
888
|
}, []);
|
|
889
|
+
const addExtValue = useCallback4((key, value) => {
|
|
890
|
+
setUserState((prev) => {
|
|
891
|
+
var _a;
|
|
892
|
+
const next = __spreadProps(__spreadValues({}, prev), {
|
|
893
|
+
ext: __spreadProps(__spreadValues({}, (_a = prev.ext) != null ? _a : {}), {
|
|
894
|
+
[key]: value
|
|
895
|
+
})
|
|
896
|
+
});
|
|
897
|
+
StateChangeCallbacks.current.forEach((callback) => {
|
|
898
|
+
callback(next);
|
|
899
|
+
});
|
|
900
|
+
return next;
|
|
901
|
+
});
|
|
902
|
+
}, []);
|
|
903
|
+
const removeExtValue = useCallback4((key) => {
|
|
904
|
+
setUserState((prev) => {
|
|
905
|
+
if (!prev.ext || !(key in prev.ext)) {
|
|
906
|
+
return prev;
|
|
907
|
+
}
|
|
908
|
+
const nextExt = __spreadValues({}, prev.ext);
|
|
909
|
+
delete nextExt[key];
|
|
910
|
+
const next = __spreadProps(__spreadValues({}, prev), {
|
|
911
|
+
ext: Object.keys(nextExt).length > 0 ? nextExt : void 0
|
|
912
|
+
});
|
|
913
|
+
StateChangeCallbacks.current.forEach((callback) => {
|
|
914
|
+
callback(next);
|
|
915
|
+
});
|
|
916
|
+
return next;
|
|
917
|
+
});
|
|
918
|
+
}, []);
|
|
860
919
|
const getUserState = useCallback4(() => userRef.current, []);
|
|
861
920
|
const onUserStateChange = useCallback4(
|
|
862
921
|
(callback) => {
|
|
@@ -873,6 +932,8 @@ function UserContextProvider({ children }) {
|
|
|
873
932
|
value: {
|
|
874
933
|
user,
|
|
875
934
|
setUser,
|
|
935
|
+
addExtValue,
|
|
936
|
+
removeExtValue,
|
|
876
937
|
getUserState,
|
|
877
938
|
onUserStateChange
|
|
878
939
|
},
|
|
@@ -1030,7 +1091,7 @@ var MessageController = class {
|
|
|
1030
1091
|
this.getThreadContextApi().setThreadMessages(threadId, threadMessages);
|
|
1031
1092
|
}
|
|
1032
1093
|
async outbound(message, threadId) {
|
|
1033
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1094
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
1034
1095
|
const backendState = this.config.backendStateRef.current;
|
|
1035
1096
|
const text = message.content.filter(
|
|
1036
1097
|
(part) => part.type === "text"
|
|
@@ -1053,18 +1114,19 @@ var MessageController = class {
|
|
|
1053
1114
|
const app = this.config.getApp();
|
|
1054
1115
|
const publicKey = (_b = (_a = this.config).getPublicKey) == null ? void 0 : _b.call(_a);
|
|
1055
1116
|
const apiKey = (_e = (_d = (_c = this.config).getApiKey) == null ? void 0 : _d.call(_c)) != null ? _e : void 0;
|
|
1056
|
-
const
|
|
1117
|
+
const clientId = (_g = (_f = this.config).getClientId) == null ? void 0 : _g.call(_f);
|
|
1118
|
+
const userState = (_i = (_h = this.config).getUserState) == null ? void 0 : _i.call(_h);
|
|
1057
1119
|
try {
|
|
1058
1120
|
this.markRunning(threadId, true);
|
|
1059
1121
|
const response = await this.config.aomiClientRef.current.sendMessage(
|
|
1060
1122
|
backendThreadId,
|
|
1061
1123
|
text,
|
|
1062
|
-
{ app, publicKey, apiKey, userState }
|
|
1124
|
+
{ app, publicKey, apiKey, userState, clientId }
|
|
1063
1125
|
);
|
|
1064
1126
|
if (response == null ? void 0 : response.messages) {
|
|
1065
1127
|
this.inbound(threadId, response.messages);
|
|
1066
1128
|
}
|
|
1067
|
-
if (((
|
|
1129
|
+
if (((_j = response == null ? void 0 : response.system_events) == null ? void 0 : _j.length) && this.config.onSyncEvents) {
|
|
1068
1130
|
this.config.onSyncEvents(backendThreadId, response.system_events);
|
|
1069
1131
|
}
|
|
1070
1132
|
if (response == null ? void 0 : response.is_processing) {
|
|
@@ -1123,7 +1185,7 @@ var PollingController = class {
|
|
|
1123
1185
|
const backendThreadId = resolveThreadId(backendState, threadId);
|
|
1124
1186
|
setThreadRunning(backendState, threadId, true);
|
|
1125
1187
|
const tick = async () => {
|
|
1126
|
-
var _a2, _b2;
|
|
1188
|
+
var _a2, _b2, _c, _d;
|
|
1127
1189
|
if (!this.intervals.has(threadId)) return;
|
|
1128
1190
|
try {
|
|
1129
1191
|
console.log(
|
|
@@ -1131,9 +1193,11 @@ var PollingController = class {
|
|
|
1131
1193
|
threadId
|
|
1132
1194
|
);
|
|
1133
1195
|
const userState = (_b2 = (_a2 = this.config).getUserState) == null ? void 0 : _b2.call(_a2);
|
|
1196
|
+
const clientId = (_d = (_c = this.config).getClientId) == null ? void 0 : _d.call(_c);
|
|
1134
1197
|
const state = await this.config.aomiClientRef.current.fetchState(
|
|
1135
1198
|
backendThreadId,
|
|
1136
|
-
userState
|
|
1199
|
+
userState,
|
|
1200
|
+
clientId
|
|
1137
1201
|
);
|
|
1138
1202
|
if (!this.intervals.has(threadId)) return;
|
|
1139
1203
|
this.handleState(threadId, state);
|
|
@@ -1200,6 +1264,7 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1200
1264
|
},
|
|
1201
1265
|
onSyncEvents: options.onSyncEvents,
|
|
1202
1266
|
getUserState: options.getUserState,
|
|
1267
|
+
getClientId: options.getClientId,
|
|
1203
1268
|
onStart: (threadId) => {
|
|
1204
1269
|
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1205
1270
|
setIsRunning(true);
|
|
@@ -1222,29 +1287,32 @@ function useRuntimeOrchestrator(aomiClient, options) {
|
|
|
1222
1287
|
getPublicKey: options.getPublicKey,
|
|
1223
1288
|
getApp: options.getApp,
|
|
1224
1289
|
getApiKey: options.getApiKey,
|
|
1290
|
+
getClientId: options.getClientId,
|
|
1225
1291
|
getUserState: options.getUserState,
|
|
1226
1292
|
onSyncEvents: options.onSyncEvents
|
|
1227
1293
|
});
|
|
1228
1294
|
}
|
|
1229
1295
|
const ensureInitialState = useCallback5(async (threadId) => {
|
|
1230
|
-
var _a, _b, _c, _d;
|
|
1296
|
+
var _a, _b, _c, _d, _e;
|
|
1231
1297
|
if (pendingFetches.current.has(threadId)) return;
|
|
1232
1298
|
const backendThreadId = resolveThreadId(backendStateRef.current, threadId);
|
|
1233
1299
|
pendingFetches.current.add(threadId);
|
|
1234
1300
|
try {
|
|
1235
1301
|
const userState = (_a = options.getUserState) == null ? void 0 : _a.call(options);
|
|
1302
|
+
const clientId = (_b = options.getClientId) == null ? void 0 : _b.call(options);
|
|
1236
1303
|
const state = await aomiClientRef.current.fetchState(
|
|
1237
1304
|
backendThreadId,
|
|
1238
|
-
userState
|
|
1305
|
+
userState,
|
|
1306
|
+
clientId
|
|
1239
1307
|
);
|
|
1240
|
-
(
|
|
1241
|
-
if (((
|
|
1308
|
+
(_c = messageControllerRef.current) == null ? void 0 : _c.inbound(threadId, state.messages);
|
|
1309
|
+
if (((_d = state.system_events) == null ? void 0 : _d.length) && options.onSyncEvents) {
|
|
1242
1310
|
options.onSyncEvents(backendThreadId, state.system_events);
|
|
1243
1311
|
}
|
|
1244
1312
|
if (threadContextRef.current.currentThreadId === threadId) {
|
|
1245
1313
|
if (state.is_processing) {
|
|
1246
1314
|
setIsRunning(true);
|
|
1247
|
-
(
|
|
1315
|
+
(_e = pollingRef.current) == null ? void 0 : _e.start(threadId);
|
|
1248
1316
|
} else {
|
|
1249
1317
|
setIsRunning(false);
|
|
1250
1318
|
}
|
|
@@ -1580,7 +1648,7 @@ function AomiRuntimeCore({
|
|
|
1580
1648
|
const notificationContext = useNotification();
|
|
1581
1649
|
const { dispatchInboundSystem: dispatchSystemEvents } = eventContext;
|
|
1582
1650
|
const { user, onUserStateChange, getUserState } = useUser();
|
|
1583
|
-
const { getControlState, getCurrentThreadApp } = useControl();
|
|
1651
|
+
const { getControlState, getCurrentThreadApp, clearSecrets } = useControl();
|
|
1584
1652
|
const {
|
|
1585
1653
|
backendStateRef,
|
|
1586
1654
|
polling,
|
|
@@ -1594,24 +1662,46 @@ function AomiRuntimeCore({
|
|
|
1594
1662
|
getPublicKey: () => getUserState().address,
|
|
1595
1663
|
getUserState,
|
|
1596
1664
|
getApp: getCurrentThreadApp,
|
|
1597
|
-
getApiKey: () => getControlState().apiKey
|
|
1665
|
+
getApiKey: () => getControlState().apiKey,
|
|
1666
|
+
getClientId: () => {
|
|
1667
|
+
var _a;
|
|
1668
|
+
return (_a = getControlState().clientId) != null ? _a : void 0;
|
|
1669
|
+
}
|
|
1598
1670
|
});
|
|
1671
|
+
const walletSnapshot = useCallback7(
|
|
1672
|
+
(nextUser) => ({
|
|
1673
|
+
address: nextUser.address,
|
|
1674
|
+
chainId: nextUser.chainId,
|
|
1675
|
+
isConnected: nextUser.isConnected,
|
|
1676
|
+
ensName: nextUser.ensName
|
|
1677
|
+
}),
|
|
1678
|
+
[getUserState]
|
|
1679
|
+
);
|
|
1680
|
+
const lastWalletStateRef = useRef7(walletSnapshot(getUserState()));
|
|
1599
1681
|
useEffect4(() => {
|
|
1682
|
+
lastWalletStateRef.current = walletSnapshot(getUserState());
|
|
1600
1683
|
const unsubscribe = onUserStateChange(async (newUser) => {
|
|
1684
|
+
const nextWalletState = walletSnapshot(newUser);
|
|
1685
|
+
const prevWalletState = lastWalletStateRef.current;
|
|
1686
|
+
if (prevWalletState.address === nextWalletState.address && prevWalletState.chainId === nextWalletState.chainId && prevWalletState.isConnected === nextWalletState.isConnected && prevWalletState.ensName === nextWalletState.ensName) {
|
|
1687
|
+
return;
|
|
1688
|
+
}
|
|
1689
|
+
lastWalletStateRef.current = nextWalletState;
|
|
1601
1690
|
const sessionId = threadContext.currentThreadId;
|
|
1602
1691
|
const message = JSON.stringify({
|
|
1603
1692
|
type: "wallet:state_changed",
|
|
1604
|
-
payload:
|
|
1605
|
-
address: newUser.address,
|
|
1606
|
-
chainId: newUser.chainId,
|
|
1607
|
-
isConnected: newUser.isConnected,
|
|
1608
|
-
ensName: newUser.ensName
|
|
1609
|
-
}
|
|
1693
|
+
payload: nextWalletState
|
|
1610
1694
|
});
|
|
1611
1695
|
await aomiClientRef.current.sendSystemMessage(sessionId, message);
|
|
1612
1696
|
});
|
|
1613
1697
|
return unsubscribe;
|
|
1614
|
-
}, [
|
|
1698
|
+
}, [
|
|
1699
|
+
onUserStateChange,
|
|
1700
|
+
aomiClientRef,
|
|
1701
|
+
threadContext.currentThreadId,
|
|
1702
|
+
getUserState,
|
|
1703
|
+
walletSnapshot
|
|
1704
|
+
]);
|
|
1615
1705
|
const threadContextRef = useRef7(threadContext);
|
|
1616
1706
|
threadContextRef.current = threadContext;
|
|
1617
1707
|
const currentThreadIdRef = useRef7(threadContext.currentThreadId);
|
|
@@ -1803,8 +1893,9 @@ function AomiRuntimeCore({
|
|
|
1803
1893
|
useEffect4(() => {
|
|
1804
1894
|
return () => {
|
|
1805
1895
|
polling.stopAll();
|
|
1896
|
+
void clearSecrets();
|
|
1806
1897
|
};
|
|
1807
|
-
}, [polling]);
|
|
1898
|
+
}, [polling, clearSecrets]);
|
|
1808
1899
|
const userContext = useUser();
|
|
1809
1900
|
const sendMessage = useCallback7(
|
|
1810
1901
|
async (text) => {
|
|
@@ -1867,6 +1958,8 @@ function AomiRuntimeCore({
|
|
|
1867
1958
|
user: userContext.user,
|
|
1868
1959
|
getUserState: userContext.getUserState,
|
|
1869
1960
|
setUser: userContext.setUser,
|
|
1961
|
+
addExtValue: userContext.addExtValue,
|
|
1962
|
+
removeExtValue: userContext.removeExtValue,
|
|
1870
1963
|
onUserStateChange: userContext.onUserStateChange,
|
|
1871
1964
|
// Thread API
|
|
1872
1965
|
currentThreadId: threadContext.currentThreadId,
|