test_init_fallback_on_exhausted_pool.py
1 """Regression test for #17929: AIAgent.__init__ should try fallback_model 2 when primary provider credentials are exhausted.""" 3 import pytest 4 from unittest.mock import patch, MagicMock 5 from run_agent import AIAgent 6 7 8 def _make_tool_defs(): 9 return [{"type": "function", "function": {"name": "web_search", 10 "description": "search", "parameters": {"type": "object", "properties": {}}}}] 11 12 13 def _mock_client(api_key="fb-key-1234567890", base_url="https://fb.example.com/v1"): 14 c = MagicMock() 15 c.api_key = api_key 16 c.base_url = base_url 17 c._default_headers = None 18 return c 19 20 21 def test_init_tries_fallback_when_primary_returns_none(): 22 """When resolve_provider_client returns None for primary but succeeds for 23 a fallback entry, __init__ should NOT raise RuntimeError.""" 24 fb = _mock_client() 25 26 def fake_resolve(provider, model=None, raw_codex=False, 27 explicit_base_url=None, explicit_api_key=None): 28 if provider == "tencent-token-plan": 29 return fb, "kimi2.5" 30 return None, None # primary exhausted 31 32 with patch("agent.auxiliary_client.resolve_provider_client", side_effect=fake_resolve), \ 33 patch("run_agent.get_tool_definitions", return_value=_make_tool_defs()), \ 34 patch("run_agent.check_toolset_requirements", return_value={}), \ 35 patch("run_agent.OpenAI", return_value=MagicMock()): 36 37 agent = AIAgent( 38 provider="alibaba-coding-plan", 39 model="qwen3.6-plus", 40 api_key=None, 41 base_url=None, 42 quiet_mode=True, 43 skip_context_files=True, 44 skip_memory=True, 45 fallback_model=[{"provider": "tencent-token-plan", "model": "kimi2.5"}], 46 ) 47 assert agent.provider == "tencent-token-plan" 48 assert agent.model == "kimi2.5" 49 assert agent._fallback_activated is True 50 51 52 def test_init_raises_when_no_fallback_configured(): 53 """When primary returns None and no fallback is set, should raise.""" 54 with patch("agent.auxiliary_client.resolve_provider_client", return_value=(None, None)), \ 55 patch("run_agent.get_tool_definitions", return_value=_make_tool_defs()), \ 56 patch("run_agent.check_toolset_requirements", return_value={}), \ 57 patch("run_agent.OpenAI", return_value=MagicMock()): 58 59 with pytest.raises(RuntimeError, match="no API key was found"): 60 AIAgent( 61 provider="alibaba-coding-plan", 62 model="qwen3.6-plus", 63 api_key=None, 64 base_url=None, 65 quiet_mode=True, 66 skip_context_files=True, 67 skip_memory=True, 68 fallback_model=None, 69 )