feat(anthropic): add User-Agent header for Anthropic API calls (#35268)

This commit is contained in:
Mike Lambert
2026-02-17 15:59:54 -05:00
committed by GitHub
parent 8166e0137d
commit 0d13463e7f
2 changed files with 18 additions and 1 deletions

View File

@@ -57,6 +57,7 @@ from langchain_core.utils.utils import _build_model_kwargs
from pydantic import BaseModel, ConfigDict, Field, SecretStr, model_validator
from typing_extensions import NotRequired, Self, TypedDict
from langchain_anthropic import __version__
from langchain_anthropic._client_utils import (
_get_default_async_httpx_client,
_get_default_httpx_client,
@@ -74,6 +75,8 @@ _message_type_lookups = {
_MODEL_PROFILES = cast(ModelProfileRegistry, _PROFILES)
_USER_AGENT: Final[str] = f"langchain-anthropic/{__version__}"
def _get_default_model_profile(model_name: str) -> ModelProfile:
"""Get the default profile for a model.
@@ -1025,11 +1028,16 @@ class ChatAnthropic(BaseChatModel):
@cached_property
def _client_params(self) -> dict[str, Any]:
# Merge User-Agent with user-provided headers (user headers take precedence)
default_headers = {"User-Agent": _USER_AGENT}
if self.default_headers:
default_headers.update(self.default_headers)
client_params: dict[str, Any] = {
"api_key": self.anthropic_api_key.get_secret_value(),
"base_url": self.anthropic_api_url,
"max_retries": self.max_retries,
"default_headers": (self.default_headers or None),
"default_headers": default_headers,
}
# value <= 0 indicates the param should be ignored. None is a meaningful value
# for Anthropic client and treated differently than not specifying the param at

View File

@@ -53,6 +53,15 @@ def test_initialization() -> None:
assert model.anthropic_api_url == "https://api.anthropic.com"
def test_user_agent_header_in_client_params() -> None:
"""Test that _client_params includes a User-Agent header."""
llm = ChatAnthropic(model=MODEL_NAME, api_key="test-key") # type: ignore[arg-type]
params = llm._client_params
assert "default_headers" in params
assert "User-Agent" in params["default_headers"]
assert params["default_headers"]["User-Agent"].startswith("langchain-anthropic/")
@pytest.mark.parametrize("async_api", [True, False])
def test_streaming_attribute_should_stream(async_api: bool) -> None: # noqa: FBT001
llm = ChatAnthropic(model=MODEL_NAME, streaming=True)