Approval timeout hardcoded 60s, make configurable

NousResearch/hermes-agent · cluster 3765 · acp

Data as of

6 open items. Fix merged in #3886. Check it covers your case.

The short answer

2open issues
4open PRs
12items grouped
Known?
Yes. 12 related items grouped here, 1 issue already closed.
Fix event
A fix was merged to main in PR #3886. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this partially resolved, deciding PR #3886. That is separate from the fix event.
Still open
2 issues and 4 PRs.

Multiple bug reports and fixes addressing that ACP and CLI approval callbacks ignore the approvals.timeout config and use a hardcoded 60-second timeout. Related work adds the ability to configure the dangerous-command approval timeout.

Open issues2

  • Issue#63302[Bug]: ACP edit approval ignores `approvals.timeout` — hardcoded 60s, times out as a silent denial
  • Issue#63538[Bug]: ACP dangerous-command approval callback ignores `approvals.timeout` — hardcoded 60s (sibling of #63302)

Open PRs4

  • PR#13088fix: honor approvals.timeout across CLI and ACP
  • PR#63308fix(acp): honor edit approval timeout
  • PR#63575fix(acp): use approvals.timeout for both command and edit approval callbacks
  • PR#64336fix: honor approvals.timeout for ACP edit approval prompts (#63302)

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #3886 feat(approvals): make dangerous command approval timeout configurable

    merged to main

    files: hermes_cli/callbacks.py, hermes_cli/config.py, tools/approval.py

    Show the diff
    • hermes_cli/callbacks.py
      @@ -241,7 +241,8 @@ def approval_callback(cli, command: str, description: str) -> str:
               lock = cli._approval_lock
       
           with lock:
      -        timeout = 60
      +        from cli import CLI_CONFIG
      +        timeout = CLI_CONFIG.get("approvals", {}).get("timeout", 60)
               response_queue = queue.Queue()
               choices = ["once", "session", "always", "deny"]
               if len(command) > 70:
    • hermes_cli/config.py
      @@ -407,6 +407,7 @@ def ensure_hermes_home():
           #   off    — skip all approval prompts (equivalent to --yolo)
           "approvals": {
               "mode": "manual",
      +        "timeout": 60,
           },
       
           # Permanently allowed dangerous command patterns (added via "always" approval)
    • tools/approval.py
      @@ -241,7 +241,7 @@ def save_permanent_allowlist(patterns: set):
       # =========================================================================
       
       def prompt_dangerous_approval(command: str, description: str,
      -                              timeout_seconds: int = 60,
      +                              timeout_seconds: int | None = None,
                                     allow_permanent: bool = True,
                                     approval_callback=None) -> str:
           """Prompt the user to approve a dangerous command (CLI only).
      @@ -256,6 +256,9 @@ def prompt_dangerous_approval(command: str, description: str,
       
           Returns: 'once', 'session', 'always', or 'deny'
           """
      +    if timeout_seconds is None:
      +        timeout_seconds = _get_approval_timeout()
      +
           if approval_callback is not None:
               try:
                   return approval_callback(command, description,
      @@ -336,15 +339,28 @@ def _normalize_approval_mode(mode) -> str:
           return "manual"
       
       
      -def _get_approval_mode() -> str:
      -    """Read the approval mode from config. Returns 'manual', 'smart', or 'off'."""
      +def _get_approval_config() -> dict:
      +    """Read the approvals config block. Returns a dict with 'mode', 'timeout', etc."""
           try:
               from hermes_cli.config import load_config
               config = load_config()
      -        mode = config.get("approvals", {}).get("mode", "manual")
      -        return _normalize_approval_mode(mode)
      +        return config.get("approvals", {}) or {}
           except Exception:
      -        return "manual"
      +        return {}
      +
      +
      +def _get_approval_mode() -> str:
      +    """Read the approval mode from config. Returns 'manual', 'smart', or 'off'."""
      +    mode = _get_approval_config().get("mode", "manual")
      +    return _normalize_approval_mode(mode)
      +
      +
      +def _get_approval_timeout() -> int:
      +    """Read the approval timeout from config. Defaults to 60 seconds."""
      +    try:
      +        return int(_get_approval_config().get("timeout", 60))
      +    except (ValueError, TypeError):
      +        return 60
       
       
       def _smart_approve(command: str, description: str) -> str:

4 PRs closed without merging

From the close comments: superseded by another PR 2 · duplicate 1 · merged via another change 1

  • #3766 ✨(approvals): make dangerous command approval timeout configurable · merged via another change → #3886
  • #63484 fix(acp): honor approvals.timeout config in ACP edit approval timeout · superseded by another PR
  • #63689 fix(acp): honor approvals.timeout config for edit approval timeout · superseded by another PR
  • #64030 fix(acp): honor approvals.timeout config in ACP edit approval prompt (#63302) · duplicate → #63308, #63302, #64030
Closed issues · 1
  • Closed#3765feat: make dangerous command approval timeout configurable
How this cluster was grouped
  • Link evidence (partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text.
  • Members outside that structural core may belong to a different underlying problem.
  • Pairwise link density 0.15: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Subsystem
acp
Merged PRs
#3886
Closed issues
1
Attempts
4 PRs closed without merging
Fix link checked
30 Mar 2026. This confirmation is old and may be out of date (a revert or reopen would not have invalidated it here); re-verify.

For your agent

The same facts, typed.