You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Python: Embedding clients have no close()/context manager and leak their internally created SDK clients #9814
#9748 added deterministic lifecycle to chat clients (async with, close(), connector-owned resource release), but the embedding client family was left out:
BaseEmbeddingClient has no __aenter__/__aexit__/close(), so async with does not work for any embedding client, and there is no contract for releasing resources.
OpenAIEmbeddingClient creates an AsyncOpenAI/AsyncAzureOpenAI SDK client internally (owning an httpx connection pool) when async_client is not supplied, and offers no way to close it — only GC ever releases the pool.
BedrockEmbeddingClient creates a boto3 bedrock-runtime client internally with the same gap.
OllamaEmbeddingClient creates an AsyncClient (httpx transport) internally with the same gap.
GeminiEmbeddingClient already implements close() with _owns_client — the rest of the family is inconsistent with it and with the chat clients.
Repro
fromagent_framework_openaiimportOpenAIEmbeddingClientclient=OpenAIEmbeddingClient(api_key="...")
asyncwithclient: # TypeError: 'async with' received an object that does not implement __aenter__
...
# and the internally created AsyncOpenAI is never closed deterministically
Long-lived processes that build embedding clients per unit of work (e.g. per request/tenant) accumulate unclosed httpx pools until GC runs, which is exactly the class of leak #9748 fixed for chat clients.
Expected
Embedding clients follow the same contract #9748 established for chat clients: base-class context trio with a no-op default close(), and resource-owning implementations that close only the SDK client they created (caller-supplied clients stay open), idempotent on repeated close.
changed the title [-]Embedding clients have no close()/context manager and leak their internally created SDK clients[/-][+]Python: Embedding clients have no close()/context manager and leak their internally created SDK clients[/+]on Oct 29, 2026
Thanks for raising this. The team will consider a common lifecycle contract for embedding clients, including deterministic release of framework-created SDK clients while leaving caller-supplied resources open. This is a foundational cross-provider concern, rather than a vendor-specific integration. This acknowledgement does not promise implementation or timing; the public lifecycle and ownership details need planning, using existing #9815 as input rather than starting competing work.
/plan Plan the accepted core ownership of a uniform embedding-client lifecycle, using existing #9815 and the chat-client/Gemini ownership contracts as input rather than starting another PR. Decide the additive BaseEmbeddingClient close/async-context contract, no-context use, legacy synchronous overrides, idempotency/reuse and close-failure behavior. Audit OpenAI/Azure OpenAI, Bedrock, Ollama and Gemini: release only framework-created SDK clients and leave injected clients, transports, sessions and credentials caller-owned; verify actual supported SDK close APIs and avoid unnecessary private-transport coupling. Cover normal/exceptional context exit, explicit/repeated close, construction/close failures and serialization of internal ownership flags across providers. Distinguish the confirmed lifecycle API gap from the unmeasured accumulating-pool claim. Review the existing implementation/tests for these boundaries; no ready label or new assignment while the public cross-package contract is pending, and retain triage for planning.
Activity
[-]Embedding clients have no close()/context manager and leak their internally created SDK clients[/-][+]Python: Embedding clients have no close()/context manager and leak their internally created SDK clients[/+]eavanvalkenburg commentedon Nov 2, 2026
Thanks for raising this. The team will consider a common lifecycle contract for embedding clients, including deterministic release of framework-created SDK clients while leaving caller-supplied resources open. This is a foundational cross-provider concern, rather than a vendor-specific integration. This acknowledgement does not promise implementation or timing; the public lifecycle and ownership details need planning, using existing #9815 as input rather than starting competing work.
eavanvalkenburg commentedon Nov 2, 2026
/plan Plan the accepted core ownership of a uniform embedding-client lifecycle, using existing #9815 and the chat-client/Gemini ownership contracts as input rather than starting another PR. Decide the additive BaseEmbeddingClient close/async-context contract, no-context use, legacy synchronous overrides, idempotency/reuse and close-failure behavior. Audit OpenAI/Azure OpenAI, Bedrock, Ollama and Gemini: release only framework-created SDK clients and leave injected clients, transports, sessions and credentials caller-owned; verify actual supported SDK close APIs and avoid unnecessary private-transport coupling. Cover normal/exceptional context exit, explicit/repeated close, construction/close failures and serialization of internal ownership flags across providers. Distinguish the confirmed lifecycle API gap from the unmeasured accumulating-pool claim. Review the existing implementation/tests for these boundaries; no ready label or new assignment while the public cross-package contract is pending, and retain triage for planning.