diff --git a/python/packages/a2a/agent_framework_a2a/_agent.py b/python/packages/a2a/agent_framework_a2a/_agent.py index 3d5ac41e86..435f204030 100644 --- a/python/packages/a2a/agent_framework_a2a/_agent.py +++ b/python/packages/a2a/agent_framework_a2a/_agent.py @@ -263,6 +263,8 @@ def __init__( super().__init__(id=id, name=name, description=description, **kwargs) self._http_client: httpx.AsyncClient | None = http_client + # By default, leave a caller-supplied HTTP client open; specific paths may override this below. + self._close_http_client = False self._timeout_config = self._create_timeout_config(timeout) bindings = supported_protocol_bindings if supported_protocol_bindings is not None else ["JSONRPC"] if client is not None: diff --git a/python/packages/a2a/tests/test_a2a_agent.py b/python/packages/a2a/tests/test_a2a_agent.py index 8ff147f98a..2a0205cb49 100644 --- a/python/packages/a2a/tests/test_a2a_agent.py +++ b/python/packages/a2a/tests/test_a2a_agent.py @@ -465,6 +465,16 @@ async def test_context_manager_no_cleanup_when_no_http_client() -> None: pass +async def test_context_manager_does_not_close_caller_supplied_http_client() -> None: + """A caller-supplied http_client (without client=) must survive __aexit__. See issue #7950.""" + mock_http_client = AsyncMock() + + async with A2AAgent(url="http://localhost:9999/", http_client=cast(Any, mock_http_client)): + pass + + mock_http_client.aclose.assert_not_called() + + def test_prepare_message_for_a2a_with_multiple_contents() -> None: """Test conversion of Message with multiple contents."""