Skip to content

Surface sandbox model fallbacks and honour confirmation editability - #334133

Merged
Osvaldo Ortega (osortega) merged 3 commits into
mainfrom
osortega/sandbox-model-selection-and-confirmation-fixes
Sep 2, 2026
Merged

Surface sandbox model fallbacks and honour confirmation editability#334133
Osvaldo Ortega (osortega) merged 3 commits into
mainfrom
osortega/sandbox-model-selection-and-confirmation-fixes

Conversation

@osortega

@osortega Osvaldo Ortega (osortega) commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Three follow-ups to #333897 and #333883, found while re-reviewing both against the agent host protocol. They are independent and can be reviewed in any order.

Important

Part of this intentionally reverts #333897 — see "2. Context tier" below. That deletion is the point of the change, not an accident. Flagging it so it isn't reported as a regression.

1. A sandbox turn silently ran on a model the user did not pick

_carryModelToSandbox has three paths that give up on the user's selection: no model target, the model isn't advertised, or the catalog doesn't arrive within the wait. All three logged and then dispatched the turn with no model at all.

An absent model on the message means the agent decides — for a session that has never run, that is its default. So the turn ran at a capability and a price the user hadn't chosen, and because that is a legitimate protocol state, nothing downstream had any reason to report it.

Each path now tells the user which model was dropped. Still a fallback rather than a hard failure: a sandbox has already been provisioned by this point, and failing the send would strand it.

2. Context tier was hidden whenever the workbench couldn't decorate it

This partially reverts #333897. That change labelled a host's contextTier values with token counts (264K / 1M) taken from the workbench's own model catalogue, and dropped the property entirely when it couldn't find them.

Two problems:

  • The labels were paired by array position. The host's tier enum and the catalogue's context-size list are independent sources. Nothing guarantees they are the same length or the same order, so the pairing mislabels as soon as either changes — showing the user a specific, wrong number.
  • Absent decoration was treated as absent capability. A host advertises an option because it will honour it. A model the workbench doesn't know, a staged rollout, and a catalogue that hasn't resolved yet are indistinguishable here, and all three silently removed a control the session actually supports.

The host's own labels (Default / Long context) are now used. This is a deliberate downgrade in label quality — real token counts should come from the host describing its own tiers, not from a client-side join.

3. Confirmations invited edits that were thrown away

A tool confirmation renders its input in an editor and writes changes back. Two separate paths do this, and both are affected:

  • Generic inputrawInput is written back, and ILanguageModelToolsService assigns it to the tool's parameters after confirmation.
  • Terminal — the command line is written back to commandLine.userEdited, which only the built-in terminal tool reads when it runs the command.

Agent-host confirmations reach neither. They confirm through the protocol, which does define a field for an edited input — but nothing in the workbench populates it. So a user could edit a shell command they were approving and watch the original one run.

Adds an optional editable flag to both invocation-data shapes:

  • omitted → editable, so every existing caller is unchanged;
  • agent-host confirmations set false, and the write-back handler isn't attached at all.

The terminal case sits alongside the existing presentationOverrides read-only rule rather than replacing it.

The adapter hardcodes false rather than forwarding the protocol's own editable, because forwarding a true would recreate the exact bug until the edited-input round trip is implemented. Noted in a comment and pinned by tests.

Testing

npm run typecheck-client clean. 3,765 chat tests pass.

New: two tests for the unavailable-model and timeout notifications; two for context-tier labelling and retention; one asserting a generic confirmation is read-only, and one for the terminal confirmation.

One existing assertion in stateToProgressAdapter.test.ts updated for the new editable: false — it failed first, which is the test doing its job.

Not verified

No UI run. The read-only editors and the notification are covered by unit tests and by reading the render paths, not by observation. The 5-second model wait is unchanged and still unvalidated — this only makes its expiry visible.

Not included

  • Removing the permission-metadata fallback from Render sandbox command approvals as terminal confirmations #333883. Still in the wrong layer, but its replacement doesn't exist yet, so removing it now would regress shipped behaviour. Documented in place with the condition for deleting it.
  • Removing the model catalogue join. Its token-limit half is a shim that a host can make dead by populating native protocol fields; its pricing half is not, because pricing is deliberately kept off the protocol as operator-sensitive. Dropping the join therefore means dropping pricing for these models — a product decision rather than a cleanup. The comment now separates the two.
  • Implementing the edited-input round trip.

Three follow-ups to the sandbox model and approval work in #333897 and
#333883, all found while re-reviewing those changes against the agent
host protocol.

Report when a sandbox turn does not use the model the user picked. The
three give-up paths logged and sent the turn with no model, which the
protocol reads as "the host decides" - so the turn ran at a capability
and price the user had not chosen and nothing said so.

Keep a host's context-tier option instead of dropping it when the
workbench cannot label it. Partially reverts #333897: the token-count
labels paired two independent catalogues by array position, which
mislabels as soon as either list changes, and dropping the property
outright hid a control the session supports whenever the model was
unknown to the workbench. The host's own labels are used instead.

Honour editability on tool confirmation inputs. The confirmation editor
writes back into rawInput, which ILanguageModelToolsService applies for
extension tools, but an agent-host confirmation never returns it - so a
user could edit a command they were approving and watch the original
run. Adds an optional editable flag, defaulting to editable so existing
tools are unaffected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings September 2, 2026 22:22

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.

Copilot review overview

🟡 Changes recommended

Terminal confirmations can still accept discarded edits, potentially executing the original command.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Balanced
Findings: 1 High severity · 1 Low severity

New issues introduced by this change (2)
Severity Finding
High severity src/​vs/​workbench/​contrib/​chat/​browser/​agentSessions/​agentHost/​stateToProgressAdapter.ts — The read-only safeguard only covers the generic-input branch; terminal confirmations built…
Low severity src/​vs/​sessions/​contrib/​providers/​copilotChatSessions/​browser/​copilotChatSessionsProvider.ts — This warning is emitted before sendRequest, so “was used” is false when dispatch subsequently…
What changed in this PR

Surfaces sandbox model fallbacks, preserves host-provided context tiers, and adds read-only controls for agent-host confirmations.

Changes:

  • Warns when sandbox model selection falls back.
  • Uses host-owned context-tier labels.
  • Adds confirmation input editability controls.
File Review
src/​vs/​workbench/​contrib/​chat/​test/​browser/​agentSessions/​stateToProgressAdapter.test.ts Tests read-only generic confirmations.
src/​vs/​workbench/​contrib/​chat/​test/​browser/​agentSessions/​agentHostLanguageModelProvider.test.ts Tests host context-tier metadata.
src/​vs/​workbench/​contrib/​chat/​common/​chatService/​chatService.ts Adds the input editability contract.
src/​vs/​workbench/​contrib/​chat/​browser/​widget/​chatContentParts/​toolInvocationParts/​chatToolConfirmationSubPart.ts Honors generic input editability.
src/​vs/​workbench/​contrib/​chat/​browser/​agentSessions/​agentHost/​stateToProgressAdapter.ts Critical: Terminal confirmations remain editable although edited commands are not dispatched.
src/​vs/​workbench/​contrib/​chat/​browser/​agentSessions/​agentHost/​agentHostLanguageModelProvider.ts Preserves host configuration properties.
src/​vs/​sessions/​contrib/​providers/​copilotChatSessions/​test/​browser/​copilotChatSessionsProvider.test.ts Tests model fallback notifications.
src/​vs/​sessions/​contrib/​providers/​copilotChatSessions/​browser/​copilotChatSessionsProvider.ts Nit: Warning claims a fallback model “was used” before dispatch succeeds.
src/​vs/​platform/​agentHost/​common/​state/​sessionReducers.ts Clarifies tool-kind fallback behavior.
src/​vs/​platform/​agentHost/​common/​meta/​agentPermissionRequestMeta.ts Documents compatibility metadata.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

The comment claimed the join could be removed once the agent host
publishes its own token counts and billing metadata. The billing half is
not coming: pricing is deliberately kept off the protocol as
operator-sensitive, so removing the join means dropping pricing for
these models rather than tidying up after a migration.

Separates the two halves: token limits are native protocol fields a host
can populate, pricing is a product decision.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The read-only safeguard only covered the generic-input branch. A
terminal confirmation renders its own editor, writes edits into
commandLine.userEdited, and only the built-in terminal tool reads that
back when it runs the command. An agent-host confirmation returns
nothing, so the edit was discarded and the original command ran - the
same bug as the generic input, on the path that actually carries shell
commands.

Adds editable to the terminal invocation data, sets it false in the
agent-host adapter, and honours it alongside the existing
presentationOverrides read-only case.

Also states the model fallback in the future tense: the warning is
raised before the turn is dispatched, so the fallback has not been used
yet at that point.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@osortega
Osvaldo Ortega (osortega) marked this pull request as ready for review September 2, 2026 23:31
@osortega
Osvaldo Ortega (osortega) merged commit 9a92570 into main Sep 2, 2026
40 checks passed
@osortega
Osvaldo Ortega (osortega) deleted the osortega/sandbox-model-selection-and-confirmation-fixes branch September 2, 2026 23:45
@vs-code-engineering vs-code-engineering Bot added this to the 1.137.0 milestone Sep 2, 2026
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.

3 participants