http_client_proxies is silently dropped by every provider except the three Azure paths (docs promise All)
Component
sdk-python (mem0/llms/*, mem0/embeddings/* — http_client_proxies plumbing)
Description
TL;DR: http_client_proxies is documented as available for "All" providers, but it is actually wired through to the underlying SDK client only in the three Azure paths. On 17 other LLM/embedding providers the proxy is silently dropped — traffic (prompts and API keys included) goes out direct, with no warning, no error, and a config.http_client that looks configured if you inspect it. This extends #6651 (which covered the OpenAI paths and was closed as not_planned) to the full provider matrix.
What the docs promise
docs/components/llms/config.mdx:102 and docs/components/embedders/config.mdx:79 both list http_client_proxies as available for All providers. The parameter sits on the shared BaseLlmConfig / BaseEmbedderConfig signatures and both factories pass it through uniformly, so at the API level it is a whole-surface promise. #5447 shipped it as a general feature.
What the code does
build_http_client() correctly builds a proxied httpx.Client into config.http_client for every provider. The drop happens one step later: most provider constructors build their SDK client without passing that client along.
Verified on current origin/main (94c3fe9f) by inspecting the real httpx transport pool type (transport._pool being httpcore.HTTPProxy) of the constructed client — not by looking at config objects:
| Outcome | Providers |
|---|---|
| Proxy applied (3) | llms/azure_openai, llms/azure_openai_structured, embeddings/azure_openai |
| Proxy dropped (17) | LLMs: openai, openai_structured, anthropic, deepseek, groq, together, xai, minimax, vllm, lmstudio, ollama, gemini · Embeddings: openai, together, lmstudio, ollama, gemini |
| Not applicable (no httpx client at all) | llms/aws_bedrock (boto3), llms/litellm, llms/sarvam (requests), embeddings/aws_bedrock |
End-to-end check with a local API and a dead proxy port: OpenAILLM configured with the dead proxy succeeds by going direct; AzureOpenAILLM with the same config fails with APIConnectionError (the proxy is honored). So this is not "proxy support partially implemented" — the requests genuinely bypass the configured proxy.
There is no warning, no log line, and no validation. The failure mode is fully silent; the only mitigations are ambient (trust_env=True still honors HTTP_PROXY/HTTPS_PROXY environment variables, so users who only use env vars are unaffected).
For users behind a corporate proxy this is both an availability bug (requests fail to reach the API) and a compliance one (prompts and credentials leave through a path the operator believes is proxied).
Two adjacent defects found while mapping this
mem0/llms/xai.py:31passeshttp_client_proxies=config.http_client— the wrong object entirely; constructingXAILLMwithhttp_client_proxiesset raisesAttributeError: 'Client' object has no attribute 'url'. This is what #6230 (open) reports.mem0/llms/gemini.py:23-32converts aBaseLlmConfigwithout carryinghttp_client_proxies, so it isNoneeven on the base config. Same shape as #6385 (closed as not_planned).
Why a new issue rather than reopening #6651
#6651 reported the OpenAI LLM + embedder paths and was closed as not_planned with the diagnosis confirmed but nothing fixed; the three fix PRs that followed (#6653, #6661, #6737) were all closed unmerged. The increments this issue adds beyond it:
- the full provider matrix (17 dropped paths, 3 working, 4 not applicable) — the fix needs a per-provider plan, not a one-liner for OpenAI;
- the existing test suite (
tests/test_http_client_proxies.py) only asserts at the config layer (config.http_clientexists), which is exactly why this has stayed green in CI while broken in production — the coverage gap is part of the bug; - a constraint any fix must know: anthropic 1.9.0 depends on httpx2 and rejects an
httpx.Clientwith aTypeError, so "passhttp_client=everywhere like Azure does" does not work for the Anthropic provider as-is; - ollama's client takes no injected client but forwards kwargs (
proxy=/mounts=work), and google-genai needstypes.HttpOptions(httpx_client=...)— per-provider wiring is genuinely heterogeneous.
Happy to contribute the fix once this is accepted; a draft with per-provider tests that fail on current main is ready.
How You Verified This
On origin/main (94c3fe9f238f3dbf29c9ce98643bd71eb13077cd), Python 3.12:
- For every LLM and embedding provider registered in both factories, constructed the provider with
http_client_proxiesset (string form and dict form, both), then inspected the constructed SDK client's real transport: a working proxy showshttpcore.HTTPProxyintransport._pool. Two deliberate guards against false results:config.http_clientitself is excluded from the check (it always exists and always has the proxy — counting it is how a whole-matrix false pass happens), and httpx-family clients are recognized structurally (openai>=3's_DefaultHttpxClientis not anhttpx.Clientsubclass, soisinstancewould under-count). The 17/3/4 split above is from that run. - End-to-end differential: pointed
OpenAILLMat a local API through a proxy port that is deliberately dead. Direct connection succeeds (proving the request ignored the proxy); the same setup onAzureOpenAILLMfails withAPIConnectionError(proving Azure honors it). - Confirmed the drop points by reading each constructor (
llms/openai.py:43,53,anthropic.py:45,deepseek.py:41,groq.py:26,together.py:23,xai.py:41,minimax.py:45,vllm.py:40,lmstudio.py:41,ollama.py:41,gemini.py:40,43, plus the five embedding paths) — none pass the built client into the SDK client constructor. - Confirmed the anthropic/httpx2 constraint by constructing an Anthropic client with an
httpx.Client: it raisesTypeError. - Confirmed the ollama kwargs path (
proxy=/mounts=forwarded to the underlyinghttpx.Client) and the google-genaiHttpOptions(httpx_client=...)path construct working proxied clients. - A parametrized regression test that asserts the transport pool type for every provider runs 21 cases: 17 fail on current main; the 4 passing cases are exactly the three Azure paths plus the
build_http_clientself-check. Test file available on request — it deliberately imports the repo'smem0(not a PyPI-installed copy). - Prior art checked: #6651 (closed not_planned, OpenAI paths), #6653/#6661/#6737 (fix PRs, closed unmerged), #5648/#5447 (merged, config-layer only), #6230 (open, xai), #6385 (closed, gemini). None covers the full matrix, the test-coverage gap, or the httpx2 constraint.
AI Assistance
AI-generated (an agent wrote most or all of this report): the provider matrix, the transport-level verification, the end-to-end differential, and the prior-art scan were produced by an AI agent against a local clone at 94c3fe9f; every claim under "How You Verified This" comes from real runs logged locally, reviewed and confirmed by the contributor before filing. No external API keys were used — the dead-proxy differential runs against a local endpoint.
Source: mem0ai/mem0