fix(openrouter): surface router models in the picker and add Fusion - #46067
fix(openrouter): surface router models in the picker and add Fusion#46067MaxFreedomPollard wants to merge 1 commit into
Conversation
OpenRouter router aliases (openrouter/pareto-code, openrouter/fusion) route each request to an underlying tool-capable model, so the alias reports supported_parameters: [] in /api/v1/models. The picker's tool-support filter treats that empty list as "no tool calling" and silently drops every router - openrouter/pareto-code ships today but never appears in `hermes model` for this reason. Add an explicit router allowlist so known OpenRouter routers survive the filter (not an openrouter/* glob, so a genuine non-router model lacking tools is still filtered), and add openrouter/fusion to the curated OpenRouter list (both the in-repo OPENROUTER_MODELS fallback and the hosted model-catalog.json the picker prefers). The bare openrouter/fusion alias works with no client config; OpenRouter applies its Quality-preset panel/judge defaults server-side.
|
Competing PR note — OpenRouter Fusion model slug This PR and #46094 (by teknium1) both add Comparison:
Both approaches are correct. The key difference is that #46094's If only one lands, #46094 covers the manifest-lag edge case. If both land, the second will need a rebase since they modify the same functions. |
|
Closing in favor of #46094, which adds configurable Fusion presets as the canonical OpenRouter Fusion implementation. Thanks for the contribution — the Fusion direction is being consolidated there. |
Summary
Two changes, one root cause:
hermes model.openrouter/pareto-codeships today (curated, documented, tested) but never appears in the picker, because the tool-support filter reads a router'ssupported_parameters: []as "no tool calling." This restores routers to the picker.openrouter/fusionas a built-in selectable model.The two belong together because the feature is impossible without the fix:
openrouter/fusionis itself a router, so without fixing the filter it would be added and then immediately hidden - dead on arrival. Fixing the filter is the minimum required for the addition to work at all, and the same fix incidentally unblocks the already-shippedpareto-code. Keeping it one change avoids landing a fix and then a feature that re-touches the same five lines.After this,
hermes model//model(TUI/CLI) and the desktop model picker list both router entries (todayopenrouter/pareto-codeis silently absent):Because the picker reads the hosted catalog manifest at runtime, the entry reaches existing installs without an app update.
What Fusion is (OpenRouter docs)
A panel of 1-8 models answers in parallel (each with
openrouter:web_search/openrouter:web_fetch), a judge compares them (it does not merge) and returns structured analysis - consensus, contradictions, blind spots - and a model writes the final answer. Useful when the cost of being wrong outweighs a few extra completions. Pricing, verbatim: "Because Fusion runs every panel member plus a judge call, your request is priced as the sum of those underlying completions rather than a single model."Changes
hermes_cli/models.py: add_OPENROUTER_TOOL_CAPABLE_ROUTERS(openrouter/pareto-code,openrouter/fusion) and short-circuit_openrouter_model_supports_tools()toTruefor those ids. Explicit allowlist, not anopenrouter/*glob, so a real non-routeropenrouter/*model lacking tools is still filtered. Addopenrouter/fusionto theOPENROUTER_MODELSfallback snapshot.website/static/api/model-catalog.json: addopenrouter/fusionto the hosted curated manifest - the source the picker prefers over the in-repo snapshot, so both are required for the entry to surface.tests/hermes_cli/test_models.py: router-survives-filter, allowlist-is-not-a-glob, fusion-curated, and an end-to-end picker test that keeps fusion when its catalog entry advertisessupported_parameters: [].Tests
pytest tests/hermes_cli/test_models.py tests/hermes_cli/test_model_catalog.py tests/providers/test_provider_profiles.pyruff check hermes_cli/models.pyfetch_openrouter_models(force_refresh=True)against live/api/v1/modelswith the updated manifestopenrouter/fusionandopenrouter/pareto-codeboth present (both dropped before the fix)Tested on macOS, Python 3.11.
Deliberately out of scope
A
fusionconfig block (panelanalysis_models+ judgemodel) translated into the OpenRouterpluginsarray inOpenRouterProfile.build_extra_body- mirroring the existingpareto-routerbranch - is left out to keep this narrow: the bare alias already deliberates with server-side defaults, so wiring config now would be unused surface. A Fusion subsection forwebsite/docs/integrations/providers.md(mirroring the Pareto Code section, with the verbatim pricing note) can be added here or as a follow-up - happy to include it in this PR if preferred.Closes #46064