File size: 1,722 Bytes
5f40163 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | import { create } from "zustand";
import type { FreeModelSet } from "#/utils/format-model-name";
interface FreeModelsState {
/**
* DB-driven set of free ``provider/model`` ids (the same channel that carries
* `verified`). Empty on backends without free metadata (e.g. the local
* agent-server), so consumers uniformly treat "not in set" as paid.
*/
freeModels: FreeModelSet;
/** DB-driven default OpenHands model id (``openhands/<model>``), or null. */
defaultModel: string | null;
/** True once the backend flags query has settled at least once. */
defaultModelReady: boolean;
}
interface FreeModelsActions {
/**
* Replaces the DB-driven flags. Called once by the app-level hydrator
* ({@link useHydrateFreeModels}) after the backend model list is fetched, so
* leaf components can read the flags synchronously via zustand selectors
* without needing a QueryClientProvider in scope.
*/
setFlags: (flags: {
freeModels: FreeModelSet;
defaultModel: string | null;
}) => void;
markDefaultModelReady: () => void;
resetFlags: () => void;
}
type FreeModelsStore = FreeModelsState & FreeModelsActions;
const EMPTY_FREE_MODELS: FreeModelSet = new Set<string>();
export const useFreeModelsStore = create<FreeModelsStore>()((set) => ({
freeModels: EMPTY_FREE_MODELS,
defaultModel: null,
defaultModelReady: false,
setFlags: (flags) =>
set({
freeModels: flags.freeModels,
defaultModel: flags.defaultModel,
defaultModelReady: true,
}),
markDefaultModelReady: () => set({ defaultModelReady: true }),
resetFlags: () =>
set({
freeModels: EMPTY_FREE_MODELS,
defaultModel: null,
defaultModelReady: false,
}),
}));
|