fix(honcho): memoize timeout staleness check + host-aware status cadence

Follow-ups for the consolidated salvage:
- Memoize the config.yaml-derived timeout on the file's mtime_ns so the
  rebuild-on-timeout-change check from PR #57437 costs one stat() per
  get_honcho_client() call instead of a full YAML load on the hot path.
- hermes honcho status now displays the host-block-resolved
  dialecticCadence (remnant from PR #63776, whose runtime fix landed
  in #62290).
- AUTHOR_MAP entries for the salvaged contributor emails.
This commit is contained in:
Teknium 2026-07-16 19:49:35 -07:00
parent e5bebe2cad
commit 04d84df63c
3 changed files with 40 additions and 14 deletions

View file

@ -1099,7 +1099,7 @@ def cmd_status(args) -> None:
print(f" Recall mode: {hcfg.recall_mode}")
print(f" Context budget: {hcfg.context_tokens or '(uncapped)'} tokens")
raw = getattr(hcfg, "raw", None) or {}
dialectic_cadence = raw.get("dialecticCadence") or 1
dialectic_cadence = getattr(hcfg, "dialectic_cadence", None) or raw.get("dialecticCadence") or 1
print(f" Dialectic cad: every {dialectic_cadence} turn{'s' if dialectic_cadence != 1 else ''}")
reasoning_cap = raw.get("reasoningLevelCap") or hcfg.reasoning_level_cap
heuristic_on = "on" if hcfg.reasoning_heuristic else "off"

View file

@ -856,6 +856,39 @@ class HonchoClientConfig:
_honcho_client_slot: SingletonSlot = SingletonSlot()
_cached_timeout: float | None = None
# Memo for the config.yaml-derived timeout, keyed on the file's mtime_ns so
# the staleness check on every get_honcho_client() call costs one stat()
# instead of a full YAML load. (None, None) = not yet populated.
_config_timeout_memo: tuple[int | None, float | None] = (None, None)
def _config_yaml_timeout() -> float | None:
"""Read honcho.timeout / honcho.request_timeout from config.yaml, memoized on mtime."""
global _config_timeout_memo
try:
from hermes_constants import get_hermes_home
cfg_path = get_hermes_home() / "config.yaml"
try:
mtime_ns: int | None = cfg_path.stat().st_mtime_ns
except OSError:
mtime_ns = None
if _config_timeout_memo[0] is not None and _config_timeout_memo[0] == mtime_ns:
return _config_timeout_memo[1]
from hermes_cli.config import load_config
honcho_cfg = load_config().get("honcho", {})
timeout = None
if isinstance(honcho_cfg, dict):
timeout = _resolve_optional_float(
honcho_cfg.get("timeout"),
honcho_cfg.get("request_timeout"),
)
_config_timeout_memo = (mtime_ns, timeout)
return timeout
except Exception:
return None
def _resolve_timeout_from_sources(config: HonchoClientConfig | None) -> float:
@ -864,18 +897,7 @@ def _resolve_timeout_from_sources(config: HonchoClientConfig | None) -> float:
if timeout is None:
timeout = _resolve_optional_float(os.environ.get("HONCHO_TIMEOUT"))
if timeout is None:
try:
from hermes_cli.config import load_config
hermes_cfg = load_config()
honcho_cfg = hermes_cfg.get("honcho", {})
if isinstance(honcho_cfg, dict):
timeout = _resolve_optional_float(
honcho_cfg.get("timeout"),
honcho_cfg.get("request_timeout"),
)
except Exception:
pass
timeout = _config_yaml_timeout()
return timeout if timeout is not None else _DEFAULT_HTTP_TIMEOUT
@ -1055,6 +1077,7 @@ def get_honcho_client(config: HonchoClientConfig | None = None) -> Honcho:
def reset_honcho_client() -> None:
"""Reset the Honcho client singleton (useful for testing)."""
global _cached_timeout
global _cached_timeout, _config_timeout_memo
_honcho_client_slot.reset()
_cached_timeout = None
_config_timeout_memo = (None, None)