mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-01 07:01:41 +00:00
fix(skills-hub): fix dedup in browse_skills() programmatic API
browse_skills() is the TUI gateway's API for the web UI skills browser (tui_gateway/server.py:6574). It had the same dedup-by-name bug as do_browse() and unified_search() fixed in the parent commit: r.name is not unique for browse-sh skills (Airbnb, Booking.com, Zillow all publish "search-listings"), so the dedup loop silently dropped all but the first skill with each task name. Switch to r.identifier, which is always globally unique. Add a regression test asserting that two browse-sh skills with the same name but different hostnames both appear in the browse_skills() result.
This commit is contained in:
parent
fc7e04e9ed
commit
8f92327891
2 changed files with 41 additions and 2 deletions
|
|
@ -704,8 +704,8 @@ def browse_skills(page: int = 1, page_size: int = 20, source: str = "all") -> di
|
|||
seen: dict = {}
|
||||
for r in all_results:
|
||||
rank = _TRUST_RANK.get(r.trust_level, 0)
|
||||
if r.name not in seen or rank > _TRUST_RANK.get(seen[r.name].trust_level, 0):
|
||||
seen[r.name] = r
|
||||
if r.identifier not in seen or rank > _TRUST_RANK.get(seen[r.identifier].trust_level, 0):
|
||||
seen[r.identifier] = r
|
||||
deduped = list(seen.values())
|
||||
deduped.sort(key=lambda r: (-_TRUST_RANK.get(r.trust_level, 0), r.source != "official", r.name.lower()))
|
||||
total = len(deduped)
|
||||
|
|
|
|||
|
|
@ -524,3 +524,42 @@ def test_existing_categories_returns_empty_when_skills_dir_missing(monkeypatch,
|
|||
|
||||
from hermes_cli.skills_hub import _existing_categories
|
||||
assert _existing_categories() == []
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# browse_skills — dedup by identifier, not name
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_browse_skills_dedup_uses_identifier_not_name(monkeypatch):
|
||||
"""browse_skills() must not collapse browse-sh skills that share a task name.
|
||||
|
||||
Airbnb and Booking.com both publish a 'search-listings' skill. Before the
|
||||
fix, both were keyed by name so only one survived deduplication. After the
|
||||
fix, each unique identifier produces a distinct result.
|
||||
"""
|
||||
from tools.skills_hub import SkillMeta
|
||||
from hermes_cli.skills_hub import browse_skills
|
||||
|
||||
airbnb = SkillMeta(
|
||||
name="search-listings", description="Airbnb search", source="browse-sh",
|
||||
identifier="browse-sh/airbnb.com/search-listings-ddgioa", trust_level="community",
|
||||
)
|
||||
booking = SkillMeta(
|
||||
name="search-listings", description="Booking.com search", source="browse-sh",
|
||||
identifier="browse-sh/booking.com/search-listings-xyzab", trust_level="community",
|
||||
)
|
||||
|
||||
mock_src = type("S", (), {
|
||||
"source_id": lambda self: "browse-sh",
|
||||
"search": lambda self, q, limit=500: [airbnb, booking],
|
||||
})()
|
||||
|
||||
with patch("hermes_cli.skills_hub.create_source_router", return_value=[mock_src]):
|
||||
result = browse_skills(page=1, page_size=50)
|
||||
|
||||
names = [item["name"] for item in result["items"]]
|
||||
assert names.count("search-listings") == 2, (
|
||||
"browse_skills() must not deduplicate browse-sh skills with the same name "
|
||||
"but different identifiers"
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue