Skip to content

feat(vscode): migrate the models settings to v2 - #15594

Merged
marius-kilocode merged 12 commits into
settings-foundationfrom
settings-models
Oct 29, 2026
Merged

marius-kilocode merged 12 commits into
settings-foundationfrom
settings-models

Conversation

@marius-kilocode

@marius-kilocode marius-kilocode commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Migrate the Models settings tab to the v2 extension

What Problem This Solves

The native v2 VS Code extension had a placeholder Models tab. This ports the v1 Models settings so users can pick the default model, the small (title) model, the compaction model, one model per agent, and the prompt-training privacy switch, all against the v2 configuration.

Why This Change Was Made

v2 stores models in the Kilo v2 config, not in v1 keys. The top-level model accepts the ConfigModel.Selection form ({ providerID, model, variant? } or provider/model#variant). The v1 small_model and agent.compaction.model normalize to the agents title and compaction entries under agents.<id>.model. The prompt-training switch is the Kilo-only top-level key hide_prompt_training_models, which is not part of the core schema and is read from the raw config files. The tab writes through the shared useSettingsConfig() layer, which applies changes immediately (no save bar).

User Impact

The Models tab matches the v1 layout, labels, and control order:

  • Default Model, Small Model, Compaction model, and one row per selectable v2 agent.
  • Hide Prompt-Training Models toggle.
  • Rows show the plain v1 model picker with the v1 empty labels (Not set (use server default), and Use chat model for compaction). No separate variant control is shown, as in v1.
  • Every change writes to the Kilo config at once and survives a reload; an external edit of the config file appears in the tab without a reload.

Parity table

v1 control v2 key / API Status
Default Model top-level model (ConfigModel.Selection) Migrated
Small Model (with the automatic small option) agents.title.model Migrated
Compaction model (Use chat model when empty) agents.compaction.model Migrated
Model per Mode (one row per agent) agents.<id>.model Migrated
Hide Prompt-Training Models top-level Kilo key hide_prompt_training_models (read with raw()) Migrated

Out of scope

v1 control Reason
Subagent Model (and its variant) v2 core has no subagent model key; the agents entries cover the selectable agents only.
Autocomplete model v2 has no autocomplete model feature.
Speech to Text Base URL, API Key, Model v2 has no speech-to-text settings.

The out-of-scope i18n keys are added to EXCLUDED_KEYS in settings-search.ts so the settings search does not surface rows this tab does not render.

Evidence

Screenshots (v1 before from the built main checkout, v2 after from this branch):

Before (v1), full tab and model picker:
v1 Models tab
v1 Default Model picker

After (v2), full tab and model picker:
v2 Models tab
v2 Default Model picker

Automated checks (in packages/kilo-vscode):

  • bun typecheck: pass.
  • bun test: pass, with a focused test for the selection mapping in models-selection.ts.
  • bun run lint: 0 warnings, 0 errors.

Self-test (isolated v2 profile):

  • Default Model change wrote {"model":{"providerID":"kilo","model":"cohere/north-mini-code:free"}} to the global kilo2.json at once, with no save bar.
  • Hide Prompt-Training Models toggle wrote "hide_prompt_training_models": true at once.
  • An external edit of the config file (setting hide_prompt_training_models to false and adding agents.title.model) updated the switch and the Small Model row in the tab with no reload.

Notes

  • The explicit v1 "automatic" small-model entry has no separate v2 catalog model; leaving the Small Model unset uses the server default, which is the automatic behavior.
  • Variants already present in the config are preserved, but this tab does not offer a variant control, matching v1.
  • Mode rows are labelled with the v1 capitalization of the agent name.

Part of #15589

@github-actions github-actions Bot added the area:vscode VS Code extension label Oct 29, 2026
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

➖ v2 migration progress: 6.4% → 6.4% (0 done, 0 total, 0 dropped; 626/9819 cells)

Placement: 0 new marked lines in shared files, 0 new kilo_port annotations, 0 new core-internal imports.

Ratchets: 27 core-internal imports (base 27); shared patches by rung 35 seam, 25 patch (base 35 seam, 25 patch).

No change to the progress map.

Map on v2 · how cells close

@kilo-code-bot

kilo-code-bot Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Overview

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

WARNING

File Line Issue
packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx 44 The pending guard only covers the write itself; once configWritten resolves, the stale configLoaded snapshot again wins over the optimistic value until the reload round trip finishes, so the row reverts to the previous model (or Not set) for that window.

The incremental commit b7969a4e9b correctly stops preferring config.raw(scope) while a write for the path is in flight, and the earlier variant-preservation, scope-aware set/unset, and EXCLUDED_KEYS findings are all still fixed in current HEAD.

One part of the previous finding remains. pending is cleared when the host resolves the write: writeConfig posts configWritten immediately after writeFile (packages/kilo-vscode/src/settings-host.ts:141), while files() is only refreshed by the configRead → configLoaded cycle. That cycle is driven by the entries() effect (packages/kilo-vscode/webview-ui/src/v2/settings-config.tsx:129-131), which waits for the server reload (debounced 100ms in packages/core/src/config.ts:344-347) plus the event relay and configRead round trip. During that gap pending is false and config.raw(scope) still holds the pre-write text, so raw ?? config.value(path) returns the old value again: after a pick the row flashes back to the previous model, and after a clear it flashes the cleared model back. For a key that was not in any file yet, config.source(path) is also still undefined, so the row shows Not set for the same window.

The optimistic value is still present in config.value(path) at that point (it is dropped only by the configLoaded that covers it), so the guard should last until that reply arrives rather than until configWritten: for example treat a path as "pending" while an optimistic entry exists, or keep inflight until the covering configLoaded instead of clearing it when the write promise resolves.

Files Reviewed (1 file)
  • packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx - 1 issue

Fix these issues in Kilo Cloud

Previous Review Summaries (5 snapshots, latest commit a34cf39)

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

Previous review (commit a34cf39)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

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

WARNING

File Line Issue
packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx 43 current() prefers the last configLoaded file snapshot over the optimistic value, so a pick or clear on a row whose key already exists keeps showing the old model until the config is re-read.
Files Reviewed (3 files)
  • packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx - 1 issue
  • packages/kilo-vscode/webview-ui/src/components/settings/models-selection.ts - no issues
  • packages/kilo-vscode/test/models-selection.test.ts - no issues

The variant-dropping fix and the scope-aware set/unset remain in place, and the out-of-scope search keys are now in EXCLUDED_KEYS. This incremental review covers a34cf393da only.

Fix these issues in Kilo Cloud

Previous review (commit 709704c)

Status: No Issues Found | Recommendation: Merge

The incremental commit 709704cd2d addresses the earlier variant-dropping finding: change() now runs the picked value through preserveVariant(selection(config.value(path)), value), so a variant already stored in model, agents.title.model, or agents.<id>.model is retained when the same model is re-picked, and it is covered by a unit test. The scope-aware set/unset and the excluded-keys search fix remain in place. No new issues found in the changed code.

Files Reviewed (7 files)
  • packages/kilo-vscode/test/models-selection.test.ts
  • packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx
  • packages/kilo-vscode/webview-ui/src/components/settings/models-selection.ts
  • packages/kilo-vscode/webview-ui/src/components/settings/ModelPicker.tsx
  • packages/kilo-vscode/webview-ui/src/components/settings/settings-search.ts
  • packages/kilo-vscode/webview-ui/src/components/settings/tabs.ts
  • packages/kilo-vscode/webview-ui/src/components/shared/ModelSelector.tsx

Previous review (commit f243e2d)

Status: 1 Issue Found | Recommendation: Address before merge

The follow-up commit f243e2d860 only merges the current settings-foundation base into the branch; the Models files are unchanged from d48c802e09. Both earlier findings remain resolved (config.source(path) ?? "global" for set/clear scope, and the search entries the tab does not render are excluded). Files brought into the local incremental diff by the base merge are settings-foundation content and are not part of this PR's diff.

Overview

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

WARNING

File Line Issue
packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx 63 showVariants={false} hides an existing variant; re-picking a model writes { providerID, model } and silently removes the stored variant (v1 preserved it with preserveVariant).
Files Reviewed (3 files)
  • packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx - 1 issue
  • packages/kilo-vscode/webview-ui/src/components/settings/ModelPicker.tsx - 0 issues
  • packages/kilo-vscode/webview-ui/src/components/shared/ModelSelector.tsx - 0 issues

Fix these issues in Kilo Cloud

Previous review (commit 65fbe46)

Status: No Issues Found | Recommendation: Merge

The follow-up commit 65fbe4624f resolves both earlier findings: model set/clear now writes the scope that already defines the key (config.source(path) ?? "global", matching the prompt-training toggle), and the Models-tab entries the tab does not render (subagentModel, autocomplete.model, the three speechToText* keys) are excluded from the search index. I re-read settings-search.ts, ModelsTab.tsx, tabs.ts, and Settings.tsx and the exclusion list covers every settings.models.* / settings.providers.* title key the tab does not render, while the ready-tab filter still applies.

Files Reviewed (2 files)
  • packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx
  • packages/kilo-vscode/webview-ui/src/components/settings/settings-search.ts

Previous review (commit a684269)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

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

WARNING

File Line Issue
packages/kilo-vscode/webview-ui/src/components/settings/tabs.ts 26 Marking the Models tab ready exposes derived search entries for rows the tab does not render (subagentModel, three speechToText* keys, autocomplete.model); selecting them opens Models and reveals nothing.
packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx 38 Model set/clear always writes the global scope while reads use the merged config, so project-scoped model / agents.<id>.model values are never updated or cleared and the row reverts after resync.
Files Reviewed (4 files)
  • packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx - 1 issue
  • packages/kilo-vscode/webview-ui/src/components/settings/models-selection.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/components/settings/tabs.ts - 1 issue
  • packages/kilo-vscode/test/models-selection.test.ts - 0 issues

Fix these issues in Kilo Cloud


Reviewed by deepseek-flash-latest · Input: 82.4K · Output: 18.9K · Cached: 699.6K

Review guidance: REVIEW.md from base branch settings-foundation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:vscode VS Code extension

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants