mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-23 10:42:00 +00:00
fix(approval): honor interrupt in blocking gateway approval wait (#8697)
A dangerous-command gateway approval blocks the agent's execution thread inside _await_gateway_decision() on threading.Event.wait() until the user responds or the 5-minute approval timeout fires. The poll loop never checked is_interrupted(), so /stop (which flags the agent's execution thread via AIAgent.interrupt()) was silently ignored — the session stayed wedged until timeout, even though /stop reported the session unlocked. Check is_interrupted() at the top of the poll loop. The wait runs on the agent's execution thread, the exact thread interrupt() flags, so the check sees the signal and resolves the pending approval as deny — the agent loop receives a normal denial and unwinds cleanly. Covers /stop, /new, and the gateway inactivity-timeout interrupt through the single shared wait loop used by both the terminal and execute_code guards.
This commit is contained in:
parent
824c9d3812
commit
a9c8025984
1 changed files with 18 additions and 0 deletions
|
|
@ -20,6 +20,7 @@ import unicodedata
|
|||
from typing import Optional
|
||||
from hermes_cli.config import cfg_get
|
||||
|
||||
from tools.interrupt import is_interrupted
|
||||
from utils import env_var_enabled, is_truthy_value
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -1343,6 +1344,23 @@ def _await_gateway_decision(session_key: str, notify_cb, approval_data: dict,
|
|||
_activity_state = {"last_touch": _now, "start": _now}
|
||||
resolved = False
|
||||
while True:
|
||||
# Respect interrupt signals (e.g. /stop, /new, or an inactivity
|
||||
# timeout from the gateway) so a pending approval doesn't keep the
|
||||
# session wedged on threading.Event.wait() until the 5-minute approval
|
||||
# timeout. The wait runs on the agent's execution thread, which is the
|
||||
# exact thread AIAgent.interrupt() flags — so is_interrupted() here
|
||||
# sees the signal. Resolve as "deny" so the agent loop receives a
|
||||
# normal denial and unwinds cleanly (#8697).
|
||||
if is_interrupted():
|
||||
logger.info(
|
||||
"Approval wait interrupted by user signal — "
|
||||
"returning deny for session %s",
|
||||
session_key,
|
||||
)
|
||||
entry.result = "deny"
|
||||
entry.event.set()
|
||||
resolved = True
|
||||
break
|
||||
_remaining = _deadline - time.monotonic()
|
||||
if _remaining <= 0:
|
||||
break
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue