refactor(gateway): dedupe drain-timeout resolution + share active_agents parse

Follow-up cleanups on top of the busy/idle readout (PR #50103):

- web_server.py /api/status reused the single drain-timeout resolver
  hermes_cli.gateway._get_restart_drain_timeout() (HERMES_RESTART_DRAIN_TIMEOUT
  env -> agent.restart_drain_timeout config -> default) instead of inlining a
  third hand-rolled copy of that precedence chain. Also fixes a subtle
  divergence: the inline copy used os.environ.get() so a set-but-empty env var
  was treated as a value rather than falling through to config; the shared
  resolver .strip()s and falls through correctly.
- Added gateway.status.parse_active_agents() and routed BOTH HTTP surfaces
  (/api/status and /health/detailed) through it, so the exposed active_agents
  field is consistently clamped non-negative. Previously /api/status clamped
  while /health/detailed exposed the raw file value, diverging on a corrupt
  count.
- Added TestParseActiveAgents covering the shared coercion contract.
This commit is contained in:
kshitijk4poor 2026-06-21 16:37:42 +05:30
parent 0ee75469d7
commit b577f25100
4 changed files with 55 additions and 19 deletions

View file

@ -1106,12 +1106,13 @@ class APIServerAdapter(BasePlatformAdapter):
from gateway.status import (
derive_gateway_busy,
derive_gateway_drainable,
parse_active_agents,
read_runtime_status,
)
runtime = read_runtime_status() or {}
gw_state = runtime.get("gateway_state")
gw_active = runtime.get("active_agents", 0)
gw_active = parse_active_agents(runtime.get("active_agents", 0))
# This endpoint is served BY the gateway process, so it is by definition
# alive — gateway_running is True. Derive busy/drainable from the same
# shared contract /api/status uses so the two surfaces never disagree.