You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds first-class approval support to the API Server /v1/runs control plane so Web UI clients can surface and resolve dangerous-command approval gates without scraping assistant text or sending /approve as a normal chat message.
Changes:
Emits structured approval.request events on GET /v1/runs/{run_id}/events
Adds POST /v1/runs/{run_id}/approval for once | session | always | deny
Emits approval.responded after successful resolution
Advertises approval support in /v1/capabilities
Binds API runs into the existing approval/session context using contextvars rather than process-global env mutation
Cleans up approval callbacks/session mappings on completion, stop/cancel, and orphan sweep
Adds regression tests for request event + response unblocking and no-pending response handling
Without an API-level approval event/response path, WUI cannot reliably know that an approval is pending or unblock the in-flight run. DOM-scanning or sending /approve as chat text is brittle and targets the wrong control plane.
Related: #6059 (open PR) addresses the same issue (#15802) with a similar approach. This PR appears to supersede #6059 with a more complete implementation (contextvar-based binding, cleanup on stop/cancel, capabilities endpoint).
Salvaged onto current main via PR #21899 (#21899), merged as commit 839cdd1. Your commit was cherry-picked with authorship preserved via rebase-merge — git log shows you as the author of feat(api-server): expose run approval events.
Added one follow-up commit on top: the new _is_gateway_approval_context() widened the gateway classification to any call with HERMES_SESSION_PLATFORM bound via contextvars, but cron/scheduler.py binds that same contextvar for delivery routing on cron jobs that originate from a gateway platform. That would route cron-from-telegram/discord/etc. through submit_pending with no listener, hanging the job instead of honoring approvals.cron_mode. Short-circuited on HERMES_CRON_SESSION before the gateway check and added regression coverage in TestCronWithGatewayOrigin.
Thanks for this — clean mirror of the run.py / telegram / discord pattern, and the contextvar-based approach was exactly right for concurrent API runs.
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
comp/gatewayGateway runner, session dispatch, deliveryP2Medium — degraded but workaround existstype/featureNew feature or request
3 participants
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
Adds first-class approval support to the API Server
/v1/runscontrol plane so Web UI clients can surface and resolve dangerous-command approval gates without scraping assistant text or sending/approveas a normal chat message.Changes:
approval.requestevents onGET /v1/runs/{run_id}/eventsPOST /v1/runs/{run_id}/approvalforonce | session | always | denyapproval.respondedafter successful resolution/v1/capabilitiesWhy
Downstream WUI issue: EKKOLearnAI/hermes-studio#368
The Web UI path uses:
POST /v1/runsGET /v1/runs/{run_id}/eventsWithout an API-level approval event/response path, WUI cannot reliably know that an approval is pending or unblock the in-flight run. DOM-scanning or sending
/approveas chat text is brittle and targets the wrong control plane.Fixes #15802
API shape
Approval request event:
{ "event": "approval.request", "run_id": "run_...", "timestamp": 1234567890.0, "command": "...", "pattern_key": "...", "pattern_keys": ["..."], "description": "...", "choices": ["once", "session", "always", "deny"] }Approval response:
{ "choice": "once", "all": false }Successful response:
{ "object": "hermes.run.approval_response", "run_id": "run_...", "choice": "once", "resolved": 1 }Tests
Targeted suite:
scripts/run_tests.sh tests/gateway/test_api_server.py tests/gateway/test_api_server_runs.py tests/gateway/test_api_server_toolset.py tests/gateway/test_api_server_jobs.py tests/gateway/test_api_server_bind_guard.py tests/gateway/test_api_server_multimodal.py tests/gateway/test_api_server_normalize.py tests/tools/test_approval.py tests/tools/test_approval_heartbeat.py tests/acp/test_approval_isolation.py -o 'addopts=' -qResult: