Improve interactive terminal input handling#308855
Merged
meganrogge merged 9 commits intomainfrom Apr 9, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Improves the terminal chat agent’s handling of interactive prompts by steering the model to send one prompt answer at a time (including “press Enter” sends) and by adding explicit guidance/notifications for input-needed cases across sync/async/background flows.
Changes:
- Update SendToTerminal UI messages to treat empty/whitespace sends as “Press Enter” rather than a command send.
- Expand RunInTerminal model guidance to require one-answer-per-prompt behavior (ask via
vscode_askQuestionswhen not auto-approved). - Add a background “input needed” steering notification when the output monitor detects an interactive prompt in a background terminal.
Show a summary per file
| File | Description |
|---|---|
| src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/sendToTerminalTool.ts | Adds “press Enter” messaging for empty input sends and adjusts confirmation text formatting. |
| src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts | Strengthens interactive-input guidance and sends a steering request when background terminals need input. |
Copilot's findings
Comments suppressed due to low confidence (2)
src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/sendToTerminalTool.ts:103
- New behavior for empty input ("Pressing Enter") in
prepareToolInvocationisn't covered by the existing SendToTerminalTool tests (they only assert general message presence/truncation/newline normalization). Add a unit test that passes an empty/whitespacecommandand asserts the progressive/past/confirmation messages match the Enter semantics, to prevent regressions in interactive prompt flows.
const pastTenseMessage = new MarkdownString();
if (isEmptyInput) {
invocationMessage.appendMarkdown(localize('send.progressive.enter', "Pressing `Enter` in terminal"));
pastTenseMessage.appendMarkdown(localize('send.past.enter', "Pressed `Enter` in terminal"));
} else {
src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts:1924
- The new background input-needed notification path (steering request sent from
_registerCompletionNotificationwhenonDidDetectInputNeededfires) isn't covered by the existing RunInTerminalTool tests. Consider adding a focused test that stubsIChatService.sendRequest, triggersonDidDetectInputNeeded, and asserts a single steering request is queued, so future refactors don't break interactive input handling for background terminals.
// When the output monitor detects the terminal is waiting for input,
// send a steering message so the agent handles it via send_to_terminal.
store.add(outputMonitor.onDidDetectInputNeeded(() => {
const execution = RunInTerminalTool._activeExecutions.get(termId);
if (!execution) {
return;
}
const currentOutput = execution.getOutput();
const isAutoApproved = isSessionAutoApproveLevel(chatSessionResource, this._configurationService, this._chatWidgetService, this._chatService);
const inputAction = isAutoApproved
? `Determine the best answer for the current prompt from context and immediately call ${TerminalToolId.SendToTerminal} with id "${termId}" to send ONLY that one answer. Then call ${TerminalToolId.GetTerminalOutput} to read the next prompt. Repeat one prompt at a time until the command finishes. Do NOT send multiple answers at once. Do NOT ask the user or respond with a text message.`
: `You MUST call the vscode_askQuestions tool to ask the user what values to provide. Do NOT respond with a text message asking the user — use the tool. Then send ONLY the answer for the current prompt using ${TerminalToolId.SendToTerminal} with id "${termId}", call ${TerminalToolId.GetTerminalOutput} to read the next prompt, and repeat one prompt at a time.`;
const message = `[Terminal ${termId} notification: command is waiting for input. ${inputAction}]\nTerminal output:\n${currentOutput}`;
this._logService.debug(`RunInTerminalTool: Input needed in background terminal ${termId}, notifying chat session`);
this._chatService.sendRequest(chatSessionResource, message, {
queue: ChatRequestQueueKind.Steering,
isSystemInitiated: true,
- Files reviewed: 2/2 changed files
- Comments generated: 2
Contributor
eleanorjboyd
approved these changes
Apr 9, 2026
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.
When a terminal command waits for interactive input (e.g. npm init), the agent would sometimes respond with a text message suggesting the user interact directly, or batch all answers into a single send. This PR fixes that across sync, async, and background notification paths.
Also:
Enterin terminal" instead of "Sent" for empty input insend_to_terminalcommandcan be empty/whitespace to press EnteronDidDetectInputNeededsteering messages (same output within 5s)