Skip to content

fix(vscode): default model not persistent after explicit user choice - #14180

Merged
WebReflection merged 4 commits into
mainfrom
explicit-model-selection-lost
Sep 16, 2026
Merged

WebReflection merged 4 commits into
mainfrom
explicit-model-selection-lost

Conversation

@WebReflection

@WebReflection WebReflection commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fixes #14178. Switching modes in Agent Manager could discard the selected model and reasoning effort. Choosing a model for a new session also failed to reliably become the default for subsequent sessions, allowing configured or organization defaults to replace an explicit choice.

Why This Change Was Made

Defaults should initialize an untouched choice, not erase user intent. Preserve scoped selections and remember the latest explicit new-session model/effort pair across modes. Keep that pair in extension-owned state so CLI/TUI updates to the shared model file cannot remove it, without changing upstream client behavior.

User Impact

  • Keep the current model and effort when switching modes, including explicit Default effort and mode-only commands.
  • Reuse an explicit next-session choice while available, without changing other open sessions, historical sessions, or comparison allocations.
  • Retain saved choices through catalog refreshes, delayed startup loading, dialog reopening, and worktree creation without an initial prompt.
  • Keep unavailable preferences intact so they can be restored when available again.

Evidence

Before this change, the mode-switch handler deleted the session model override and cleared remembered mode choices; the worktree dialog explicitly reset both model and effort. Those destructive resets are gone. Regression cases reproduced the unwanted replacement before the fix and now retain the original combo, including the actual outgoing request.

While refining the review fixes, regression testing exposed two additional cases. Both are fixed and tested in 50f7d01ad7; fa6cc2d4fd adds explanatory release notes and code comments without changing behavior:

  1. Cross-draft effort drift. Drafts A and B shared a model with no saved effort. Choosing high in B also changed untouched A from Default to high. Updating shared defaults now snapshots the displayed effort of other open drafts, including Default. This is separate from model/mode switching, where an unset effort must remain distinct from an explicit Default choice.
  2. Mixed model and effort in a new command session. With Code configured as model X/high and Ask as model Y/low, a mode-only command creating a fresh draft could send X/low. Its generated UUID was not yet recognized as an initialized draft, so the preservation guard skipped it. Known-new command drafts are now initialized before mode overrides, preserving X/high while switching the agent to Ask. The safeguard against pinning unopened historical sessions remains intact.

Coverage exercises the real SessionProvider, real sidebar tab lifecycle, directly imported reactive dialog logic, history recovery, and real preference files. It includes late hydration and reconnect retries, temporary model/effort disappearance, concurrent saves, and a simulated TUI rewrite that must not erase the saved pair.

Local compilation, typechecks, lint, guards, 358 focused tests, and the real-provider integration test pass. The full unit suite has 5,501 passes and the same 312 baseline environment failures: sandbox-blocked Git fixtures and one unrelated process-helper test. The documentation-only follow-up also passed lint and 74 targeted tests.

Comment thread packages/kilo-vscode/webview-ui/src/context/session-variants.ts
Comment thread packages/kilo-vscode/webview-ui/agent-manager/NewWorktreeDialog.tsx Outdated
Comment thread packages/kilo-vscode/webview-ui/src/context/session.tsx
Comment thread packages/kilo-vscode/tests/fixtures/session-provider-activity.tsx Outdated
Comment thread packages/kilo-vscode/tests/unit/new-worktree-dialog-sandbox.test.ts Outdated
@kilo-code-bot

kilo-code-bot Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

The incremental commit 0d2fee251c runs the draft message-cache cleanup for every promotion that carries a draftID, so /goal command sessions no longer leave an empty messages[draftID] entry behind. The added line lives in the same batch() as the promotion and only deletes a retired draft key, so it cannot clobber the promoted session's messages. No new issues found on the changed lines.

Files Reviewed (2 files)
  • packages/kilo-vscode/webview-ui/src/context/session.tsx
  • packages/kilo-vscode/tests/fixtures/session-provider-activity.tsx
Previous Review Summaries (2 snapshots, latest commit fa6cc2d)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit fa6cc2d)

Status: 1 Issue Found | Recommendation: Address before merge

Reviewed the incremental commits 50f7d01ad7 and fa6cc2d4fd on top of dd2f2f9a. The prior critical/warning findings are addressed: pin() now resolves through variants.choice (no implicit Default write-back), the dialog's mode switch no longer coerces an unset effort to DEFAULT_VARIANT, and retain() scopes are bounded. One new resource leak was found.

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-vscode/webview-ui/src/context/session.tsx 2303 /goal commands leak an empty messages[draftID] entry: goal skips addOptimistic, so the promotion branch that deletes the draft message list never runs
Incremental Files Reviewed (18 files)
  • .changeset/preserve-explicit-model-choice.md
  • packages/kilo-vscode/tests/fixtures/session-preference-loader.ts
  • packages/kilo-vscode/tests/fixtures/session-provider-activity.tsx
  • packages/kilo-vscode/tests/unit/new-worktree-dialog-sandbox.test.ts
  • packages/kilo-vscode/tests/unit/prompt-send-contract.test.ts
  • packages/kilo-vscode/tests/unit/session-preference-loader.test.ts
  • packages/kilo-vscode/tests/unit/session-variants.test.ts
  • packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx
  • packages/kilo-vscode/webview-ui/agent-manager/NewWorktreeDialog.tsx
  • packages/kilo-vscode/webview-ui/agent-manager/new-worktree-models.ts
  • packages/kilo-vscode/webview-ui/agent-manager/project/registry.ts
  • packages/kilo-vscode/webview-ui/src/context/local-tabs.tsx
  • packages/kilo-vscode/webview-ui/src/context/session-model-preferences.ts
  • packages/kilo-vscode/webview-ui/src/context/session-preference-loader.ts
  • packages/kilo-vscode/webview-ui/src/context/session-types.ts
  • packages/kilo-vscode/webview-ui/src/context/session-variants.ts
  • packages/kilo-vscode/webview-ui/src/context/session.tsx - 1 issue
  • packages/kilo-vscode/webview-ui/src/stories/StoryProviders.tsx

Fix these issues in Kilo Cloud

Previous review (commit dd2f2f9)

Status: 6 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 1
WARNING 2
SUGGESTION 3
Issue Details (click to expand)

CRITICAL

File Line Issue
packages/kilo-vscode/webview-ui/src/context/session-variants.ts 110 carry now writes the empty-string Default sentinel for implicit defaults (because deps.variant became variants.request), which shadows the target model's remembered/configured effort and persists it as an explicit Default

WARNING

File Line Issue
packages/kilo-vscode/webview-ui/agent-manager/NewWorktreeDialog.tsx 190 ?? DEFAULT_VARIANT coerces an unset outgoing effort to an explicit Default, masking the newly selected mode's configured effort
packages/kilo-vscode/webview-ui/src/context/session-model-preferences.ts 37 retain() pins every session ever loaded; sessionOverrides/variantSelections entries are never reclaimed and each pick is O(loaded sessions)

SUGGESTION

File Line Issue
packages/kilo-vscode/webview-ui/src/context/session.tsx 781 preferencesReady can remain false forever if the host never posts modelSelectionsLoaded, leaving the dialog pending gate open
packages/kilo-vscode/tests/fixtures/session-provider-activity.tsx 807 Assertion compares against a value produced by the code under test, so the guarded regression is no longer detectable
packages/kilo-vscode/tests/unit/new-worktree-dialog-sandbox.test.ts 123 Source-slice/regex extraction of the component plus expect(src).toContain assertions provide no behavioral coverage
Files Reviewed (23 files)
  • .changeset/preserve-explicit-model-choice.md
  • packages/kilo-vscode/src/agent-manager/multi-version.ts
  • packages/kilo-vscode/src/kilo-provider/model-state.ts
  • packages/kilo-vscode/tests/fixtures/session-provider-activity.tsx - 1 issue
  • packages/kilo-vscode/tests/unit/model-state.test.ts
  • packages/kilo-vscode/tests/unit/multi-version.test.ts
  • packages/kilo-vscode/tests/unit/new-worktree-dialog-sandbox.test.ts - 1 issue
  • packages/kilo-vscode/tests/unit/prompt-send-contract.test.ts
  • packages/kilo-vscode/tests/unit/session-model-store.test.ts
  • packages/kilo-vscode/tests/unit/session-variant-store.test.ts
  • packages/kilo-vscode/tests/unit/session-variants.test.ts
  • packages/kilo-vscode/webview-ui/agent-manager/NewWorktreeDialog.tsx - 1 issue
  • packages/kilo-vscode/webview-ui/agent-manager/new-worktree-models.ts
  • packages/kilo-vscode/webview-ui/src/context/model-selection.ts
  • packages/kilo-vscode/webview-ui/src/context/session-model-preferences.ts - 1 issue
  • packages/kilo-vscode/webview-ui/src/context/session-model-store.ts
  • packages/kilo-vscode/webview-ui/src/context/session-types.ts
  • packages/kilo-vscode/webview-ui/src/context/session-variant-store.ts
  • packages/kilo-vscode/webview-ui/src/context/session-variants.ts - 1 issue
  • packages/kilo-vscode/webview-ui/src/context/session.tsx - 1 issue
  • packages/kilo-vscode/webview-ui/src/stories/StoryProviders.tsx
  • packages/kilo-vscode/webview-ui/src/types/messages/extension-messages.ts
  • packages/kilo-vscode/webview-ui/src/types/messages/webview-messages.ts

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

@marius-kilocode

Copy link
Copy Markdown
Collaborator

Self-test report: model and effort persistence

Tested in a real isolated VS Code Extension Development Host (dev mode) with the bundled CLI backend. The extension was built from this PR head.

Item Value
PR head dd2f2f9a977891920896d5bc371468fde8f0f76e
Baseline origin/main at ae338dd4b33
Harness vscode-self-test, isolated VS Code profile and backend
Auth Isolated copy of the Kilo credential, only the kilo provider staged
Workspaces Two disposable git fixture repos
Surfaces Kilo sidebar composer, Agent Manager local composer, Agent Manager session composer, New Worktree dialog

Baseline on main (bug reproduced)

The explicit model and effort were set in mode Code, then the mode was changed.

Surface Before mode change After Code to Plan After Plan to Code
Agent Manager local composer Code / Gemini 3.8 Flash (50% off) / High Plan / Claude Opus 4.8 / Default (lost) Code / Claude Opus 4.8 / Default (lost)
Kilo sidebar composer Code / Gemini 3.8 Flash / High Plan / Claude Opus 4.8 / Default (lost) not re-checked

This PR (all variations)

# Surface Variation Observed result
1 Agent Manager local Explicit Gemini 3.8 Flash + High, then Code, Plan, Debug, Ask, Code Model and effort kept in every mode
2 Agent Manager local Explicit Default effort, then Code to Orchestrator Gemini 3.8 Flash kept, effort Default
3 Kilo sidebar Explicit Gemini 3.8 Flash + Low, then Code to Debug Model and effort kept
4 Kilo sidebar Explicit Default effort, then Code to Plan Gemini 3.8 Flash kept, effort Default
5 New Worktree dialog Explicit Gemini 3.8 Flash + High, then Code, Plan, Orchestrator Model and effort kept
6 New Worktree dialog Pick Orchestrator + Gemini 3.5 Flash + Medium, close, reopen Selection kept
7 New Worktree dialog Create a worktree with no prompt New session used Orchestrator + Gemini 3.5 Flash + Medium
8 Both surfaces Full VS Code restart with the same user dir Sidebar and Agent Manager draft defaulted to Gemini 3.5 Flash + Medium
9 Agent Manager Change one draft, reopen another session The other session model and effort were unchanged
10 Agent Manager session Mode change after restart, Code to Plan Gemini 3.5 Flash + Medium kept
11 Persistence Simulated CLI or TUI reset of model.json, then relaunch Sidebar still defaulted to Gemini 3.8 Flash + High
12 Diagnostics Webview console errors, extension log filter for persist failures No application errors, no persistence errors

Persisted state after the last explicit choice:

File Content
state/kilo/vscode-model.json {"preferred":{"providerID":"kilo","modelID":"google/gemini-3.8-flash","variant":"high"}}
state/kilo/model.json per-mode entries, for example code to google/gemini-3.8-flash

Case 11 shows that a CLI or TUI rewrite of the shared model.json does not erase the explicit pair held in vscode-model.json.

Automated checks

Check Result
bun run compile in packages/kilo-vscode (host types, webview types, lint, bundle) Pass
Focused tests: model-state, multi-version, new-worktree-dialog-sandbox, session-model-store, session-variant-store, session-variants, prompt-send-contract 217 pass, 0 fail
Broader model, session, and worktree subset, 15 files 322 pass, 0 fail

Not covered

  • Only the Kilo provider was connected, so a cross-provider model test was not possible.
  • No variant-free model was found in the available catalog, so that case was left to the unit tests.
  • The compare and versions allocation rows were not exercised.
  • Paid prompt send and mode-only slash commands were not run.

Result

The reported issue is fixed. The explicit model and effort survive mode changes in the sidebar, the Agent Manager, and the New Worktree dialog, and they survive a VS Code restart and a CLI or TUI state reset. The cases listed under Not covered remain unverified.

Document why updating shared effort defaults must preserve an untouched draft on Default, and why generated mode-only command drafts must retain the outgoing model and effort together. Both fixes and their regression tests shipped in 50f7d01; this follow-up only clarifies release notes and code comments.
Comment thread packages/kilo-vscode/webview-ui/src/context/session.tsx
@WebReflection

Copy link
Copy Markdown
Contributor Author

@marius-kilocode mind having a (hopefully) final look? all issues have been addressed and resolved, regressions are tested, behavior seems to be the expected one + edge cases solved, thanks.

@WebReflection
WebReflection merged commit 1e598e8 into main Sep 16, 2026
25 checks passed
@WebReflection
WebReflection deleted the explicit-model-selection-lost branch September 16, 2026 11:41
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.

Agent manager not persisting model

2 participants