mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-17 09:41:58 +00:00
fix(inventory): keep user-defined custom providers in model dedup
The #45954 model-dedup builds `user_models` from every is_user_defined row, then strips those model IDs from every row where is_aggregator(slug) is True. But is_aggregator() returns True for *every* `custom:*` slug, and list_authenticated_providers emits named custom providers with slug `custom:<name>` and is_user_defined=True. So a user's own custom provider is treated as an aggregator and filtered against user_models — which holds exactly its own models (the row helped build that set). Every model is removed, the row drops to zero, and the provider disappears from the model picker. Guard the dedup loop to skip is_user_defined rows: a user's configured provider is never an aggregator duplicate of itself. Built-in aggregators (openrouter, etc.) are still deduped as before. Adds a regression test.
This commit is contained in:
parent
f4ef70f6fc
commit
b7fa62c530
2 changed files with 40 additions and 0 deletions
|
|
@ -178,6 +178,14 @@ def build_models_payload(
|
|||
user_models.update(m.lower() for m in (row.get("models") or []))
|
||||
if user_models:
|
||||
for row in rows:
|
||||
# A user's own configured provider is never an "aggregator
|
||||
# duplicate" of itself: user_models is built from these very
|
||||
# rows, and is_aggregator() reports True for every custom:*
|
||||
# slug. Without this guard the dedup strips a user-defined
|
||||
# custom provider's entire model list (all of it lives in
|
||||
# user_models), emptying its picker row.
|
||||
if row.get("is_user_defined"):
|
||||
continue
|
||||
slug = row.get("slug", "")
|
||||
if not _is_aggregator(slug):
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -606,3 +606,35 @@ def test_aggregator_dedup_multiple_user_providers():
|
|||
assert or_row["models"] == ["model-z"]
|
||||
assert or_row["total_models"] == 1
|
||||
|
||||
|
||||
def test_aggregator_dedup_does_not_empty_user_defined_custom_provider():
|
||||
"""A named custom provider has slug ``custom:<name>``, which makes it
|
||||
*both* ``is_user_defined=True`` *and* ``is_aggregator()==True``
|
||||
(is_aggregator reports True for every ``custom:*`` slug). The dedup
|
||||
must skip user-defined rows: their models populate ``user_models``, so
|
||||
filtering them against that set would strip the row's entire catalog and
|
||||
hide the provider from the picker. Regression for the #45954 dedup
|
||||
emptying ``custom:*`` providers (e.g. a local llama.cpp endpoint or an
|
||||
Anthropic-compatible proxy)."""
|
||||
rows = [
|
||||
_user_provider_row("custom:my-proxy", ["my-model-a", "my-model-b"]),
|
||||
_aggregator_row("openrouter", ["my-model-a", "other/model"]),
|
||||
]
|
||||
ctx = _empty_ctx()
|
||||
with _list_auth_returning(rows):
|
||||
payload = build_models_payload(ctx)
|
||||
|
||||
proxy_row = next(
|
||||
r for r in payload["providers"] if r["slug"] == "custom:my-proxy"
|
||||
)
|
||||
or_row = next(r for r in payload["providers"] if r["slug"] == "openrouter")
|
||||
|
||||
# The user's own custom provider keeps all of its models.
|
||||
assert proxy_row["models"] == ["my-model-a", "my-model-b"]
|
||||
assert proxy_row["total_models"] == 2
|
||||
|
||||
# A genuine aggregator is still deduped against the user's models.
|
||||
assert "my-model-a" not in or_row["models"]
|
||||
assert "other/model" in or_row["models"]
|
||||
assert or_row["total_models"] == 1
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue