mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-02 08:33:36 +00:00
Merge pull request #490 from thesobercoder/fix/openrouter-models-kanban
fix: load OpenCode models on Kanban
This commit is contained in:
@@ -166,6 +166,8 @@ export function PhaseModelSelector({
|
|||||||
codexModelsLoading,
|
codexModelsLoading,
|
||||||
fetchCodexModels,
|
fetchCodexModels,
|
||||||
dynamicOpencodeModels,
|
dynamicOpencodeModels,
|
||||||
|
opencodeModelsLoading,
|
||||||
|
fetchOpencodeModels,
|
||||||
} = useAppStore();
|
} = useAppStore();
|
||||||
|
|
||||||
// Detect mobile devices to use inline expansion instead of nested popovers
|
// Detect mobile devices to use inline expansion instead of nested popovers
|
||||||
@@ -185,6 +187,15 @@ export function PhaseModelSelector({
|
|||||||
}
|
}
|
||||||
}, [codexModels.length, codexModelsLoading, fetchCodexModels]);
|
}, [codexModels.length, codexModelsLoading, fetchCodexModels]);
|
||||||
|
|
||||||
|
// Fetch OpenCode models on mount
|
||||||
|
useEffect(() => {
|
||||||
|
if (dynamicOpencodeModels.length === 0 && !opencodeModelsLoading) {
|
||||||
|
fetchOpencodeModels().catch(() => {
|
||||||
|
// Silently fail - user will see only static OpenCode models
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [dynamicOpencodeModels.length, opencodeModelsLoading, fetchOpencodeModels]);
|
||||||
|
|
||||||
// Close expanded group when trigger scrolls out of view
|
// Close expanded group when trigger scrolls out of view
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const triggerElement = expandedTriggerRef.current;
|
const triggerElement = expandedTriggerRef.current;
|
||||||
|
|||||||
@@ -601,6 +601,10 @@ export interface AppState {
|
|||||||
authenticated: boolean;
|
authenticated: boolean;
|
||||||
authMethod?: string;
|
authMethod?: string;
|
||||||
}>; // Cached providers
|
}>; // Cached providers
|
||||||
|
opencodeModelsLoading: boolean; // Whether OpenCode models are being fetched
|
||||||
|
opencodeModelsError: string | null; // Error message if fetch failed
|
||||||
|
opencodeModelsLastFetched: number | null; // Timestamp of last successful fetch
|
||||||
|
opencodeModelsLastFailedAt: number | null; // Timestamp of last failed fetch
|
||||||
|
|
||||||
// Claude Agent SDK Settings
|
// Claude Agent SDK Settings
|
||||||
autoLoadClaudeMd: boolean; // Auto-load CLAUDE.md files using SDK's settingSources option
|
autoLoadClaudeMd: boolean; // Auto-load CLAUDE.md files using SDK's settingSources option
|
||||||
@@ -1182,6 +1186,9 @@ export interface AppActions {
|
|||||||
}>
|
}>
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
|
// OpenCode Models actions
|
||||||
|
fetchOpencodeModels: (forceRefresh?: boolean) => Promise<void>;
|
||||||
|
|
||||||
// Init Script State actions (keyed by projectPath::branch to support concurrent scripts)
|
// Init Script State actions (keyed by projectPath::branch to support concurrent scripts)
|
||||||
setInitScriptState: (
|
setInitScriptState: (
|
||||||
projectPath: string,
|
projectPath: string,
|
||||||
@@ -1253,6 +1260,10 @@ const initialState: AppState = {
|
|||||||
dynamicOpencodeModels: [], // Empty until fetched from OpenCode CLI
|
dynamicOpencodeModels: [], // Empty until fetched from OpenCode CLI
|
||||||
enabledDynamicModelIds: [], // Empty until user enables dynamic models
|
enabledDynamicModelIds: [], // Empty until user enables dynamic models
|
||||||
cachedOpencodeProviders: [], // Empty until fetched from OpenCode CLI
|
cachedOpencodeProviders: [], // Empty until fetched from OpenCode CLI
|
||||||
|
opencodeModelsLoading: false,
|
||||||
|
opencodeModelsError: null,
|
||||||
|
opencodeModelsLastFetched: null,
|
||||||
|
opencodeModelsLastFailedAt: null,
|
||||||
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)
|
||||||
mcpServers: [], // No MCP servers configured by default
|
mcpServers: [], // No MCP servers configured by default
|
||||||
@@ -3251,6 +3262,65 @@ export const useAppStore = create<AppState & AppActions>()((set, get) => ({
|
|||||||
codexModelsLastFetched: Date.now(),
|
codexModelsLastFetched: Date.now(),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
// OpenCode Models actions
|
||||||
|
fetchOpencodeModels: async (forceRefresh = false) => {
|
||||||
|
const FAILURE_COOLDOWN_MS = 30 * 1000; // 30 seconds
|
||||||
|
const SUCCESS_CACHE_MS = 5 * 60 * 1000; // 5 minutes
|
||||||
|
|
||||||
|
const { opencodeModelsLastFetched, opencodeModelsLoading, opencodeModelsLastFailedAt } = get();
|
||||||
|
|
||||||
|
// Skip if already loading
|
||||||
|
if (opencodeModelsLoading) return;
|
||||||
|
|
||||||
|
// Skip if recently failed and not forcing refresh
|
||||||
|
if (
|
||||||
|
!forceRefresh &&
|
||||||
|
opencodeModelsLastFailedAt &&
|
||||||
|
Date.now() - opencodeModelsLastFailedAt < FAILURE_COOLDOWN_MS
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip if recently fetched successfully and not forcing refresh
|
||||||
|
if (
|
||||||
|
!forceRefresh &&
|
||||||
|
opencodeModelsLastFetched &&
|
||||||
|
Date.now() - opencodeModelsLastFetched < SUCCESS_CACHE_MS
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
set({ opencodeModelsLoading: true, opencodeModelsError: null });
|
||||||
|
|
||||||
|
try {
|
||||||
|
const api = getElectronAPI();
|
||||||
|
if (!api.setup) {
|
||||||
|
throw new Error('Setup API not available');
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await api.setup.getOpencodeModels(forceRefresh);
|
||||||
|
|
||||||
|
if (!result.success) {
|
||||||
|
throw new Error(result.error || 'Failed to fetch OpenCode models');
|
||||||
|
}
|
||||||
|
|
||||||
|
set({
|
||||||
|
dynamicOpencodeModels: result.models || [],
|
||||||
|
opencodeModelsLastFetched: Date.now(),
|
||||||
|
opencodeModelsLoading: false,
|
||||||
|
opencodeModelsError: null,
|
||||||
|
opencodeModelsLastFailedAt: null, // Clear failure on success
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
||||||
|
set({
|
||||||
|
opencodeModelsError: errorMessage,
|
||||||
|
opencodeModelsLoading: false,
|
||||||
|
opencodeModelsLastFailedAt: Date.now(), // Record failure time for cooldown
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// Pipeline actions
|
// Pipeline actions
|
||||||
setPipelineConfig: (projectPath, config) => {
|
setPipelineConfig: (projectPath, config) => {
|
||||||
set({
|
set({
|
||||||
|
|||||||
Reference in New Issue
Block a user