Skip to content

fix(llm): route http_client to the matching sync/async Anthropic client#565

Open
matteomedioli wants to merge 4 commits into
mainfrom
matteo/anthropic-kwargs-bugfix
Open

fix(llm): route http_client to the matching sync/async Anthropic client#565
matteomedioli wants to merge 4 commits into
mainfrom
matteo/anthropic-kwargs-bugfix

Conversation

@matteomedioli

@matteomedioli matteomedioli commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Description

AnthropicLLM.__init__ currently passes the exact same **kwargs dict to both anthropic.Anthropic(**kwargs) (sync) and anthropic.AsyncAnthropic(**kwargs) (async):

self.client = anthropic.Anthropic(**kwargs)
self.async_client = anthropic.AsyncAnthropic(**kwargs)

Most kwargs (api_key, max_retries, default_headers, ...) are safe to share. http_client is not: it must be an httpx.Client for the sync client and an httpx.AsyncClient for the async client — two incompatible types. Whichever one you pass, the other client receives the wrong type. Today there is effectively no way to inject a custom transport into AnthropicLLM at all.

BaseOpenAILLM (the OpenAI integration) already solves this correctly — it splits http_client into separate sync/async parameter sets before constructing OpenAI/AsyncOpenAI. This PR brings AnthropicLLM to the same standard:

  • http_client is popped from kwargs and routed only to the client whose type it matches (httpx.Client → sync, httpx.AsyncClient → async).
  • An http_client of an unrecognized type emits a warning and is ignored (both clients fall back to their default transport), matching OpenAILLM's existing behavior rather than crashing or silently misbehaving.
  • Every other kwarg continues to be shared between both clients exactly as before.

This is a pure bugfix — no new parameter, no constructor signature change. Anyone not passing http_client sees no behavior difference.

Every provider SDK Anthropic ships (anthropic.Anthropic, anthropic.AnthropicVertex, etc.) already supports a custom http_client and base_url — the coupling to the default endpoint is an artifact of how this class forwards constructor kwargs, not a limitation of the underlying SDK. Fixing the sync/async split is the prerequisite for that to actually work; a natural follow-up (open separately for focused review) extracts a BaseAnthropicLLM base class mirroring BaseOpenAILLM/AzureOpenAILLM.

Type of Change

  • New feature
  • Bug fix
  • Breaking change
  • Documentation update
  • Project configuration change

Complexity

Complexity: Low

How Has This Been Tested?

  • Unit tests
  • E2E tests
  • Manual tests

Checklist

The following requirements should have been met (depending on the changes in the branch):

  • Documentation has been updated
  • Unit tests have been updated
  • E2E tests have been updated
  • Examples have been updated
  • New files have copyright header
  • CLA (https://neo4j.com/developer/cla/) has been signed
  • CHANGELOG.md updated if appropriate

…ync Anthropic clients

Route httpx.Client only to the sync anthropic.Anthropic constructor and
httpx.AsyncClient only to the async anthropic.AsyncAnthropic constructor,
mirroring BaseOpenAILLM's existing param-splitting pattern, so passing a
sync-only or async-only http_client no longer collides across both clients.
… type

Mirror BaseOpenAILLM's existing behavior: when http_client is provided but
is neither an httpx.Client nor an httpx.AsyncClient instance, emit a warning
and construct both clients with the default (no custom) http_client instead
of raising.
…tests

Add unit tests verifying httpx.Client reaches only the sync Anthropic
client, httpx.AsyncClient reaches only the async client, and an invalid
http_client type warns and falls back to defaults for both clients.
Also note the stale-venv anthropic version gotcha in AGENTS.md.
Documents the AnthropicLLM sync/async http_client kwargs collision bug
fixed in tasks 001-002, matching the repo's existing changelog style.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant