@aomi-labs/react 0.3.14 → 0.3.15
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 +276 -106
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -2
- package/dist/index.d.ts +22 -2
- package/dist/index.js +275 -106
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -56,9 +56,12 @@ declare function useCurrentThreadMessages(): ThreadMessageLike[];
|
|
|
56
56
|
declare function useCurrentThreadMetadata(): ThreadMetadata | undefined;
|
|
57
57
|
|
|
58
58
|
type ThreadStatus = "regular" | "archived";
|
|
59
|
+
type ModelSelectionMode = "auto" | "manual";
|
|
59
60
|
type ThreadControlState = {
|
|
60
61
|
/** Selected model for this thread (human-readable label) */
|
|
61
62
|
model: string | null;
|
|
63
|
+
/** Whether the selected model should be displayed as auto or explicit */
|
|
64
|
+
modelMode?: ModelSelectionMode;
|
|
62
65
|
/** Selected app for this thread */
|
|
63
66
|
app: string | null;
|
|
64
67
|
/** Whether control state has changed but chat hasn't started yet */
|
|
@@ -327,12 +330,23 @@ declare const SUPPORTED_CHAINS: ChainInfo[];
|
|
|
327
330
|
/** Look up ChainInfo by chain ID. Returns undefined for unknown chains. */
|
|
328
331
|
declare const getChainInfo: (chainId: number | undefined) => ChainInfo | undefined;
|
|
329
332
|
|
|
333
|
+
/**
|
|
334
|
+
* Resolve the actual backend model for auto mode.
|
|
335
|
+
* Prefers known cheaper/performance-oriented models before falling back to the
|
|
336
|
+
* backend order.
|
|
337
|
+
*/
|
|
338
|
+
declare function resolveAutoModel(models: string[]): string | null;
|
|
339
|
+
|
|
330
340
|
/** A stored provider API key (BYOK) */
|
|
331
341
|
type StoredProviderKey = {
|
|
332
342
|
apiKey: string;
|
|
333
343
|
keyPrefix: string;
|
|
334
344
|
label?: string;
|
|
335
345
|
};
|
|
346
|
+
type StoredModelPreference = {
|
|
347
|
+
mode: ModelSelectionMode;
|
|
348
|
+
model: string | null;
|
|
349
|
+
};
|
|
336
350
|
/** Global control state (shared across all threads) */
|
|
337
351
|
type ControlState = {
|
|
338
352
|
/** API key for authenticated requests */
|
|
@@ -376,13 +390,19 @@ type ControlContextApi = {
|
|
|
376
390
|
/** Get the current thread's effective app after auth fallback */
|
|
377
391
|
getCurrentThreadApp: () => string;
|
|
378
392
|
/** Select a model for the current thread (updates metadata + calls backend) */
|
|
379
|
-
onModelSelect: (model: string
|
|
393
|
+
onModelSelect: (model: string, options?: {
|
|
394
|
+
mode?: ModelSelectionMode;
|
|
395
|
+
}) => Promise<void>;
|
|
380
396
|
/** Select an app for the current thread (updates metadata only) */
|
|
381
397
|
onAppSelect: (app: string) => void;
|
|
382
398
|
/** Whether the current thread is processing (disables control switching) */
|
|
383
399
|
isProcessing: boolean;
|
|
384
400
|
/** Mark control state as synced (called after chat starts) */
|
|
385
401
|
markControlSynced: () => void;
|
|
402
|
+
/** Sync pending control state to the backend before sending */
|
|
403
|
+
syncCurrentThreadControl: () => Promise<void>;
|
|
404
|
+
/** Build initial control state for new local threads */
|
|
405
|
+
getPreferredThreadControl: () => ThreadControlState;
|
|
386
406
|
/** Get global control state */
|
|
387
407
|
getControlState: () => ControlState;
|
|
388
408
|
/** Subscribe to global state changes */
|
|
@@ -406,4 +426,4 @@ type ControlContextProviderProps = {
|
|
|
406
426
|
};
|
|
407
427
|
declare function ControlContextProvider({ children, aomiClient, sessionId, publicKey, getThreadMetadata, updateThreadMetadata, }: ControlContextProviderProps): react_jsx_runtime.JSX.Element;
|
|
408
428
|
|
|
409
|
-
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, RuntimeUserStateProvider, type SSEStatus, SUPPORTED_CHAINS, type NotificationData as ShowNotificationParams, type StoredProviderKey, type ThreadContext, ThreadContextProvider, type ThreadControlState, type ThreadMetadata, type UserConfig, UserContextProvider, type WalletHandlerApi, type WalletHandlerConfig, type WalletRequestKind, type WalletRequestStatus, cn, formatAddress, getChainInfo, getNetworkName, initThreadControl, useAomiRuntime, useControl, useCurrentThreadMessages, useCurrentThreadMetadata, useEventContext, useNotification, useNotificationHandler, useThreadContext, useUser, useWalletHandler };
|
|
429
|
+
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 ModelSelectionMode, type Notification$1 as Notification, type NotificationApi, NotificationContextProvider, type NotificationContextProviderProps, type NotificationContextApi as NotificationContextValue, type NotificationHandlerConfig, type NotificationType, RuntimeUserStateProvider, type SSEStatus, SUPPORTED_CHAINS, type NotificationData as ShowNotificationParams, type StoredModelPreference, type StoredProviderKey, type ThreadContext, ThreadContextProvider, type ThreadControlState, type ThreadMetadata, type UserConfig, UserContextProvider, type WalletHandlerApi, type WalletHandlerConfig, type WalletRequestKind, type WalletRequestStatus, cn, formatAddress, getChainInfo, getNetworkName, initThreadControl, resolveAutoModel, useAomiRuntime, useControl, useCurrentThreadMessages, useCurrentThreadMetadata, useEventContext, useNotification, useNotificationHandler, useThreadContext, useUser, useWalletHandler };
|
package/dist/index.d.ts
CHANGED
|
@@ -56,9 +56,12 @@ declare function useCurrentThreadMessages(): ThreadMessageLike[];
|
|
|
56
56
|
declare function useCurrentThreadMetadata(): ThreadMetadata | undefined;
|
|
57
57
|
|
|
58
58
|
type ThreadStatus = "regular" | "archived";
|
|
59
|
+
type ModelSelectionMode = "auto" | "manual";
|
|
59
60
|
type ThreadControlState = {
|
|
60
61
|
/** Selected model for this thread (human-readable label) */
|
|
61
62
|
model: string | null;
|
|
63
|
+
/** Whether the selected model should be displayed as auto or explicit */
|
|
64
|
+
modelMode?: ModelSelectionMode;
|
|
62
65
|
/** Selected app for this thread */
|
|
63
66
|
app: string | null;
|
|
64
67
|
/** Whether control state has changed but chat hasn't started yet */
|
|
@@ -327,12 +330,23 @@ declare const SUPPORTED_CHAINS: ChainInfo[];
|
|
|
327
330
|
/** Look up ChainInfo by chain ID. Returns undefined for unknown chains. */
|
|
328
331
|
declare const getChainInfo: (chainId: number | undefined) => ChainInfo | undefined;
|
|
329
332
|
|
|
333
|
+
/**
|
|
334
|
+
* Resolve the actual backend model for auto mode.
|
|
335
|
+
* Prefers known cheaper/performance-oriented models before falling back to the
|
|
336
|
+
* backend order.
|
|
337
|
+
*/
|
|
338
|
+
declare function resolveAutoModel(models: string[]): string | null;
|
|
339
|
+
|
|
330
340
|
/** A stored provider API key (BYOK) */
|
|
331
341
|
type StoredProviderKey = {
|
|
332
342
|
apiKey: string;
|
|
333
343
|
keyPrefix: string;
|
|
334
344
|
label?: string;
|
|
335
345
|
};
|
|
346
|
+
type StoredModelPreference = {
|
|
347
|
+
mode: ModelSelectionMode;
|
|
348
|
+
model: string | null;
|
|
349
|
+
};
|
|
336
350
|
/** Global control state (shared across all threads) */
|
|
337
351
|
type ControlState = {
|
|
338
352
|
/** API key for authenticated requests */
|
|
@@ -376,13 +390,19 @@ type ControlContextApi = {
|
|
|
376
390
|
/** Get the current thread's effective app after auth fallback */
|
|
377
391
|
getCurrentThreadApp: () => string;
|
|
378
392
|
/** Select a model for the current thread (updates metadata + calls backend) */
|
|
379
|
-
onModelSelect: (model: string
|
|
393
|
+
onModelSelect: (model: string, options?: {
|
|
394
|
+
mode?: ModelSelectionMode;
|
|
395
|
+
}) => Promise<void>;
|
|
380
396
|
/** Select an app for the current thread (updates metadata only) */
|
|
381
397
|
onAppSelect: (app: string) => void;
|
|
382
398
|
/** Whether the current thread is processing (disables control switching) */
|
|
383
399
|
isProcessing: boolean;
|
|
384
400
|
/** Mark control state as synced (called after chat starts) */
|
|
385
401
|
markControlSynced: () => void;
|
|
402
|
+
/** Sync pending control state to the backend before sending */
|
|
403
|
+
syncCurrentThreadControl: () => Promise<void>;
|
|
404
|
+
/** Build initial control state for new local threads */
|
|
405
|
+
getPreferredThreadControl: () => ThreadControlState;
|
|
386
406
|
/** Get global control state */
|
|
387
407
|
getControlState: () => ControlState;
|
|
388
408
|
/** Subscribe to global state changes */
|
|
@@ -406,4 +426,4 @@ type ControlContextProviderProps = {
|
|
|
406
426
|
};
|
|
407
427
|
declare function ControlContextProvider({ children, aomiClient, sessionId, publicKey, getThreadMetadata, updateThreadMetadata, }: ControlContextProviderProps): react_jsx_runtime.JSX.Element;
|
|
408
428
|
|
|
409
|
-
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, RuntimeUserStateProvider, type SSEStatus, SUPPORTED_CHAINS, type NotificationData as ShowNotificationParams, type StoredProviderKey, type ThreadContext, ThreadContextProvider, type ThreadControlState, type ThreadMetadata, type UserConfig, UserContextProvider, type WalletHandlerApi, type WalletHandlerConfig, type WalletRequestKind, type WalletRequestStatus, cn, formatAddress, getChainInfo, getNetworkName, initThreadControl, useAomiRuntime, useControl, useCurrentThreadMessages, useCurrentThreadMetadata, useEventContext, useNotification, useNotificationHandler, useThreadContext, useUser, useWalletHandler };
|
|
429
|
+
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 ModelSelectionMode, type Notification$1 as Notification, type NotificationApi, NotificationContextProvider, type NotificationContextProviderProps, type NotificationContextApi as NotificationContextValue, type NotificationHandlerConfig, type NotificationType, RuntimeUserStateProvider, type SSEStatus, SUPPORTED_CHAINS, type NotificationData as ShowNotificationParams, type StoredModelPreference, type StoredProviderKey, type ThreadContext, ThreadContextProvider, type ThreadControlState, type ThreadMetadata, type UserConfig, UserContextProvider, type WalletHandlerApi, type WalletHandlerConfig, type WalletRequestKind, type WalletRequestStatus, cn, formatAddress, getChainInfo, getNetworkName, initThreadControl, resolveAutoModel, useAomiRuntime, useControl, useCurrentThreadMessages, useCurrentThreadMetadata, useEventContext, useNotification, useNotificationHandler, useThreadContext, useUser, useWalletHandler };
|
package/dist/index.js
CHANGED
|
@@ -90,6 +90,7 @@ var logThreadMetadataChange = (source, threadId, prev, next) => {
|
|
|
90
90
|
function initThreadControl() {
|
|
91
91
|
return {
|
|
92
92
|
model: null,
|
|
93
|
+
modelMode: "auto",
|
|
93
94
|
app: null,
|
|
94
95
|
controlDirty: false,
|
|
95
96
|
isProcessing: false
|
|
@@ -233,16 +234,36 @@ var ThreadStore = class {
|
|
|
233
234
|
}
|
|
234
235
|
};
|
|
235
236
|
|
|
237
|
+
// packages/react/src/utils/model-selection.ts
|
|
238
|
+
var PREFERRED_DEFAULT_MODEL_PATTERNS = [
|
|
239
|
+
/^claude-4\.5-haiku/i,
|
|
240
|
+
/^claude.*haiku/i,
|
|
241
|
+
/^gpt-4o-mini/i,
|
|
242
|
+
/^gemini.*flash/i
|
|
243
|
+
];
|
|
244
|
+
function resolveAutoModel(models) {
|
|
245
|
+
var _a;
|
|
246
|
+
if (models.length === 0) return null;
|
|
247
|
+
for (const pattern of PREFERRED_DEFAULT_MODEL_PATTERNS) {
|
|
248
|
+
const match = models.find((model) => pattern.test(model));
|
|
249
|
+
if (match) return match;
|
|
250
|
+
}
|
|
251
|
+
return (_a = models[0]) != null ? _a : null;
|
|
252
|
+
}
|
|
253
|
+
|
|
236
254
|
// packages/react/src/contexts/control-context.tsx
|
|
237
255
|
import { jsx } from "react/jsx-runtime";
|
|
238
256
|
var API_KEY_STORAGE_KEY = "aomi_api_key";
|
|
239
257
|
var CLIENT_ID_STORAGE_KEY = "aomi_client_id";
|
|
240
258
|
var PROVIDER_KEYS_STORAGE_KEY = "aomi_provider_keys";
|
|
259
|
+
var MODEL_SELECTION_STORAGE_KEY = "aomi_model_selection";
|
|
241
260
|
var PROVIDER_KEY_SECRET_PREFIX = "PROVIDER_KEY:";
|
|
242
261
|
function getOrCreateClientId() {
|
|
243
262
|
var _a, _b, _c, _d, _e;
|
|
244
263
|
try {
|
|
245
|
-
const storedClientId = (_a = globalThis.localStorage) == null ? void 0 : _a.getItem(
|
|
264
|
+
const storedClientId = (_a = globalThis.localStorage) == null ? void 0 : _a.getItem(
|
|
265
|
+
CLIENT_ID_STORAGE_KEY
|
|
266
|
+
);
|
|
246
267
|
if (storedClientId && storedClientId.trim().length > 0) {
|
|
247
268
|
return storedClientId;
|
|
248
269
|
}
|
|
@@ -259,6 +280,49 @@ function getDefaultApp(apps) {
|
|
|
259
280
|
var _a;
|
|
260
281
|
return apps.includes("default") ? "default" : (_a = apps[0]) != null ? _a : null;
|
|
261
282
|
}
|
|
283
|
+
function readStoredModelPreference() {
|
|
284
|
+
var _a;
|
|
285
|
+
try {
|
|
286
|
+
const raw = (_a = globalThis.localStorage) == null ? void 0 : _a.getItem(MODEL_SELECTION_STORAGE_KEY);
|
|
287
|
+
if (!raw) return { mode: "auto", model: null };
|
|
288
|
+
const parsed = JSON.parse(raw);
|
|
289
|
+
return {
|
|
290
|
+
mode: parsed.mode === "manual" ? "manual" : "auto",
|
|
291
|
+
model: typeof parsed.model === "string" ? parsed.model : null
|
|
292
|
+
};
|
|
293
|
+
} catch (e) {
|
|
294
|
+
return { mode: "auto", model: null };
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
function writeStoredModelPreference(preference) {
|
|
298
|
+
var _a;
|
|
299
|
+
try {
|
|
300
|
+
(_a = globalThis.localStorage) == null ? void 0 : _a.setItem(
|
|
301
|
+
MODEL_SELECTION_STORAGE_KEY,
|
|
302
|
+
JSON.stringify(preference)
|
|
303
|
+
);
|
|
304
|
+
} catch (e) {
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
function resolvePreferredModelSelection(preference, models, defaultModel) {
|
|
308
|
+
var _a;
|
|
309
|
+
if (preference.mode === "manual" && preference.model && models.includes(preference.model)) {
|
|
310
|
+
return preference;
|
|
311
|
+
}
|
|
312
|
+
if (preference.mode === "auto") {
|
|
313
|
+
return {
|
|
314
|
+
mode: "auto",
|
|
315
|
+
model: (_a = resolveAutoModel(models)) != null ? _a : defaultModel
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
return {
|
|
319
|
+
mode: "auto",
|
|
320
|
+
model: defaultModel != null ? defaultModel : resolveAutoModel(models)
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
function getFallbackModel(models, defaultModel) {
|
|
324
|
+
return defaultModel != null ? defaultModel : resolveAutoModel(models);
|
|
325
|
+
}
|
|
262
326
|
function resolveAuthorizedApp(app, authorizedApps, defaultApp) {
|
|
263
327
|
if (app && authorizedApps.includes(app)) {
|
|
264
328
|
return app;
|
|
@@ -378,13 +442,10 @@ function ControlContextProvider({
|
|
|
378
442
|
const fetchApps = async () => {
|
|
379
443
|
var _a2;
|
|
380
444
|
try {
|
|
381
|
-
const apps = await aomiClientRef.current.getApps(
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
apiKey: (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
|
|
386
|
-
}
|
|
387
|
-
);
|
|
445
|
+
const apps = await aomiClientRef.current.getApps(sessionIdRef.current, {
|
|
446
|
+
publicKey: publicKeyRef.current,
|
|
447
|
+
apiKey: (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
|
|
448
|
+
});
|
|
388
449
|
const defaultApp = getDefaultApp(apps);
|
|
389
450
|
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
390
451
|
authorizedApps: apps,
|
|
@@ -406,13 +467,10 @@ function ControlContextProvider({
|
|
|
406
467
|
const models = await aomiClientRef.current.getModels(
|
|
407
468
|
sessionIdRef.current
|
|
408
469
|
);
|
|
409
|
-
setStateInternal((prev) => {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
defaultModel: (_a2 = models[0]) != null ? _a2 : null
|
|
414
|
-
});
|
|
415
|
-
});
|
|
470
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
471
|
+
availableModels: models,
|
|
472
|
+
defaultModel: resolveAutoModel(models)
|
|
473
|
+
}));
|
|
416
474
|
} catch (error) {
|
|
417
475
|
console.error("Failed to fetch models:", error);
|
|
418
476
|
}
|
|
@@ -495,26 +553,20 @@ function ControlContextProvider({
|
|
|
495
553
|
() => stateRef.current.providerKeys,
|
|
496
554
|
[]
|
|
497
555
|
);
|
|
498
|
-
const hasProviderKey = useCallback(
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
},
|
|
504
|
-
[]
|
|
505
|
-
);
|
|
556
|
+
const hasProviderKey = useCallback((provider) => {
|
|
557
|
+
const keys = stateRef.current.providerKeys;
|
|
558
|
+
if (provider) return provider in keys;
|
|
559
|
+
return Object.keys(keys).length > 0;
|
|
560
|
+
}, []);
|
|
506
561
|
const getAvailableModels = useCallback(async () => {
|
|
507
562
|
try {
|
|
508
563
|
const models = await aomiClientRef.current.getModels(
|
|
509
564
|
sessionIdRef.current
|
|
510
565
|
);
|
|
511
|
-
setStateInternal((prev) => {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
defaultModel: (_b2 = (_a2 = prev.defaultModel) != null ? _a2 : models[0]) != null ? _b2 : null
|
|
516
|
-
});
|
|
517
|
-
});
|
|
566
|
+
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
567
|
+
availableModels: models,
|
|
568
|
+
defaultModel: resolveAutoModel(models)
|
|
569
|
+
}));
|
|
518
570
|
return models;
|
|
519
571
|
} catch (error) {
|
|
520
572
|
console.error("Failed to fetch models:", error);
|
|
@@ -524,13 +576,10 @@ function ControlContextProvider({
|
|
|
524
576
|
const getAuthorizedApps = useCallback(async () => {
|
|
525
577
|
var _a2;
|
|
526
578
|
try {
|
|
527
|
-
const apps = await aomiClientRef.current.getApps(
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
apiKey: (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
|
|
532
|
-
}
|
|
533
|
-
);
|
|
579
|
+
const apps = await aomiClientRef.current.getApps(sessionIdRef.current, {
|
|
580
|
+
publicKey: publicKeyRef.current,
|
|
581
|
+
apiKey: (_a2 = stateRef.current.apiKey) != null ? _a2 : void 0
|
|
582
|
+
});
|
|
534
583
|
const defaultApp = getDefaultApp(apps);
|
|
535
584
|
setStateInternal((prev) => __spreadProps(__spreadValues({}, prev), {
|
|
536
585
|
authorizedApps: apps,
|
|
@@ -551,6 +600,19 @@ function ControlContextProvider({
|
|
|
551
600
|
const metadata = getThreadMetadataRef.current(sessionIdRef.current);
|
|
552
601
|
return (_a2 = metadata == null ? void 0 : metadata.control) != null ? _a2 : initThreadControl();
|
|
553
602
|
}, []);
|
|
603
|
+
const getPreferredThreadControl = useCallback(() => {
|
|
604
|
+
const preference = readStoredModelPreference();
|
|
605
|
+
const selection = resolvePreferredModelSelection(
|
|
606
|
+
preference,
|
|
607
|
+
stateRef.current.availableModels,
|
|
608
|
+
stateRef.current.defaultModel
|
|
609
|
+
);
|
|
610
|
+
return __spreadProps(__spreadValues({}, initThreadControl()), {
|
|
611
|
+
model: selection.model,
|
|
612
|
+
modelMode: selection.mode,
|
|
613
|
+
controlDirty: selection.model !== null
|
|
614
|
+
});
|
|
615
|
+
}, []);
|
|
554
616
|
const getCurrentThreadApp = useCallback(() => {
|
|
555
617
|
var _a2, _b2, _c;
|
|
556
618
|
const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(sessionIdRef.current)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
|
|
@@ -560,60 +622,75 @@ function ControlContextProvider({
|
|
|
560
622
|
stateRef.current.defaultApp
|
|
561
623
|
)) != null ? _c : "default";
|
|
562
624
|
}, []);
|
|
563
|
-
const onModelSelect = useCallback(
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
});
|
|
588
|
-
updateThreadMetadataRef.current(threadId, {
|
|
589
|
-
control: __spreadProps(__spreadValues({}, currentControl), {
|
|
625
|
+
const onModelSelect = useCallback(
|
|
626
|
+
async (model, options) => {
|
|
627
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h;
|
|
628
|
+
const threadId = sessionIdRef.current;
|
|
629
|
+
const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
|
|
630
|
+
const isProcessing2 = currentControl.isProcessing;
|
|
631
|
+
const modelMode = (_c = options == null ? void 0 : options.mode) != null ? _c : "manual";
|
|
632
|
+
console.log("[control-context] onModelSelect called", {
|
|
633
|
+
model,
|
|
634
|
+
modelMode,
|
|
635
|
+
isProcessing: isProcessing2,
|
|
636
|
+
threadId
|
|
637
|
+
});
|
|
638
|
+
if (isProcessing2) {
|
|
639
|
+
console.warn("[control-context] Cannot switch model while processing");
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
const app = (_d = resolveAuthorizedApp(
|
|
643
|
+
currentControl.app,
|
|
644
|
+
stateRef.current.authorizedApps,
|
|
645
|
+
stateRef.current.defaultApp
|
|
646
|
+
)) != null ? _d : "default";
|
|
647
|
+
console.log("[control-context] onModelSelect updating metadata", {
|
|
648
|
+
threadId,
|
|
590
649
|
model,
|
|
591
650
|
app,
|
|
592
|
-
|
|
593
|
-
})
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
651
|
+
currentControl
|
|
652
|
+
});
|
|
653
|
+
updateThreadMetadataRef.current(threadId, {
|
|
654
|
+
control: __spreadProps(__spreadValues({}, currentControl), {
|
|
655
|
+
model,
|
|
656
|
+
modelMode,
|
|
657
|
+
app,
|
|
658
|
+
controlDirty: true
|
|
659
|
+
})
|
|
660
|
+
});
|
|
661
|
+
console.log("[control-context] onModelSelect calling backend setModel", {
|
|
603
662
|
threadId,
|
|
604
663
|
model,
|
|
605
|
-
|
|
664
|
+
app,
|
|
665
|
+
backendUrl: aomiClientRef.current
|
|
666
|
+
});
|
|
667
|
+
try {
|
|
668
|
+
const result = await aomiClientRef.current.setModel(threadId, model, {
|
|
606
669
|
app,
|
|
607
|
-
apiKey: (
|
|
608
|
-
clientId: (
|
|
670
|
+
apiKey: (_e = stateRef.current.apiKey) != null ? _e : void 0,
|
|
671
|
+
clientId: (_f = stateRef.current.clientId) != null ? _f : void 0
|
|
672
|
+
});
|
|
673
|
+
console.log("[control-context] onModelSelect backend result", result);
|
|
674
|
+
writeStoredModelPreference({
|
|
675
|
+
mode: modelMode,
|
|
676
|
+
model: modelMode === "manual" ? model : null
|
|
677
|
+
});
|
|
678
|
+
const latestControl = (_h = (_g = getThreadMetadataRef.current(threadId)) == null ? void 0 : _g.control) != null ? _h : currentControl;
|
|
679
|
+
if (latestControl.model === model && latestControl.app === app) {
|
|
680
|
+
updateThreadMetadataRef.current(threadId, {
|
|
681
|
+
control: __spreadProps(__spreadValues({}, latestControl), {
|
|
682
|
+
modelMode,
|
|
683
|
+
controlDirty: false
|
|
684
|
+
})
|
|
685
|
+
});
|
|
609
686
|
}
|
|
610
|
-
)
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
687
|
+
} catch (err) {
|
|
688
|
+
console.error("[control-context] setModel failed:", err);
|
|
689
|
+
throw err;
|
|
690
|
+
}
|
|
691
|
+
},
|
|
692
|
+
[]
|
|
693
|
+
);
|
|
617
694
|
const onAppSelect = useCallback((app) => {
|
|
618
695
|
var _a2, _b2;
|
|
619
696
|
const threadId = sessionIdRef.current;
|
|
@@ -625,9 +702,7 @@ function ControlContextProvider({
|
|
|
625
702
|
threadId
|
|
626
703
|
});
|
|
627
704
|
if (isProcessing2) {
|
|
628
|
-
console.warn(
|
|
629
|
-
"[control-context] Cannot switch app while processing"
|
|
630
|
-
);
|
|
705
|
+
console.warn("[control-context] Cannot switch app while processing");
|
|
631
706
|
return;
|
|
632
707
|
}
|
|
633
708
|
if (stateRef.current.authorizedApps.length > 0 && !stateRef.current.authorizedApps.includes(app)) {
|
|
@@ -659,6 +734,86 @@ function ControlContextProvider({
|
|
|
659
734
|
});
|
|
660
735
|
}
|
|
661
736
|
}, []);
|
|
737
|
+
const syncCurrentThreadControl = useCallback(async () => {
|
|
738
|
+
var _a2, _b2, _c, _d, _e, _f, _g;
|
|
739
|
+
const threadId = sessionIdRef.current;
|
|
740
|
+
const currentControl = (_b2 = (_a2 = getThreadMetadataRef.current(threadId)) == null ? void 0 : _a2.control) != null ? _b2 : initThreadControl();
|
|
741
|
+
if (!currentControl.controlDirty || currentControl.isProcessing || !currentControl.model) {
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
const app = (_c = resolveAuthorizedApp(
|
|
745
|
+
currentControl.app,
|
|
746
|
+
stateRef.current.authorizedApps,
|
|
747
|
+
stateRef.current.defaultApp
|
|
748
|
+
)) != null ? _c : "default";
|
|
749
|
+
await aomiClientRef.current.setModel(threadId, currentControl.model, {
|
|
750
|
+
app,
|
|
751
|
+
apiKey: (_d = stateRef.current.apiKey) != null ? _d : void 0,
|
|
752
|
+
clientId: (_e = stateRef.current.clientId) != null ? _e : void 0
|
|
753
|
+
});
|
|
754
|
+
const latestControl = (_g = (_f = getThreadMetadataRef.current(threadId)) == null ? void 0 : _f.control) != null ? _g : currentControl;
|
|
755
|
+
if (latestControl.model === currentControl.model && latestControl.app === currentControl.app) {
|
|
756
|
+
updateThreadMetadataRef.current(threadId, {
|
|
757
|
+
control: __spreadProps(__spreadValues({}, latestControl), {
|
|
758
|
+
app,
|
|
759
|
+
controlDirty: false
|
|
760
|
+
})
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
}, []);
|
|
764
|
+
useEffect(() => {
|
|
765
|
+
var _a2;
|
|
766
|
+
const threadId = sessionIdRef.current;
|
|
767
|
+
const metadata = getThreadMetadataRef.current(threadId);
|
|
768
|
+
if (!metadata || metadata.control.isProcessing) return;
|
|
769
|
+
const currentControl = metadata.control;
|
|
770
|
+
let nextControl = null;
|
|
771
|
+
if (currentControl.model === null) {
|
|
772
|
+
const preferred = getPreferredThreadControl();
|
|
773
|
+
if (!preferred.model) return;
|
|
774
|
+
nextControl = __spreadProps(__spreadValues({}, currentControl), {
|
|
775
|
+
model: preferred.model,
|
|
776
|
+
modelMode: preferred.modelMode,
|
|
777
|
+
controlDirty: true
|
|
778
|
+
});
|
|
779
|
+
} else if (state.availableModels.length > 0) {
|
|
780
|
+
const currentMode = (_a2 = currentControl.modelMode) != null ? _a2 : "manual";
|
|
781
|
+
if (currentMode === "auto") {
|
|
782
|
+
const autoModel = getFallbackModel(
|
|
783
|
+
state.availableModels,
|
|
784
|
+
state.defaultModel
|
|
785
|
+
);
|
|
786
|
+
if (autoModel && currentControl.model !== autoModel) {
|
|
787
|
+
nextControl = __spreadProps(__spreadValues({}, currentControl), {
|
|
788
|
+
model: autoModel,
|
|
789
|
+
modelMode: "auto",
|
|
790
|
+
controlDirty: true
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
} else if (!state.availableModels.includes(currentControl.model)) {
|
|
794
|
+
const fallbackModel = getFallbackModel(
|
|
795
|
+
state.availableModels,
|
|
796
|
+
state.defaultModel
|
|
797
|
+
);
|
|
798
|
+
if (fallbackModel) {
|
|
799
|
+
nextControl = __spreadProps(__spreadValues({}, currentControl), {
|
|
800
|
+
model: fallbackModel,
|
|
801
|
+
modelMode: "auto",
|
|
802
|
+
controlDirty: true
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
if (!nextControl) return;
|
|
808
|
+
updateThreadMetadataRef.current(threadId, {
|
|
809
|
+
control: nextControl
|
|
810
|
+
});
|
|
811
|
+
}, [
|
|
812
|
+
getPreferredThreadControl,
|
|
813
|
+
sessionId,
|
|
814
|
+
state.availableModels,
|
|
815
|
+
state.defaultModel
|
|
816
|
+
]);
|
|
662
817
|
const getControlState = useCallback(() => stateRef.current, []);
|
|
663
818
|
const onControlStateChange = useCallback(
|
|
664
819
|
(callback) => {
|
|
@@ -701,6 +856,8 @@ function ControlContextProvider({
|
|
|
701
856
|
onAppSelect,
|
|
702
857
|
isProcessing,
|
|
703
858
|
markControlSynced,
|
|
859
|
+
syncCurrentThreadControl,
|
|
860
|
+
getPreferredThreadControl,
|
|
704
861
|
getControlState,
|
|
705
862
|
onControlStateChange,
|
|
706
863
|
setState
|
|
@@ -1363,7 +1520,8 @@ function buildThreadLists(threadMetadata) {
|
|
|
1363
1520
|
function buildThreadListAdapter({
|
|
1364
1521
|
aomiClientRef,
|
|
1365
1522
|
threadContext,
|
|
1366
|
-
setIsRunning
|
|
1523
|
+
setIsRunning,
|
|
1524
|
+
getInitialControl = initThreadControl
|
|
1367
1525
|
}) {
|
|
1368
1526
|
const { regularThreads, archivedThreads } = buildThreadLists(
|
|
1369
1527
|
threadContext.allThreadsMetadata
|
|
@@ -1379,7 +1537,7 @@ function buildThreadListAdapter({
|
|
|
1379
1537
|
title: "New Chat",
|
|
1380
1538
|
status: "regular",
|
|
1381
1539
|
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1382
|
-
control:
|
|
1540
|
+
control: getInitialControl()
|
|
1383
1541
|
})
|
|
1384
1542
|
);
|
|
1385
1543
|
threadContext.setThreadMessages(threadId, []);
|
|
@@ -1451,7 +1609,7 @@ function buildThreadListAdapter({
|
|
|
1451
1609
|
title: "New Chat",
|
|
1452
1610
|
status: "regular",
|
|
1453
1611
|
lastActiveAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1454
|
-
control:
|
|
1612
|
+
control: getInitialControl()
|
|
1455
1613
|
})
|
|
1456
1614
|
);
|
|
1457
1615
|
threadContext.setThreadMessages(defaultId, []);
|
|
@@ -1613,7 +1771,12 @@ function AomiRuntimeCore({
|
|
|
1613
1771
|
const eventContext = useEventContext();
|
|
1614
1772
|
const notificationContext = useNotification();
|
|
1615
1773
|
const { user, onUserStateChange, getUserState } = useUser();
|
|
1616
|
-
const {
|
|
1774
|
+
const {
|
|
1775
|
+
getControlState,
|
|
1776
|
+
getCurrentThreadApp,
|
|
1777
|
+
getPreferredThreadControl,
|
|
1778
|
+
syncCurrentThreadControl
|
|
1779
|
+
} = useControl();
|
|
1617
1780
|
const sessionManagerRef = useRef8(null);
|
|
1618
1781
|
const walletHandler = useWalletHandler({
|
|
1619
1782
|
getSession: () => {
|
|
@@ -1699,18 +1862,15 @@ function AomiRuntimeCore({
|
|
|
1699
1862
|
[aomiClientRef, getUserState]
|
|
1700
1863
|
);
|
|
1701
1864
|
useEffect4(() => {
|
|
1702
|
-
const unsubscribe = eventContext.subscribe(
|
|
1703
|
-
|
|
1704
|
-
()
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
});
|
|
1712
|
-
}
|
|
1713
|
-
);
|
|
1865
|
+
const unsubscribe = eventContext.subscribe("user_state_request", () => {
|
|
1866
|
+
var _a, _b, _c;
|
|
1867
|
+
const session = (_b = (_a = sessionManagerRef.current) == null ? void 0 : _a.get(threadContext.currentThreadId)) != null ? _b : getSession(threadContext.currentThreadId);
|
|
1868
|
+
eventContext.sendOutboundSystem({
|
|
1869
|
+
type: "user_state_response",
|
|
1870
|
+
sessionId: threadContext.currentThreadId,
|
|
1871
|
+
payload: (_c = session.getUserState()) != null ? _c : getUserState()
|
|
1872
|
+
});
|
|
1873
|
+
});
|
|
1714
1874
|
return unsubscribe;
|
|
1715
1875
|
}, [eventContext, threadContext.currentThreadId, getSession, getUserState]);
|
|
1716
1876
|
useEffect4(() => {
|
|
@@ -1799,10 +1959,12 @@ function AomiRuntimeCore({
|
|
|
1799
1959
|
() => buildThreadListAdapter({
|
|
1800
1960
|
aomiClientRef,
|
|
1801
1961
|
threadContext,
|
|
1802
|
-
setIsRunning
|
|
1962
|
+
setIsRunning,
|
|
1963
|
+
getInitialControl: getPreferredThreadControl
|
|
1803
1964
|
}),
|
|
1804
1965
|
[
|
|
1805
1966
|
aomiClientRef,
|
|
1967
|
+
getPreferredThreadControl,
|
|
1806
1968
|
setIsRunning,
|
|
1807
1969
|
threadContext,
|
|
1808
1970
|
threadContext.currentThreadId,
|
|
@@ -1848,6 +2010,7 @@ function AomiRuntimeCore({
|
|
|
1848
2010
|
(part) => part.type === "text"
|
|
1849
2011
|
).map((part) => part.text).join("\n");
|
|
1850
2012
|
if (text) {
|
|
2013
|
+
await syncCurrentThreadControl();
|
|
1851
2014
|
await orchestratorSendMessage(text, threadContext.currentThreadId);
|
|
1852
2015
|
}
|
|
1853
2016
|
},
|
|
@@ -1865,9 +2028,14 @@ function AomiRuntimeCore({
|
|
|
1865
2028
|
const userContext = useUser();
|
|
1866
2029
|
const sendMessage = useCallback7(
|
|
1867
2030
|
async (text) => {
|
|
2031
|
+
await syncCurrentThreadControl();
|
|
1868
2032
|
await orchestratorSendMessage(text, threadContext.currentThreadId);
|
|
1869
2033
|
},
|
|
1870
|
-
[
|
|
2034
|
+
[
|
|
2035
|
+
orchestratorSendMessage,
|
|
2036
|
+
syncCurrentThreadControl,
|
|
2037
|
+
threadContext.currentThreadId
|
|
2038
|
+
]
|
|
1871
2039
|
);
|
|
1872
2040
|
const cancelGeneration = useCallback7(() => {
|
|
1873
2041
|
void orchestratorCancel(threadContext.currentThreadId);
|
|
@@ -2101,6 +2269,7 @@ export {
|
|
|
2101
2269
|
initThreadControl,
|
|
2102
2270
|
normalizeSimulatedFee,
|
|
2103
2271
|
parseChainId,
|
|
2272
|
+
resolveAutoModel,
|
|
2104
2273
|
toAAWalletCall,
|
|
2105
2274
|
toAAWalletCalls,
|
|
2106
2275
|
toViemSignTypedDataArgs,
|