RUGitHubInstall

Native Telegram question previews

The Telegram channel records the message reference when the Telegram channel posts an input.requested question. After Eve emits its authoritative input.resolved event, the channel removes all choices and shows the accepted selection. This status does not claim that the subsequent business operation succeeded.

The reference and accepted display status are part of persisted channel state. If Telegram editing fails, the accepted answer remains accepted; only delivery happens again when the turn completes, starts, or enters session.waiting. No business operation is replayed. A definite Telegram 400 saying the message was deleted or cannot be edited retires its preview reference; there is nothing left to deliver there. Transient or ambiguous failures keep the accepted display status. One recovery pass shares the existing five-second edit deadline across text and keyboard removal. The first retained failure moves to the end and stops that pass, so a backlog cannot add five seconds per preview or repeatedly starve later accepted questions. No new queue, TTL or persisted redelivery fields are introduced. Rich previews are edited without their embedded button tags. Classic previews use an empty inline keyboard; if text editing fails, keyboard removal is attempted separately. UI delivery can still fail, so an old-looking preview is not evidence that its action is available. Existing unresolved questions from before this change have no recorded reference and cannot be retroactively edited.

Question text remains literal, including native ForceReply and long-message posting. For long classic questions the recorded first message owns the keyboard; adding a status can exceed Telegram’s text limit, in which case only keyboard removal may succeed. Once Telegram definitively rejects the status as too long and keyboard removal is confirmed, that preview reference is retired rather than retried forever. If keyboard removal is still uncertain, the reference remains recoverable. Freeform answers are never echoed in the status because they can contain credentials or personal data.

Eve 0.51.1 already produces input.resolved but does not expose it in the public channel-handler event list. Iva backports that exposure through the existing vendored eve sources. An upstream implementation should add the same event to Eve’s public channel definition and Telegram event types rather than mutate a compiled adapter at runtime. Normal question resolution still belongs to Eve.

Upstream already implemented public input.resolved exposure in vercel/eve#4028, commit 9c36b7c. Remove the three exposure edits from eve/ when the pinned Eve version exposes the public generic and Telegram event types and the adapter boundary test passes without them. Keep Iva’s question preview delivery: the upstream change exposes the event and does not implement that UI. The upstream 0.51.1 boundary test fails because Eve silently drops this handler. This is one channel mechanism for all providers, as required by ADR-0019.

The existing Compaction lifecycle (ADR-0021) keeps ownership of the chat. Normal turn completion still finishes its status and closes the Compaction turn even if preview delivery fails. On session.waiting, Eve’s Compaction request and claim happen before preview recovery. An edit cannot release that claim, repeat the request, or replay an accepted answer.

Group and forum rich questions update the same conversation anchor as Eve’s native post() and rekey through the public continuation operations using Eve’s exported telegramContinuationToken. This keeps a button’s callback attached to the session waiting for its answer. If public continuation routing is unavailable, groups use native posting. Private questions do not rekey.

Native posting preserves Eve’s formatting and ForceReply. Rich questions fall back to native posting only after a definite Bot API request rejection. Network failures, timeouts and missing message IDs do not trigger another post, because delivery may already have happened. Failed rich edits never switch to HTML or post a replacement: the old embedded buttons must be removed by editing that same rich message.

Adapted from @mamysh’s independent question-preview prototype in issue #272. Plugin-owned screens and the proposal in #274 are outside this change.

Reverting to released Iva requires no data migration. Additional channel-state fields are unused there, and automatic preview settling is unavailable again.

View original Markdown ↗