diff --git a/core/matcher.py b/core/matcher.py index 35deea7..8bf4f09 100644 --- a/core/matcher.py +++ b/core/matcher.py @@ -98,9 +98,13 @@ def find_matches( """ matches = [] + # Normalize path separators in target_model based on current OS + # This ensures paths with \ vs / separators are treated as identical + target_model_normalized = os.path.normpath(target_model) if target_model else '' + # Extract just the filename from target_model (remove any subfolder paths) # target_model might be just a filename or might include subfolder paths - target_filename = os.path.basename(target_model) + target_filename = os.path.basename(target_model_normalized) # Normalize target filename once for exact match comparisons target_norm = normalize_filename(target_filename) @@ -108,16 +112,45 @@ def find_matches( for candidate in candidate_models: # Get filename from candidate (prefer 'filename' key, fallback to extracting from 'path' or 'relative_path') candidate_filename = candidate.get('filename') + candidate_path = candidate.get('path', '') or candidate.get('relative_path', '') # If no filename key, try to extract from path or relative_path if not candidate_filename: - candidate_path = candidate.get('path', '') or candidate.get('relative_path', '') if candidate_path: candidate_filename = os.path.basename(candidate_path) if not candidate_filename: continue + # Normalize candidate path separators based on current OS + # This ensures paths with \ vs / separators are treated as identical + candidate_path_normalized = os.path.normpath(candidate_path) if candidate_path else '' + candidate_relative_path = candidate.get('relative_path', '') + candidate_relative_path_normalized = os.path.normpath(candidate_relative_path) if candidate_relative_path else '' + + # Check if normalized paths are identical (100% match) + # This handles cases where paths differ only by separator (e.g., path/to/model vs path\to\model) + # Compare both absolute paths and relative paths + path_match = False + if candidate_path_normalized and target_model_normalized: + if candidate_path_normalized == target_model_normalized: + path_match = True + elif candidate_relative_path_normalized and target_model_normalized: + # Also check if relative path matches the target (which might be relative) + if candidate_relative_path_normalized == target_model_normalized: + path_match = True + + if path_match: + # Exact path match after normalization = 100% confidence + similarity = 1.0 + matches.append({ + 'model': candidate, + 'filename': candidate_filename, + 'similarity': similarity, + 'confidence': round(similarity * 100, 1) + }) + continue + # Calculate similarity comparing just filenames (not paths) # This ensures we're comparing apples to apples diff --git a/web/linker.js b/web/linker.js index a2207c0..d07d8e4 100644 --- a/web/linker.js +++ b/web/linker.js @@ -276,19 +276,14 @@ class LinkerManagerDialog extends ComfyDialog { return b.confidence - a.confidence; }); - // Find the highest confidence match (even if not 100%) - const highestConfidenceMatch = sortedMatches.length > 0 ? sortedMatches[0] : null; - sortedMatches.forEach((match, matchIndex) => { - // Only attach listener if this match would have a button (100% or highest confidence) - if (match.confidence === 100 || match === highestConfidenceMatch) { - const buttonId = `resolve-${missing.node_id}-${missing.widget_index}-${matchIndex}`; - const resolveButton = container.querySelector(`#${buttonId}`); - if (resolveButton) { - resolveButton.addEventListener('click', () => { - this.resolveModel(missing, match.model); - }); - } + // Attach listener to all matches (all now have resolve buttons) + const buttonId = `resolve-${missing.node_id}-${missing.widget_index}-${matchIndex}`; + const resolveButton = container.querySelector(`#${buttonId}`); + if (resolveButton) { + resolveButton.addEventListener('click', () => { + this.resolveModel(missing, match.model); + }); } }); }); @@ -346,9 +341,6 @@ class LinkerManagerDialog extends ComfyDialog { return b.confidence - a.confidence; }); - // Find the highest confidence match (even if not 100%) - const highestConfidenceMatch = sortedMatches.length > 0 ? sortedMatches[0] : null; - for (let matchIndex = 0; matchIndex < sortedMatches.length; matchIndex++) { const match = sortedMatches[matchIndex]; const buttonId = `resolve-${missing.node_id}-${missing.widget_index}-${matchIndex}`; @@ -357,13 +349,11 @@ class LinkerManagerDialog extends ComfyDialog { html += ` (${match.confidence}% confidence) `; - // Show resolve button for 100% matches OR for the highest confidence match (even if not 100%) - if (match.confidence === 100 || match === highestConfidenceMatch) { - html += ` `; - } + // Show resolve button for all matches (100% or < 100%) + html += ` `; html += ``; }