fix(plugins): re-enable pre_tool_call approve escalation with correct gateway notify path (#59201)#60544
Open
kyssta-exe wants to merge 2 commits into
Open
Conversation
added 2 commits
July 7, 2026 19:38
…search#60345) When a MoA reference model's context window is smaller than the conversation history sent to it (e.g. kimi-k2.7-code @ 262K tokens as reference, glm-5 @ 1M as aggregator), the reference call would fail with a hard HTTP 400 that _run_reference's try/except silently converts into a [failed: ...] label — degrading the MoA turn with no user-visible signal. This fix adds _fit_to_context_window(), which: 1. Looks up the reference model's context window via get_model_context_length 2. Estimates message token count (~4 chars/token) 3. If the estimate exceeds 90% of the window, drops the oldest non-system messages (preserving the system prompt and most recent conversation) 4. If even the last 3 messages + system prompt exceed the window, prepends a warning in the system prompt so the aggregator sees the reference was constrained The trimming mirrors what ContextCompressor does for the acting model's conversation, but applies specifically to the disposable advisory copy each reference sees — the acting aggregator's transcript is untouched. Fixes NousResearch#60345
… gateway notify path Restore the pre_tool_call plugin hook 'approve' directive (reverted in 9efc24a) with the critical gateway fix: plugin-triggered approvals now use _await_gateway_decision() instead of submit_pending(), so the notify callback fires and the approval request is visible to users on desktop and messaging gateways. Includes: - get_pre_tool_call_directive() returns (action, message) tuples for both 'block' and 'approve' directives - resolve_pre_tool_block() is the single dispatch chokepoint across all four tool-execution paths (model_tools, agent_runtime_helpers, tool_executor concurrent + sequential) - _run_approval_gate() extracted as shared human-approval core for both check_dangerous_command() and request_tool_approval() - request_tool_approval() escalates plugin-flagged tool calls through the same gate as Tier-2 dangerous commands - Gateway path in _run_approval_gate() now properly uses _await_gateway_decision() with the registered notify callback, resolving NousResearch#59201 where plugin approval prompts silently timed out on desktop/gateway because submit_pending() never emitted an approval.request event Closes NousResearch#59201
Collaborator
Duplicate of #60504 — that PR (merged 2026-07-07) already re-landed the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Re-enables the
pre_tool_callplugin hook"approve"directive (previously reverted) with the critical gateway fix: plugin-triggered approvals now use_await_gateway_decision()instead ofsubmit_pending(), so the notification callback fires and the approval request is visible to users on desktop and messaging gateways.Problem
When a plugin's
pre_tool_callhook returns{"action": "approve", "message": "..."}, the tool call requires human approval. On CLI this worked, but on desktop and gateway bridges, the approval was silently stored viasubmit_pending()with no notification emitted — the user never saw a prompt, the/approvecommand found nothing pending, and the tool call timed out after 300s.Root Cause
The original implementation in commit
f512d6f02(reverted in9efc24a61) routed the gateway branch throughsubmit_pending(), which only writes to a_pendingdict that nothing reads. The working command-guard path uses_await_gateway_decision()with the per-session notify callback (_gateway_notify_cbs) which emitsapproval.requestevents to the gateway event stream.This fix replaces
submit_pending()with_await_gateway_decision()in the shared_run_approval_gate()function, giving plugin-triggered approvals the same user-visible treatment as dangerous-command prompts.Changes
tools/approval.py: Added_run_approval_gate()— shared human-approval core extracted fromcheck_dangerous_command(), called by both command and plugin paths. Gateway branch uses_await_gateway_decision()with notify callback. Addedrequest_tool_approval()— entry point for plugin approve escalations.hermes_cli/plugins.py: Addedget_pre_tool_call_directive()returning(action, message)for both"block"and"approve"directives. Addedresolve_pre_tool_block()as the single dispatch chokepoint that invokes the human gate for"approve". Keptget_pre_tool_call_block_message()as back-compat shim.model_tools.py,agent/agent_runtime_helpers.py,agent/tool_executor.py: All four tool-dispatch sites now callresolve_pre_tool_block()instead ofget_pre_tool_call_block_message().Closes #59201