Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion astrbot/core/provider/sources/anthropic_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,17 @@ def _init_api_key(self, provider_config: dict) -> None:
self.chosen_api_key: str = ""
self.api_keys: list = super().get_keys()
self.chosen_api_key = self.api_keys[0] if len(self.api_keys) > 0 else ""
# SDK 2.x uses Bearer auth; compatible endpoints may require X-Api-Key.
default_headers = {"X-Api-Key": self.chosen_api_key}
for name, value in (self.custom_headers or {}).items():
# Match older SDK casing to avoid duplicate API key headers.
name = "X-Api-Key" if name.lower() == "x-api-key" else name
default_headers[name] = value
self.client = AsyncAnthropic(
api_key=self.chosen_api_key,
timeout=self.timeout,
base_url=self.base_url,
default_headers=self.custom_headers,
default_headers=default_headers,
http_client=self._create_http_client(provider_config),
)

Expand Down
2 changes: 2 additions & 0 deletions tests/test_anthropic_kimi_code_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def test_anthropic_provider_passes_custom_headers_via_default_headers(monkeypatc
assert provider.client.kwargs["default_headers"] == {
"User-Agent": "custom-agent/1.0",
"X-Test-Header": "123",
"X-Api-Key": "test-key",
}
assert provider.client.kwargs["http_client"] is None

Expand All @@ -103,6 +104,7 @@ def test_kimi_code_provider_sets_defaults_and_preserves_custom_headers(monkeypat
assert provider.client.kwargs["default_headers"] == {
"User-Agent": kimi_code_source.KIMI_CODE_USER_AGENT,
"X-Trace-Id": "trace-1",
"X-Api-Key": "test-key",
}


Expand Down
39 changes: 39 additions & 0 deletions tests/test_anthropic_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,45 @@ def _provider() -> ProviderAnthropic:
return ProviderAnthropic.__new__(ProviderAnthropic)


@pytest.mark.asyncio
@pytest.mark.parametrize(
("custom_headers", "expected_key"),
[({}, "test-key"), ({"x-api-key": "override-key"}, "override-key")],
)
async def test_anthropic_request_sends_single_api_key_header(
monkeypatch, custom_headers, expected_key
):
monkeypatch.delenv("ANTHROPIC_AUTH_TOKEN", raising=False)
monkeypatch.delenv("ANTHROPIC_CUSTOM_HEADERS", raising=False)

def handle(request):
assert request.headers.get_list("x-api-key") == [expected_key]
return sdk_httpx.Response(200, json={})

async with sdk_httpx.AsyncClient(
transport=sdk_httpx.MockTransport(handle)
) as http_client:
monkeypatch.setattr(
ProviderAnthropic,
"_create_http_client",
lambda self, config: http_client,
)
provider = ProviderAnthropic(
provider_config={
"key": ["test-key"],
"api_base": "https://opencode.ai/zen/go",
"custom_headers": custom_headers,
},
provider_settings={},
)
provider.client.max_retries = 0
await provider.client.messages.with_raw_response.create(
model="claude-test",
max_tokens=16,
messages=[{"role": "user", "content": "hi"}],
)


def test_anthropic_extract_usage_counts_cache_creation_input():
provider = _provider()

Expand Down
Loading