Skip to content

Further Unify Model Picker Architecture - #326351

Merged
lramos15 merged 3 commits into
mainfrom
lramos15/unique-salamander
Jul 17, 2026
Merged

Further Unify Model Picker Architecture#326351
lramos15 merged 3 commits into
mainfrom
lramos15/unique-salamander

Conversation

@lramos15

@lramos15 lramos15 commented Jul 17, 2026

Copy link
Copy Markdown
Member

Summary

This further unifies model selection and restoration across the editor/workbench and Agents window.

  • Adds one shared pure model-selection policy in vs/workbench/contrib/chat/common/modelSelection.ts.
  • Shares catalog resolution, configured-model matching, initial precedence, pending state, and fallback semantics across ChatInputPart and SessionModelSelectionModel.
  • Uses the shared lifecycle transition in the Sessions adapter for existing-session repair, new-chat repush, and late catalog changes.
  • Replaces the ambiguous provider isResolved signal with desiredModelResolution: notRequested, pending, available, or unavailable.
  • Adds provider-owned modelTarget metadata so provider-scoped model pools use the same remembered-selection key as their Workbench counterpart.
  • Unifies remembered-model persistence through chatSelectedModel.ts, using profile-scoped user storage keyed by chat location and optional model target, with lazy migration from legacy Workbench and Sessions keys.
  • Keeps a remembered Copilot model pending while model discovery is still loading instead of committing an early BYOK fallback.
  • Treats automatic first-model fallback as provisional so a later provider default or Auto model can replace it.
  • In Sessions, persists only provider-accepted explicit user choices; automatic restore, repair, and fallback effects update the provider without overwriting the remembered preference.
  • Cancels pending restoration when the user explicitly selects another model.
  • Routes phone model actions through the owning Workbench or Sessions selection adapter instead of maintaining a separate persistence path.
  • Removes the duplicate Agents-window selection policy and separates shared policy, shared storage, surface adapters, input utilities, and picker presentation by ownership.

Fixes #326260

Previous Architecture

The workbench and Agents window used independent restoration policies. They shared picker presentation, but each surface separately interpreted model readiness, precedence, fallback, and persistence.

flowchart LR
    Registry[Language model registry and cache]
    Providers[ISessionsProvider snapshots]

    Workbench[Editor and Workbench<br/>ChatInputPart]
    WorkbenchPolicy[chatModelSelectionLogic<br/>workbench restore and fallback policy]

    Agents[Agents window<br/>ModelPickerModel]
    AgentsPolicy[modelPickerSelection<br/>Agents restore and fallback policy]

    Registry --> WorkbenchPolicy --> Workbench
    Providers --> AgentsPolicy --> Agents

    WorkbenchPolicy -. duplicated semantics .- AgentsPolicy
Loading

This allowed the two surfaces to diverge. In particular, the Agents window could treat a partial model list as complete, select the first BYOK model, and persist it before Copilot models arrived.

New Architecture

Both surfaces now use the same pure catalog-resolution, matching, initial-selection, and fallback building blocks. The Sessions adapter also delegates catalog-driven lifecycle transitions to that shared policy. Both adapters use one canonical remembered-selection storage contract while retaining the application and lifecycle concerns that genuinely differ.

flowchart TD
    SharedPolicy[common/modelSelection.ts<br/>resolution, matching, precedence, transition effects]
    SharedStorage[common/chatSelectedModel.ts<br/>canonical remembered-selection storage]

    Registry[Language model registry and cache]
    Providers[ISessionsProvider.getModelsSnapshot<br/>desiredModelResolution and modelTarget]

    WorkbenchAdapter[ChatInputPart<br/>workbench lifecycle adapter]
    AgentsAdapter[SessionModelSelectionModel<br/>Sessions provider adapter]

    PickerUI[modelPicker folder<br/>widget, items, hover, presentation]

    Registry --> WorkbenchAdapter
    Providers --> AgentsAdapter

    WorkbenchAdapter --> SharedPolicy
    AgentsAdapter --> SharedPolicy

    WorkbenchAdapter --> SharedStorage
    AgentsAdapter --> SharedStorage

    WorkbenchAdapter --> PickerUI
    AgentsAdapter --> PickerUI
Loading

The shared policy owns:

  1. Catalog readiness and identifier resolution.
  2. Configured model matching, including model families and Auto.
  3. Initial configured, restored, pending, unavailable, and fallback precedence.
  4. Automatic selection provenance, including provisional first-available fallback.
  5. Sessions lifecycle transitions for stale-model repair, existing-session restoration, and new-chat repush.
  6. Selection reasons and provider effects.

The shared storage helper owns canonical (location, modelTarget) keys, profile-scoped user storage, and migration from the previous application-scoped Workbench keys. The Sessions adapter additionally migrates its previous provider/session-type key into that canonical store.

ChatInputPart and SessionModelSelectionModel remain separate adapters because their model inputs, application paths, and session lifecycles differ. Workbench controls its wait-listener lifecycle and input-model synchronization. Sessions controls provider snapshots and writes, and remembers only provider-accepted explicit choices. Providers expose the concrete modelTarget for their model pool so both surfaces address the same remembered selection.

Behavior

When BYOK models arrive before a remembered Copilot model:

sequenceDiagram
    participant Catalog as Model catalog
    participant Policy as Shared selection policy
    participant Picker as Model picker
    participant Storage as Remembered selection
    Catalog->>Policy: BYOK available, Copilot still pending
    Policy->>Picker: Keep remembered selection pending
    Policy->>Storage: Do not overwrite preference
    Catalog->>Policy: Copilot model becomes available
    Policy->>Picker: Apply remembered Copilot model
    Policy->>Storage: Preserve remembered preference
Loading

When there is no remembered choice, an early BYOK model may be applied provisionally so the session remains usable. A later provider default or Auto model replaces that provisional fallback. In the Sessions adapter, neither automatic choice is written as a user preference.

If the user explicitly chooses a model while discovery is pending, that explicit choice wins and cancels pending restoration. In Sessions, the provider is updated first and the canonical remembered preference is written only after the provider accepts the change.

Validation

  • npm run typecheck-client
  • npm run transpile-client
  • npm run valid-layers-check
  • VS Code hygiene checks for all changed TypeScript files
  • Affected unit tests covering shared selection policy and storage, Agents selection coordination, provider snapshots, quota notifications, and Sessions management

Copilot AI review requested due to automatic review settings July 17, 2026 14:27
@vs-code-engineering

Copy link
Copy Markdown
Contributor

📬 CODENOTIFY

The following users are being notified based on files changed in this PR:

@sandy081

Matched files:

  • src/vs/sessions/services/sessions/common/sessionsProvider.ts
  • src/vs/sessions/services/sessions/test/browser/sessionsManagementService.test.ts

@lszomoru

Matched files:

  • src/vs/sessions/services/sessions/common/sessionsProvider.ts
  • src/vs/sessions/services/sessions/test/browser/sessionsManagementService.test.ts

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

Unifies model restoration and selection policy across the workbench and Agents window.

Changes:

  • Adds shared model resolution, precedence, pending, and fallback logic.
  • Updates provider snapshots to expose explicit resolution states.
  • Reorganizes picker utilities and expands regression coverage.
Show a summary per file
File Description
src/vs/workbench/contrib/chat/test/common/modelSelection.test.ts Tests shared selection policy.
src/vs/workbench/contrib/chat/test/browser/widget/input/modelPicker/modelPickerUtils.test.ts Removes superseded utility tests.
src/vs/workbench/contrib/chat/test/browser/widget/input/modelPicker/modelPickerPresentation.test.ts Tests picker presentation helpers.
src/vs/workbench/contrib/chat/test/browser/widget/input/modelPicker/modelPickerItems.test.ts Updates utility import.
src/vs/workbench/contrib/chat/test/browser/widget/input/chatInputModelUtils.test.ts Updates and reorganizes input utility tests.
src/vs/workbench/contrib/chat/common/modelSelection.ts Adds shared model-selection policy.
src/vs/workbench/contrib/chat/common/languageModels.ts Adds vendor absence resolution helper.
src/vs/workbench/contrib/chat/browser/widget/input/modelPicker/modelPickerWidget.ts Uses presentation-owned helpers.
src/vs/workbench/contrib/chat/browser/widget/input/modelPicker/modelPickerPresentation.ts Adds picker availability and cache-hint logic.
src/vs/workbench/contrib/chat/browser/widget/input/modelPicker/modelPickerItems.ts Updates presentation imports.
src/vs/workbench/contrib/chat/browser/widget/input/modelPicker/modelPickerHover.ts Updates presentation imports.
src/vs/workbench/contrib/chat/browser/widget/input/chatInputPart.ts Adopts shared resolution and pending restoration.
src/vs/workbench/contrib/chat/browser/widget/input/chatInputModelUtils.ts Retains input-specific model utilities.
src/vs/workbench/contrib/chat/browser/chatManagement/chatModelsViewModel.ts Uses shared metadata helper.
src/vs/workbench/contrib/chat/browser/agentSessions/sessionTypeAvailability.ts Simplifies targeted-model detection.
src/vs/sessions/SESSIONS.md Documents unified selection architecture.
src/vs/sessions/services/sessions/test/browser/sessionsManagementService.test.ts Updates provider snapshot mock.
src/vs/sessions/services/sessions/common/sessionsProvider.ts Replaces isResolved with explicit resolution.
src/vs/sessions/contrib/providers/remoteAgentHost/REMOTE_AGENT_HOST_SESSIONS_PROVIDER.md Documents resolution states.
src/vs/sessions/contrib/providers/localChatSessions/test/browser/localChatSessionsProvider.test.ts Tests delayed Copilot resolution.
src/vs/sessions/contrib/providers/localChatSessions/LOCAL_CHAT_SESSIONS_PROVIDER.md Updates provider documentation.
src/vs/sessions/contrib/providers/localChatSessions/browser/localChatSessionsProvider.ts Computes catalog-aware resolution.
src/vs/sessions/contrib/providers/copilotChatSessions/test/browser/copilotChatSessionsProvider.test.ts Updates snapshot expectations.
src/vs/sessions/contrib/providers/copilotChatSessions/COPILOT_CHAT_SESSIONS_PROVIDER.md Documents snapshot resolution.
src/vs/sessions/contrib/providers/copilotChatSessions/browser/copilotChatSessionsProvider.ts Produces explicit model resolution.
src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileChatPhoneInputPresenter.ts Updates selection helper import.
src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileChatInputConfigPicker.ts Updates selection model import.
src/vs/sessions/contrib/providers/agentHost/browser/baseAgentHostSessionsProvider.ts Resolves restored agent-host models.
src/vs/sessions/contrib/providers/agentHost/AGENT_HOST_SESSIONS_PROVIDER.md Documents agent-host resolution.
src/vs/sessions/contrib/chat/test/browser/sessionWorkspacePicker.test.ts Updates provider mock.
src/vs/sessions/contrib/chat/test/browser/sessionModelSelectionModel.test.ts Adds pending and explicit-selection coverage.
src/vs/sessions/contrib/chat/test/browser/modelPickerSelection.test.ts Removes duplicate policy tests.
src/vs/sessions/contrib/chat/test/browser/modelPicker.test.ts Updates selection model import.
src/vs/sessions/contrib/chat/browser/sessionModelSelectionModel.ts Adapts Agents sessions to shared policy.
src/vs/sessions/contrib/chat/browser/newChatInput.ts Gates sending while restoration is pending.
src/vs/sessions/contrib/chat/browser/modelPickerSelection.ts Removes duplicate Agents policy.
src/vs/sessions/contrib/chat/browser/modelPicker.ts Uses renamed selection model.

Review details

  • Files reviewed: 37/37 changed files
  • Comments generated: 4
  • Review effort level: Medium

Comment thread src/vs/workbench/contrib/chat/common/modelSelection.ts Outdated
Comment thread src/vs/workbench/contrib/chat/common/modelSelection.ts
Comment thread src/vs/workbench/contrib/chat/common/modelSelection.ts Outdated
Comment thread src/vs/sessions/contrib/chat/browser/newChatInput.ts
aeschli
aeschli previously approved these changes Jul 17, 2026
@lramos15
lramos15 merged commit 401631c into main Jul 17, 2026
29 checks passed
@lramos15
lramos15 deleted the lramos15/unique-salamander branch July 17, 2026 17:59
@vs-code-engineering vs-code-engineering Bot added this to the 1.130.0 milestone Jul 17, 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.

When models arrive late the first available model is selected as the default in Agents Window

4 participants