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

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #55598 fix(moa): disabled presets no longer hijack a plain model switch

    merged to main

    files: hermes_cli/moa_config.py, tests/hermes_cli/test_moa_config.py

    Show 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.00 means 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 Lab

At a glance

Merged PRs
#55598
Closed issues
1
Attempts
1 PR closed without merging
Fix link checked
30 Jun 2026

For your agent

The same facts, typed.