From 0c0a2eb0a27923e8a801a19d5c151d8abb27af8d Mon Sep 17 00:00:00 2001 From: adavyas Date: Fri, 27 Feb 2026 21:19:29 -0800 Subject: [PATCH] fix(agent): fail fast on Anthropic native base URLs --- mini_swe_runner.py | 7 +++++++ run_agent.py | 6 ++++++ tests/test_run_agent.py | 17 +++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/mini_swe_runner.py b/mini_swe_runner.py index 3fe0e0162..ffa28f769 100644 --- a/mini_swe_runner.py +++ b/mini_swe_runner.py @@ -199,6 +199,13 @@ class MiniSWERunner: client_kwargs["base_url"] = base_url else: client_kwargs["base_url"] = "https://openrouter.ai/api/v1" + + if base_url and "api.anthropic.com" in base_url.strip().lower(): + raise ValueError( + "Anthropic /v1/messages is not supported yet. " + "Hermes uses OpenAI-compatible /chat/completions. " + "Use OpenRouter or leave base_url unset." + ) # Handle API key - OpenRouter is the primary provider if api_key: diff --git a/run_agent.py b/run_agent.py index 8958353f5..0a539616d 100644 --- a/run_agent.py +++ b/run_agent.py @@ -183,6 +183,12 @@ class AIAgent: # Store effective base URL for feature detection (prompt caching, reasoning, etc.) # When no base_url is provided, the client defaults to OpenRouter, so reflect that here. self.base_url = base_url or OPENROUTER_BASE_URL + if base_url and "api.anthropic.com" in base_url.strip().lower(): + raise ValueError( + "Anthropic /v1/messages is not supported yet. " + "Hermes uses OpenAI-compatible /chat/completions. " + "Use OpenRouter or leave base_url unset." + ) self.tool_progress_callback = tool_progress_callback self.clarify_callback = clarify_callback self._last_reported_tool = None # Track for "new tool" mode diff --git a/tests/test_run_agent.py b/tests/test_run_agent.py index a07c52f84..77ef460ab 100644 --- a/tests/test_run_agent.py +++ b/tests/test_run_agent.py @@ -278,6 +278,23 @@ class TestMaskApiKey: class TestInit: + def test_anthropic_base_url_fails_fast(self): + """Anthropic native endpoints should error before building an OpenAI client.""" + with ( + patch("run_agent.get_tool_definitions", return_value=[]), + patch("run_agent.check_toolset_requirements", return_value={}), + patch("run_agent.OpenAI") as mock_openai, + ): + with pytest.raises(ValueError, match="Anthropic /v1/messages is not supported yet"): + AIAgent( + api_key="test-key-1234567890", + base_url="https://api.anthropic.com/v1/messages", + quiet_mode=True, + skip_context_files=True, + skip_memory=True, + ) + mock_openai.assert_not_called() + def test_prompt_caching_claude_openrouter(self): """Claude model via OpenRouter should enable prompt caching.""" with (