mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 13:03:42 +00:00
Fix model selector fuzzy search to match provider and support multi-token queries
This commit is contained in:
parent
7272eb9274
commit
3de8e0757d
3 changed files with 36 additions and 7 deletions
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Model selector fuzzy search now matches against provider name (not just model ID) and supports space-separated tokens where all tokens must match
|
||||
|
||||
## [0.21.0] - 2025-12-14
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ export class ModelSelectorComponent extends Container {
|
|||
}
|
||||
|
||||
private filterModels(query: string): void {
|
||||
this.filteredModels = fuzzyFilter(this.allModels, query, ({ id }) => id);
|
||||
this.filteredModels = fuzzyFilter(this.allModels, query, ({ id, provider }) => `${id} ${provider}`);
|
||||
this.selectedIndex = Math.min(this.selectedIndex, Math.max(0, this.filteredModels.length - 1));
|
||||
this.updateList();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,23 +61,48 @@ export function fuzzyMatch(query: string, text: string): FuzzyMatch {
|
|||
}
|
||||
|
||||
// Filter and sort items by fuzzy match quality (best matches first)
|
||||
// Supports space-separated tokens: all tokens must match, sorted by match count then score
|
||||
export function fuzzyFilter<T>(items: T[], query: string, getText: (item: T) => string): T[] {
|
||||
if (!query.trim()) {
|
||||
return items;
|
||||
}
|
||||
|
||||
const results: { item: T; score: number }[] = [];
|
||||
// Split query into tokens
|
||||
const tokens = query
|
||||
.trim()
|
||||
.split(/\s+/)
|
||||
.filter((t) => t.length > 0);
|
||||
|
||||
if (tokens.length === 0) {
|
||||
return items;
|
||||
}
|
||||
|
||||
const results: { item: T; totalScore: number }[] = [];
|
||||
|
||||
for (const item of items) {
|
||||
const text = getText(item);
|
||||
const match = fuzzyMatch(query, text);
|
||||
if (match.matches) {
|
||||
results.push({ item, score: match.score });
|
||||
let totalScore = 0;
|
||||
let allMatch = true;
|
||||
|
||||
// Check each token against the text - ALL must match
|
||||
for (const token of tokens) {
|
||||
const match = fuzzyMatch(token, text);
|
||||
if (match.matches) {
|
||||
totalScore += match.score;
|
||||
} else {
|
||||
allMatch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Only include if all tokens match
|
||||
if (allMatch) {
|
||||
results.push({ item, totalScore });
|
||||
}
|
||||
}
|
||||
|
||||
// Sort ascending by score (lower = better match)
|
||||
results.sort((a, b) => a.score - b.score);
|
||||
// Sort by score (asc, lower is better)
|
||||
results.sort((a, b) => a.totalScore - b.totalScore);
|
||||
|
||||
return results.map((r) => r.item);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue