Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions hermes_cli/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ def _urlopen_model_catalog_request(req: urllib.request.Request, *, timeout: floa
("sakana/fugu-ultra", ""),
# OpenRouter routers
("openrouter/pareto-code", "auto-routes to cheapest coder meeting openrouter.min_coding_score"),
("openrouter/fusion", "multi-model deliberation panel + analyst; ~4-5x cost when invoked"),
("openrouter/fusion-flash", "fusion with latency-tuned general-fast preset"),
# Free tier
("openrouter/elephant-alpha", "free"),
("poolside/laguna-m.1:free", "free"),
Expand Down Expand Up @@ -1490,13 +1492,21 @@ def _openrouter_model_supports_tools(item: Any) -> bool:
so the picker doesn't silently empty for those users. Only hide models
whose ``supported_parameters`` is an explicit list that omits ``tools``.

**Permissive when the list is empty.** OpenRouter's meta-routers (e.g.
``openrouter/fusion``) publish ``supported_parameters: []`` because the
concrete model is resolved per-request, yet they fully support tool
calling (verified against the live endpoint). An empty list carries no
capability information, so treat it like a missing field rather than an
explicit "no tools" declaration.

Ported from Kilo-Org/kilocode#9068.
"""
if not isinstance(item, dict):
return True
params = item.get("supported_parameters")
if not isinstance(params, list):
# Field absent / malformed / None — be permissive.
if not isinstance(params, list) or not params:
# Field absent / malformed / None / empty — carries no capability
# information, so be permissive.
return True
return "tools" in params

Expand Down
18 changes: 15 additions & 3 deletions tests/hermes_cli/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,23 @@ def test_tools_in_supported_parameters(self):
) is True


def test_empty_supported_parameters_list_drops_model(self):
"""Explicit empty list → no tools → drop."""
def test_empty_supported_parameters_list_is_permissive(self):
"""Empty list carries no capability info → allow (openrouter/fusion).

OpenRouter meta-routers (e.g. ``openrouter/fusion``) publish
``supported_parameters: []`` because the concrete model is resolved
per-request, yet they support tool calling. Treat empty like missing.
"""
from hermes_cli.models import _openrouter_model_supports_tools
assert _openrouter_model_supports_tools(
{"id": "openrouter/fusion", "supported_parameters": []}
) is True

def test_explicit_list_without_tools_drops_model(self):
"""Non-empty list that omits 'tools' → drop."""
from hermes_cli.models import _openrouter_model_supports_tools
assert _openrouter_model_supports_tools(
{"id": "x", "supported_parameters": []}
{"id": "x", "supported_parameters": ["temperature", "response_format"]}
) is False


Expand Down