mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-04 21:23:07 +00:00
feat(opencode): persist dynamic model selection
This commit is contained in:
@@ -158,6 +158,8 @@ export function parseLocalStorageSettings(): Partial<GlobalSettings> | null {
|
|||||||
cursorDefaultModel: state.cursorDefaultModel as GlobalSettings['cursorDefaultModel'],
|
cursorDefaultModel: state.cursorDefaultModel as GlobalSettings['cursorDefaultModel'],
|
||||||
enabledOpencodeModels: state.enabledOpencodeModels as GlobalSettings['enabledOpencodeModels'],
|
enabledOpencodeModels: state.enabledOpencodeModels as GlobalSettings['enabledOpencodeModels'],
|
||||||
opencodeDefaultModel: state.opencodeDefaultModel as GlobalSettings['opencodeDefaultModel'],
|
opencodeDefaultModel: state.opencodeDefaultModel as GlobalSettings['opencodeDefaultModel'],
|
||||||
|
enabledDynamicModelIds:
|
||||||
|
state.enabledDynamicModelIds as GlobalSettings['enabledDynamicModelIds'],
|
||||||
autoLoadClaudeMd: state.autoLoadClaudeMd as boolean,
|
autoLoadClaudeMd: state.autoLoadClaudeMd as boolean,
|
||||||
keyboardShortcuts: state.keyboardShortcuts as GlobalSettings['keyboardShortcuts'],
|
keyboardShortcuts: state.keyboardShortcuts as GlobalSettings['keyboardShortcuts'],
|
||||||
mcpServers: state.mcpServers as GlobalSettings['mcpServers'],
|
mcpServers: state.mcpServers as GlobalSettings['mcpServers'],
|
||||||
@@ -517,6 +519,12 @@ export function hydrateStoreFromSettings(settings: GlobalSettings): void {
|
|||||||
sanitizedEnabledOpencodeModels.push(sanitizedOpencodeDefaultModel);
|
sanitizedEnabledOpencodeModels.push(sanitizedOpencodeDefaultModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const persistedDynamicModelIds =
|
||||||
|
settings.enabledDynamicModelIds ?? current.enabledDynamicModelIds;
|
||||||
|
const sanitizedDynamicModelIds = persistedDynamicModelIds.filter(
|
||||||
|
(modelId) => !modelId.startsWith('amazon-bedrock/')
|
||||||
|
);
|
||||||
|
|
||||||
// Convert ProjectRef[] to Project[] (minimal data, features will be loaded separately)
|
// Convert ProjectRef[] to Project[] (minimal data, features will be loaded separately)
|
||||||
const projects = (settings.projects ?? []).map((ref) => ({
|
const projects = (settings.projects ?? []).map((ref) => ({
|
||||||
id: ref.id,
|
id: ref.id,
|
||||||
@@ -562,6 +570,7 @@ export function hydrateStoreFromSettings(settings: GlobalSettings): void {
|
|||||||
cursorDefaultModel: settings.cursorDefaultModel ?? 'auto',
|
cursorDefaultModel: settings.cursorDefaultModel ?? 'auto',
|
||||||
enabledOpencodeModels: sanitizedEnabledOpencodeModels,
|
enabledOpencodeModels: sanitizedEnabledOpencodeModels,
|
||||||
opencodeDefaultModel: sanitizedOpencodeDefaultModel,
|
opencodeDefaultModel: sanitizedOpencodeDefaultModel,
|
||||||
|
enabledDynamicModelIds: sanitizedDynamicModelIds,
|
||||||
autoLoadClaudeMd: settings.autoLoadClaudeMd ?? false,
|
autoLoadClaudeMd: settings.autoLoadClaudeMd ?? false,
|
||||||
skipSandboxWarning: settings.skipSandboxWarning ?? false,
|
skipSandboxWarning: settings.skipSandboxWarning ?? false,
|
||||||
keyboardShortcuts: {
|
keyboardShortcuts: {
|
||||||
@@ -615,6 +624,7 @@ function buildSettingsUpdateFromStore(): Record<string, unknown> {
|
|||||||
enhancementModel: state.enhancementModel,
|
enhancementModel: state.enhancementModel,
|
||||||
validationModel: state.validationModel,
|
validationModel: state.validationModel,
|
||||||
phaseModels: state.phaseModels,
|
phaseModels: state.phaseModels,
|
||||||
|
enabledDynamicModelIds: state.enabledDynamicModelIds,
|
||||||
autoLoadClaudeMd: state.autoLoadClaudeMd,
|
autoLoadClaudeMd: state.autoLoadClaudeMd,
|
||||||
skipSandboxWarning: state.skipSandboxWarning,
|
skipSandboxWarning: state.skipSandboxWarning,
|
||||||
keyboardShortcuts: state.keyboardShortcuts,
|
keyboardShortcuts: state.keyboardShortcuts,
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ const SETTINGS_FIELDS_TO_SYNC = [
|
|||||||
'cursorDefaultModel',
|
'cursorDefaultModel',
|
||||||
'enabledOpencodeModels',
|
'enabledOpencodeModels',
|
||||||
'opencodeDefaultModel',
|
'opencodeDefaultModel',
|
||||||
|
'enabledDynamicModelIds',
|
||||||
'autoLoadClaudeMd',
|
'autoLoadClaudeMd',
|
||||||
'keyboardShortcuts',
|
'keyboardShortcuts',
|
||||||
'mcpServers',
|
'mcpServers',
|
||||||
|
|||||||
@@ -592,7 +592,7 @@ export interface AppState {
|
|||||||
// Dynamic models are session-only (not persisted) because they're discovered at runtime
|
// Dynamic models are session-only (not persisted) because they're discovered at runtime
|
||||||
// from `opencode models` CLI and depend on current provider authentication state
|
// from `opencode models` CLI and depend on current provider authentication state
|
||||||
dynamicOpencodeModels: ModelDefinition[]; // Dynamically discovered models from OpenCode CLI
|
dynamicOpencodeModels: ModelDefinition[]; // Dynamically discovered models from OpenCode CLI
|
||||||
enabledDynamicModelIds: string[]; // Which dynamic models are enabled (session-only)
|
enabledDynamicModelIds: string[]; // Which dynamic models are enabled
|
||||||
cachedOpencodeProviders: Array<{
|
cachedOpencodeProviders: Array<{
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
@@ -1241,7 +1241,7 @@ const initialState: AppState = {
|
|||||||
enabledOpencodeModels: getAllOpencodeModelIds(), // All OpenCode models enabled by default
|
enabledOpencodeModels: getAllOpencodeModelIds(), // All OpenCode models enabled by default
|
||||||
opencodeDefaultModel: DEFAULT_OPENCODE_MODEL, // Default to OpenCode free tier
|
opencodeDefaultModel: DEFAULT_OPENCODE_MODEL, // Default to OpenCode free tier
|
||||||
dynamicOpencodeModels: [], // Empty until fetched from OpenCode CLI
|
dynamicOpencodeModels: [], // Empty until fetched from OpenCode CLI
|
||||||
enabledDynamicModelIds: [], // All dynamic models enabled by default (populated when models are fetched)
|
enabledDynamicModelIds: [], // Empty until user enables dynamic models
|
||||||
cachedOpencodeProviders: [], // Empty until fetched from OpenCode CLI
|
cachedOpencodeProviders: [], // Empty until fetched from OpenCode CLI
|
||||||
autoLoadClaudeMd: false, // Default to disabled (user must opt-in)
|
autoLoadClaudeMd: false, // Default to disabled (user must opt-in)
|
||||||
skipSandboxWarning: false, // Default to disabled (show sandbox warning dialog)
|
skipSandboxWarning: false, // Default to disabled (show sandbox warning dialog)
|
||||||
@@ -2041,9 +2041,8 @@ export const useAppStore = create<AppState & AppActions>()((set, get) => ({
|
|||||||
: state.enabledOpencodeModels.filter((m) => m !== model),
|
: state.enabledOpencodeModels.filter((m) => m !== model),
|
||||||
})),
|
})),
|
||||||
setDynamicOpencodeModels: (models) => {
|
setDynamicOpencodeModels: (models) => {
|
||||||
// Dynamic models are session-only (not persisted to server) because they depend on
|
// Dynamic models depend on CLI authentication state and are re-discovered each session.
|
||||||
// current CLI authentication state and are re-discovered each session
|
// Persist enabled model IDs, but do not auto-enable new models.
|
||||||
// When setting dynamic models, auto-enable all of them if enabledDynamicModelIds is empty
|
|
||||||
const filteredModels = models.filter(
|
const filteredModels = models.filter(
|
||||||
(model) =>
|
(model) =>
|
||||||
model.provider !== OPENCODE_BEDROCK_PROVIDER_ID &&
|
model.provider !== OPENCODE_BEDROCK_PROVIDER_ID &&
|
||||||
@@ -2051,14 +2050,10 @@ export const useAppStore = create<AppState & AppActions>()((set, get) => ({
|
|||||||
);
|
);
|
||||||
const currentEnabled = get().enabledDynamicModelIds;
|
const currentEnabled = get().enabledDynamicModelIds;
|
||||||
const newModelIds = filteredModels.map((m) => m.id);
|
const newModelIds = filteredModels.map((m) => m.id);
|
||||||
|
const filteredEnabled = currentEnabled.filter((modelId) => newModelIds.includes(modelId));
|
||||||
|
|
||||||
// If no models were previously enabled, enable all new ones
|
const nextEnabled = currentEnabled.length === 0 ? [] : filteredEnabled;
|
||||||
if (currentEnabled.length === 0) {
|
set({ dynamicOpencodeModels: filteredModels, enabledDynamicModelIds: nextEnabled });
|
||||||
set({ dynamicOpencodeModels: filteredModels, enabledDynamicModelIds: newModelIds });
|
|
||||||
} else {
|
|
||||||
// Keep existing enabled state, just update the models list
|
|
||||||
set({ dynamicOpencodeModels: filteredModels });
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
setEnabledDynamicModelIds: (ids) => set({ enabledDynamicModelIds: ids }),
|
setEnabledDynamicModelIds: (ids) => set({ enabledDynamicModelIds: ids }),
|
||||||
toggleDynamicModel: (modelId, enabled) =>
|
toggleDynamicModel: (modelId, enabled) =>
|
||||||
|
|||||||
@@ -401,6 +401,8 @@ export interface GlobalSettings {
|
|||||||
enabledOpencodeModels?: OpencodeModelId[];
|
enabledOpencodeModels?: OpencodeModelId[];
|
||||||
/** Default OpenCode model selection when switching to OpenCode CLI */
|
/** Default OpenCode model selection when switching to OpenCode CLI */
|
||||||
opencodeDefaultModel?: OpencodeModelId;
|
opencodeDefaultModel?: OpencodeModelId;
|
||||||
|
/** Which dynamic OpenCode models are enabled (empty = all discovered) */
|
||||||
|
enabledDynamicModelIds?: string[];
|
||||||
|
|
||||||
// Input Configuration
|
// Input Configuration
|
||||||
/** User's keyboard shortcut bindings */
|
/** User's keyboard shortcut bindings */
|
||||||
@@ -704,6 +706,7 @@ export const DEFAULT_GLOBAL_SETTINGS: GlobalSettings = {
|
|||||||
cursorDefaultModel: 'auto',
|
cursorDefaultModel: 'auto',
|
||||||
enabledOpencodeModels: getAllOpencodeModelIds(),
|
enabledOpencodeModels: getAllOpencodeModelIds(),
|
||||||
opencodeDefaultModel: DEFAULT_OPENCODE_MODEL,
|
opencodeDefaultModel: DEFAULT_OPENCODE_MODEL,
|
||||||
|
enabledDynamicModelIds: [],
|
||||||
keyboardShortcuts: DEFAULT_KEYBOARD_SHORTCUTS,
|
keyboardShortcuts: DEFAULT_KEYBOARD_SHORTCUTS,
|
||||||
projects: [],
|
projects: [],
|
||||||
trashedProjects: [],
|
trashedProjects: [],
|
||||||
|
|||||||
Reference in New Issue
Block a user