Add model switching to the lean TUI#3674
Conversation
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟡 NEEDS ATTENTION
One medium-severity issue found in the model picker filtering logic introduced by this PR.
| if isCustomQuery && !slices.ContainsFunc(d.models, func(model runtime.ModelChoice) bool { | ||
| return strings.EqualFold(model.Ref, query) || strings.EqualFold(model.Provider+"/"+model.Model, query) | ||
| }) { | ||
| d.filtered = []runtime.ModelChoice{{ |
There was a problem hiding this comment.
[MEDIUM] Custom-model override replaces all fuzzy matches when query contains "/" but isn't an exact match
In filterModels(), the comment says "show Custom option as well as matches" but the code replaces d.filtered entirely instead of appending to it:
// A provider/model query is an explicit reference rather than a fuzzy
// search when it does not identify an available choice.
if isCustomQuery && !slices.ContainsFunc(d.models, func(model runtime.ModelChoice) bool {
return strings.EqualFold(model.Ref, query) || strings.EqualFold(model.Provider+"/"+model.Model, query)
}) {
d.filtered = []runtime.ModelChoice{{ // ← replaces, does not append
Name: "Custom: " + query,
Ref: query,
}}
}The condition checks d.models (all models, for an exact match) — not d.filtered (fuzzy results already computed). So for a partial query like openai/gpt, modelpicker.Filter may have returned several relevant matches, but since "openai/gpt" is not an exact EqualFold match for any model's Ref or Provider+"/"+Model, those fuzzy results are discarded and only "Custom: openai/gpt" is shown.
Suggested fix: append the custom entry to the existing fuzzy results rather than replacing them, and only show the custom entry when fuzzy search returns nothing:
if isCustomQuery && !slices.ContainsFunc(d.models, func(model runtime.ModelChoice) bool {
return strings.EqualFold(model.Ref, query) || strings.EqualFold(model.Provider+"/"+model.Model, query)
}) {
customEntry := runtime.ModelChoice{
Name: "Custom: " + query,
Ref: query,
}
if len(d.filtered) == 0 {
d.filtered = []runtime.ModelChoice{customEntry}
} else {
d.filtered = append(d.filtered, customEntry)
}
}There was a problem hiding this comment.
Good catch. This was a real issue: partial provider/model queries could produce useful fuzzy matches, but the custom entry replaced them. The picker now appends the custom entry after the fuzzy results, and the test covers retaining a fuzzy match alongside the custom option. Fixed in fe27014.
There was a problem hiding this comment.
Thanks for the quick fix! The refactoring looks solid — extracting the fuzzy search into a shared package is a nice improvement, and appending the custom entry after fuzzy matches solves the replacement issue perfectly. The updated test also correctly validates that both fuzzy matches and the custom option are retained.
Extract model-choice filtering and ranking into a shared package backed by the existing fzf matcher. Search across the display name, provider, model ID, and reference while preserving the configured order for an empty query. Update the full TUI model picker to use the shared search so other interfaces can provide identical matching and ranking without duplicating the implementation. Signed-off-by: Djordje Lukic <[email protected]>
Add the /model command to the lean TUI with direct provider/model selection, default-model reset, and an interactive scoped completion list. Use the shared fzf model scorer so searching by display name, provider, model ID, or reference behaves consistently with the full TUI. Restore regular slash-command completions when the model picker is dismissed. Signed-off-by: Djordje Lukic <[email protected]>
f0cb625 to
381267f
Compare
- Add Mermaid diagram section under Thinking and Tool Details documenting which diagram types are rendered inline and the fallback behavior for unsupported types (PR #3679) - Update the Lean TUI section to list supported slash commands and explicitly note that /model is available (PR #3674) - Update Runtime Model Switching to clarify that /model works in both the full TUI and the lean TUI, while Ctrl+M is full TUI only
Add
/modelsupport to the lean TUI and share fuzzy model search between the lean and full TUIs.