/ tests / run_agent / test_invalid_context_length_warning.py
test_invalid_context_length_warning.py
  1  """Tests that invalid context_length values in config produce visible warnings."""
  2  
  3  from unittest.mock import patch, MagicMock, call
  4  
  5  
  6  def _build_agent(model_cfg, custom_providers=None, model="anthropic/claude-opus-4.6"):
  7      """Build an AIAgent with the given model config."""
  8      cfg = {"model": model_cfg}
  9      if custom_providers is not None:
 10          cfg["custom_providers"] = custom_providers
 11  
 12      base_url = model_cfg.get("base_url", "")
 13  
 14      with (
 15          patch("hermes_cli.config.load_config", return_value=cfg),
 16          patch("agent.model_metadata.get_model_context_length", return_value=128_000),
 17          patch("run_agent.get_tool_definitions", return_value=[]),
 18          patch("run_agent.check_toolset_requirements", return_value={}),
 19          patch("run_agent.OpenAI"),
 20      ):
 21          from run_agent import AIAgent
 22  
 23          agent = AIAgent(
 24              model=model,
 25              api_key="test-key-1234567890",
 26              base_url=base_url,
 27              quiet_mode=True,
 28              skip_context_files=True,
 29              skip_memory=True,
 30          )
 31      return agent
 32  
 33  
 34  def test_valid_integer_context_length_no_warning():
 35      """Plain integer context_length should work silently."""
 36      with patch("run_agent.logger") as mock_logger:
 37          agent = _build_agent({"default": "gpt5.4", "provider": "custom",
 38                                "base_url": "http://localhost:4000/v1",
 39                                "context_length": 256000})
 40      assert agent._config_context_length == 256000
 41      # No warning about invalid context_length
 42      for c in mock_logger.warning.call_args_list:
 43          assert "Invalid" not in str(c)
 44  
 45  
 46  def test_string_k_suffix_context_length_warns():
 47      """context_length: '256K' should warn the user clearly."""
 48      with patch("run_agent.logger") as mock_logger:
 49          agent = _build_agent({"default": "gpt5.4", "provider": "custom",
 50                                "base_url": "http://localhost:4000/v1",
 51                                "context_length": "256K"})
 52      assert agent._config_context_length is None
 53      # Should have warned
 54      warning_calls = [c for c in mock_logger.warning.call_args_list
 55                       if "Invalid" in str(c) and "256K" in str(c)]
 56      assert len(warning_calls) == 1
 57      assert "plain integer" in str(warning_calls[0])
 58  
 59  
 60  def test_string_numeric_context_length_works():
 61      """context_length: '256000' (string) should parse fine via int()."""
 62      with patch("run_agent.logger") as mock_logger:
 63          agent = _build_agent({"default": "gpt5.4", "provider": "custom",
 64                                "base_url": "http://localhost:4000/v1",
 65                                "context_length": "256000"})
 66      assert agent._config_context_length == 256000
 67      for c in mock_logger.warning.call_args_list:
 68          assert "Invalid" not in str(c)
 69  
 70  
 71  def test_custom_providers_invalid_context_length_warns():
 72      """Invalid context_length in custom_providers should warn."""
 73      custom_providers = [
 74          {
 75              "name": "LiteLLM",
 76              "base_url": "http://localhost:4000/v1",
 77              "models": {
 78                  "gpt5.4": {"context_length": "256K"}
 79              },
 80          }
 81      ]
 82      with patch("run_agent.logger") as mock_logger:
 83          agent = _build_agent(
 84              {"default": "gpt5.4", "provider": "custom",
 85               "base_url": "http://localhost:4000/v1"},
 86              custom_providers=custom_providers,
 87              model="gpt5.4",
 88          )
 89      warning_calls = [c for c in mock_logger.warning.call_args_list
 90                       if "Invalid" in str(c) and "256K" in str(c)]
 91      assert len(warning_calls) == 1
 92      assert "custom_providers" in str(warning_calls[0])
 93  
 94  
 95  def test_custom_providers_valid_context_length():
 96      """Valid integer in custom_providers should work silently."""
 97      custom_providers = [
 98          {
 99              "name": "LiteLLM",
100              "base_url": "http://localhost:4000/v1",
101              "models": {
102                  "gpt5.4": {"context_length": 256000}
103              },
104          }
105      ]
106      with patch("run_agent.logger") as mock_logger:
107          agent = _build_agent(
108              {"default": "gpt5.4", "provider": "custom",
109               "base_url": "http://localhost:4000/v1"},
110              custom_providers=custom_providers,
111              model="gpt5.4",
112          )
113      for c in mock_logger.warning.call_args_list:
114          assert "Invalid" not in str(c)