feat: improve base model resolution and scoring in search panel

- Add resolveBaseModelAlias with exact-then-fuzzy matching
- Use weighted scoring in getDominantWorkflowBaseModel to prefer
  checkpoints/diffusion/unet (weight 8) over loras (weight 2)
- Skip URN-prefixed values during model reference extraction
- Refresh base model select labels after download panel re-render
- Update HuggingFace author index metadata and repo list
This commit is contained in:
Dariusz L
2026-06-07 14:57:04 +02:00
parent 7224d87135
commit 37005d9f18
3 changed files with 81 additions and 1 deletions
File diff suppressed because one or more lines are too long
@@ -1181,6 +1181,7 @@ export const resolveDownloadMethods = {
if (downloadEl && data.civitai?.download_url) {
if (missing) {
this.applyCivitaiUrnResult(missing, data.civitai);
this.refreshSearchBaseModelLabels?.();
const downloadParent = downloadEl.parentElement;
downloadEl.outerHTML = this.renderKnownDownloadPanel(missing, missing.download_source);
this.wireDownloadSearchPanel(downloadParent || this.contentElement, missing);
+79
View File
@@ -81,6 +81,27 @@ export const searchPanelMethods = {
.replace(/[^a-z0-9]+/g, '');
},
resolveBaseModelAlias(value = '') {
const token = this.normalizeBaseModelToken(value);
if (!token) return '';
for (const entry of this.getBaseModelAliases()) {
const aliases = [entry.value, ...(entry.aliases || [])];
if (aliases.some(alias => this.normalizeBaseModelToken(alias) === token)) {
return entry.value;
}
}
for (const entry of this.getBaseModelAliases()) {
const aliases = [entry.value, ...(entry.aliases || [])];
if (aliases.some(alias => {
const aliasToken = this.normalizeBaseModelToken(alias);
return aliasToken && (aliasToken.includes(token) || token.includes(aliasToken));
})) {
return entry.value;
}
}
return '';
},
getBaseModelAliases() {
const baseModelsList = this.baseModels?.base_models;
if (Array.isArray(baseModelsList) && baseModelsList.length > 0) {
@@ -109,6 +130,9 @@ export const searchPanelMethods = {
const values = [];
const visit = (value, key = '') => {
if (typeof value === 'string') {
if (/^urn:/i.test(value.trim())) {
return;
}
if (/\.(safetensors|ckpt|pt|pth|bin|gguf|onnx)\b/i.test(value) || /model|checkpoint|unet|diffusion/i.test(key)) {
values.push(value);
}
@@ -126,7 +150,52 @@ export const searchPanelMethods = {
return values.join(' ');
},
getMissingBaseModelWeight(missing = {}) {
const category = String(missing.category || '').toLowerCase();
const nodeType = String(missing.node_type || '').toLowerCase();
if (
category.includes('checkpoint')
|| category.includes('diffusion')
|| category.includes('unet')
|| nodeType.includes('checkpoint')
|| nodeType.includes('unet')
) {
return 8;
}
if (category.includes('lora') || nodeType.includes('lora')) {
return 2;
}
return 1;
},
getResolvedWorkflowBaseModelScores() {
const primaryScores = new Map();
const secondaryScores = new Map();
for (const missing of this.missingModels || []) {
const baseModel = missing?.civitai_info?.base_model
|| missing?.download_source?.base_model
|| '';
const canonical = this.resolveBaseModelAlias(baseModel);
if (!canonical) continue;
const weight = this.getMissingBaseModelWeight(missing);
const scores = weight >= 8 ? primaryScores : secondaryScores;
scores.set(canonical, (scores.get(canonical) || 0) + weight);
}
return primaryScores.size ? primaryScores : secondaryScores;
},
getDominantWorkflowBaseModel() {
const resolvedScores = this.getResolvedWorkflowBaseModelScores();
if (resolvedScores.size) {
let bestResolved = null;
for (const [value, score] of resolvedScores.entries()) {
if (!bestResolved || score > bestResolved.score) {
bestResolved = { value, score };
}
}
if (bestResolved) return bestResolved.value;
}
const text = this.getWorkflowModelReferenceText();
if (!text) return '';
const normalizedText = this.normalizeBaseModelToken(text);
@@ -813,6 +882,16 @@ export const searchPanelMethods = {
el.value = label || value || '';
},
refreshSearchBaseModelLabels(container = this.contentElement) {
if (!container) return;
container.querySelectorAll?.('.mr-search-base-select').forEach((baseEl) => {
const value = baseEl.dataset?.value || 'auto';
if (value === 'auto') {
this.setDropdownValue(baseEl, value, this.getSearchBaseModelLabel(value));
}
});
},
normalizeVersionName(versionName) {
return String(versionName || '').trim().replace(/^v{2,}(?=\d)/i, 'v');
},