diff --git a/api/plugins/__init__.py b/api/plugins/__init__.py index e2818752..4c306590 100644 --- a/api/plugins/__init__.py +++ b/api/plugins/__init__.py @@ -91,7 +91,7 @@ class SettingConfig(TypedDict): "supported_models": [ { "provider": ModelProvider.OPENAI.value, - "models": ["gpt-4o", "gpt-4o-mini", "o1"], + "models": ["gpt-4.5-preview", "gpt-4o", "gpt-4o-mini", "o1"], }, { "provider": ModelProvider.ANTHROPIC.value, diff --git a/app/chat/page.tsx b/app/chat/page.tsx index b183d532..b7034008 100644 --- a/app/chat/page.tsx +++ b/app/chat/page.tsx @@ -743,6 +743,7 @@ export default function ChatPage() { provider={currentSettings?.selectedProvider || ""} isOpen={showApiKeyModal} onSubmit={handleApiKeySubmit} + onClose={() => setShowApiKeyModal(false)} /> ); diff --git a/app/page.tsx b/app/page.tsx index 95f92791..75ca7013 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -305,6 +305,7 @@ export default function Home() { provider={currentSettings?.selectedProvider || ""} isOpen={showApiKeyModal} onSubmit={handleApiKeySubmit} + onClose={() => setShowApiKeyModal(false)} /> ); diff --git a/components/ui/AuthModal.tsx b/components/ui/AuthModal.tsx index d38e3c9f..11233191 100644 --- a/components/ui/AuthModal.tsx +++ b/components/ui/AuthModal.tsx @@ -18,9 +18,10 @@ interface AuthModalProps { provider: string; isOpen: boolean; onSubmit: (key: string) => void; + onClose?: () => void; } -export function AuthModal({ provider, isOpen, onSubmit }: AuthModalProps) { +export function AuthModal({ provider, isOpen, onSubmit, onClose }: AuthModalProps) { const [apiKey, setApiKey] = useState(""); const [error, setError] = useState(""); @@ -35,7 +36,14 @@ export function AuthModal({ provider, isOpen, onSubmit }: AuthModalProps) { }; return ( - {}}> + { + if (!open && onClose) { + onClose(); + } + }} + > void }) { const { currentSettings, updateSettings } = useSettings(); const [apiKey, setApiKey] = useState(""); + const [showApiKeyModal, setShowApiKeyModal] = useState(false); + const [pendingModelChange, setPendingModelChange] = useState(null); const router = useRouter(); const { clearInitialState } = useChatContext(); const { resetSession } = useSteelContext(); @@ -239,14 +242,23 @@ function SettingsContent({ closeSettings }: { closeSettings: () => void }) { (m: SupportedModel) => m.provider === currentSettings.selectedProvider ); + // Only reset the model if the current provider doesn't support it if ( providerModels && providerModels.models.length > 0 && - !providerModels.models.includes(currentSettings.selectedModel) + !providerModels.models.includes(currentSettings.selectedModel) && + currentSettings.selectedProvider === providerModels.provider ) { + // Don't auto-switch to GPT-4.5-preview if no API key + const defaultModel = + providerModels.models[0] === "gpt-4.5-preview" && + !currentSettings.providerApiKeys?.[currentSettings.selectedProvider] + ? providerModels.models[1] // Use the next available model + : providerModels.models[0]; + updateSettings({ ...currentSettings, - selectedModel: providerModels.models[0], + selectedModel: defaultModel, }); } } @@ -273,6 +285,28 @@ function SettingsContent({ closeSettings }: { closeSettings: () => void }) { } }; + const handleApiKeySubmit = (key: string) => { + if (!currentSettings) return; + + const currentKeys = currentSettings.providerApiKeys || {}; + const updatedSettings = { + ...currentSettings, + providerApiKeys: { + ...currentKeys, + [currentSettings.selectedProvider]: key, + }, + }; + + // If there was a pending model change, apply it now + if (pendingModelChange) { + updatedSettings.selectedModel = pendingModelChange; + setPendingModelChange(null); + } + + updateSettings(updatedSettings); + setShowApiKeyModal(false); + }; + if (!currentSettings?.selectedAgent) { return null; } @@ -413,10 +447,29 @@ function SettingsContent({ closeSettings }: { closeSettings: () => void }) { (m: SupportedModel) => m.provider === value ); if (providerModels && providerModels.models.length > 0) { + // Keep the current model if it's available in the new provider's list + let newModel = providerModels.models.includes(currentSettings.selectedModel) + ? currentSettings.selectedModel + : providerModels.models[0]; + + // If switching to GPT-4.5-preview but no API key, show modal + if ( + newModel === "gpt-4.5-preview" && + !currentSettings.providerApiKeys?.[value] + ) { + setPendingModelChange(newModel); + updateSettings({ + ...currentSettings, + selectedProvider: value, + }); + setShowApiKeyModal(true); + return; + } + updateSettings({ ...currentSettings, selectedProvider: value, - selectedModel: providerModels.models[0], + selectedModel: newModel, }); } }} @@ -450,6 +503,17 @@ function SettingsContent({ closeSettings }: { closeSettings: () => void }) { }); return; } + + // Check if trying to use GPT-4.5-preview without an API key + if ( + value === "gpt-4.5-preview" && + !currentSettings.providerApiKeys?.[currentSettings.selectedProvider] + ) { + setPendingModelChange(value); + setShowApiKeyModal(true); + return; + } + updateSettings({ ...currentSettings, selectedModel: value, @@ -598,7 +662,7 @@ function SettingsContent({ closeSettings }: { closeSettings: () => void }) {

2. Install Ollama from{" "} - ollama.com + ollama.com

3. Run Ollama locally with the model of your choice: @@ -608,7 +672,7 @@ function SettingsContent({ closeSettings }: { closeSettings: () => void }) {

Visit{" "} - + our GitHub repository {" "} for detailed setup instructions. @@ -752,6 +816,17 @@ function SettingsContent({ closeSettings }: { closeSettings: () => void }) { + + {/* API Key Modal */} + { + setShowApiKeyModal(false); + setPendingModelChange(null); // Clear any pending model change + }} + /> ); }