@aomi-labs/react 0.3.6 → 0.3.7

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.d.cts CHANGED
@@ -306,11 +306,17 @@ declare const SUPPORTED_CHAINS: ChainInfo[];
306
306
  /** Look up ChainInfo by chain ID. Returns undefined for unknown chains. */
307
307
  declare const getChainInfo: (chainId: number | undefined) => ChainInfo | undefined;
308
308
 
309
+ /** A stored provider API key (BYOK) */
310
+ type StoredProviderKey = {
311
+ apiKey: string;
312
+ keyPrefix: string;
313
+ label?: string;
314
+ };
309
315
  /** Global control state (shared across all threads) */
310
316
  type ControlState = {
311
317
  /** API key for authenticated requests */
312
318
  apiKey: string | null;
313
- /** Stable client identifier for this browser tab (associates sessions with secrets) */
319
+ /** Stable client identifier for this browser profile (associates sessions with secrets) */
314
320
  clientId: string | null;
315
321
  /** Available models fetched from backend */
316
322
  availableModels: string[];
@@ -320,6 +326,8 @@ type ControlState = {
320
326
  defaultModel: string | null;
321
327
  /** Default app (from authorizedApps) */
322
328
  defaultApp: string | null;
329
+ /** Provider API keys stored locally (BYOK) — keyed by provider name */
330
+ providerKeys: Record<string, StoredProviderKey>;
323
331
  };
324
332
  type ControlContextApi = {
325
333
  /** Global state (apiKey, clientId, available models/apps) */
@@ -330,6 +338,14 @@ type ControlContextApi = {
330
338
  ingestSecrets: (secrets: Record<string, string>) => Promise<Record<string, string>>;
331
339
  /** Clear all secrets from the backend vault */
332
340
  clearSecrets: () => Promise<void>;
341
+ /** Store a provider API key (BYOK) in localStorage and ingest into backend vault */
342
+ setProviderKey: (provider: string, apiKey: string, label?: string) => Promise<void>;
343
+ /** Remove a provider API key from localStorage and backend vault */
344
+ removeProviderKey: (provider: string) => Promise<void>;
345
+ /** Get all stored provider keys (metadata only — keys are in state.providerKeys) */
346
+ getProviderKeys: () => Record<string, StoredProviderKey>;
347
+ /** Check if a provider key is stored */
348
+ hasProviderKey: (provider?: string) => boolean;
333
349
  /** Fetch available models from backend */
334
350
  getAvailableModels: () => Promise<string[]>;
335
351
  /** Fetch authorized apps from backend */
@@ -369,4 +385,4 @@ type ControlContextProviderProps = {
369
385
  };
370
386
  declare function ControlContextProvider({ children, aomiClient, sessionId, publicKey, getThreadMetadata, updateThreadMetadata, }: ControlContextProviderProps): react_jsx_runtime.JSX.Element;
371
387
 
372
- export { type AomiRuntimeApi, AomiRuntimeProvider, type AomiRuntimeProviderProps, type ChainInfo, type ControlContextApi, ControlContextProvider, type ControlContextProviderProps, type ControlState, type EventContext, EventContextProvider, type EventContextProviderProps, type EventSubscriber, type InboundEvent, type Notification$1 as Notification, type NotificationApi, NotificationContextProvider, type NotificationContextProviderProps, type NotificationContextApi as NotificationContextValue, type NotificationHandlerConfig, type NotificationType, type SSEStatus, SUPPORTED_CHAINS, type NotificationData as ShowNotificationParams, type ThreadContext, ThreadContextProvider, type ThreadControlState, type ThreadMetadata, type UserConfig, UserContextProvider, type UserState, type WalletHandlerApi, type WalletHandlerConfig, type WalletRequestKind, type WalletRequestResult, type WalletRequestStatus, cn, formatAddress, getChainInfo, getNetworkName, initThreadControl, useAomiRuntime, useControl, useCurrentThreadMessages, useCurrentThreadMetadata, useEventContext, useNotification, useNotificationHandler, useThreadContext, useUser, useWalletHandler };
388
+ export { type AomiRuntimeApi, AomiRuntimeProvider, type AomiRuntimeProviderProps, type ChainInfo, type ControlContextApi, ControlContextProvider, type ControlContextProviderProps, type ControlState, type EventContext, EventContextProvider, type EventContextProviderProps, type EventSubscriber, type InboundEvent, type Notification$1 as Notification, type NotificationApi, NotificationContextProvider, type NotificationContextProviderProps, type NotificationContextApi as NotificationContextValue, type NotificationHandlerConfig, type NotificationType, type SSEStatus, SUPPORTED_CHAINS, type NotificationData as ShowNotificationParams, type StoredProviderKey, type ThreadContext, ThreadContextProvider, type ThreadControlState, type ThreadMetadata, type UserConfig, UserContextProvider, type UserState, type WalletHandlerApi, type WalletHandlerConfig, type WalletRequestKind, type WalletRequestResult, type WalletRequestStatus, cn, formatAddress, getChainInfo, getNetworkName, initThreadControl, useAomiRuntime, useControl, useCurrentThreadMessages, useCurrentThreadMetadata, useEventContext, useNotification, useNotificationHandler, useThreadContext, useUser, useWalletHandler };
package/dist/index.d.ts CHANGED
@@ -306,11 +306,17 @@ declare const SUPPORTED_CHAINS: ChainInfo[];
306
306
  /** Look up ChainInfo by chain ID. Returns undefined for unknown chains. */
307
307
  declare const getChainInfo: (chainId: number | undefined) => ChainInfo | undefined;
308
308
 
309
+ /** A stored provider API key (BYOK) */
310
+ type StoredProviderKey = {
311
+ apiKey: string;
312
+ keyPrefix: string;
313
+ label?: string;
314
+ };
309
315
  /** Global control state (shared across all threads) */
310
316
  type ControlState = {
311
317
  /** API key for authenticated requests */
312
318
  apiKey: string | null;
313
- /** Stable client identifier for this browser tab (associates sessions with secrets) */
319
+ /** Stable client identifier for this browser profile (associates sessions with secrets) */
314
320
  clientId: string | null;
315
321
  /** Available models fetched from backend */
316
322
  availableModels: string[];
@@ -320,6 +326,8 @@ type ControlState = {
320
326
  defaultModel: string | null;
321
327
  /** Default app (from authorizedApps) */
322
328
  defaultApp: string | null;
329
+ /** Provider API keys stored locally (BYOK) — keyed by provider name */
330
+ providerKeys: Record<string, StoredProviderKey>;
323
331
  };
324
332
  type ControlContextApi = {
325
333
  /** Global state (apiKey, clientId, available models/apps) */
@@ -330,6 +338,14 @@ type ControlContextApi = {
330
338
  ingestSecrets: (secrets: Record<string, string>) => Promise<Record<string, string>>;
331
339
  /** Clear all secrets from the backend vault */
332
340
  clearSecrets: () => Promise<void>;
341
+ /** Store a provider API key (BYOK) in localStorage and ingest into backend vault */
342
+ setProviderKey: (provider: string, apiKey: string, label?: string) => Promise<void>;
343
+ /** Remove a provider API key from localStorage and backend vault */
344
+ removeProviderKey: (provider: string) => Promise<void>;
345
+ /** Get all stored provider keys (metadata only — keys are in state.providerKeys) */
346
+ getProviderKeys: () => Record<string, StoredProviderKey>;
347
+ /** Check if a provider key is stored */
348
+ hasProviderKey: (provider?: string) => boolean;
333
349
  /** Fetch available models from backend */
334
350
  getAvailableModels: () => Promise<string[]>;
335
351
  /** Fetch authorized apps from backend */
@@ -369,4 +385,4 @@ type ControlContextProviderProps = {
369
385
  };
370
386
  declare function ControlContextProvider({ children, aomiClient, sessionId, publicKey, getThreadMetadata, updateThreadMetadata, }: ControlContextProviderProps): react_jsx_runtime.JSX.Element;
371
387
 
372
- export { type AomiRuntimeApi, AomiRuntimeProvider, type AomiRuntimeProviderProps, type ChainInfo, type ControlContextApi, ControlContextProvider, type ControlContextProviderProps, type ControlState, type EventContext, EventContextProvider, type EventContextProviderProps, type EventSubscriber, type InboundEvent, type Notification$1 as Notification, type NotificationApi, NotificationContextProvider, type NotificationContextProviderProps, type NotificationContextApi as NotificationContextValue, type NotificationHandlerConfig, type NotificationType, type SSEStatus, SUPPORTED_CHAINS, type NotificationData as ShowNotificationParams, type ThreadContext, ThreadContextProvider, type ThreadControlState, type ThreadMetadata, type UserConfig, UserContextProvider, type UserState, type WalletHandlerApi, type WalletHandlerConfig, type WalletRequestKind, type WalletRequestResult, type WalletRequestStatus, cn, formatAddress, getChainInfo, getNetworkName, initThreadControl, useAomiRuntime, useControl, useCurrentThreadMessages, useCurrentThreadMetadata, useEventContext, useNotification, useNotificationHandler, useThreadContext, useUser, useWalletHandler };
388
+ export { type AomiRuntimeApi, AomiRuntimeProvider, type AomiRuntimeProviderProps, type ChainInfo, type ControlContextApi, ControlContextProvider, type ControlContextProviderProps, type ControlState, type EventContext, EventContextProvider, type EventContextProviderProps, type EventSubscriber, type InboundEvent, type Notification$1 as Notification, type NotificationApi, NotificationContextProvider, type NotificationContextProviderProps, type NotificationContextApi as NotificationContextValue, type NotificationHandlerConfig, type NotificationType, type SSEStatus, SUPPORTED_CHAINS, type NotificationData as ShowNotificationParams, type StoredProviderKey, type ThreadContext, ThreadContextProvider, type ThreadControlState, type ThreadMetadata, type UserConfig, UserContextProvider, type UserState, type WalletHandlerApi, type WalletHandlerConfig, type WalletRequestKind, type WalletRequestResult, type WalletRequestStatus, cn, formatAddress, getChainInfo, getNetworkName, initThreadControl, useAomiRuntime, useControl, useCurrentThreadMessages, useCurrentThreadMetadata, useEventContext, useNotification, useNotificationHandler, useThreadContext, useUser, useWalletHandler };
package/dist/index.js CHANGED
@@ -17,6 +17,19 @@ var __spreadValues = (a, b) => {
17
17
  return a;
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __restKey = (key) => typeof key === "symbol" ? key : key + "";
21
+ var __objRest = (source, exclude) => {
22
+ var target = {};
23
+ for (var prop in source)
24
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
25
+ target[prop] = source[prop];
26
+ if (source != null && __getOwnPropSymbols)
27
+ for (var prop of __getOwnPropSymbols(source)) {
28
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
29
+ target[prop] = source[prop];
30
+ }
31
+ return target;
32
+ };
20
33
 
21
34
  // packages/react/src/index.ts
22
35
  import { AomiClient as AomiClient2 } from "@aomi-labs/client";
@@ -210,6 +223,25 @@ var ThreadStore = class {
210
223
  // packages/react/src/contexts/control-context.tsx
211
224
  import { jsx } from "react/jsx-runtime";
212
225
  var API_KEY_STORAGE_KEY = "aomi_api_key";
226
+ var CLIENT_ID_STORAGE_KEY = "aomi_client_id";
227
+ var PROVIDER_KEYS_STORAGE_KEY = "aomi_provider_keys";
228
+ var PROVIDER_KEY_SECRET_PREFIX = "PROVIDER_KEY:";
229
+ function getOrCreateClientId() {
230
+ var _a, _b, _c, _d, _e;
231
+ try {
232
+ const storedClientId = (_a = globalThis.localStorage) == null ? void 0 : _a.getItem(CLIENT_ID_STORAGE_KEY);
233
+ if (storedClientId && storedClientId.trim().length > 0) {
234
+ return storedClientId;
235
+ }
236
+ } catch (e) {
237
+ }
238
+ const clientId = (_d = (_c = (_b = globalThis.crypto) == null ? void 0 : _b.randomUUID) == null ? void 0 : _c.call(_b)) != null ? _d : `client-${Date.now()}`;
239
+ try {
240
+ (_e = globalThis.localStorage) == null ? void 0 : _e.setItem(CLIENT_ID_STORAGE_KEY, clientId);
241
+ } catch (e) {
242
+ }
243
+ return clientId;
244
+ }
213
245
  function getDefaultApp(apps) {
214
246
  var _a;
215
247
  return apps.includes("default") ? "default" : (_a = apps[0]) != null ? _a : null;
@@ -239,11 +271,12 @@ function ControlContextProvider({
239
271
  var _a, _b;
240
272
  const [state, setStateInternal] = useState(() => ({
241
273
  apiKey: null,
242
- clientId: null,
274
+ clientId: getOrCreateClientId(),
243
275
  availableModels: [],
244
276
  authorizedApps: [],
245
277
  defaultModel: null,
246
- defaultApp: null
278
+ defaultApp: null,
279
+ providerKeys: {}
247
280
  }));
248
281
  const stateRef = useRef(state);
249
282
  stateRef.current = state;
@@ -261,10 +294,14 @@ function ControlContextProvider({
261
294
  const currentThreadMetadata = getThreadMetadata(sessionId);
262
295
  const isProcessing = (_b = (_a = currentThreadMetadata == null ? void 0 : currentThreadMetadata.control) == null ? void 0 : _a.isProcessing) != null ? _b : false;
263
296
  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
- }, []);
297
+ var _a2;
298
+ try {
299
+ if (state.clientId) {
300
+ (_a2 = globalThis.localStorage) == null ? void 0 : _a2.setItem(CLIENT_ID_STORAGE_KEY, state.clientId);
301
+ }
302
+ } catch (e) {
303
+ }
304
+ }, [state.clientId]);
268
305
  useEffect(() => {
269
306
  var _a2, _b2;
270
307
  try {
@@ -275,6 +312,17 @@ function ControlContextProvider({
275
312
  } catch (e) {
276
313
  }
277
314
  }, []);
315
+ useEffect(() => {
316
+ var _a2;
317
+ try {
318
+ const raw = (_a2 = globalThis.localStorage) == null ? void 0 : _a2.getItem(PROVIDER_KEYS_STORAGE_KEY);
319
+ if (raw) {
320
+ const parsed = JSON.parse(raw);
321
+ setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), { providerKeys: parsed }));
322
+ }
323
+ } catch (e) {
324
+ }
325
+ }, []);
278
326
  useEffect(() => {
279
327
  var _a2, _b2;
280
328
  try {
@@ -286,6 +334,33 @@ function ControlContextProvider({
286
334
  } catch (e) {
287
335
  }
288
336
  }, [state.apiKey]);
337
+ useEffect(() => {
338
+ var _a2, _b2;
339
+ try {
340
+ const keys = state.providerKeys;
341
+ if (Object.keys(keys).length > 0) {
342
+ (_a2 = globalThis.localStorage) == null ? void 0 : _a2.setItem(
343
+ PROVIDER_KEYS_STORAGE_KEY,
344
+ JSON.stringify(keys)
345
+ );
346
+ } else {
347
+ (_b2 = globalThis.localStorage) == null ? void 0 : _b2.removeItem(PROVIDER_KEYS_STORAGE_KEY);
348
+ }
349
+ } catch (e) {
350
+ }
351
+ }, [state.providerKeys]);
352
+ useEffect(() => {
353
+ if (!state.clientId) return;
354
+ const keys = stateRef.current.providerKeys;
355
+ if (Object.keys(keys).length === 0) return;
356
+ const secrets = {};
357
+ for (const [provider, entry] of Object.entries(keys)) {
358
+ secrets[`${PROVIDER_KEY_SECRET_PREFIX}${provider}`] = entry.apiKey;
359
+ }
360
+ void aomiClientRef.current.ingestSecrets(state.clientId, secrets).catch((err) => {
361
+ console.error("Failed to auto-ingest provider keys:", err);
362
+ });
363
+ }, [state.clientId, state.providerKeys]);
289
364
  useEffect(() => {
290
365
  const fetchApps = async () => {
291
366
  var _a2;
@@ -356,6 +431,65 @@ function ControlContextProvider({
356
431
  if (!clientId) return;
357
432
  await ((_b2 = (_a2 = aomiClientRef.current).clearSecrets) == null ? void 0 : _b2.call(_a2, clientId));
358
433
  }, []);
434
+ const setProviderKey = useCallback(
435
+ async (provider, apiKey, label) => {
436
+ const trimmed = apiKey.trim();
437
+ if (!trimmed) return;
438
+ const entry = {
439
+ apiKey: trimmed,
440
+ keyPrefix: trimmed.slice(0, 7),
441
+ label
442
+ };
443
+ setStateInternal((prev) => {
444
+ const next = __spreadProps(__spreadValues({}, prev), {
445
+ providerKeys: __spreadProps(__spreadValues({}, prev.providerKeys), { [provider]: entry })
446
+ });
447
+ callbacks.current.forEach((cb) => cb(next));
448
+ return next;
449
+ });
450
+ const clientId = stateRef.current.clientId;
451
+ if (clientId) {
452
+ try {
453
+ await aomiClientRef.current.ingestSecrets(clientId, {
454
+ [`${PROVIDER_KEY_SECRET_PREFIX}${provider}`]: trimmed
455
+ });
456
+ } catch (err) {
457
+ console.error("Failed to ingest provider key:", err);
458
+ }
459
+ }
460
+ },
461
+ []
462
+ );
463
+ const removeProviderKey = useCallback(
464
+ async (provider) => {
465
+ const clientId = stateRef.current.clientId;
466
+ if (clientId) {
467
+ await aomiClientRef.current.deleteSecret(
468
+ clientId,
469
+ `${PROVIDER_KEY_SECRET_PREFIX}${provider}`
470
+ );
471
+ }
472
+ setStateInternal((prev) => {
473
+ const _a2 = prev.providerKeys, { [provider]: _ } = _a2, rest = __objRest(_a2, [__restKey(provider)]);
474
+ const next = __spreadProps(__spreadValues({}, prev), { providerKeys: rest });
475
+ callbacks.current.forEach((cb) => cb(next));
476
+ return next;
477
+ });
478
+ },
479
+ []
480
+ );
481
+ const getProviderKeys = useCallback(
482
+ () => stateRef.current.providerKeys,
483
+ []
484
+ );
485
+ const hasProviderKey = useCallback(
486
+ (provider) => {
487
+ const keys = stateRef.current.providerKeys;
488
+ if (provider) return provider in keys;
489
+ return Object.keys(keys).length > 0;
490
+ },
491
+ []
492
+ );
359
493
  const getAvailableModels = useCallback(async () => {
360
494
  try {
361
495
  const models = await aomiClientRef.current.getModels(
@@ -414,7 +548,7 @@ function ControlContextProvider({
414
548
  )) != null ? _c : "default";
415
549
  }, []);
416
550
  const onModelSelect = useCallback(async (model) => {
417
- var _a2, _b2, _c, _d;
551
+ var _a2, _b2, _c, _d, _e;
418
552
  const threadId = sessionIdRef.current;
419
553
  const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
420
554
  const isProcessing2 = currentControl.isProcessing;
@@ -455,7 +589,11 @@ function ControlContextProvider({
455
589
  const result = await aomiClientRef.current.setModel(
456
590
  threadId,
457
591
  model,
458
- { app, apiKey: (_d = stateRef.current.apiKey) != null ? _d : void 0 }
592
+ {
593
+ app,
594
+ apiKey: (_d = stateRef.current.apiKey) != null ? _d : void 0,
595
+ clientId: (_e = stateRef.current.clientId) != null ? _e : void 0
596
+ }
459
597
  );
460
598
  console.log("[control-context] onModelSelect backend result", result);
461
599
  } catch (err) {
@@ -538,6 +676,10 @@ function ControlContextProvider({
538
676
  setApiKey,
539
677
  ingestSecrets,
540
678
  clearSecrets,
679
+ setProviderKey,
680
+ removeProviderKey,
681
+ getProviderKeys,
682
+ hasProviderKey,
541
683
  getAvailableModels,
542
684
  getAuthorizedApps,
543
685
  getCurrentThreadControl,