fix(moa): route per-slot reasoning effort through the canonical parser

_clean_reasoning_effort kept its own whitelist that stopped at 'max',
silently dropping 'ultra' from MoA slot configs. Route it through
hermes_constants.parse_reasoning_effort — the same one-source-of-truth
fix the salvaged commit applies to the gateway — so future effort
levels can't drift here either. Docs updated to list ultra.

Follow-up to salvaged PR #64012.
This commit is contained in:
Teknium 2026-07-16 05:44:57 -07:00
parent 4ad5036a44
commit 75c878217d
4 changed files with 10 additions and 9 deletions

View file

@ -75,18 +75,16 @@ def _coerce_fanout(value: Any) -> str:
def _clean_reasoning_effort(value: Any) -> str | None:
"""Return a canonical per-slot reasoning effort, or None when unset/invalid."""
from hermes_constants import parse_reasoning_effort
if value is None or value is True:
return None
if value is False:
return "none"
text = str(value or "").strip().lower()
if not text:
parsed = parse_reasoning_effort(value)
if parsed is None:
return None
if text in {"none", "false", "disabled"}:
if parsed.get("enabled") is False:
return "none"
if text in {"minimal", "low", "medium", "high", "xhigh", "max"}:
return text
return None
return parsed.get("effort")
def _clean_slot(slot: Any) -> dict[str, Any] | None:

View file

@ -45,6 +45,7 @@ ACP_REGISTRY_MANIFEST = REPO_ROOT / "acp_registry" / "agent.json"
# Auto-extracted from noreply emails + manual overrides
AUTHOR_MAP = {
"kar.iskakov@gmail.com": "karfly", # PR #64012 salvage (gateway: surface extended reasoning efforts)
"agungsubastian1963@gmail.com": "aguung", # PR #64461 salvage (gateway: multiplex secret_scope for authz/Slack/webhooks)
"jtstothard@gmail.com": "jtstothard", # PR #63256 salvage (gateway: multiplex secondary adapter config validation)
"doogie@spark.local": "SAMBAS123", # PR #64986 salvage (gateway: multiplex primary bot token scope)

View file

@ -106,6 +106,7 @@ def test_normalize_moa_config_preserves_slot_reasoning_effort():
{"provider": "openai-codex", "model": "gpt-5.6-sol", "reasoning_effort": "LOW"},
{"provider": "openai-codex", "model": "gpt-5.6-sol", "reasoning_effort": False},
{"provider": "openai-codex", "model": "gpt-5.6-sol", "reasoning_effort": "nonsense"},
{"provider": "openai-codex", "model": "gpt-5.6-sol", "reasoning_effort": "ultra"},
],
"aggregator": {"provider": "openai-codex", "model": "gpt-5.6-sol", "reasoning_effort": "xhigh"},
}
@ -117,6 +118,7 @@ def test_normalize_moa_config_preserves_slot_reasoning_effort():
assert preset["reference_models"][0]["reasoning_effort"] == "low"
assert preset["reference_models"][1]["reasoning_effort"] == "none"
assert "reasoning_effort" not in preset["reference_models"][2]
assert preset["reference_models"][3]["reasoning_effort"] == "ultra"
assert preset["aggregator"]["reasoning_effort"] == "xhigh"

View file

@ -138,7 +138,7 @@ Reference and aggregator slots may also set `reasoning_effort`. Use this when
you want the same model to contribute at different depths, or when the
aggregator should think harder than the advisory references. Valid values match
Hermes' normal reasoning controls: `none`, `minimal`, `low`, `medium`, `high`,
`xhigh`, and `max`.
`xhigh`, `max`, and `ultra`.
```yaml
moa: