diff --git a/src/components/chat/hooks/useChatProviderState.ts b/src/components/chat/hooks/useChatProviderState.ts index 7842ecb..0657c75 100644 --- a/src/components/chat/hooks/useChatProviderState.ts +++ b/src/components/chat/hooks/useChatProviderState.ts @@ -4,6 +4,8 @@ import { CLAUDE_MODELS, CODEX_MODELS, CURSOR_MODELS, GEMINI_MODELS } from '../.. import type { PendingPermissionRequest, PermissionMode } from '../types/types'; import type { ProjectSession, LLMProvider } from '../../../types/app'; +type ModelOption = { value: string; label: string }; + const getPermissionModesForProvider = (provider: LLMProvider): PermissionMode[] => { if (provider === 'codex') { return ['default', 'acceptEdits', 'bypassPermissions']; @@ -37,6 +39,38 @@ export function useChatProviderState({ selectedSession }: UseChatProviderStateAr return localStorage.getItem('gemini-model') || GEMINI_MODELS.DEFAULT; }); + // Live model lists — fall back to static constants until API responds + const [claudeModelOptions, setClaudeModelOptions] = useState(CLAUDE_MODELS.OPTIONS); + const [codexModelOptions] = useState(CODEX_MODELS.OPTIONS); + const [geminiModelOptions] = useState(GEMINI_MODELS.OPTIONS); + const [cursorModelOptions] = useState(CURSOR_MODELS.OPTIONS); + + // Fetch live model list and validate the saved claude model + useEffect(() => { + authenticatedFetch('/api/models') + .then((res) => { + if (!res.ok) return; + return res.json(); + }) + .then((data) => { + if (!Array.isArray(data?.claude) || data.claude.length === 0) return; + const options: ModelOption[] = data.claude; + setClaudeModelOptions(options); + + // Validate saved model — if it's no longer in the list, reset to default + setClaudeModel((current) => { + const valid = options.some((o) => o.value === current); + if (valid) return current; + const fallback = options[0]?.value ?? CLAUDE_MODELS.DEFAULT; + localStorage.setItem('claude-model', fallback); + return fallback; + }); + }) + .catch(() => { + // Static fallback already in place — nothing to do + }); + }, []); + const lastProviderRef = useRef(provider); useEffect(() => { @@ -118,6 +152,10 @@ export function useChatProviderState({ selectedSession }: UseChatProviderStateAr setCodexModel, geminiModel, setGeminiModel, + claudeModelOptions, + codexModelOptions, + geminiModelOptions, + cursorModelOptions, permissionMode, setPermissionMode, pendingPermissionRequests,