23036e20a6
Squashed integration of the user-facing message audit for this surface set. Full per-finding receipts: /tmp/ux-audit/lanes/*-receipt.md (campaign artifacts).
44 lines
2.0 KiB
Python
44 lines
2.0 KiB
Python
"""Shared wording for the exec-approval prompt every messaging surface renders.
|
|
|
|
The button card (``BasePlatformAdapter._format_exec_approval``) and the plain-text
|
|
``/approve`` fallback (``gateway.run._format_exec_approval_fallback``) must tell the user
|
|
the same three things: what Hermes wants to run, why it was flagged, and that silence means
|
|
the command does NOT run once ``approvals.timeout`` elapses. Keeping the text here means one
|
|
edit changes every platform; adapters only wrap these strings in their own markup.
|
|
|
|
No imports from ``gateway.platforms.base`` or ``gateway.run`` — both import this module.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
# Bare strings; adapters add their own bold/HTML around them.
|
|
EA_HEADER_TEXT = "Hermes wants to run a command that needs your OK"
|
|
EA_REASON_LABEL_TEXT = "Why it was flagged"
|
|
|
|
# Timeout notice posted when nobody answered the prompt (``{window}`` = "5 minutes").
|
|
APPROVAL_TIMED_OUT_NOTICE = (
|
|
"⌛ Approval timed out after {window} — the command was NOT run. "
|
|
"Ask me to try again if you still want it, or raise approvals.timeout in config.yaml.")
|
|
|
|
|
|
def approval_timeout_seconds() -> int:
|
|
"""The configured ``approvals.timeout`` (default 300s); module attribute so tests can pin it."""
|
|
from tools.approval_context import _get_approval_timeout
|
|
return _get_approval_timeout()
|
|
|
|
|
|
def format_approval_window(seconds: int) -> str:
|
|
"""Human wording for a timeout (300 → "5 minutes"); one formatter shared with the CLI notice and
|
|
the tool result's ``user_summary`` — see ``tools.approval_context.format_approval_window``."""
|
|
from tools.approval_context import format_approval_window as _shared
|
|
return _shared(seconds)
|
|
|
|
|
|
def format_approval_deadline_line(timeout_s: int) -> str:
|
|
"""The last line of every approval prompt: doing nothing is a safe no."""
|
|
return f"If you don't answer within {format_approval_window(timeout_s)} it will NOT run."
|
|
|
|
|
|
def format_approval_timed_out_notice(timeout_s: int) -> str:
|
|
return APPROVAL_TIMED_OUT_NOTICE.format(window=format_approval_window(timeout_s))
|