Skip to content

fix: improve interactive command handling and tool cancellation#139

Merged
jexShain merged 1 commit into
AI-Shell-Team:rustfrom
jexShain:rust-rewrite
Apr 24, 2026
Merged

fix: improve interactive command handling and tool cancellation#139
jexShain merged 1 commit into
AI-Shell-Team:rustfrom
jexShain:rust-rewrite

Conversation

@jexShain
Copy link
Copy Markdown
Collaborator

@jexShain jexShain commented Apr 24, 2026

Summary

  • Add cancellation token bridging from AI handler to BashTool so Ctrl+C during AI tool execution terminates the PTY child process
  • Expand interactive command detection with explicit lists for TUI programs (vim, htop, less) and session commands (ssh, telnet, mosh)
  • Re-enable echo and output processing (OPOST/ONLCR) for session commands so remote PTY displays correctly
  • Improve PTY initialization to prevent stale PromptReady events from shifting exit codes
  • Enhance readline with gray hint highlighting and autosuggest pre-population from saved history

Test plan

  • cargo build — 0 warnings
  • cargo clippy — clean
  • cargo test — 524 passed, 0 failed, 3 ignored
  • Manual: run ssh user@host from aish and verify remote prompt displays correctly
  • Manual: run AI tool with long command, press Ctrl+C, verify child process is terminated

Summary by CodeRabbit

  • New Features

    • Shell readline now shows colored hint highlighting.
    • Tools can receive shared cancellation tokens so long-running shell tools respect LLM-driven cancellation.
  • Bug Fixes

    • Restored terminal echo for remote-session commands to prevent broken remote shells.
    • Prevented prompt concatenation by improving interactive prompt handling and output translation.
  • Improvements

    • Better propagation of cancellation tokens across LLM and tooling paths.
    • Autosuggest seeded from loaded history for immediate hints.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 24, 2026

📝 Walkthrough

Walkthrough

Propagates a shared, Arc-wrapped cancellation token from LLM session through AiHandler into Bash/SecureBash tools; updates BashTool to observe and bridge AI cancellation, enhances interactive-command detection; refines PTY session startup/draining behavior and shell readline hinting/history seeding.

Changes

Cohort / File(s) Summary
LLM session & AiHandler
crates/aish-llm/src/session.rs, crates/aish-shell/src/ai_handler.rs
Store cancellation token as Arc<CancellationToken>; add cancellation_token_arc() accessor; AiHandler exposes the Arc token.
Tool wiring & BashTool
crates/aish-tools/src/bash.rs, crates/aish-tools/src/secure_bash.rs, crates/aish-shell/src/app.rs
BashTool holds optional Arc<CancellationToken> with set_cancellation_token; polling bridge thread cancels tool when LLM token is cancelled; SecureBashTool forwards token; app injects token into SecureBashTool.
PTY control & startup
crates/aish-pty/src/persistent.rs, crates/aish-pty/src/bash_rc_wrapper.sh
Use wait_for_session_ready and best-effort PromptReady consumption; add raw control-pipe drain helper; drain master output before command registration; re-enable OPOST
Readline & autosuggest
crates/aish-shell/src/readline.rs
Implement hint highlighter returning ANSI-colored hint text; increase AutoSuggest capacity (1000→5000); seed autosuggest from loaded history.
Tests & heuristics
crates/aish-tools/src/bash.rs (tests)
Update/add unit tests for new interactive/session command detection behavior and heuristics.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User as "User"
  participant App as "App / AiHandler"
  participant LLM as "LlmSession\n(Arc<CancellationToken>)"
  participant ToolReg as "SecureBashTool"
  participant Bash as "BashTool"
  participant PTY as "PTY Process"

  rect rgba(200,230,255,0.5)
    User->>App: invoke AI action / run command
    App->>LLM: hold / clone cancellation token (cancellation_token_arc)
    App->>ToolReg: construct SecureBashTool
    App->>ToolReg: set_cancellation_token(Arc<CancellationToken>)
    ToolReg->>Bash: forward token to inner BashTool
    Bash->>PTY: execute command via PTY
  end

  rect rgba(255,200,200,0.5)
    Note right of LLM: External cancel triggered
    LLM-->>Bash: Arc token cancelled (observed via bridge thread)
    Bash->>PTY: send local cancel / stop polling
    PTY-->>Bash: exit/EOF
    Bash-->>ToolReg: execution finished
    ToolReg-->>App: notify completion
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

tools, tests, size: L

Poem

🐰 I stitched an Arc through token threads,
A tiny bridge where cancel treads,
PTYs hush and prompts align,
Hints glow bright — a carrot sign! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: improve interactive command handling and tool cancellation' directly addresses the main changes: adding cancellation token bridging, expanding interactive command detection, and enhancing PTY handling.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

Thanks for the pull request. A maintainer will review it when available.

Please keep the PR focused, explain the why in the description, and make sure local checks pass before requesting review.

Contribution guide: https://github.com/AI-Shell-Team/aish/blob/main/CONTRIBUTING.md

@github-actions
Copy link
Copy Markdown
Contributor

This pull request description looks incomplete. Please update the missing sections below before review.

Missing items:

  • User-visible Changes
  • Compatibility
  • Testing
  • Change Type
  • Scope

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/aish-pty/src/bash_rc_wrapper.sh`:
- Around line 171-181: The session command detection currently uses local
__aish_cmd_name="${BASH_COMMAND%% *}" which can include an absolute path (e.g.,
/usr/bin/ssh) so the case in the wrapper (matching ssh|telnet|...) will miss
such calls; change the extraction to strip any directory components and use the
basename of BASH_COMMAND (e.g., via parameter expansion to remove everything up
to the last '/') before the case check so names like /usr/bin/ssh match the ssh
pattern (update references to __aish_cmd_name and the case block accordingly to
use the basename).

In `@crates/aish-shell/src/readline.rs`:
- Around line 359-364: The loop that loads history reverses iteration causing
older entries to be prioritized; in the block where you check
self.editor.load_history(path).is_ok() and then iterate history =
self.editor.history(), remove the .rev() so you iterate in forward chronological
order (oldest→newest) while calling guard.add(...) (AutoSuggest::add uses
push_front), ensuring the newest commands end up at the front of the suggestion
queue; update the iteration over Editor::history().iter() accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f77194de-da0d-4126-9695-71427c379dc0

📥 Commits

Reviewing files that changed from the base of the PR and between a82d260 and 4fcf830.

📒 Files selected for processing (8)
  • crates/aish-llm/src/session.rs
  • crates/aish-pty/src/bash_rc_wrapper.sh
  • crates/aish-pty/src/persistent.rs
  • crates/aish-shell/src/ai_handler.rs
  • crates/aish-shell/src/app.rs
  • crates/aish-shell/src/readline.rs
  • crates/aish-tools/src/bash.rs
  • crates/aish-tools/src/secure_bash.rs

Comment thread crates/aish-pty/src/bash_rc_wrapper.sh
Comment thread crates/aish-shell/src/readline.rs
- Add cancellation token bridging from AI handler to BashTool so Ctrl+C
  during AI tool execution actually terminates the PTY child process
- Expand interactive command detection with explicit lists for TUI
  programs (vim, htop, less) and session commands (ssh, telnet, mosh)
- Re-enable echo and output processing (OPOST/ONLCR) for session
  commands so remote PTY displays correctly
- Extract basename in bash DEBUG trap so absolute paths like
  /usr/bin/ssh are correctly matched
- Improve PTY initialization: wait_for_session_ready now reports
  whether PromptReady co-arrived, add drain_control_pipe_raw to
  prevent stale events from shifting exit codes
- Enhance readline: gray hint highlighting, pre-populate autosuggest
  from saved history (oldest-first for correct recency), increase
  autosuggest capacity to 5000
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/aish-pty/src/persistent.rs`:
- Around line 662-676: In PersistentPty::start the temporary read into mtmp can
drop data because output_callback is None; change the read-handling in the
unsafe libc::read block so that if self.output_callback is None you append the
bytes read to an internal pending buffer (e.g., pending_master_output) or
forward them to the existing drain_master_to_stdout logic, otherwise call the
callback as before; update the struct to hold that pending buffer and ensure
drain_master_to_stdout consumes and clears it when invoked (reference symbols:
PersistentPty::start, output_callback, mtmp, drain_master_to_stdout, master_fd).

In `@crates/aish-tools/src/bash.rs`:
- Around line 37-43: The current check uses the first lexical token (let first =
command.split_whitespace().next()) which misses wrapper/env prefixes; update the
logic in crates/aish-tools/src/bash.rs to iterate over
command.split_whitespace() and skip leading tokens that are environment
assignments (tokens containing '=') or known wrapper tokens (e.g., "env",
"command", "nohup", "TERM" wrappers—introduce a small WRAPPER_TOKENS set), then
take the next non-skipped token as first and derive basename from it before
testing INTERACTIVE_COMMANDS and SESSION_COMMANDS; apply the same skip behavior
to the mirrored places in crates/aish-pty/src/bash_rc_wrapper.sh and
crates/aish-pty/src/persistent.rs so interactive/session routing works
end-to-end.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0985ea96-c538-44f4-9c55-ebe1559c0357

📥 Commits

Reviewing files that changed from the base of the PR and between 4fcf830 and 46835c7.

📒 Files selected for processing (8)
  • crates/aish-llm/src/session.rs
  • crates/aish-pty/src/bash_rc_wrapper.sh
  • crates/aish-pty/src/persistent.rs
  • crates/aish-shell/src/ai_handler.rs
  • crates/aish-shell/src/app.rs
  • crates/aish-shell/src/readline.rs
  • crates/aish-tools/src/bash.rs
  • crates/aish-tools/src/secure_bash.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/aish-tools/src/secure_bash.rs
  • crates/aish-llm/src/session.rs

Comment thread crates/aish-pty/src/persistent.rs
Comment thread crates/aish-tools/src/bash.rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant