mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-01 12:02:05 +00:00
fix(moa): tolerate non-numeric values in hand-edited MoA preset config
_normalize_preset uses bare float() and int() to coerce reference_temperature, aggregator_temperature, and max_tokens from config.yaml. When a user hand-edits a non-numeric value (e.g. max_tokens: "8k" or reference_temperature: "hot"), the coercion raises ValueError. Since normalize_moa_config runs on every model-selection and MoA turn (via resolve_moa_preset), the crash is unrecoverable and blocks all MoA usage until the config is manually fixed. Replace the bare casts with _coerce_float / _coerce_int helpers that fall back to the default on TypeError/ValueError instead of raising.
This commit is contained in:
parent
9b2af36d5a
commit
f0678b031e
2 changed files with 63 additions and 3 deletions
|
|
@ -21,6 +21,27 @@ DEFAULT_MOA_AGGREGATOR: dict[str, str] = {
|
|||
}
|
||||
|
||||
|
||||
def _coerce_float(value: Any, default: float) -> float:
|
||||
if value is None or value == "":
|
||||
return default
|
||||
try:
|
||||
return float(value)
|
||||
except (TypeError, ValueError):
|
||||
return default
|
||||
|
||||
|
||||
def _coerce_int(value: Any, default: int) -> int:
|
||||
if value is None or value == "":
|
||||
return default
|
||||
try:
|
||||
return int(value)
|
||||
except (TypeError, ValueError):
|
||||
try:
|
||||
return int(float(value))
|
||||
except (TypeError, ValueError):
|
||||
return default
|
||||
|
||||
|
||||
def _clean_slot(slot: Any) -> dict[str, str] | None:
|
||||
if not isinstance(slot, dict):
|
||||
return None
|
||||
|
|
@ -57,9 +78,9 @@ def _normalize_preset(raw: Any) -> dict[str, Any]:
|
|||
"enabled": bool(raw.get("enabled", True)),
|
||||
"reference_models": refs,
|
||||
"aggregator": aggregator,
|
||||
"reference_temperature": float(raw.get("reference_temperature", 0.6) or 0.6),
|
||||
"aggregator_temperature": float(raw.get("aggregator_temperature", 0.4) or 0.4),
|
||||
"max_tokens": int(raw.get("max_tokens", 4096) or 4096),
|
||||
"reference_temperature": _coerce_float(raw.get("reference_temperature"), 0.6),
|
||||
"aggregator_temperature": _coerce_float(raw.get("aggregator_temperature"), 0.4),
|
||||
"max_tokens": _coerce_int(raw.get("max_tokens"), 4096),
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,45 @@ def test_legacy_flat_config_becomes_default_preset():
|
|||
]
|
||||
|
||||
|
||||
def test_normalize_moa_config_tolerates_non_numeric_values():
|
||||
"""Non-numeric strings in hand-edited config.yaml must degrade to defaults
|
||||
instead of crashing normalize_moa_config with ValueError."""
|
||||
cfg = normalize_moa_config(
|
||||
{
|
||||
"presets": {
|
||||
"broken": {
|
||||
"max_tokens": "notanumber",
|
||||
"reference_temperature": "hot",
|
||||
"aggregator_temperature": "",
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
preset = cfg["presets"]["broken"]
|
||||
assert preset["max_tokens"] == 4096
|
||||
assert preset["reference_temperature"] == 0.6
|
||||
assert preset["aggregator_temperature"] == 0.4
|
||||
|
||||
|
||||
def test_normalize_moa_config_coerces_numeric_strings():
|
||||
"""Valid numeric strings (e.g. from YAML round-trip) must coerce correctly."""
|
||||
cfg = normalize_moa_config({"max_tokens": "8192", "reference_temperature": "0.9"})
|
||||
|
||||
preset = cfg["presets"][DEFAULT_MOA_PRESET_NAME]
|
||||
assert preset["max_tokens"] == 8192
|
||||
assert preset["reference_temperature"] == 0.9
|
||||
|
||||
|
||||
def test_normalize_moa_config_coerces_float_max_tokens():
|
||||
"""max_tokens: 4096.0 (float from YAML) must coerce to int."""
|
||||
cfg = normalize_moa_config({"max_tokens": 4096.0})
|
||||
assert cfg["presets"][DEFAULT_MOA_PRESET_NAME]["max_tokens"] == 4096
|
||||
|
||||
cfg2 = normalize_moa_config({"max_tokens": "4096.5"})
|
||||
assert cfg2["presets"][DEFAULT_MOA_PRESET_NAME]["max_tokens"] == 4096
|
||||
|
||||
|
||||
def test_exact_preset_matching_is_not_fuzzy():
|
||||
config = {"presets": {"coding": {}, "review": {}}}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue