Skip to content

fix(approval): surface pending-approval state with explicit marker vi…#28000

Closed
LifeJiggy wants to merge 1 commit into
NousResearch:mainfrom
LifeJiggy:fix/tool-approval-pending-signal
Closed

fix(approval): surface pending-approval state with explicit marker vi…#28000
LifeJiggy wants to merge 1 commit into
NousResearch:mainfrom
LifeJiggy:fix/tool-approval-pending-signal

Conversation

@LifeJiggy

Copy link
Copy Markdown
Contributor

What does this PR do?

When a tool requires approval (e.g., write_file, patch on sensitive paths), the approval prompt fires asynchronously but the tool result returned to the LLM is indistinguishable from an empty success result. The LLM proceeds as if the action completed, leading to incorrect assumptions about filesystem state.

Add an explicit pending-approval marker in the tool result so the LLM can clearly see that the operation is awaiting user confirmation and has not yet taken effect.

Related Issue
Fixes #14806

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • tools/approval.py — Mark pending-approval state with explicit visible marker in tool result
  • tools/terminal_tool.py — Propagate pending-approval state through terminal tool results so the LLM sees the waiting state

How to Test

  1. Trigger a tool that requires approval (e.g., write to a sensitive path)
  2. Observe the tool result — it should contain a clear pending-approval indication
  3. Verify the LLM responds with a waiting message rather than proceeding as if the action completed

…sible to LLM

When a tool call requires user approval in the non-blocking gateway path,
the LLM previously received a result that was indistinguishable from a
failed tool call (exit_code=-1, error=message). The LLM could not tell
whether the tool was pending approval, had returned empty results, or had
failed silently — causing it to burn context on wrong hypotheses.

Fix changes the result format to include:
- status: pending_approval (clear state name)
- approval_pending: True (explicit boolean for LLMs to detect)
- error: cleared to empty string (removes misleading error signal)

This lets the LLM reason about approval latency vs actual errors,
short-circuiting the previous silent failure mode.

Fixes NousResearch#14806
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent loop, run_agent.py, prompt builder comp/tools Tool registry, model_tools, toolsets labels May 18, 2026
@BoardJames-Bot

Copy link
Copy Markdown

BoardJames triage: this looks shared/systemic rather than branch-local. All non-test checks are green (including both Docker builds); the only blocker is the full Tests / test job cancelling after ~20m with no failed-log details, matching the current shared full-suite timeout/cancellation pattern. Local smoke on the changed files passed: python -m py_compile tools/approval.py tools/terminal_tool.py. Next action is shared CI/main unblock + rerun, not an approval-status branch fix.

@outsourc-e outsourc-e left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not merge-ready as submitted.

The new pending_approval status breaks an existing fallback contract: tests/gateway/test_approve_deny_commands.py::TestFallbackNoCallback::test_no_callback_returns_approval_required now fails because the no-callback path used to return approval_required and now returns pending_approval.

Local repro:

  • scripts/run_tests.sh tests/gateway/test_approve_deny_commands.py -k "approval_required or callback" tests/tools/test_cron_approval_mode.py
  • Fails on assert result.get("status") == "approval_required"

So either the compatibility path needs to stay approval_required, or the broader gateway/tests/callers need to be updated in a coordinated change.

@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #28323 (cherry-picked onto current main with your authorship preserved via rebase-merge — commit 6d495d9). Thanks for the contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent loop, run_agent.py, prompt builder comp/tools Tool registry, model_tools, toolsets P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tool-approval pending state is invisible to the LLM — indistinguishable from "executed + empty result"

5 participants