diff --git a/run_agent.py b/run_agent.py index 8b53d030c0..bf88c3719c 100644 --- a/run_agent.py +++ b/run_agent.py @@ -2119,12 +2119,14 @@ class AIAgent: # ("switched to anthropic, tui keeps trying openrouter"). old_norm = (old_provider or "").strip().lower() new_norm = (new_provider or "").strip().lower() + fallback_chain = list(getattr(self, "_fallback_chain", []) or []) if old_norm and new_norm and old_norm != new_norm: - self._fallback_chain = [ - entry for entry in self._fallback_chain + fallback_chain = [ + entry for entry in fallback_chain if (entry.get("provider") or "").strip().lower() not in {old_norm, new_norm} ] - self._fallback_model = self._fallback_chain[0] if self._fallback_chain else None + self._fallback_chain = fallback_chain + self._fallback_model = fallback_chain[0] if fallback_chain else None logging.info( "Model switched in-place: %s (%s) -> %s (%s)", diff --git a/tests/run_agent/test_switch_model_fallback_prune.py b/tests/run_agent/test_switch_model_fallback_prune.py index 99af3579f3..f0600c7ee8 100644 --- a/tests/run_agent/test_switch_model_fallback_prune.py +++ b/tests/run_agent/test_switch_model_fallback_prune.py @@ -78,6 +78,17 @@ def test_switch_with_empty_chain_stays_empty(): assert agent._fallback_model is None +def test_switch_initializes_missing_fallback_attrs(): + agent = _make_agent([]) + del agent._fallback_chain + del agent._fallback_model + + _switch_to_anthropic(agent) + + assert agent._fallback_chain == [] + assert agent._fallback_model is None + + def test_switch_within_same_provider_preserves_chain(): chain = [{"provider": "openrouter", "model": "x-ai/grok-4"}] agent = _make_agent(chain)