Skip to content

fix(cli): route interactive slash commands inline to prevent CLI freeze - #23604

Closed
mcndjxlefnd wants to merge 1 commit into
NousResearch:mainfrom
mcndjxlefnd:fix/destructive-slash-cli-freeze
Closed

fix(cli): route interactive slash commands inline to prevent CLI freeze#23604
mcndjxlefnd wants to merge 1 commit into
NousResearch:mainfrom
mcndjxlefnd:fix/destructive-slash-cli-freeze

Conversation

@mcndjxlefnd

Copy link
Copy Markdown
Contributor

Problem

/new, /clear, /undo, /reset, and /reload-mcp call _confirm_destructive_slash which calls _prompt_text_input to ask the user for confirmation. These commands are dispatched from the process_loop daemon thread where _prompt_text_input falls back to a bare input() call — but prompt_toolkit owns stdin in raw mode on the main thread, causing a stdin race that freezes the terminal.

This is identical to the deadlock fixed for tools/approval.py in PR #16477.

Root cause

Commit b9c001116 introduced _confirm_destructive_slash using the _prompt_text_input pattern from _confirm_and_reload_mcp. Commit c5f1f863a added the daemon-thread input() fallback to _prompt_text_input which inadvertently enabled this race condition for destructive slash commands.

Fix

Route interactive slash commands inline on the UI thread — exactly like /model already does. This lets _prompt_text_input use run_in_terminal instead of the broken daemon-thread input() fallback.

  • New _INTERACTIVE_SLASH_COMMANDS frozenset with the 6 commands that call _prompt_text_input: model, new, clear, undo, reset, reload-mcp
  • New _should_handle_interactive_slash_inline() gate method
  • Accept handler updated to use the new gate

Testing

  • All 28 existing CLI tests pass (destructive slash confirm, prompt_text_input thread safety, new session, steer busy path)
  • 10 new tests in tests/cli/test_interactive_slash_inline_routing.py verify each command routes inline and non-interactive commands do not

Closes the freeze regression from PR #22687 / issue #4069.

/new, /clear, /undo, /reset, and /reload-mcp call _prompt_text_input
which must run on the UI thread so prompt_toolkit's run_in_terminal
works instead of falling back to a daemon-thread input() that races
with stdin and freezes the terminal.

Mirrors the existing /model inline dispatch pattern by introducing
_should_handle_interactive_slash_inline, gated by a frozenset of
commands that need the UI thread for user interaction.

Fixes the regression introduced in b9c0011 (feat: confirm prompt
for destructive slash commands) where the confirmation prompt was
dispatched from the process_loop daemon thread, causing a stdin
race identical to the one fixed for tools/approval.py in PR NousResearch#16477.
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