feat(dashboard): add provider, modality, and capability filters to Model Registry
This commit enhances the Model Registry UI by adding dropdown filters for Provider, Modality (Text/Image/Audio), and Capabilities (Tool Calling/Reasoning) alongside the existing text search. The filtering logic has been refactored to be non-destructive and apply instantly on the client side.
This commit is contained in:
@@ -30,14 +30,59 @@ class ModelsPage {
|
||||
tableBody.innerHTML = '<tr><td colspan="7" class="text-center">No models found in registry</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
const searchInput = document.getElementById('model-search');
|
||||
const providerFilter = document.getElementById('model-provider-filter');
|
||||
const modalityFilter = document.getElementById('model-modality-filter');
|
||||
const capabilityFilter = document.getElementById('model-capability-filter');
|
||||
|
||||
const q = searchInput ? searchInput.value.toLowerCase() : '';
|
||||
const providerVal = providerFilter ? providerFilter.value : '';
|
||||
const modalityVal = modalityFilter ? modalityFilter.value : '';
|
||||
const capabilityVal = capabilityFilter ? capabilityFilter.value : '';
|
||||
|
||||
// Apply filters non-destructively
|
||||
let filteredModels = this.models.filter(m => {
|
||||
// Text search
|
||||
if (q && !(m.id.toLowerCase().includes(q) || m.name.toLowerCase().includes(q) || m.provider.toLowerCase().includes(q))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Provider filter
|
||||
if (providerVal) {
|
||||
if (providerVal === 'other') {
|
||||
const known = ['openai', 'anthropic', 'google', 'deepseek', 'xai', 'meta', 'cohere', 'mistral'];
|
||||
if (known.includes(m.provider.toLowerCase())) return false;
|
||||
} else if (m.provider.toLowerCase() !== providerVal) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Modality filter
|
||||
if (modalityVal) {
|
||||
const mods = m.modalities && m.modalities.input ? m.modalities.input.map(x => x.toLowerCase()) : [];
|
||||
if (!mods.includes(modalityVal)) return false;
|
||||
}
|
||||
|
||||
// Capability filter
|
||||
if (capabilityVal === 'tool_call' && !m.tool_call) return false;
|
||||
if (capabilityVal === 'reasoning' && !m.reasoning) return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (filteredModels.length === 0) {
|
||||
tableBody.innerHTML = '<tr><td colspan="7" class="text-center">No models match the selected filters</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Sort by provider then name
|
||||
this.models.sort((a, b) => {
|
||||
filteredModels.sort((a, b) => {
|
||||
if (a.provider !== b.provider) return a.provider.localeCompare(b.provider);
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
|
||||
tableBody.innerHTML = this.models.map(model => {
|
||||
tableBody.innerHTML = filteredModels.map(model => {
|
||||
const statusClass = model.enabled ? 'success' : 'secondary';
|
||||
const statusIcon = model.enabled ? 'check-circle' : 'ban';
|
||||
|
||||
@@ -150,27 +195,18 @@ class ModelsPage {
|
||||
}
|
||||
|
||||
setupEventListeners() {
|
||||
const searchInput = document.getElementById('model-search');
|
||||
if (searchInput) {
|
||||
searchInput.oninput = (e) => this.filterModels(e.target.value);
|
||||
}
|
||||
}
|
||||
const attachFilter = (id) => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) {
|
||||
el.addEventListener('input', () => this.renderModelsTable());
|
||||
el.addEventListener('change', () => this.renderModelsTable());
|
||||
}
|
||||
};
|
||||
|
||||
filterModels(query) {
|
||||
if (!query) {
|
||||
this.renderModelsTable();
|
||||
return;
|
||||
}
|
||||
|
||||
const q = query.toLowerCase();
|
||||
const originalModels = this.models;
|
||||
this.models = this.models.filter(m =>
|
||||
m.id.toLowerCase().includes(q) ||
|
||||
m.name.toLowerCase().includes(q) ||
|
||||
m.provider.toLowerCase().includes(q)
|
||||
);
|
||||
this.renderModelsTable();
|
||||
this.models = originalModels;
|
||||
attachFilter('model-search');
|
||||
attachFilter('model-provider-filter');
|
||||
attachFilter('model-modality-filter');
|
||||
attachFilter('model-capability-filter');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user