fix(autocomplete): strip file extensions from model names in search suggestions

Remove .safetensors/.ckpt/.pt/.bin extensions from model names in autocomplete
suggestions to improve UX and search relevance:

Frontend (web/comfyui/autocomplete.js):
- Add _getDisplayText() helper to strip extensions from model paths
- Update _matchItem() to match against filename without extension
- Update render() and createItemElement() to display clean names

Backend (py/services/base_model_service.py):
- Add _remove_model_extension() helper method
- Update _relative_path_matches_tokens() to ignore extensions in matching
- Update _relative_path_sort_key() to sort based on names without extensions

Tests (tests/services/test_relative_path_search.py):
- Add tests to verify 's' and 'safe' queries don't match all .safetensors files

Fixes issue where typing 's' would match all .safetensors files and cluttered
suggestions with redundant extension names.
This commit is contained in:
Will Miao
2026-03-07 23:07:10 +08:00
parent a802a89ff9
commit 43f6bfab36
3 changed files with 95 additions and 12 deletions

View File

@@ -62,3 +62,42 @@ async def test_search_relative_paths_excludes_tokens():
matching = await service.search_relative_paths("flux -detail")
assert matching == [f"flux{os.sep}keep-me.safetensors"]
@pytest.mark.asyncio
async def test_search_does_not_match_extension():
"""Searching for 's' or 'safe' should not match .safetensors extension."""
scanner = FakeScanner(
[
{"file_path": "/models/lora1.safetensors"},
{"file_path": "/models/lora2.safetensors"},
{"file_path": "/models/special-model.safetensors"}, # 's' in filename
],
["/models"],
)
service = DummyService("stub", scanner, BaseModelMetadata)
# Searching for 's' should only match 'special-model', not all .safetensors
matching = await service.search_relative_paths("s")
# Should only match 'special-model' because 's' is in the filename
assert len(matching) == 1
assert "special-model" in matching[0]
@pytest.mark.asyncio
async def test_search_safe_does_not_match_all_files():
"""Searching for 'safe' should not match .safetensors extension."""
scanner = FakeScanner(
[
{"file_path": "/models/flux.safetensors"},
{"file_path": "/models/detail.safetensors"},
],
["/models"],
)
service = DummyService("stub", scanner, BaseModelMetadata)
# Searching for 'safe' should return nothing (no file has 'safe' in its name)
matching = await service.search_relative_paths("safe")
assert len(matching) == 0