Skip to content

fix(pi): Honor AbortSignal so Escape cancels in-flight - #1182

Open
rabi wants to merge 1 commit into
mksglu:mainfrom
rabi:pi-esc-cancel
Open

rabi wants to merge 1 commit into
mksglu:mainfrom
rabi:pi-esc-cancel

Conversation

@rabi

@rabi rabi commented Sep 19, 2026

Copy link
Copy Markdown

What / Why / How

Pi passes the run's AbortSignal as the third execute() argument, but the pi MCP bridge dropped it: execute() awaited callTool() with no timeout (tools/call intentionally uses POSITIVE_INFINITY, #643) and no notifications/cancelled, so an in-flight ctx_execute froze the TUI until the tool returned.

Two-part fix:

  1. Client (adapters/pi/mcp-bridge.ts): forward the signal through execute() -> callTool() -> request(). On abort the pending request is rejected immediately and a notifications/cancelled notification is sent to the MCP server.

  2. Server (server.ts, executor.ts): thread the per-request abort signal from the SDK handler extra into PolyglotExecutor; on abort the spawned sandbox process group is killed (killTree). The existing wrapToolHandler (Pi host: MCP servers accumulate under a long-lived parent — self-shutdown gated entirely on parent-death (same class as #565, still present in 1.0.163) #854 in-flight marker) dropped the handler's second argument (extra), so it now forwards it.

Affected platforms

  • Claude Code
  • Cursor
  • VS Code Copilot (GitHub Copilot)
  • JetBrains Copilot
  • Gemini CLI
  • Qwen Code
  • OpenCode
  • KiloCode
  • Codex CLI
  • OpenClaw (Pi Agent)
  • Pi
  • Kiro
  • Antigravity
  • Zed
  • All platforms

Test plan

Verified: standalone harness — callTool rejects ~1ms after abort and server-side sandbox child is killed ~6ms after abort; 162 repo tests pass (pi-mcp-bridge, pi-bridge-parent-death, executor). Tested locally with Pi.

Checklist

  • Tests added/updated (TDD: red → green)
  • npm test passes
  • npm run typecheck passes

Fixes: #1175

Pi passes the run's AbortSignal as the third execute() argument, but the
pi MCP bridge dropped it: execute() awaited callTool() with no timeout
(tools/call intentionally uses POSITIVE_INFINITY, mksglu#643) and no
notifications/cancelled, so an in-flight ctx_execute froze the TUI until
the tool returned.

Two-part fix:

1. Client (adapters/pi/mcp-bridge.ts): forward the signal through
   execute() -> callTool() -> request(). On abort the pending request is
   rejected immediately and a notifications/cancelled notification is
   sent to the MCP server.

2. Server (server.ts, executor.ts): thread the per-request abort signal
   from the SDK handler extra into PolyglotExecutor; on abort the
   spawned sandbox process group is killed (killTree). The existing
   wrapToolHandler (mksglu#854 in-flight marker) dropped the handler's second
   argument (extra), so it now forwards it.

Verified: standalone harness — callTool rejects ~1ms after abort and
server-side sandbox child is killed ~6ms after abort; 162 repo tests
pass (pi-mcp-bridge, pi-bridge-parent-death, executor). Tested locally
with Pi.

Fixes: mksglu#1175
Signed-off-by: rabi <mishra.rabi@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: ctx_execute cannot be cancelled with Esc mid-run; no intermediate progress visible

1 participant