Description
Please define and document whether Python ChatClient instances are safe to reuse across concurrent async calls, including mixed streaming and non-streaming calls.
Long-lived hosts such as Azure Functions need to reuse SDK clients and their HTTP connection pools across invocations to avoid connection churn and SNAT exhaustion. That means one OpenAIChatClient or FoundryChatClient wrapper may serve multiple fresh Agent/AgentSession instances concurrently. Today, the Python API documentation does not state whether this is supported or which objects must remain request-scoped.
The expected contract would clarify:
- whether one
OpenAIChatClient / FoundryChatClient can be shared by simultaneous Agent.run() calls;
- whether streaming + streaming, non-streaming + non-streaming, and mixed streaming/non-streaming use are supported;
- that messages, function-call IDs/arguments, middleware state, sessions, and stream events remain isolated per call;
- whether the guarantee is limited to async tasks on one event loop or also covers OS threads/event loops;
- which mutable extensions (for example middleware) are excluded from the guarantee.
A framework-level concurrency regression test for the supported combinations would make this contract durable.
In Azure/azure-functions-agents-runtime#158 we inspected Agent Framework Python 1.3 and added deterministic characterization tests using the real wrappers over a mock OpenAI Responses transport. Those tests show overlapping calls remain isolated for both wrappers across all three combinations, including distinct streamed function-call IDs. This gives us confidence in the pinned version, but it is not a substitute for an upstream compatibility guarantee.
Alternative considered: create a fresh ChatClient wrapper per invocation while sharing only the underlying HTTP transport. That avoids relying on wrapper concurrency but couples hosts to private transport ownership and defeats some of the intended SDK-client reuse model.
Code Sample
client = OpenAIChatClient(async_client=shared_async_openai, model="model")
# Each request gets fresh mutable Agent/session state while sharing the ChatClient.
first = Agent(client)
second = Agent(client)
await asyncio.gather(
first.run("first", session=first.create_session()),
second.run("second", stream=True, session=second.create_session()).get_final_response(),
)
Language/SDK
Python
Description
Please define and document whether Python
ChatClientinstances are safe to reuse across concurrent async calls, including mixed streaming and non-streaming calls.Long-lived hosts such as Azure Functions need to reuse SDK clients and their HTTP connection pools across invocations to avoid connection churn and SNAT exhaustion. That means one
OpenAIChatClientorFoundryChatClientwrapper may serve multiple freshAgent/AgentSessioninstances concurrently. Today, the Python API documentation does not state whether this is supported or which objects must remain request-scoped.The expected contract would clarify:
OpenAIChatClient/FoundryChatClientcan be shared by simultaneousAgent.run()calls;A framework-level concurrency regression test for the supported combinations would make this contract durable.
In Azure/azure-functions-agents-runtime#158 we inspected Agent Framework Python 1.3 and added deterministic characterization tests using the real wrappers over a mock OpenAI Responses transport. Those tests show overlapping calls remain isolated for both wrappers across all three combinations, including distinct streamed function-call IDs. This gives us confidence in the pinned version, but it is not a substitute for an upstream compatibility guarantee.
Alternative considered: create a fresh ChatClient wrapper per invocation while sharing only the underlying HTTP transport. That avoids relying on wrapper concurrency but couples hosts to private transport ownership and defeats some of the intended SDK-client reuse model.
Code Sample
Language/SDK
Python