mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
fix(coding-agent): process idle ctx.shutdown() requests in RPC mode (#11746)
In RPC mode, `shutdownHandler` only set a `shutdownRequested` flag. That flag was checked in two places: after a stdin command was handled and on `agent_settled`. If an extension called `ctx.shutdown()` while the session was idle (for example from a timer), neither check ever ran. The process stayed alive until the client sent another command. Interactive mode already shuts down right away in this case. Changes in `packages/coding-agent/src/modes/rpc/rpc-mode.ts`: - **One check for all paths:** `checkShutdownRequested()` shuts down only when a request is pending, input is attached, no command is being handled, and the session is idle. Each of those ending calls it again: command completion, prompt settle, `agent_settled`, and input attach. - **Idle requests:** the shutdown handler schedules the check on the next tick, so the requesting handler finishes first. The conditions are checked when the tick runs, not when it is scheduled: a stdin command that arrives in between is handled first, and shutdown follows when it finishes. - **Requests during startup:** a request made before input is attached (for example a synchronous `ctx.shutdown()` in `session_start`) is checked once the input reader is attached. - **Requests during a command:** shutdown waits until the command finishes, including extension commands. A `prompt` command returns before `session.prompt()` settles, so it stays counted as in flight until the prompt settles, and the shutdown check runs then. This also fixes an existing ordering problem: an extension command that called `ctx.shutdown()` could exit the process before its `prompt` response was written. - **Repeated requests:** `checkShutdownRequested()` does nothing once shutdown has started, so a second `ctx.shutdown()` does not call `process.exit` in the middle of async cleanup. A second stdin EOF or signal still forces exit, as before. Shutdown requested during a running turn is still handled on `agent_settled`, as before. A request made while an extension-started compaction runs (not idle, no run to settle) still waits for the next command or run; `docs/rpc.md` and `docs/extensions.md` note this. Docs (`docs/rpc.md`, `docs/extensions.md`) and the CHANGELOG are updated. ## Testing - Added three tests to `test/rpc-prompt-response-semantics.test.ts`: - an async `ctx.shutdown()` on an idle session exits; - an extension command that calls `ctx.shutdown()` gets its `prompt` response written before exit; - a command that arrives after an idle request but before the scheduled check runs gets its response written before exit. All three fail without the change and pass with it. - `npm run check` passes. All `test/rpc*` tests pass. - In `./test.sh`, all coding-agent tests pass. The only failures were timeouts in durable/harness tests (`store-storage`, `tools-images`, connection close), which this change does not touch. - Reproduction from the issue: run `pi --mode rpc --no-session -ne -e ./shutdown-probe.mjs` with stdin held open and nothing sent. - Before the change, the process stayed alive until a timeout killed it (exit 124). - After the change, `session_shutdown` fires and the process exits with code 0. - A synchronous `ctx.shutdown()` in `session_start` also exits with code 0. Fixes #11599 Requested by @petrroll --------- Co-authored-by: triagent <triagent@localhost> Co-authored-by: Petr Houška <houskape@gmail.com>
This commit is contained in:
parent
3d11c3510b
commit
1708b47889
5 changed files with 138 additions and 13 deletions
|
|
@ -92,7 +92,7 @@ Clients must also handle child-process startup failures, unexpected exits, stder
|
|||
|
||||
Close the child's stdin to request an orderly shutdown. Pi disposes the active runtime before exiting. Clients should still handle process signals and unexpected exits.
|
||||
|
||||
An extension can also request shutdown through its extension context. Pi completes shutdown after the current command or after the active run emits `agent_settled`.
|
||||
An extension can also request shutdown with `ctx.shutdown()`. If the session is idle and no command is being handled, Pi shuts down right away. Otherwise it shuts down once the current command finishes (for `prompt`, once the prompt settles) or the active run emits `agent_settled`. (A request made while an extension-started compaction is running waits for the next command or run to finish.)
|
||||
|
||||
## Minimal client
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue