From fffa66122345e87a23fb4ba4266ea4dce3181cd3 Mon Sep 17 00:00:00 2001 From: Ben Barclay Date: Sun, 26 Jul 2026 07:57:39 +1000 Subject: [PATCH] =?UTF-8?q?feat(relay):=20Phase=203=20interactive=20?= =?UTF-8?q?=E2=80=94=20native=20prompt=20UX=20(approvals/confirms/clarify)?= =?UTF-8?q?=20+=20react=20ack=20lifecycle=20(#71404)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - RelayAdapter.send_exec_approval / send_slash_confirm / send_clarify: override the base text fallbacks with ONE platform-abstract `prompt` op (connector renders Discord components / Telegram inline keyboards / Slack Block Kit / WhatsApp buttons+lists). Option sets mirror the native adapters exactly (once/session/always/deny with the same allow_session/allow_permanent/smart_denied gating; once/always/cancel; choices + Other). Clarify option ids are positional (c0..cN/other) — choice text is arbitrary UTF-8, callback budgets are 64 bytes. - Pending-prompt registry: gateway-minted 8-hex prompt ids → {kind, session_key, extras}; one answer wins, lazy expiry, unanswered prompts swept opportunistically. Wire timeout_s stays advisory. - _consume_prompt_response (wired into _on_inbound AND the Discord passthrough lane): routes answers to the SAME primitives the native button handlers call — tools.approval.resolve_gateway_approval, tools.slash_confirm.resolve, tools.clarify_gateway resolve/mark_awaiting_text — then acks in-channel. Unknown/expired ids fall through as command-shaped text (typed-reply degradation, the relay's analog of the native 'approval expired' edit). - Discord type-3 stub replaced: an hp1::