fix(shell): kill subprocess on CancelledError to prevent orphan processes

When an agent task is cancelled (e.g. via /stop), the ExecTool was only
handling TimeoutError but not CancelledError. This left the child process
running as an orphan. Now CancelledError also triggers process.kill() and
waitpid cleanup before re-raising.
This commit is contained in:
Lingao Meng
2026-04-06 13:47:09 +08:00
committed by Xubin Ren
parent 202938ae73
commit 0e617c32cd
+13
View File
@@ -128,6 +128,19 @@ class ExecTool(Tool):
except (ProcessLookupError, ChildProcessError) as e:
logger.debug("Process already reaped or not found: {}", e)
return f"Error: Command timed out after {effective_timeout} seconds"
except asyncio.CancelledError:
process.kill()
try:
await asyncio.wait_for(process.wait(), timeout=5.0)
except asyncio.TimeoutError:
pass
finally:
if sys.platform != "win32":
try:
os.waitpid(process.pid, os.WNOHANG)
except (ProcessLookupError, ChildProcessError) as e:
logger.debug("Process already reaped or not found: {}", e)
raise
output_parts = []