Files
hermes-agent/tools
yflmq001 349e6611a1 fix(approval): enforce explicit timeout on smart-approval guardian call and log its outcome
The smart-approval guardian (`_smart_approve`) gates every flagged
terminal command with a synchronous auxiliary LLM call, but it never
passes `timeout=` and logs nothing on the normal path. In production a
stalled provider response silently froze the agent turn for 62 minutes
with zero log output; the gateway kill-switch eventually fired, and only
an unrelated error surfaced afterwards (#82846; watchdog-style fix in
#72500). The call was invisible by design — nothing logs at the hang
point.

Changes in tools/approval.py:
- Resolve the same configured timeout the client would use internally
  (`auxiliary.approval.timeout` via `_get_task_timeout("approval")`) and
  pass it explicitly to `call_llm`, so the deadline cannot be lost if the
  internal default resolution changes or is misconfigured.
- Log the assessment call and its duration (DEBUG), and promote the
  failure branch from DEBUG to WARNING with elapsed time + exception
  class, so a wedged guardian call is visible in the logs instead of
  silent.
- Failure still returns "escalate" (fail open to the human/pattern
  gate) — behavior unchanged, observability only.

Complements #72500 (watchdog hard ceiling) rather than duplicating it:
explicit timeout is the root-cause hardening, logging closes the
silence gap; the watchdog remains the safety net if the SDK-level
timeout itself is defeated.

Tests: explicit timeout forwarded to call_llm (revert-fails), failure
logs WARNING + escalates. 49 approval-adjacent tests pass; one unrelated
test_approval.py failure is pre-existing (fails on clean main too).
2026-08-27 14:28:22 +05:30
..