fix(config): preserve lossy decimal values as strings

This commit is contained in:
Gille
2026-08-26 13:55:19 -06:00
committed by kshitij
parent 2ea42a44e0
commit 6defe7eb6c
2 changed files with 24 additions and 1 deletions

View File

@@ -15,6 +15,7 @@ This module provides:
"""
import copy
from decimal import Decimal, InvalidOperation
from hermes_cli.cli_output import line_input
import json
import logging
@@ -5434,7 +5435,12 @@ def _coerce_int(value: str):
def _coerce_float(value: str):
"""Return float(value) for a clean float literal, else None."""
"""Return ``float(value)`` when conversion preserves its decimal value.
Decimal-looking identifiers can be much more precise than a binary float.
Silently rounding one here corrupts it before it reaches ``config.yaml``,
so values that do not round-trip through ``float`` remain strings.
"""
try:
f = float(value)
except (TypeError, ValueError):
@@ -5443,6 +5449,11 @@ def _coerce_float(value: str):
# and round-trip confusingly through YAML.
if f != f or f in (float("inf"), float("-inf")):
return None
try:
if Decimal(value) != Decimal(str(f)):
return None
except InvalidOperation:
return None
return f

View File

@@ -42,6 +42,18 @@ class TestNumericCoercion:
v = _read(tmp_path, "agent", "max_turns")
assert v == -2.5 and isinstance(v, float)
def test_lossy_decimal_identifier_stays_string(self, tmp_path, monkeypatch):
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
client_id = "123456789012.98765432109876"
cfg.set_config_value("mcp_servers.example.oauth.client_id", client_id)
saved = _read(
tmp_path, "mcp_servers", "example", "oauth", "client_id"
)
assert saved == client_id
assert isinstance(saved, str)
class TestNullCoercion:
@pytest.mark.parametrize("token", ["null", "none", "None", "~"])