Deprecate chat.tools.terminal.backgroundNotifications — always send terminal notifications#309555
Merged
meganrogge merged 2 commits intomainfrom Apr 13, 2026
Merged
Deprecate chat.tools.terminal.backgroundNotifications — always send terminal notifications#309555meganrogge merged 2 commits intomainfrom
chat.tools.terminal.backgroundNotifications — always send terminal notifications#309555meganrogge merged 2 commits intomainfrom
Conversation
Contributor
Contributor
There was a problem hiding this comment.
Pull request overview
This PR deprecates chat.tools.terminal.backgroundNotifications and makes terminal completion/input-needed steering notifications unconditional for background terminal executions (excluding subagent-initiated terminals), to remove confusing/untestable partial “off” behavior.
Changes:
- Deprecated
chat.tools.terminal.backgroundNotifications(default set totrue+ deprecation message). - Removed
backgroundNotificationsplumbing fromrunInTerminaltool model-description helpers and always included notification guidance. - Updated
RunInTerminalToolto always register background completion/input-needed notifications unless invoked by a subagent.
Show a summary per file
| File | Description |
|---|---|
src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalChatAgentToolsConfiguration.ts |
Deprecates the background notifications setting and updates default/deprecation messaging. |
src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts |
Removes config gating + always registers background notifications; updates model-facing tool descriptions accordingly. |
Copilot's findings
Comments suppressed due to low confidence (3)
src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts:235
- This model-facing guidance says notifications happen for "async terminal commands" only, but notifications are now sent for any command that continues running after the tool returns (including sync-timeout / fg→bg). Consider rewording to "background terminal commands" or explicitly include the sync-timeout/continue-in-background case so the model’s expectations match actual behavior.
Best Practices:
- Quote variables: "$var" instead of $var to handle spaces
- Use find with -exec or xargs for file operations
- Be specific with commands to avoid excessive output
- Avoid printing credentials unless absolutely required
- NEVER run sleep or similar wait commands in a terminal. You will be automatically notified on your next turn when async terminal commands complete or need input. Use ${TerminalToolId.GetTerminalOutput} to check output before then
Interactive Input Handling:
- When a terminal command is waiting for interactive input, do NOT suggest alternatives or ask the user whether to proceed. Instead, use the vscode_askQuestions tool to collect the needed values from the user, then send them.
- Send exactly one answer per prompt using ${TerminalToolId.SendToTerminal}. Never send multiple answers in a single send.
- After each send, call ${TerminalToolId.GetTerminalOutput} to read the next prompt before sending the next answer.
- Continue one prompt at a time until the command finishes.`);
src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts:334
- The tool’s
modelDescriptionsection is titled and worded as "Async terminal notifications" and refers specifically to commands in an async terminal, but the implementation now also notifies for sync executions that time out/continue in background. Please adjust this text to describe notifications for any background/continued execution (mode=async and mode=sync when the command continues running after return).
displayName: localize('runInTerminalTool.displayName', 'Run in Terminal'),
modelDescription: `${modelDescription}\n\nExecution mode:\n- mode='sync': wait for completion up to timeout; if still running, return with a terminal ID.\n- mode='async': wait for an initial idle/output signal, then return with terminal output snapshot and ID. Timeout caps how long to wait for the initial idle/output signal.\n- Prefer mode='sync' for commands that will prompt for interactive input (e.g., npm init, interactive installers, configuration wizards).\n\nAsync terminal notifications: When a command finishes in an async terminal, you will be automatically notified on your next turn with the exit code and terminal output. You will also be notified if the terminal needs input. Use ${TerminalToolId.GetTerminalOutput} to check output before then. Do NOT poll or sleep to wait for completion.`,
userDescription: localize('runInTerminalTool.userDescription', 'Run commands in the terminal'),
src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.ts:1709
- In the timeout guidance, the tool now promises an automatic notification only "when it completes", but background notifications also include input-needed events. To keep the model instructions accurate (and consistent with the rest of the descriptions), mention that it will be notified if the terminal needs input as well, not just on completion.
resultText.push(`Note: Command timed out after ${timeoutValue}ms. The command may still be running in terminal ID ${termId}. You will be automatically notified on your next turn when it completes. Use ${TerminalToolId.GetTerminalOutput} to check output before then, ${TerminalToolId.SendToTerminal} to send further input, or ${TerminalToolId.KillTerminal} to stop it. Do NOT use sleep or manual polling to wait. Evaluate the terminal output to determine if the command is waiting for input (e.g. a password prompt, confirmation, or interactive question). A normal shell prompt does NOT count as waiting for input. ${inputAction}\n\n`);
}
- Files reviewed: 2/2 changed files
- Comments generated: 2
Contributor
|
@meganrogge Seems like test might be acting flaky |
roblourens
approved these changes
Apr 13, 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.
Addresses #309523
Addresses #308548
Why this needs to be fixed now
This was filed as part of testing the terminal tool improvements (#309095). The
chat.tools.terminal.backgroundNotificationssetting has an inconsistent off-state: setting it tofalsesuppresses notifications for true async terminals (mode=async) but not for foreground terminals that moved to background (timeout/input-needed). This is because the code intentionally bypasses the setting for fg-to-bg transitions — the tool result already promises the model "you will be notified when it completes," so suppressing the notification would leave the agent unable to learn the command finished.This means the setting was never truly "off" — it only partially suppressed notifications, making it confusing for users and impossible to test deterministically (#309523).
What changed
trueand a deprecation messagebackgroundNotificationsparameter plumbing from all model description helper functionsRationale
get_terminal_outputcallsexperiment: { mode: 'auto' }), not intended as a permanent user preference