From 0ee9e43a21f0ce4dc3caa5dd33680595e310fae5 Mon Sep 17 00:00:00 2001 From: Johan Jongsma Date: Tue, 24 Feb 2026 00:47:55 -0500 Subject: [PATCH 1/3] fix(settings): pre-populate model field from active routing config When editing an already-configured provider, the model field previously always showed the hardcoded defaultModel (e.g. llama-v3p3-70b-instruct for Fireworks) regardless of what model was actually active. This caused confusion: users saw a stale default instead of their real running model. Fix: fetch the default agent's routing config when on the providers tab. When opening the edit dialog for a configured provider, pre-populate the model field with routing.channel if it belongs to that provider. Falls back to defaultModel for new/unconfigured providers. Also updates the Fireworks defaultModel from the outdated llama-v3p3-70b-instruct to minimax-m2p5. --- interface/src/routes/Settings.tsx | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/interface/src/routes/Settings.tsx b/interface/src/routes/Settings.tsx index 4e06a29e3..bace63672 100644 --- a/interface/src/routes/Settings.tsx +++ b/interface/src/routes/Settings.tsx @@ -134,7 +134,7 @@ const PROVIDERS = [ description: "Fast inference for popular OSS models", placeholder: "...", envVar: "FIREWORKS_API_KEY", - defaultModel: "fireworks/accounts/fireworks/models/llama-v3p3-70b-instruct", + defaultModel: "fireworks/accounts/fireworks/models/minimax-m2p5", }, { id: "deepseek", @@ -262,6 +262,24 @@ export function Settings() { enabled: activeSection === "providers", }); + // Fetch agents list and default agent config so we can pre-populate the + // model field with the currently active routing model when editing an + // already-configured provider (instead of always showing the hardcoded + // defaultModel). + const { data: agentsData } = useQuery({ + queryKey: ["agents"], + queryFn: api.agents, + staleTime: 10_000, + enabled: activeSection === "providers", + }); + const defaultAgentId = agentsData?.agents?.[0]?.id; + const { data: defaultAgentConfig } = useQuery({ + queryKey: ["agent-config", defaultAgentId], + queryFn: () => api.agentConfig(defaultAgentId!), + staleTime: 10_000, + enabled: activeSection === "providers" && !!defaultAgentId, + }); + // Fetch global settings (only when on api-keys, server, or worker-logs tabs) const { data: globalSettings, isLoading: globalSettingsLoading } = useQuery({ queryKey: ["global-settings"], @@ -591,7 +609,16 @@ export function Settings() { onEdit={() => { setEditingProvider(provider.id); setKeyInput(""); - setModelInput(provider.defaultModel ?? ""); + // When the provider is already configured, pre-populate + // the model field with the current routing model so the + // user sees (and can adjust) what's actually active, + // rather than the hardcoded defaultModel placeholder. + const currentChannel = defaultAgentConfig?.routing?.channel; + const currentModel = + isConfigured(provider.id) && currentChannel?.startsWith(`${provider.id}/`) + ? currentChannel + : null; + setModelInput(currentModel ?? provider.defaultModel ?? ""); setTestedSignature(null); setTestResult(null); setMessage(null); From 4e07754bb69a6d72ca178db37b612e56a4c987cb Mon Sep 17 00:00:00 2001 From: Johan Jongsma Date: Tue, 24 Feb 2026 01:22:41 -0500 Subject: [PATCH 2/3] fix(providers): include Anthropic OAuth in provider status check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit get_providers() only checked for anthropic_key in config.toml or the ANTHROPIC_API_KEY env var to determine if the Anthropic provider was configured. This caused the SetupBanner to show "No LLM provider configured" even when valid OAuth credentials existed in anthropic_oauth.json — which is the correct path after `spacebot auth login`. Mirror the existing openai_oauth_configured pattern for Anthropic: check credentials_path(&instance_dir).exists() and OR it into the anthropic bool in both config-exists and fallback branches. --- src/api/providers.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/api/providers.rs b/src/api/providers.rs index 954409992..2aae17ed2 100644 --- a/src/api/providers.rs +++ b/src/api/providers.rs @@ -426,6 +426,7 @@ pub(super) async fn get_providers( ) -> Result, StatusCode> { let config_path = state.config_path.read().await.clone(); let instance_dir = (**state.instance_dir.load()).clone(); + let anthropic_oauth_configured = crate::auth::credentials_path(&instance_dir).exists(); let openai_oauth_configured = crate::openai_auth::credentials_path(&instance_dir).exists(); let ( @@ -470,7 +471,7 @@ pub(super) async fn get_providers( }; ( - has_value("anthropic_key", "ANTHROPIC_API_KEY"), + has_value("anthropic_key", "ANTHROPIC_API_KEY") || anthropic_oauth_configured, has_value("openai_key", "OPENAI_API_KEY"), openai_oauth_configured, has_value("openrouter_key", "OPENROUTER_API_KEY"), @@ -493,7 +494,7 @@ pub(super) async fn get_providers( ) } else { ( - std::env::var("ANTHROPIC_API_KEY").is_ok(), + std::env::var("ANTHROPIC_API_KEY").is_ok() || anthropic_oauth_configured, std::env::var("OPENAI_API_KEY").is_ok(), openai_oauth_configured, std::env::var("OPENROUTER_API_KEY").is_ok(), From 8fd761cbb6e38374bb9530b525ecfb757c4541bb Mon Sep 17 00:00:00 2001 From: Johan Jongsma Date: Tue, 24 Feb 2026 01:25:31 -0500 Subject: [PATCH 3/3] fix(settings): address review feedback on provider model pre-population - Use agents.find(a => a.id === 'main') instead of agents[0] to select the default agent more robustly (suggested by tembo bot) - Add useEffect to re-sync modelInput when defaultAgentConfig arrives after the edit dialog is already open, closing the race condition where clicking edit before the query resolves would leave the field showing defaultModel permanently (suggested by tembo bot) --- interface/src/routes/Settings.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/interface/src/routes/Settings.tsx b/interface/src/routes/Settings.tsx index bace63672..0fdc2897f 100644 --- a/interface/src/routes/Settings.tsx +++ b/interface/src/routes/Settings.tsx @@ -272,7 +272,8 @@ export function Settings() { staleTime: 10_000, enabled: activeSection === "providers", }); - const defaultAgentId = agentsData?.agents?.[0]?.id; + const defaultAgentId = + agentsData?.agents?.find((agent) => agent.id === "main")?.id ?? agentsData?.agents?.[0]?.id; const { data: defaultAgentConfig } = useQuery({ queryKey: ["agent-config", defaultAgentId], queryFn: () => api.agentConfig(defaultAgentId!), @@ -280,6 +281,19 @@ export function Settings() { enabled: activeSection === "providers" && !!defaultAgentId, }); + // If the routing config loads *after* the edit dialog is already open (race + // condition: user clicks edit before the agent-config query resolves), update + // the model field to show the active routing model instead of defaultModel. + useEffect(() => { + if (!editingProvider) return; + const currentChannel = defaultAgentConfig?.routing?.channel; + if (!currentChannel?.startsWith(`${editingProvider}/`)) return; + setModelInput(currentChannel); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [defaultAgentConfig]); + // Note: intentionally omitting editingProvider and modelInput from deps — we + // only want this to fire when the config data arrives, not on every keystroke. + // Fetch global settings (only when on api-keys, server, or worker-logs tabs) const { data: globalSettings, isLoading: globalSettingsLoading } = useQuery({ queryKey: ["global-settings"],