Skip to content

Commit af5eae4

Browse files
committed
feat: add receive_timeout parameter to Connection class
- Add optional receive_timeout parameter to Connection.__init__ - Implement timeout handling in _receive_loop using asyncio.wait_for - Raise RequestError.internal_error on timeout for graceful error handling This allows users to configure a timeout for receiving messages from agents, preventing indefinite hangs when an agent becomes unresponsive.
1 parent 093a562 commit af5eae4

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

src/acp/connection.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ def __init__(
7373
sender_factory: SenderFactory | None = None,
7474
observers: list[StreamObserver] | None = None,
7575
listening: bool = True,
76+
receive_timeout: float | None = None,
7677
) -> None:
7778
self._handler = handler
7879
self._writer = writer
@@ -102,6 +103,7 @@ def __init__(
102103
)
103104
self._dispatcher.start()
104105
self._observers: list[StreamObserver] = list(observers or [])
106+
self._receive_timeout = receive_timeout
105107

106108
async def close(self) -> None:
107109
"""Stop the receive loop and cancel any in-flight handler tasks."""
@@ -148,7 +150,7 @@ async def send_notification(self, method: str, params: JsonValue | None = None)
148150
async def _receive_loop(self) -> None:
149151
try:
150152
while True:
151-
line = await self._reader.readline()
153+
line = await asyncio.wait_for(self._reader.readline(), timeout=self._receive_timeout)
152154
if not line:
153155
break
154156
try:
@@ -160,6 +162,8 @@ async def _receive_loop(self) -> None:
160162
await self._process_message(message)
161163
except asyncio.CancelledError:
162164
return
165+
except asyncio.TimeoutError:
166+
raise RequestError.internal_error({"details": "Agent timeout"}) from None
163167

164168
async def _process_message(self, message: dict[str, Any]) -> None:
165169
method = message.get("method")

0 commit comments

Comments
 (0)