Skip to content

feat(cli, config): Escalate Ctrl-C through a signal router#837

Merged
JeanMertz merged 1 commit into
mainfrom
rfd-045
Jul 3, 2026
Merged

feat(cli, config): Escalate Ctrl-C through a signal router#837
JeanMertz merged 1 commit into
mainfrom
rfd-045

Conversation

@JeanMertz

Copy link
Copy Markdown
Collaborator

Ctrl-C handling moves from a broadcast channel of ad-hoc signals to a SignalRouter that owns the root shutdown token and a LIFO stack of scoped interrupt handlers (RFD 045). The first Ctrl-C press now always reaches the topmost active handler: the streaming loop, the tool execution loop, or a new turn-level handler that covers the gaps between turn phases (persistence, thread building, response processing) and commits partial content before ending the turn. A press with no registered handler, or a second press within interrupt.escalation_cooldown_secs (default 2s), begins a graceful shutdown; any further press exits the process immediately with code
130. SIGTERM always requests a graceful shutdown and SIGQUIT always exits immediately, both bypassing the handler stack.

Cancelling an interrupt menu itself with Ctrl-C now escalates instead of silently falling back to "Stop": both the streaming and tool menus commit partial content or cancel running tools, then begin a graceful shutdown. During tool execution, a Ctrl-C is declined while an interactive tool prompt is active so the prompt keeps handling it, and propagates to the next handler down the stack otherwise. A Ctrl-C during the stream-error backoff wait now cuts the wait short and opens the interrupt menu immediately instead of after the full delay.

jp_task::TaskHandler drops its separate force-cancellation token now that SIGQUIT exits the process directly; background task draining watches the router's shutdown token instead.

Docs: RFD 045 is marked Implemented, and RFD 092 (predictable and responsive interrupt escalation) is added as a follow-up proposal covering the shutdown watchdog, a turn menu, a generic fallback menu, and Ctrl-C handling inside active prompts.

Ctrl-C handling moves from a broadcast channel of ad-hoc signals to a
`SignalRouter` that owns the root shutdown token and a LIFO stack of
scoped interrupt handlers (RFD 045). The first Ctrl-C press now always
reaches the topmost active handler: the streaming loop, the tool
execution loop, or a new turn-level handler that covers the gaps
between turn phases (persistence, thread building, response
processing) and commits partial content before ending the turn. A
press with no registered handler, or a second press within
`interrupt.escalation_cooldown_secs` (default 2s), begins a graceful
shutdown; any further press exits the process immediately with code
130. SIGTERM always requests a graceful shutdown and SIGQUIT always
exits immediately, both bypassing the handler stack.

Cancelling an interrupt menu itself with Ctrl-C now escalates instead
of silently falling back to "Stop": both the streaming and tool menus
commit partial content or cancel running tools, then begin a graceful
shutdown. During tool execution, a Ctrl-C is declined while an
interactive tool prompt is active so the prompt keeps handling it, and
propagates to the next handler down the stack otherwise. A Ctrl-C
during the stream-error backoff wait now cuts the wait short and opens
the interrupt menu immediately instead of after the full delay.

`jp_task::TaskHandler` drops its separate force-cancellation token now
that SIGQUIT exits the process directly; background task draining
watches the router's shutdown token instead.

Docs: RFD 045 is marked Implemented, and RFD 092 (predictable and
responsive interrupt escalation) is added as a follow-up proposal
covering the shutdown watchdog, a turn menu, a generic fallback menu,
and Ctrl-C handling inside active prompts.

Signed-off-by: Jean Mertz <git@jeanmertz.com>
@JeanMertz JeanMertz merged commit 494fb6d into main Jul 3, 2026
16 checks passed
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.

1 participant