Skip to main content
Agents can return a MessagePresentation alongside their reply text β€” Telegram renders it as a native inline keyboard; other platforms fall back to plain text until their renderer is wired.
The user receives a reply with inline buttons; their tap sends the choice back as the next message.

Quick Start

1

Quick-Reply Buttons

The simplest way to add buttons β€” each tapped choice feeds the value back to the agent as the next user message:
2

Inline Keyboard with Callbacks

Full control over button appearance and callback data:
3

Use with an Agent and Telegram Bot


How It Works

The adapt_presentation() function runs a channel-agnostic adaptation pass before rendering: it truncates buttons to platform limits, degrades select menus to button rows when unsupported, and degrades web_app actions to URLs on channels without mini-app support.

Block Types


Action Types


Platform Support & Limits

Telegram Limits

Callback data is capped at 64 UTF-8 bytes (Telegram platform limit). callback_data values that exceed this are truncated at the UTF-8 byte boundary. For non-ASCII payloads this means fewer than 64 characters may be kept. Use short, ASCII-safe identifiers as callback values.

WhatsApp Limits

WhatsApp uses split caps: reply-button titles are capped at 20 chars while list-row titles allow 24. Reply-button message bodies cap at 1024 chars (vs 4096 for text and list bodies). Every reply/list-row id is capped at 256 chars (Cloud API limit).

Button Priorities

When more buttons are defined than the platform limit allows, the adaptation pass keeps the highest-priority buttons and drops the rest:

Best Practices

PresentationAction.reply(value) feeds the chosen value back directly as the user’s next message β€” your agent sees it as normal input without needing any callback handler.
Telegram’s 64-byte callback cap is measured in UTF-8 bytes. Emoji, CJK, or long UUIDs can exhaust the budget quickly. Use compact IDs (e.g. "approve:42") as callback payloads.
The captured presentation is popped after chat() in both streaming and non-streaming paths, so cancelling or returning never leaves stale buttons visible.
Call adapt_presentation(presentation, PresentationLimits.telegram()) before sending to preview which buttons survive the Telegram limit and how select menus are degraded. Use PresentationLimits.whatsapp(), .slack(), or .discord() to preview the other channels.

Approval Secure Backend

Durable approval buttons with actor authorisation

Bot Presentations

Overview of bot presentation capabilities

Interactive Bot Actions

Handling button taps and callbacks

Channel Capabilities

What each platform can render