42 lines
1.3 KiB
TypeScript
42 lines
1.3 KiB
TypeScript
import type { Model } from "~/types/model";
|
|
|
|
export const filterProvidersWithModel = (providers: ProviderWithModels[], query: string): ProviderWithModels[] => {
|
|
const rawQuery = query.trim().toLowerCase();
|
|
|
|
if (!rawQuery) return providers;
|
|
|
|
return providers
|
|
.map((provider) => {
|
|
const scoredModels = filterModels(provider.models as Model[], query);
|
|
|
|
return { ...provider, models: scoredModels };
|
|
})
|
|
}
|
|
|
|
export const filterModels = (models: Model[], query: string): Model[] => {
|
|
const rawQuery = query.trim().toLowerCase();
|
|
|
|
if (!rawQuery) return models;
|
|
|
|
// Split search into individual words (tokens)
|
|
const tokens = rawQuery.split(/\s+/);
|
|
|
|
return models.map(model => {
|
|
const name = model.name.toLowerCase();
|
|
const id = model.externalId.toLowerCase();
|
|
|
|
// Check if all tokens match
|
|
const matches = tokens.every(t => name.includes(t) || id.includes(t));
|
|
if (!matches) return null;
|
|
|
|
// Calculate simple relevance score
|
|
let score = 0;
|
|
if (name.startsWith(rawQuery) || id.startsWith(rawQuery)) score += 10;
|
|
if (name === rawQuery || id === rawQuery) score += 50;
|
|
|
|
return { model, score };
|
|
})
|
|
.filter(m => m !== null)
|
|
.sort((a, b) => b.score - a.score)
|
|
.map(m => m.model);
|
|
} |