Fix AI terminal command reliability and cancellation#314
Merged
Conversation
Fix intermittent hangs where simple AI terminal commands would get stuck until the timeout, and make long-running tasks and the stop button behave correctly. - UnixPseudoTerminal.WriteAsync now loops until every byte is written, handling partial writes and transient EINTR/EAGAIN. Previously the return value of write() was ignored, so a dropped trailing carriage return left the shell waiting and the command hanging forever. - Extend the AI runTerminalCommand timeout to 12h so long-running tasks (builds, simulations, servers) are not killed prematurely. - Thread the tool invocation CancellationToken through to ExecuteInTerminalAsync so pressing stop in Copilot cancels the running command. On timeout/cancel the shell is sent Ctrl+C (SendInterrupt) and recovered to a clean prompt so the reused terminal does not stay stuck. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
AI terminal commands (
runTerminalCommand) sometimes got stuck forever for seemingly no reason, even on simple commands. There was also no way to reliably cancel a running command, and the timeout was too short for long-running tasks.Root cause
UnixPseudoTerminal.WriteAsyncignored the return value of the POSIXwrite(2)call.write()may perform a partial write or return -1 onEINTR/EAGAINwhen the pty input buffer is momentarily full. When that happened, part of the command — often the trailing carriage return — was silently dropped, so the shell never executed the command, never emitted its completion marker, and the call hung until the timeout. Because it depends on buffer timing, it was intermittent and hit even trivial commands.Changes
UnixPseudoTerminal.WriteAsyncnow loops until every byte is written, advancing on partial writes and retrying on transient failures.runTerminalCommandtimeout is raised from 1 minute to 12 hours so builds/simulations/servers aren't killed prematurely.CancellationToken(auto-bound byAIFunctionFactoryto the token the Copilot SDK cancels onAbortAsync) and threads it intoExecuteInTerminalAsync.TerminalViewModel.SendInterrupt) and given a moment to return to a clean prompt, so the reused automation terminal doesn't stay stuck for subsequent commands.Testing
dotnet buildsucceeds forOneWare.Terminal,OneWare.TerminalManager, andOneWare.Chat(only pre-existing warnings).