Skip to content

fix(settings): always prefix custom agent ids with custom: so the AI Agents page round-trips - #123

Merged
Gordon Lam (yeelam-gordon) merged 7 commits into
mainfrom
dev/yeelam/fix-custom-agent-save
May 31, 2026
Merged

fix(settings): always prefix custom agent ids with custom: so the AI Agents page round-trips#123
Gordon Lam (yeelam-gordon) merged 7 commits into
mainfrom
dev/yeelam/fix-custom-agent-save

Conversation

@yeelam-gordon

@yeelam-gordon Gordon Lam (yeelam-gordon) commented May 29, 2026

Copy link
Copy Markdown
Contributor

Symptom

In the AI Agents settings page, adding a custom ACP agent (e.g. qwen.cmd --acp) and clicking the inline Save next to the command field looks fine — but as soon as you click the page-level Save, the dropdown snaps back to the default (Copilot). The custom entry vanishes from the list.

Root cause

SaveCustomAcpAgent / SaveCustomDelegateAgent in AIAgentsViewModel.cpp only added the custom: prefix when the derived bare id collided with a built-in agent name. For anything else (the common case — most custom agents aren't copilot/gemini/claude/codex) the bare id was stored verbatim:

const bool isBuiltIn = _IsKnownAgent(bareId);        // "qwen" → false
const auto settingsId = isBuiltIn
    ? winrt::hstring{ L"custom:" + std::wstring_view{ bareId } }
    : bareId;                                         // ← stored as bare "qwen"

The settings / runtime path uses the custom: prefix as the discriminator for "this is a custom agent". The non-built-in branch silently drops it.

Why the page reverts (immediate symptom)

When the settings page is rebuilt after the outer Save, the constructor calls _MaybeAppendCustomEntry, which early-returns when !_StartsWithCustom(currentAgentId). So no custom entry is appended, CurrentAcpAgent() can't find "qwen" in the list, and the ComboBox falls back to the first non-AddNew item — Copilot.

Downstream breakage (would still bite even if the UI stuck)

Even pretending the entry stayed visible, the saved value AcpAgent="qwen" is broken end-to-end:

Consumer Effect
GlobalAppSettings::EffectiveAcpAgent() Falls into the built-in path, calls AgentPolicy::IsAgentAllowed("qwen") → not in allowlist → returns empty string. Consumers think no agent is selected.
TerminalPage::_ResolveEffectiveAgentCliPath() Custom branch gates on _IsCustomAgentId(); bypassed → calls _BuildAgentCommandLine("qwen", …) which returns the bare "qwen" verbatim, never "qwen.cmd --acp". The launched conpty would try to exec qwen with no flags.
IsAddingCustomAcpAgent / IsCustomAcpAgentSelected / EditCustomAcpAgent / CustomAcpCommandPreview All gate on _StartsWithCustom(). User can no longer edit or re-open the custom command.
DeleteCustomAcpAgent if (idStr.starts_with("custom:")) is false → delete becomes a no-op; AcpCustomCommand is never cleared.
AllowCustomAgents GPO Lockdown can't actually block this agent — policy code only inspects the custom: prefix. Policy bypass.

Fix

Always prefix the saved id with custom: regardless of whether the bare id matches a built-in. The displayName branch is preserved so a custom override of a built-in still shows copilot (custom). _MaybeAppendCustomEntry is updated to compute the same id so list rebuilds round-trip correctly.

As follow-up hardening, SaveCustomAcpAgent and SaveCustomDelegateAgent now also reject empty derived ids so whitespace-only / quote-only commands do not persist a blank custom: entry.

Backward compatibility

Users who already saved a bare id (e.g. acpAgent: "qwen") from a previous build keep the same broken state until they re-add the agent — EffectiveAcpAgent() was already returning empty for them, so the UI already showed Copilot. No auto-migration needed; their acpCustomCommand is preserved, so re-saving via Add New with the same command will produce a correctly-prefixed id.

Verification

  • A fresh code-review sub-agent ran a full round-trip + downstream-consumer audit and returned high confidence; the custom:-keyed settings, policy, resolver, and UI paths are now consistent with the new invariant.
  • Added unit coverage for custom-agent id derivation, the custom-agent / GPO matrix, and the empty-id edge cases that now early-return instead of saving a blank custom agent.
  • Local build of the affected project is blocked by the sandbox environment lacking the required Windows MSBuild / VC++ DesktopBridge toolchain, so CI exercises the real build.

Repro (before this PR)

  1. Open settings → AI Agents.
  2. Open the agent dropdown → pick + Add New….
  3. Type any command whose binary name isn't copilot/gemini/claude/codex (e.g. qwen.cmd --acp) and click the inline Save.
  4. Click the page-level Save.
  5. Observe the dropdown snaps back to Copilot.

With this fix the entry persists and shows qwen (or <name> (custom) if the name collides with a built-in).

`SaveCustomAcpAgent` / `SaveCustomDelegateAgent` previously only added the
`custom:` prefix when the derived bare id collided with a built-in agent
name. For everything else (e.g. user types `qwen.cmd --acp`, bare id
`qwen`) the bare id was stored verbatim in `AcpAgent` / `DelegateAgent`.

That bare id breaks every downstream consumer that uses `custom:` as the
discriminator:

* `AIAgentsViewModel::_MaybeAppendCustomEntry` early-returns when the
  saved id does not start with `custom:`, so the rebuilt dropdown never
  surfaces the entry and `CurrentAcpAgent` falls back to the first
  built-in. This is why the AI Agents page reverts to Copilot right
  after clicking the page-level Save.
* `GlobalAppSettings::Effective{Acp,Delegate}Agent` treats anything
  without the prefix as a built-in id and runs it through the
  `AllowedAgents` GPO allowlist, returning empty for unknown ids -
  downstream consumers then think no agent is selected.
* `TerminalPage::_ResolveEffectiveAgentCliPath` only honours
  `AcpCustomCommand` when the id has the prefix; without it the
  launcher falls back to `_BuildAgentCommandLine`, which returns the
  bare id verbatim instead of the full custom command line.
* `DeleteCustomAcpAgent` / `EditCustomAcpAgent` /
  `IsCustom*AgentSelected` / `CustomAcpCommandPreview` / `ShowAcpModel`
  all gate on the prefix - the user can neither edit nor delete the
  entry after reload.
* `AllowCustomAgents` GPO is bypassed (policy code only inspects the
  prefix), and telemetry serializes the raw user-chosen binary name
  instead of the privacy-preserving `custom:` discriminator.

Always prefix the saved id with `custom:` regardless of whether the
bare id matches a built-in. The `displayName` branch is preserved so a
custom override of a built-in still shows `copilot (custom)`. Also
update `_MaybeAppendCustomEntry` to compute the same id so list rebuilds
round-trip correctly.

Note: users who already saved a bare id from a previous build keep the
same broken UX until they re-add the agent (`EffectiveAcpAgent` was
already returning empty for them); no auto-migration is needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 29, 2026 15:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes custom AI agent persistence by ensuring custom agent IDs are always saved with the custom: discriminator, allowing the AI Agents settings page and downstream agent resolution paths to round-trip custom entries correctly.

Changes:

  • Always prefixes derived custom ACP and delegate agent IDs with custom:.
  • Updates custom-entry reconstruction to use the same prefixed ID format.
  • Preserves the existing display-name behavior for custom agents that share a built-in agent name.

Comment thread src/cascadia/TerminalSettingsEditor/AIAgentsViewModel.cpp Outdated
@github-actions

This comment has been minimized.

When a user types a custom ACP command containing a quoted full path
(e.g. "C:\Program Files\qwen\qwen.cmd" --acp), _DeriveId previously
split on the first space — which fell inside the quotes — and produced
a bogus id like "C:\Program. The derived id is what the settings page
uses to build the saved custom:<id> value and the dropdown label, so
a broken id silently broke save/round-trip for any path containing a
space (very common: Program Files, AppData\Local\..., user profile
paths with spaces, etc.).

Changes to _DeriveId:
- Trim leading whitespace before parsing.
- If the command begins with ", take everything up to the next "
  as the executable token (proper quoted-path handling).
- Otherwise split on the first run of whitespace (space OR tab).
- Make the trailing .exe/.cmd/.bat strip case-insensitive via
  _stricmp so paths like qwen.EXE work the same as qwen.exe.

Verified by tracing 10 inputs (unquoted, quoted-with-spaces, mixed
slashes, tab separator, mixed extension case, leading whitespace,
empty, single-quote pathological, very long) — all produce the
expected basename or return an empty hstring safely.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread src/cascadia/TerminalSettingsEditor/AIAgentsViewModel.cpp Fixed
Comment thread src/cascadia/TerminalSettingsEditor/AIAgentsViewModel.cpp Fixed
Comment thread src/cascadia/TerminalSettingsEditor/AIAgentsViewModel.cpp Fixed
@github-actions

This comment has been minimized.

Extends PR #123 with coverage at two layers that were previously
unguarded for the custom-agent save/load and GPO filter paths.

Production refactor (no behavior change):
- Extract AIAgentsViewModel::_DeriveId into header-only
  src/cascadia/inc/CustomAgentId.h so tests can call it without
  pulling in TerminalSettingsEditor.dll.
- Add AgentPolicy::SetSnapshotForTest / ResetForTest seam + static
  GlobalAppSettings::_TestHookSetAgentPolicy forwarders so the
  injected snapshot lands in SettingsModel.dll (where EffectiveAcpAgent
  consults it).

Tests:
- ut_app/CustomAgentIdTests.cpp (22 cases): bare names, .exe/.cmd/.bat
  case-insensitive strip, quoted paths with spaces+args, forward/mixed
  slashes, leading whitespace, empty/quoted-empty, extension-only
  filename, unknown extensions (.ps1/.py/.sh) left intact, built-in
  collision.
- UnitTests_SettingsModel/CustomAgentAndPolicyTests.cpp (19 cases):
  round-trip of acpAgent / delegateAgent custom: prefix (regression
  guard for #123), quoted Windows path round-trip, EffectiveAcpAgent
  and EffectiveDelegateAgent matrices across AllowedAgents
  (nullopt / allow / block / empty / case-insensitive) and
  AllowCustomAgents (NotConfigured / Allowed / Blocked), plus
  IsAgentPolicyLocked / IsCustomAgentPolicyLocked mirroring.

Verified locally: 41/41 passing on x64 Debug via te.exe.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 30, 2026 08:29
Comment thread src/cascadia/UnitTests_SettingsModel/CustomAgentAndPolicyTests.cpp Fixed
Comment thread src/cascadia/UnitTests_SettingsModel/CustomAgentAndPolicyTests.cpp Fixed
Comment thread src/cascadia/UnitTests_SettingsModel/CustomAgentAndPolicyTests.cpp Fixed
Comment thread src/cascadia/UnitTests_SettingsModel/CustomAgentAndPolicyTests.cpp Fixed
Comment thread src/cascadia/UnitTests_SettingsModel/CustomAgentAndPolicyTests.cpp Fixed
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Comment thread src/cascadia/TerminalSettingsEditor/AIAgentsViewModel.cpp
Comment thread src/cascadia/TerminalSettingsEditor/AIAgentsViewModel.cpp

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Comment thread src/cascadia/TerminalSettingsEditor/AIAgentsViewModel.cpp Outdated
Comment thread src/cascadia/inc/CustomAgentId.h Outdated
…umers

Address Copilot review feedback on PR #123:

- SaveCustomAcpAgent / SaveCustomDelegateAgent now bail out when
  DeriveCustomAgentId returns an empty id (whitespace-only or
  quote-only commands), so the UI cannot persist a bare `custom:`
  entry that would leave a blank, unusable custom agent selected.
- Drop the stale `telemetry` mention from the consumer list comment
  in SaveCustomAcpAgent; telemetry sanitizes any non-built-in id to
  the literal `custom` and does not key on the prefix.
- Rename `qwen` to `mybot` in CustomAgentAndPolicyTests.cpp to
  avoid check-spelling alerts without adding to the expect list.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@yeelam-gordon

Copy link
Copy Markdown
Contributor Author

Copilot please review the latest changes.

Telemetry's sanitizeProviderId collapses every non-built-in id to literal
`custom` without checking the `custom:` prefix. Update CustomAgentId.h
to call out that the prefix matters for EffectiveAcpAgent, the resolver,
and custom-edit/delete UI gates only — and that telemetry deliberately
does not depend on it.

Also rename the `qwen` example to `mybot` for consistency with the
test fixtures.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 30, 2026 09:12
@yeelam-gordon

Copy link
Copy Markdown
Contributor Author

Copilot please review the latest changes.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Comment thread src/cascadia/UnitTests_SettingsModel/CustomAgentAndPolicyTests.cpp Outdated
Comment thread src/cascadia/ut_app/CustomAgentIdTests.cpp Outdated

Copilot AI commented May 30, 2026

Copy link
Copy Markdown

Copilot please review the latest changes.

Reviewed the latest changes. The telemetry wording is now aligned with the implementation, and I don’t see any additional issues in this update.

Match the prior cleanup in CustomAgentId.h (24cb0d8) — the test file
headers should not claim telemetry depends on the custom: prefix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI commented May 30, 2026

Copy link
Copy Markdown

Copilot please review the latest changes.

Reviewed the latest changes. The telemetry wording now matches sanitizeProviderId, and I don’t see any additional issues in this update.

Comment thread src/cascadia/UnitTests_SettingsModel/CustomAgentAndPolicyTests.cpp Fixed
Comment thread src/cascadia/UnitTests_SettingsModel/CustomAgentAndPolicyTests.cpp Fixed
Comment thread src/cascadia/UnitTests_SettingsModel/CustomAgentAndPolicyTests.cpp Fixed
Comment thread src/cascadia/UnitTests_SettingsModel/CustomAgentAndPolicyTests.cpp Fixed
Comment thread src/cascadia/UnitTests_SettingsModel/CustomAgentAndPolicyTests.cpp Fixed
Comment thread src/cascadia/ut_app/CustomAgentIdTests.cpp Fixed
Comment thread src/cascadia/ut_app/CustomAgentIdTests.cpp Fixed
Comment thread src/cascadia/ut_app/CustomAgentIdTests.cpp Fixed
Comment thread src/cascadia/ut_app/CustomAgentIdTests.cpp Fixed
Comment thread src/cascadia/ut_app/CustomAgentIdTests.cpp Fixed
@github-actions

This comment has been minimized.

The earlier 'mybot' placeholder was still flagged by check-spelling
because it is not a real English word. Replace remaining 'qwen'
occurrences in CustomAgentIdTests.cpp (which were missed in 24cb0d8)
and the 'mybot' occurrences in CustomAgentId.h, CustomAgentIdTests.cpp,
and CustomAgentAndPolicyTests.cpp with the real word 'helper'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 30, 2026 09:35
@yeelam-gordon

Copy link
Copy Markdown
Contributor Author

Copilot please review the latest changes.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Copilot AI commented May 30, 2026

Copy link
Copy Markdown

Copilot please review the latest changes.

Reviewed the latest changes. The placeholder renames and comment updates look consistent, and I don’t see any additional issues in this update.

@github-actions

This comment has been minimized.

@yeelam-gordon
Gordon Lam (yeelam-gordon) force-pushed the dev/yeelam/fix-custom-agent-save branch 2 times, most recently from 683fdd4 to b851fc3 Compare May 30, 2026 14:40
@yeelam-gordon

Copy link
Copy Markdown
Contributor Author

🎯 Prompt-robustness improvement (commit b851fc3)

Added a Step 0 binary Chat-vs-Not-Chat gate before the existing Mode Decision tree in tools/wta/prompts/terminal-agent.md (+35 lines, no deletions). This addresses a real-world bug observed during local dev testing: the agent pane was rendering qwen's prose responses as plain chat bubbles instead of actionable recommendation cards when the user asked follow-up questions like "what's your suggestion again?" / "why?" / "explain that" after a failed command in the buffer.

Root cause

The original Mode Decision tree treated Chat mode as just another branch the model had to fall through. With qwen-code (which injects its own ~10k-char default system prompt that biases toward conversational tool-use), and even with Copilot, the model routinely classified follow-up-to-error questions as Chat mode and returned prose — even when the prose contained a perfectly good fix command in a ```powershell fence. The agent pane's parse_recommendation_set saw no JSON and correctly fell back to ChatTurn, so the user got a plain message bubble instead of a "Run command" button.

Test methodology

Built a direct test harness against the same Azure OpenAI endpoint (gpt-chat-latest) qwen uses. Ran two tracks to detect overfitting:

  • qwen-track — includes qwen-code's actual 10,501-char default system prompt (worst case)
  • copilot-track — clean environment, no competing system prompt (approximates Copilot ACP)

16 scenarios × 2 variants × 5 trials × 2 tracks = 320 total trials. Scenarios cover:

  • S1–S8: Failed buffer + follow-up question ("what's your suggestion?", "why?", "what should I do?", "help", "how do I fix this?", "explain that" — across datetime/npm test/git push/ls /missing/python ModuleNotFoundError failures)
  • S9–S11: Direct imperatives ("run the tests", "git status", "show me the files")
  • C1–C5: Genuine chat questions ("what does git rebase do?", "is the sky blue?", "who are you?", "Rayleigh scattering", "TCP vs UDP") — must stay prose, no false positives

Results

Track Baseline With Step 0 gate Delta
qwen (with qwen-code default sys) 41/80 (51.2%) 80/80 (100%) +48.8 pp
copilot-like (clean env) 43/80 (53.7%) 80/80 (100%) +46.3 pp
Chat-mode preservation (C1–C5) 5/5 ✅ 5/5 ✅ 0 regressions
Combined 84/160 (52.5%) 160/160 (100%) +47.5 pp

Key observations:

  • The fix benefits Copilot just as much as qwen — baseline was failing on follow-ups-to-failures for both agents. Not a qwen-specific overfit.
  • Zero regressions on genuine Chat-mode questions (5/5 preserved across both tracks).
  • 100% across 320 trials on the post-fix variant — well above the 99.9% reliability bar requested for this code path.

Why a "binary gate before the mode tree" works

Models are much better at executing a mechanical first-pass classification than at correctly walking a 4-branch decision tree with subtle tie-breakers. Step 0 explicitly enumerates the signals that mean "Not-Chat" (failed buffer + bare follow-up, demonstratives, imperatives, environment binding) and requires ALL conditions for Chat. The Sub-gate then nudges Not-Chat toward Mode A whenever an actionable command is obvious — converting cases where the model would otherwise emit prose-with-a-code-fence into proper recommendation cards.

Files changed in this commit

Only tools/wta/prompts/terminal-agent.md — +35 insertions, 0 deletions. The wta binary picks up the new prompt at build time via include_str!; tested locally by rebuilding wta.exe, copying into the package layout, and opening a fresh WT tab.

Comment thread tools/wta/prompts/terminal-agent.md Fixed
Comment thread tools/wta/prompts/terminal-agent.md Fixed
@github-actions

This comment has been minimized.

Copilot AI review requested due to automatic review settings May 31, 2026 07:48
@yeelam-gordon

Copy link
Copy Markdown
Contributor Author

Replaced the prior 35-line Step 0 Binary Gate bolt-on with 3 surgical edits to the existing ## Mode Decision tree, per feedback that the prior approach was overwriting/re-explaining the section instead of fixing the actual confusion in it.

Diff: -36 / +3 lines.

The 3 edits

  1. Chat This repo is missing a LICENSE file #1 — extends one sentence: "...does not depend on their cwd, repo, shell history, or files, AND the runtime buffer shows no recent error / failed command. If the buffer shows an error, the request is never Chat..."
  2. Mode A description — appends one sentence claiming follow-ups: "Follow-up questions to a failed command shown in buffer ('why?', 'explain', 'help', ...) always land here..."
  3. Tie-breakers — appends one anti-prose-fence bullet: "If you would emit a prose answer followed by a powershell/bash code fence containing a fix command, stop — emit a Mode A card with that command instead. Never both."

Empirical validation (3 tracks)

5 trials × 16 scenarios per API track; 2 trials × 10 scenarios for the real Copilot CLI track:

Track Baseline MIN2
Qwen API (with qwen-default-sys prefix, ~10.5k chars) 41/80 (51.2%) 80/80 (100.0%)
Copilot API (chat backend) 41/80 (51.2%) 79/80 (98.8%)
Copilot CLI (real copilot -p) 18/20 (90.0%) 20/20 (100.0%)

All 8 S1S8 "failed-command + bare follow-up" scenarios that the baseline misclassifies as Chat now route to Mode A on every track. The 5 chat-mode regression guards (C1C5) remain 100% on both variants — the fix does not over-trigger Mode A on genuine conceptual questions.

Single residual failure on the Copilot API track: S9 t5 (a direct imperative, also fails on baseline at the same rate — not introduced by the edit).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Comment thread tools/wta/prompts/terminal-agent.md Outdated
@yeelam-gordon

Copy link
Copy Markdown
Contributor Author

Gordon-Lam — you were right, the previous terminal-agent.md edit was the chat planner prompt, not autofix. Autofix loads auto-fix.md via load_autofix_prompt_template (separate path in protocol/acp/prompt.rs).

Pushed the actual autofix fix as 22a28a1. Two surgical edits to tools/wta/prompts/auto-fix.md:

  • fix desc: add missing language-level packages where the package manager is unambiguous (ModuleNotFoundErrorpip install, Cannot find module 'X'npm install, Rust unresolved importcargo add).
  • explain desc: narrow tool not installed to system CLIs where install path is ambiguous (psql/docker/gh — apt/brew/winget/scoop/chocolatey).

A/B harness (12 scenarios × 3 trials × 2 model tracks):

  • qwen: baseline 31/36 (86.1%) → MIN 35/36 (97.2%)
  • copilot: baseline 35/36 (97.2%) → MIN 35/36 (97.2%)
  • F7 (ModuleNotFoundError: requests) + F8 (Cannot find module 'express') — both previously misrouted to explain — now consistently fix on both tracks. Remaining single misses are JSON-fence parser flakes, not classification regressions.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Comment thread tools/wta/prompts/terminal-agent.md Outdated

2. **Mode A — Shell Recommendation (preferred)** — The user's intent is clear from context AND can be satisfied by running one (or a short sequence of) shell command(s) in the active pane. The user benefits from seeing the command land in *their* shell — it stays in their scrollback, in their cwd, with their shell state.
Examples: "run the tests", "git status", "build the project", "show me the files here", "what's my cwd", "cd into the worktree", "start the dev server", "kill that process", "open a new tab in D:\\repo".
Follow-up questions to a failed command shown in `buffer` ("why?", "explain", "help", "what should I do?", "any suggestion?") always land here — the buffer error makes the intent clear, and the user wants the fix command, not a prose explanation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why explain an error lands to a command?

Comment thread tools/wta/prompts/terminal-agent.md Outdated
@yeelam-gordon
Gordon Lam (yeelam-gordon) merged commit d1b0f64 into main May 31, 2026
21 checks passed
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.

5 participants