fix(computer_use): resolve gateway session-key namespace in permission-mode lookup

Follow-up to the #68246 salvage. The backend permission-mode resolution
only checked the DB session_id the tool path passes, but gateway /yolo
keys approval bypass off the gateway session_key (contextvar). Consult
both namespaces so /yolo works on messaging platforms, not just CLI/TUI.
Adds a regression test driving the real approval contextvar + yolo
toggle path E2E.
This commit is contained in:
Teknium
2026-07-29 08:47:34 -07:00
parent d59974fea5
commit 8714040954
2 changed files with 39 additions and 1 deletions
@@ -37,6 +37,29 @@ def test_any_explicit_hermes_bypass_maps_to_unrestricted_mode():
assert computer_use._cua_permission_mode("session-a") == "unrestricted"
def test_gateway_session_key_yolo_maps_to_unrestricted_mode():
"""Gateway /yolo keys bypass off the gateway session_key contextvar,
not the DB session_id the tool path passes. Mode resolution must consult
both namespaces or /yolo is silently dead on messaging platforms."""
from tools import approval
from tools.computer_use import tool as computer_use
gateway_key = "agent:main:telegram:private:12345"
token = approval.set_current_session_key(gateway_key)
try:
approval.enable_session_yolo(gateway_key)
# Tool dispatch passes the (different) DB session id.
assert computer_use._cua_permission_mode("db-sid-xyz") == "unrestricted"
approval.disable_session_yolo(gateway_key)
assert computer_use._cua_permission_mode("db-sid-xyz") == "standard"
finally:
approval.disable_session_yolo(gateway_key)
try:
approval.reset_current_session_key(token)
except Exception:
approval.set_current_session_key("")
def test_mode_change_replaces_only_that_sessions_backend():
from tools.computer_use import tool as computer_use
+16 -1
View File
@@ -169,14 +169,29 @@ _always_allow: Dict[str, set] = {}
def _cua_permission_mode(session_id: str) -> str:
"""Map Hermes's explicit approval bypass onto Cua's immutable mode."""
"""Map Hermes's explicit approval bypass onto Cua's immutable mode.
Hermes has TWO session-identity namespaces: the tool-dispatch path passes
the DB ``session_id`` (``agent.session_id``), while gateway ``/yolo``
keys approval state off the gateway ``session_key`` (set per turn via the
``set_current_session_key`` contextvar in tools/approval.py). CLI and TUI
use the DB id for both. Checking ONLY ``session_id`` here would make a
gateway ``/yolo`` toggle silently invisible to computer_use (works in
CLI, dead on messaging platforms), so we consult both namespaces —
bypass in either means the user explicitly opted out of approvals for
this run. Fails closed on any resolution error.
"""
try:
from tools.approval import (
get_current_session_key,
is_approval_bypass_active_for_session,
)
if is_approval_bypass_active_for_session(session_id):
return "unrestricted"
current_key = get_current_session_key(default="")
if current_key and is_approval_bypass_active_for_session(current_key):
return "unrestricted"
except Exception:
# Approval state must fail closed if it cannot be resolved.
pass