mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-05 07:41:39 +00:00
fix(anthropic): scope MiniMax beta-strip to MiniMax only
Cherry-pick of @sharziki's #27022 routed Azure Foundry through _requires_bearer_auth, which also triggered the MiniMax-specific beta-strip in _common_betas_for_base_url — dropping the 1M-context beta from Azure even though Azure needs it for 1M context. Split the strip predicate: introduce _is_minimax_anthropic_endpoint so the fine-grained-tool-streaming and context-1m strips only fire for MiniMax hosts, leaving Azure's bearer-auth header swap intact without losing 1M context. Also add a regression test that asserts Azure gets Bearer auth, the api-version query param, and the context-1m-2025-08-07 beta.
This commit is contained in:
parent
73407b1e30
commit
f0c6d59148
2 changed files with 40 additions and 2 deletions
|
|
@ -493,6 +493,21 @@ def _base_url_needs_context_1m_beta(base_url: str | None) -> bool:
|
|||
return "azure.com" in normalized
|
||||
|
||||
|
||||
def _is_minimax_anthropic_endpoint(base_url: str | None) -> bool:
|
||||
"""Return True for MiniMax's Anthropic-compatible endpoints.
|
||||
|
||||
MiniMax rejects the fine-grained-tool-streaming and context-1m betas;
|
||||
those need to be stripped even though MiniMax also uses Bearer auth.
|
||||
"""
|
||||
normalized = _normalize_base_url_text(base_url)
|
||||
if not normalized:
|
||||
return False
|
||||
normalized = normalized.rstrip("/").lower()
|
||||
return normalized.startswith(
|
||||
("https://api.minimax.io/anthropic", "https://api.minimaxi.com/anthropic")
|
||||
)
|
||||
|
||||
|
||||
def _common_betas_for_base_url(
|
||||
base_url: str | None,
|
||||
*,
|
||||
|
|
@ -502,7 +517,9 @@ def _common_betas_for_base_url(
|
|||
|
||||
MiniMax's Anthropic-compatible endpoints (Bearer-auth) reject requests
|
||||
that include Anthropic's ``fine-grained-tool-streaming`` beta — every
|
||||
tool-use message triggers a connection error.
|
||||
tool-use message triggers a connection error. They also reject the
|
||||
1M-context beta. Azure AI Foundry's Anthropic endpoint also uses
|
||||
Bearer auth but keeps both betas (it needs the 1M beta for 1M context).
|
||||
|
||||
The ``context-1m-2025-08-07`` beta is not sent to native Anthropic by
|
||||
default because some subscriptions reject it. Add it only for endpoint
|
||||
|
|
@ -515,7 +532,7 @@ def _common_betas_for_base_url(
|
|||
betas = list(_COMMON_BETAS)
|
||||
if _base_url_needs_context_1m_beta(base_url) and not drop_context_1m_beta:
|
||||
betas.append(_CONTEXT_1M_BETA)
|
||||
if _requires_bearer_auth(base_url):
|
||||
if _is_minimax_anthropic_endpoint(base_url):
|
||||
_stripped = {_TOOL_STREAMING_BETA, _CONTEXT_1M_BETA}
|
||||
return [b for b in betas if b not in _stripped]
|
||||
if drop_context_1m_beta:
|
||||
|
|
|
|||
|
|
@ -155,6 +155,27 @@ class TestBuildAnthropicClient:
|
|||
"anthropic-beta": "interleaved-thinking-2025-05-14"
|
||||
}
|
||||
|
||||
def test_azure_foundry_anthropic_endpoint_uses_bearer_auth(self):
|
||||
"""Azure AI Foundry's /anthropic endpoint requires Authorization: Bearer.
|
||||
|
||||
Regression test for #26970: without this, builds set api_key (x-api-key)
|
||||
and the endpoint returns HTTP 401. Also verifies that Azure retains the
|
||||
1M-context beta even though it now matches `_requires_bearer_auth`.
|
||||
"""
|
||||
with patch("agent.anthropic_adapter._anthropic_sdk") as mock_sdk:
|
||||
build_anthropic_client(
|
||||
"azure-foundry-secret-123",
|
||||
base_url="https://my-resource.openai.azure.com/anthropic",
|
||||
)
|
||||
kwargs = mock_sdk.Anthropic.call_args[1]
|
||||
assert kwargs["auth_token"] == "azure-foundry-secret-123"
|
||||
assert "api_key" not in kwargs
|
||||
# Azure endpoints still get the api-version query param plumbing.
|
||||
assert kwargs.get("default_query") == {"api-version": "2025-04-15"}
|
||||
# Azure keeps the 1M-context beta (it's not MiniMax).
|
||||
betas = kwargs["default_headers"]["anthropic-beta"]
|
||||
assert "context-1m-2025-08-07" in betas
|
||||
|
||||
|
||||
class TestReadClaudeCodeCredentials:
|
||||
@pytest.fixture(autouse=True)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue