diff --git a/server/routes/commands.js b/server/routes/commands.js index 388a8f76e..e52081bec 100644 --- a/server/routes/commands.js +++ b/server/routes/commands.js @@ -202,6 +202,7 @@ Custom commands can be created in: model: currentModel }, available: availableModels, + newModel: args.length > 0 ? args[0] : null, message: args.length > 0 ? `Switching to model: ${args[0]}` : `Current model: ${currentModel}` diff --git a/src/components/chat/hooks/useChatComposerState.ts b/src/components/chat/hooks/useChatComposerState.ts index 6e84982d4..3806eba28 100644 --- a/src/components/chat/hooks/useChatComposerState.ts +++ b/src/components/chat/hooks/useChatComposerState.ts @@ -38,6 +38,7 @@ interface UseChatComposerStateArgs { cyclePermissionMode: () => void; cursorModel: string; claudeModel: string; + setClaudeModel: (model: string) => void; codexModel: string; geminiModel: string; isLoading: boolean; @@ -110,6 +111,7 @@ export function useChatComposerState({ cyclePermissionMode, cursorModel, claudeModel, + setClaudeModel, codexModel, geminiModel, isLoading, @@ -169,6 +171,10 @@ export function useChatComposerState({ break; case 'model': + if (data.newModel) { + setClaudeModel(data.newModel); + safeLocalStorage.setItem('claude-model', data.newModel); + } addMessage({ type: 'assistant', content: `**Current Model**: ${data.current.model}\n\n**Available Models**:\n\nClaude: ${data.available.claude.join(', ')}\n\nCursor: ${data.available.cursor.join(', ')}`, @@ -232,7 +238,7 @@ export function useChatComposerState({ console.warn('Unknown built-in command action:', action); } }, - [onFileOpen, onShowSettings, addMessage, clearMessages, rewindMessages], + [onFileOpen, onShowSettings, addMessage, clearMessages, rewindMessages, setClaudeModel], ); const handleCustomCommand = useCallback(async (result: CommandExecutionResult) => { diff --git a/src/components/chat/view/ChatInterface.tsx b/src/components/chat/view/ChatInterface.tsx index 9f9d0bc0b..5b151ce37 100644 --- a/src/components/chat/view/ChatInterface.tsx +++ b/src/components/chat/view/ChatInterface.tsx @@ -179,6 +179,7 @@ function ChatInterface({ cyclePermissionMode, cursorModel, claudeModel, + setClaudeModel, codexModel, geminiModel, isLoading, diff --git a/src/components/chat/view/subcomponents/ProviderSelectionEmptyState.tsx b/src/components/chat/view/subcomponents/ProviderSelectionEmptyState.tsx index 792b12c74..1d84a6ab7 100644 --- a/src/components/chat/view/subcomponents/ProviderSelectionEmptyState.tsx +++ b/src/components/chat/view/subcomponents/ProviderSelectionEmptyState.tsx @@ -149,6 +149,9 @@ export default function ProviderSelectionEmptyState({ codexModel, geminiModel, ); + const modelOptions = modelConfig.OPTIONS.some(({ value }) => value === currentModel) + ? modelConfig.OPTIONS + : [...modelConfig.OPTIONS, { value: currentModel, label: currentModel }]; /* ── New session — provider picker ── */ if (!selectedSession && !currentSessionId) { @@ -224,7 +227,7 @@ export default function ProviderSelectionEmptyState({ tabIndex={-1} className="cursor-pointer appearance-none rounded-lg border border-border/60 bg-muted/50 py-1.5 pl-3 pr-7 text-sm font-medium text-foreground transition-colors hover:bg-muted focus:outline-none focus:ring-2 focus:ring-primary/20" > - {modelConfig.OPTIONS.map( + {modelOptions.map( ({ value, label }: { value: string; label: string }) => (