diff --git a/tests/tools/test_approval_plugin_hooks.py b/tests/tools/test_approval_plugin_hooks.py index 605306f5cb..92f5bb96d7 100644 --- a/tests/tools/test_approval_plugin_hooks.py +++ b/tests/tools/test_approval_plugin_hooks.py @@ -378,9 +378,8 @@ class TestClassicCliPromptsFireGatewayTwinHooks: approval_module.unregister_gateway_notify(isolated_session) assert result == approved - # Classic CLI: the panel callback (protected write) or stdin (consent) answers "once". + # Classic CLI: the prompt_toolkit panel callback registered on the agent thread answers "once". monkeypatch.delenv("HERMES_GATEWAY_SESSION") - monkeypatch.setattr("builtins.input", lambda _prompt="": "o") set_approval_callback(lambda *_a, **_kw: "once") try: result, cli_hooks = _capture_hooks(run) diff --git a/tools/approval_prompt.py b/tools/approval_prompt.py index bb6915363f..decd2b18f2 100644 --- a/tools/approval_prompt.py +++ b/tools/approval_prompt.py @@ -326,7 +326,6 @@ def request_elicitation_consent(message: str, description: str, *, return "cancel" # nobody answered (timeout / prompt withdrawn) — not a user refusal return _consent(decision.get("choice"), "decline") - # allow_permanent=False: elicitation is a per-call confirmation — no pattern to remember. # Same observer payload as the gateway branch (#131876); post fires in a finally so the # wait settles for observers on the early fail-closed return too. hook_kwargs = dict(command=message, description=description, pattern_key="mcp_elicitation", @@ -334,8 +333,12 @@ def request_elicitation_consent(message: str, description: str, *, _ctx._fire_approval_hook("pre_approval_request", **hook_kwargs) hook_choice = "cancelled" try: + from tools.terminal_tool import _get_approval_callback + # allow_permanent=False: elicitation is a per-call confirmation — no pattern to remember. + # Pass the agent thread's panel callback: without it prompt_toolkit fails the prompt closed unseen. choice = prompt_dangerous_approval(message, description, timeout_seconds=timeout_seconds, - allow_permanent=False, title=title) + allow_permanent=False, title=title, + approval_callback=_get_approval_callback()) hook_choice = choice except Exception as exc: logger.error("Elicitation CLI prompt failed: %s", exc, exc_info=True)