Implement fuzzy search for model/session selector and improve Input multi-key sequence handling (#122)

* implement fuzzy search and filtering for tui selectors

* update changelog and readme

* add correct pr to changelog
This commit is contained in:
Markus Ylisiurunen
2025-12-05 21:33:04 +02:00
committed by GitHub
parent ca39e899f4
commit ff047e5ee1
7 changed files with 251 additions and 27 deletions

View File

@@ -1,5 +1,6 @@
import type { Model } from "@mariozechner/pi-ai";
import { Container, Input, Spacer, Text, type TUI } from "@mariozechner/pi-tui";
import { fuzzyFilter } from "../fuzzy.js";
import { getAvailableModels } from "../model-config.js";
import type { SettingsManager } from "../settings-manager.js";
import { theme } from "../theme/theme.js";
@@ -114,19 +115,7 @@ export class ModelSelectorComponent extends Container {
}
private filterModels(query: string): void {
if (!query.trim()) {
this.filteredModels = this.allModels;
} else {
const searchTokens = query
.toLowerCase()
.split(/\s+/)
.filter((t) => t);
this.filteredModels = this.allModels.filter(({ provider, id, model }) => {
const searchText = `${provider} ${id} ${model.name}`.toLowerCase();
return searchTokens.every((token) => searchText.includes(token));
});
}
this.filteredModels = fuzzyFilter(this.allModels, query, ({ provider, id }) => `${provider} ${id}`);
this.selectedIndex = Math.min(this.selectedIndex, Math.max(0, this.filteredModels.length - 1));
this.updateList();
}

View File

@@ -1,4 +1,5 @@
import { type Component, Container, Input, Spacer, Text, truncateToWidth } from "@mariozechner/pi-tui";
import { fuzzyFilter } from "../fuzzy.js";
import type { SessionManager } from "../session-manager.js";
import { theme } from "../theme/theme.js";
import { DynamicBorder } from "./dynamic-border.js";
@@ -42,20 +43,7 @@ class SessionList implements Component {
}
private filterSessions(query: string): void {
if (!query.trim()) {
this.filteredSessions = this.allSessions;
} else {
const searchTokens = query
.toLowerCase()
.split(/\s+/)
.filter((t) => t);
this.filteredSessions = this.allSessions.filter((session) => {
// Search through all messages in the session
const searchText = session.allMessagesText.toLowerCase();
return searchTokens.every((token) => searchText.includes(token));
});
}
this.filteredSessions = fuzzyFilter(this.allSessions, query, (session) => session.allMessagesText);
this.selectedIndex = Math.min(this.selectedIndex, Math.max(0, this.filteredSessions.length - 1));
}