* NES telemetry: add isForAnotherDocument to inlineCompletion.endOfLife event
The core inlineCompletion.endOfLife telemetry event already reports
UI-accurate, cursor-jump-model-agnostic fields (shown, reason,
viewKind, longDistanceHintVisible). However it could not distinguish a
long-distance same-document NES suggestion from one targeting another
document: the long distance hint is rendered for both cases.
Add an isForAnotherDocument flag, computed at render time via the
existing TextModelValueReference.targets() helper (edit target vs the
active editor's model) - the same notion that drives cross-document
long-distance hint visibility. This lets scorecards derive valid
Shown/Accepted/Rejected cursor-jump metrics for diff-patch models
without relying on the separate cursor-jump model telemetry.
Reuse targets() at the two remaining raw URI-comparison sites
(_getLongDistanceHintState and the long distance hint view) so the
cross-document determination lives in one place and cannot drift.
Also convert the shared mutable emptyViewData singleton into a factory
so per-suggestion view data (including the new isForAnotherDocument
flag) can no longer leak across suggestions.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Trim isForAnotherDocument JSDoc to essentials
Move the scorecard consumption/derivation guidance to the PR description
and keep the in-code JSDoc to a short description of the field, per VS
Code JSDoc conventions and reviewer feedback.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Render chat turn changes as a checkpoint-style summary
Restyle the chat turn pills part to match the checkpoint file changes summary: a 'N files changed +ins -del' header with a View All File Changes action, an optional inline 'preview <file>' action for the first previewable file, and an expandable list of changed files. Each markdown/HTML row in the list gets a labelless 'Preview' action that opens the file in the Markdown preview or the integrated browser.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix turn changes summary fixtures and address review feedback
- Stub IAgentHostService.getSubscription in chat fixtures so agent-host chat widgets (turn changes summary) render without crashing (the generic config chips lane opens a session subscription). - Use the canonical agent-host session scheme for the in-chat fixtures. - Reference CHANGES_SUMMARY_ELEMENT_HEIGHT from the list delegate. - Hide the preview separator in preview-only mode.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Clamp the blocked-sessions context view width between the titlebar widget width (min 550px) and 90% of the window width, and center it on the command center box.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Record the signed line distance from the request cursor line to the
suggested edit's range start line (rangeStartLine - cursorLine, 0-based)
on the provideInlineEdit (NES) event. Only set when the suggestion targets
the active document, so both lines share the same coordinate space;
undefined otherwise. Emitted as a measurement so 0 (same line) is preserved.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
editor: floor NES long-distance hint width at minWidgetWidth
The placement logic (tryFindWidgetOutline) only accepts a location offering at least minWidgetWidth of horizontal space, but maxWidgetWidth was computed purely from the preview content width. For a cursor jump landing on a short or empty line, maxEditorWidth shrinks to just the gutter, collapsing the widget far below the space already reserved for it (observed: 725px reserved, rendered at the 150px flex floor). Floor maxWidgetWidth at layoutConstants.minWidgetWidth.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The AnimatedCounterWidget animated its initial value because the first render (empty element -> first value) was treated like a value update. Add a _hasRendered flag so the first value is set directly without animation, and reset it when the count returns to undefined so a later value renders fresh.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Record the signed line distance from the request cursor line to the
suggested edit's range start line (rangeStartLine - cursorLine, 0-based)
on the provideInlineEdit (NES) event. Only set when the suggestion targets
the active document, so both lines share the same coordinate space;
undefined otherwise. Emitted as a measurement so 0 (same line) is preserved.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Include editor headers in proxy models request; thread real editor info through chat-lib NES path
The proxy models service fetched `/models` with only an Authorization
header, bypassing the CAPIClient path that normally injects
Editor-Version / Editor-Plugin-Version. Chat-lib's NES provider also
resolved IEnvService to NullEnvService, so it would have emitted
placeholder (test) editor headers even after the fix.
- Refactor getEditorVersionHeaders() from an AbstractEnvService method
into an exported free function taking any IEnvService, so it works for
every environment (VS Code, chat-lib/CLI, tests), including impls that
don't extend AbstractEnvService.
- Inject IEnvService into ProxyModelsService and add the editor headers
to the /models fetch.
- Add required editorInfo / editorPluginInfo to INESProviderOptions and
register a real IEnvService in the NES service builder, mirroring the
completions path. Making them mandatory turns a missing value into a
compile error instead of silently shipping test headers.
- Add unit tests covering the proxy models fetch headers and the
end-to-end NES /models request headers.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* NES: add exp config to yield additive cursor-line edit first for multi-line patches
For diff-patch responses, the progressive ghost-text reveal emits the
cursor-line edit ASAP when it additively changes the cursor line, but
previously only for patches removing a single line. Extend it to fire for
multi-removed-line first patches behind a new experiment config
`chat.advanced.inlineEdits.xtabProvider.patchFastYieldLineWithCursorMultiLine`
(default off): the additive cursor-line change (removed[0] -> added[0]) is
yielded immediately and the remaining removed/added lines stream as a
continuation.
The early edit is a 1-for-1 additive replacement, so it causes no line shift
and the continuation (anchored at cursorLine+1 over the original document)
stays correctly anchored — the union is byte-identical to the original patch.
Multi-line reveal is restricted to duplicate-additions modes that preserve a
patch's removed range (Off / TrimDuplicate); DropPatch/DropAllRemaining could
skip the continuation after the early edit was already emitted. The early
reveal edit is additionally excluded from the duplicate-additions policy: it
carries no re-emitted context to trim, and running the policy on it could
spuriously trim its added line to empty and emit a cursor-line deletion when
that line coincides with the line below the cursor (cascade edits).
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Refactor NES multi-line reveal handler for readability
Behavior-preserving cleanup of the diff-patch progressive-reveal logic in
xtabPatchResponseHandler.ts. No functional change (75/75 spec tests pass
unchanged).
- Extract named policy helpers: duplicateModePreservesRemovedRange,
allowsMultiLineProgressiveReveal, and shouldApplyDuplicatePolicy (a type
guard that preserves the Exclude<..., Off> narrowing for applyDuplicatePolicy).
- Add Patch.progressiveRevealParts() factory that owns the early/continuation
split invariants; remove the misleading Patch.insertion helper (it built
non-insertions for the multi-line case).
- Split isGhostTextPatch into early returns plus a named isEmptyCursorLineShiftUp
predicate for the empty-cursor-line shift-up guard.
- Relocate long rationale comments into helper JSDoc so the streaming loop reads
top-to-bottom.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The chat input changes pill now opens a multi-diff editor identified by a special-scheme URI derived from the chat's resource, instead of running the whole-session Changes command.
A new LastTurnChangesMultiDiffSourceResolver resolves that URI to a live list of diffs for the files changed in the chat's last turn: each file's original side is the first origin resource found for it, and the modified side is the on-disk (live) resource, so the diffs update as further edits stream in.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Open File action in the session Changes per-file toolbar was gated
only on the 'changes-multi-diff-source' resource scheme, which is shared
by both the single-pane SessionChangesEditor and the generic
MultiDiffEditor fallback. The generic editor already contributes the
workbench GoToFileAction, so the session action was duplicated there.
Scope the action to the SessionChangesEditor via ActiveEditorContext so
it only appears in the single-pane editor and no longer leaks into the
multi-file diff editor.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
editor: fix multi-diff header path overlapping actions
The collapsed multi-diff entry header laid out [collapse] [.file-path]
[.actions] in a flex row, but .file-path did not clip and .actions could
shrink, so a long file path rendered underneath the trailing action
icons (screen cheese) in the Agents window Changes editor.
Clip .file-path (overflow: hidden), keep the titles shrinking with
ellipsis, and pin .actions with flex: 0 0 auto so the icons keep their
fixed width and are never overlapped.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a dropdown on the right-hand side of the breadcrumbs bar that shows
the current editor type and lets the user switch editors, set the
default, and (for diffs) open either side.
- Shown only when more than one editor can open the resource, so plain
text files and exclusive editors (e.g. Hex) do not show it.
- Menu switches the active editor (via `reopenActiveEditorWith`), with a
`Set Default` submenu that writes to `workbench.editorAssociations` or,
for diffs, `workbench.diffEditorAssociations`. Diffs also offer
`Open Original` / `Open Modified`.
- Extension editors show their source as `Label - Extension Name`;
built-in editors show just their label. In a diff the default editor
is labeled `Text Diff Editor`.
- Only on the dedicated breadcrumbs bar (tabbed mode), gated behind the
experimental `breadcrumbs.showEditorType` setting (default `true`).
- Adds `IEditorResolverService.getConfiguredDefaultEditor` and a
`forDiffEditor` flag on `updateUserAssociations`.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move `lastTurnChanges` from the session concept to the chat concept so a session with multiple chats tracks last-turn changes per chat. The changes pill above the chat input now reflects the viewed chat's last-turn changes and gates on that chat's status.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Revert "fix: builtin resolution of electron modules via asar hook (#324861)"
This reverts commit 5928613aa1.
* Revert "fix: restrict asar esm hook resolution to app resources (#324851)"
This reverts commit 89bc3825bd.
* Revert "feat: restore asar for node_modules (#324084)"
This reverts commit c9dda3b36a.
- Add ClaudeSonnet5Prompt (Sonnet 4.6 base + scope/interface/effort append) via new renderAppendedInstructions hook, gated behind chat.claudeSonnet5Prompt.enabled
- Rename Claude 4.7 Opus prompt/config to 4.8, add completionDiscipline, plan/explain restraint, tool triggering and terminal run-once guidance; gated behind chat.claude48OpusPrompt.enabled
- Opus 4.7 now falls through to the generic optimized Opus prompt
In the single side-pane layout, switching sessions restored the editor
working set but always left the Changes editor active instead of the
session's last active editor.
Two coupled causes:
1. The managed Changes tab opened as active (no `inactive`/`activation`),
stealing active state from the working-set-restored editor. It now
opens with `inactive: true` + `EditorActivation.PRESERVE` (matching the
Files placeholder); the workbench still activates it when the group is
empty, so the first-visit created-session default (Changes active) is
preserved.
2. The outgoing session's working set was saved on the workspace-gated
`activeSessionForWorkingSet` derive, which lags the raw active session.
During that lag the single-pane managed-tabs sync async-closes the
outgoing session's Changes tab, so the save captured the wrong active
editor. The save now runs eagerly on the raw `activeSession` change,
before those closes, capturing the real active editor; the gated derive
only applies (which needs workspace readiness).
Adds a focused test asserting the save is decoupled from the gated apply.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The SDK bump (#324667, @github/copilot-sdk 1.0.5 -> 1.0.6-preview.1)
reordered client-tool events so `permission.requested` now fires before
`tool.execution_start`. The agent host derives `ChatToolCallReady` from
the permission request, but the tool-call part is only created by
`ChatToolCallStart` (from `tool.execution_start`). With the new order the
ready arrived before the part existed, was dropped by the reducer, and
left the client tool stuck in `Streaming` -- the workbench never invoked
it and the parked SDK handler never resolved, hanging the turn. This hit
every client tool (browser tools, tasks, tool search, etc.).
Synthesize the `ChatToolCallStart` at permission time
(`_ensureClientToolCallStarted`) so the permission-derived ready lands on
an existing part, and skip the now-duplicate start when the real
`tool.execution_start` arrives. Restores the start-before-ready ordering
the downstream pipeline assumes.
For client tools inside subagents, the SDK's permission handler callback
drops the event's `agentId`, so recover it from the raw
`permission.requested` event (newly exposed as `onPermissionRequested` on
the session wrapper) and resolve the parent tool call. This routes the
synthesized start and the permission confirmation to the subagent
session, keeping the tool rendering in the right chat. Degrades
gracefully to the parent session if the mapping is missing -- never a
hang.
Adds unit regression tests for both the top-level and subagent orderings.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* rehaul chat input padding and spacing and icons
* some more fixes on collapsing
* address comments, fix claude
* fix auto not having copilot icon
* fix component fixtures
* fix: implement getModelConfiguration in chat fixture model service mock
Co-authored-by: justschen <54879025+justschen@users.noreply.github.com>
* fix tests
* Expand panel chat model picker before driving inline config in smoke test
The chat model-picker rehaul added a width-driven compact layout that hides
the inline model-config button (and model-name text) when the panel is narrow.
The panel chat's auxiliary bar defaults below the collapse threshold, so the
Chat Model Configuration smoke test could not find the config button.
Widen the auxiliary bar via its leading sash until the picker leaves compact
mode before interacting with the inline config UI.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Show friendly voice names in the voice selection setting
Use enumItemLabels so the `agents.voice.voice` dropdown displays
capitalized names (Victoria, Kevin, Maya, Daniel) instead of the raw
`*_neutral` keys, and drop "(neutral)" from the enum descriptions. The
underlying enum values sent to the backend are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mark microsoft-sovereign-cloud.environment and .customEnvironment as
restrictedConfigurations so their workspace-level values are ignored in
untrusted workspaces. These settings feed the MSAL authority/endpoint
URLs, so an attacker-supplied folder must not be able to override them
in Restricted Mode.
This requires switching untrustedWorkspaces.supported from `true` to
`limited`, since restrictedConfigurations is only honored for `limited`
support (see configurationExtensionPoint.ts).
Fixesmicrosoft/vscode-internalbacklog#8355
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>