/ tests / run_agent / test_init_fallback_on_exhausted_pool.py
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              )