NousResearch/hermes-agent
MoA disabled presets incorrectly matching/activating
Cluster 55187. Data as of
Nothing open on GitHub. Fix merged in #55598 on 30 Jun 2026. Check it covers your case.
The short answer
0open issues
0open PRs
3items grouped
- Known?
- Yes. 3 related items grouped here, 1 issue already closed.
- Fix event
- A fix was merged to main in PR #55598. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
resolved, deciding PR #55598. That is separate from the fix event. - Still open
- Nothing open on GitHub.
A bug where disabled MoA presets were still being selected or matched during plain chat interactions. Fixes target preset-skipping logic to respect the enabled flag.
Open issues0
Open PRs0
Fixes on record
-
#55598 fix(moa): disabled presets no longer hijack a plain model switch
files:
hermes_cli/moa_config.py,tests/hermes_cli/test_moa_config.pyShow the diff
-
hermes_cli/moa_config.py@@ -158,11 +158,26 @@ def resolve_moa_preset(config: Any, name: str | None = None) -> dict[str, Any]: def exact_moa_preset_name(config: Any, text: str) -> str | None: + """Return the preset name iff ``text`` exactly matches an *enabled* preset. + + Used by the no-explicit-provider switch path (PATH B in + ``hermes_cli/model_switch.py``) to recognize a bare ``/model <preset>`` + that the user typed without the ``moa:`` prefix. This is an *implicit* + match, so it must honor the per-preset ``enabled`` opt-out: a user who set + ``enabled: false`` to disable a preset must not have a plain model switch + whose name happens to collide with that preset key silently pivot the + session onto the MoA virtual provider (issue #55187). Explicit selection + via ``--provider moa`` / the model picker does not go through here, so a + disabled preset is still reachable when the user explicitly asks for it. + """ wanted = str(text or "").strip() if not wanted: return None cfg = normalize_moa_config(config) - return wanted if wanted in cfg["presets"] else None + preset = cfg["presets"].get(wanted) + if preset is None or not preset.get("enabled", True): + return None + return wanted def set_active_moa_preset(config: Any, name: str | None) -> dict[str, Any]: -
tests/hermes_cli/test_moa_config.py@@ -120,6 +120,38 @@ def test_exact_preset_matching_is_not_fuzzy(): assert exact_moa_preset_name(config, "coding please fix this") is None +def test_exact_preset_matching_skips_disabled_presets(): + """A disabled preset must not match the implicit bare-name switch path. + + Regression for #55187: with ``enabled: false`` presets, a plain model + switch whose name collides with a preset key (e.g. ``default``) silently + pivoted the session onto the MoA virtual provider. The per-preset + ``enabled`` opt-out must gate this implicit match. + """ + config = { + "presets": { + "default": {"enabled": False}, + "klo": {"enabled": False}, + }, + } + assert exact_moa_preset_name(config, "default") is None + assert exact_moa_preset_name(config, "klo") is None + + +def test_exact_preset_matching_allows_enabled_presets(): + """An explicitly enabled preset still matches the bare-name switch path.""" + config = { + "presets": { + "fast": {"enabled": True}, + "slow": {"enabled": False}, + }, + } + assert exact_moa_preset_name(config, "fast") == "fast" + assert exact_moa_preset_name(config, "slow") is None + # Default (no explicit enabled key) is enabled and still matches. + assert exact_moa_preset_name({"presets": {"x": {}}}, "x") == "x" + + def test_active_preset_toggle_validation(): config = {"default_preset": "coding", "presets": {"coding": {}, "review": {}}}
-
1 PR closed without merging
From the close comments: done elsewhere 1
-
#55193 fix(moa): skip disabled presets in exact_moa_preset_name · done elsewhere →
#55598
Closed issues · 1
- Closed#55187[Bug] MoA virtual provider auto-selects on plain chat message; `enabled: false` presets still match
How this cluster was grouped
-
Link evidence (
structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference. -
Pairwise link density
0.67: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the LabAt a glance
- Merged PRs
- #55598
- Closed issues
- 1
- Attempts
- 1 PR closed without merging
- Fix link checked
- 30 Jun 2026