Repository navigation
feat(tui): order the model picker by Kilo Gateway metadata - #15405
Conversation
Show Recommended and Kilo Gateway sections from the Gateway recommendedIndex, Free from Gateway isFree, BYOK and May train labels, v1 search over provider and model IDs, and the v1 model info panel. The logic is in Kilo-owned files; the upstream picker gets seven marked call-out lines.
|
📈 v2 migration progress: 1.1% → 1.4% (+27 done, -1 total, +1 dropped; 137/9828 cells) Placement: 11 new marked lines in shared files (11 patch), 15 new Ratchets: 25 core-internal imports (base 25); shared patches by rung 24 seam, 20 patch (base 24 seam, 19 patch).
26 cells closed
1 cells dropped
|
# Conflicts: # migration-tracking/progress/README.md # migration-tracking/progress/history.svg # migration-tracking/progress/progress.json # packages/tui/src/component/dialog-model.tsx # script/upstream/shared-patches.json
| searchInTitle | ||
| titlePlaceholder="Search models" | ||
| options={options()} | ||
| options={kilo.options()} // kilocode_change(tui) - Kilo: Gateway order and labels |
There was a problem hiding this comment.
[SUGGESTION]: The upstream options memo is now unused but still computed
Only the type at line 200 reads options; the memo itself no longer feeds DialogSelect. Solid createMemo runs eagerly, so on every query, favorite or recent change it re-runs the upstream filter/sortModelOptions/fuzzysort.go pass in addition to kilo.options(). Removing or guarding the memo avoids the duplicate sort and fuzzy pass per keystroke. Separately, under experimental["new-designs"] that memo also supplied the per-row detail (the ModelDetail block is only shown when an option has detail), the Free group and the favoritesAtOpen order; the Kilo options do not carry those, so those users lose the detail row. If the experiment must keep it, pass those fields through.
Code Review SummaryStatus: 2 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (18 files)
Reviewed the new TUI lifecycle ( Fix these issues in Kilo Cloud Reviewed by deepseek-flash-latest · Input: 151K · Output: 50.7K · Cached: 5.5M Review guidance: REVIEW.md from base branch |
Match the active DialogSelect row by reference, as on v1, so a recent model in Recent and in its provider section highlights and targets one row. Return the Kilo list from the first line of the upstream options memo so the upstream list is not built and sorted on every keystroke.
…el-picker # Conflicts: # migration-tracking/progress/README.md # migration-tracking/progress/progress.json # script/upstream/shared-patches.json
…el-picker # Conflicts: # migration-tracking/progress/README.md # migration-tracking/progress/badge.svg # migration-tracking/progress/dispositions.json # migration-tracking/progress/history.svg # migration-tracking/progress/progress.json # migration-tracking/progress/progress.svg # script/upstream/shared-patches.json
…el-picker # Conflicts: # migration-tracking/progress/README.md # migration-tracking/progress/history.svg # migration-tracking/progress/progress.json # migration-tracking/progress/progress.svg
Closes #15242
Part of #15337 (the sidebar order item stays open, see Limits)
What Problem This Solves
The v2 TUI model picker (
packages/tui/src/component/dialog-model.tsx) does not use the Kilo Gateway metadata that thekilocode.gatewaymodelsRPC already returns:sortModelOptionsputsopencode-goandopencodefirst, so Kilo Gateway models come after OpenCode and other providers.recommendedIndexis ignored, so there is no Recommended section.Freeis inferred from the input price, and the v1BYOKandMay trainlabels are missing.Why This Change Was Made
v1 (
origin/main) is the reference:packages/tui/src/component/dialog-model.tsx(lines 25-31, 66-72, 173): Gateway rank fromrecommendedIndex,BYOKandMay trainlabels, and the details panel in a wide terminal.packages/tui/src/kilocode/model-picker.ts(lines 156-166): Recommended section; search over title, section, provider name, provider ID and model ID, ranked inside each section; recents stay in their provider section.packages/opencode/src/kilocode/components/model-info-panel.tsx(lines 79-86) andfree-model-disclosure.ts: the BYOK and training disclosures and the price, context and benchmark rows.The picker reads the metadata from the existing
kilocode.gatewaymodelsRPC. No server or schema change is needed.User Impact
recommendedIndexorder), then Kilo Gateway (free first, then server order), then the other providers by name. OpenCode is no longer first. No provider is hidden.kilo,openai/gpt,amazon-bedrock), and section headers stay while searching.Freefrom GatewayisFree(not from the price),BYOKandMay train. Other providers keep the upstream price rule forFree.hide_prompt_training_modelsis on, fix(gateway): restore enterprise policy and organization modes #15372 removes training models from that list, so they get no row and noMay trainlabel.Evidence
Automated (pinned Bun 1.4.2, isolated
OPENCODE_TEST_HOMEand XDG paths):packages/tui:bun typecheckpasses.bun test test/kilocode test/cli/cmd/tui/model-options.test.ts, upstreamtest/cli/tui/dialog-select.test.tsxand the other tests that render DialogSelect: 103 pass. Upstreammodel-options.test.tspasses unchanged.test/kilocode/model-picker.test.ts(12): order with Favorites, Recent, Recommended, Kilo Gateway and other providers; signed out (no section headers, nothing hidden); no Gateway metadata; provider dialog; training-policy agreement; config alias; search by provider name, provider ID, model ID and title; labels fromisFree,hasUserByokAvailableandmayTrainOnYourPrompts, and noFreeinferred from a Kilo price.test/kilocode/dialog-model.test.tsx(4): a recent model listed in Recent and in Kilo Gateway highlights one row, and hover moves the highlight to the row under the pointer (fails without the DialogSelect change). Also renders the real upstreamDialogModelwith the seam at 130 columns. It checks section order, row labels, the panel rows for a recommended model, that the panel follows the highlight (a regression check for stale rows), search with section headers, and the signed-out order.free-model-disclosure.test.tsandmodel-info-panel-utils.test.ts: the v1 tests, ported.bun testinpackages/tuiin one process: 1538 pass, 54 fail (same files and count as on the previous head). The 54 failures are in 15 files that are not related to the picker (session, diff viewer, stats). Each of these files passes when run alone (all 15 rerun: 0 fail). CI uses the sharded runner.bun run check: pass.bun script/check-shared-patches.ts --worktree,bun script/check-opencode-annotations.ts --worktree,bun script/upstream/placement.ts --imports: pass.bun script/upstream/progress.tstwice (same output) and--check: pass.Self-test: the real TUI through the
vscode-self-testharness (--mode none),bun script/dev-isolated.ts --standalone, a freshKILO_V2_PROFILEper run, and a cleanenv -ichild environment. Team and personal runs used the local Gateway fixture (packages/kilo-gateway-core/src/testing.ts, with extra fixture models) throughKILO_API_URLand a fake key. No real credential and no prompt were used.ctrl+x mFree · May train; OpenCode free models after them (gone after the v2 merge with #15397). The panel shows the Auto Free description and the training disclosurenemotron,opencodeBYOK), Kilo Auto Free (Free), Claude Opus 4.6 (BYOK). Kilo Gateway: Kilo Auto Small (Free), Grok Code Fast 1 (Free · May train), GPT-5.4. Then OpenCode. The panel for Opus shows the prices, cache price, context 200K, Terminal Bench 61.0% and $2.10, Reasoning, Caps Image and the descriptionctrl+fon Opus and selecting Kilo Auto Small: Favorites (Opus), Recent (Kilo Auto Small), Recommended without Opus, and Kilo Auto Small still under Kilo Gatewayopenai/gpt,opusv2(#15397, #15401): signed out and team scopeKILO_ORG_ID)Free · May train), Kilo Auto Small (noFree, team catalog marks it paid). Then OpenCodeThe self-test found one defect, which this PR fixes: panel rows kept the values of the previous model when the next model had the same rows. The rows are now a reactive component, and
dialog-model.test.tsxcovers it (the test fails with the old code).Screenshots
Real TUI, local Gateway fixture (fixture models, no real account). Taken before the v2 merge: since #15397, the OpenCode free models below the Kilo sections are no longer listed.
Personal scope: Recommended, Kilo Gateway and other providers, with the info panel for a recommended model.
Free model that may train on prompts:
Free · May trainlabel and the training disclosure in the panel.Search by model ID keeps the section header.
Team scope: the team catalog's Recommended and Kilo Gateway sections.
Placement
tui/src/kilocode/model-picker.ts)kilo_port(tui:c29e2d297ca2)and the v1 sort cellstui/src/kilocode/dialog-model.tsx)kilo_port(unattributed:tui/component:*)tui/src/kilocode/components/*)tui/src/component/dialog-model.tsx(import,createKiloModelPicker, an earlyreturn kilo.options()in the options memo,onMove,flat={false},kilo.frame(and its closing line)kilocode_change(components:06ac8868d98e),kilocode_change(tui),shared-patches.jsonentry| Row matching by reference in
tui/src/ui/dialog-select.tsx(4 lines, as v1) | 3 | No plugin hook or host option reaches DialogSelect's private row matching. Generic, no Kilo value; same behavior for lists with unique values |kilocode_change(unattributed:tui/ui:*),shared-patches.jsonentry |packages/tui/src/component/dialog-model.tsx(new entry, rung 4) andpackages/tui/src/ui/dialog-select.tsx(added to the existing rung 4 entry from fix(tui): keep dialog footer mounted across action changes #15400; these 4 lines carry no Kilo value). Limits after merging currentv2: files 43 to 44, markedLines 316 to 327.sortModelOptionsandprioritizeFavoritesstay, so the upstream tests pass. The early return means the upstream list is not built or sorted. The v2.1.1 rewrite of this file (chore(upstream): sync v2.1.1 #15401) is merged into this branch: the call-out lines now sit inDialogConnectedModels, andcreateKiloModelPickergetsprops.onSelect.@opencode/clientand@opencode/schematypes only). Mirrored files: none. No server plugin, so no startup budget change.Progress map
95/9829 to 122/9828 cells done (25 to 26 dropped).
Done, and why:
components/model-info-panel.tsx,model-info-panel-utils.ts,free-model-disclosure.tsand their two tests;tui/src/kilocode/model-picker.tsand its test.components:06ac8868d98e, the v1 import hunk, on the seam import.tui:c29e2d297ca2(footer labels and preview) and 13unattributed:tui/componenthunks of the v1 picker (imports, terminal width, Gateway rank memo, preview and dialog size, panel frame, recommended sort) on the Kilo code that now does each of them.unattributed:tui/ui:acda41f897d2,858635f51958,aac5db9863ac(2 cells), the v1 DialogSelect reference-identity lines, ported unchanged.model-info-panel.types.test.ts. The v2 panel takes the clientModelInfotype, sobun typecheckchecks the same contract;dialog-model.test.tsxrenders it.Dropped, and why it is not needed:
unattributed:tui/component:902bf97fd9cb: v1 ranked the upstream "Popular providers" rows while searching. Upstream v2 removed those rows from the picker ("View all integrations" opens the integration dialog), so there is nothing to rank.Still open:
clicellsmodule:.../cli/cmd/tui/component/dialog-provider.tsxandpatch:cli:66a6b3781917: the v1 provider dialog module (provider priority, descriptions, failed-state gutter, local API key rules, Kilo auto method). This is the integration dialog, not the model picker. fix(gateway): promote Kilo and hide OpenCode free-tier models #15397 ports the priority part; the rest needs its own unit.Limits
append: "sidebar.content","sidebar.footer") has no numeric order. Nothing to apply in this PR. Missing:sidebar-pr,sidebar-footer(credits),sidebar-usage,sidebar-indexing,sidebar-background-processes,memory-status. They stay open in thepluginbox.newDesignsexperiment the connected picker uses the Kilo list, so it has no upstream per-row detail line or separate Free group; the info panel shows those details. The experiment is off by default....from the Gateway (for example NVIDIA Nemotron 3 Ultra), as on v1.newDesignsexperiment on and no connected integration, upstream'sDialogFreeModels(from v2.1.1) is shown instead of this picker. The experiment is off by default.