TypeScript
What reply() does
conversation.reply(input) accepts a string, a kind object (basic, buttons, …), a list of them, or a stream. With a stream it:
- Shows the typing indicator, and keeps showing it (channels clear it after a few seconds).
- Reads text out of the stream as it arrives.
- Cuts a bubble at each natural break (below) and sends it while the model is still writing. Bubbles go out in order.
- Stops refreshing typing when the stream ends, even if it failed. Typing has no “off”: it clears itself when the next message goes or after a few seconds.
Each bubble is a
basic message, sent exactly as written: no markdown is rendered or stripped. Ask the model for plain text, or style text yourself in a kind object with a channel block (telegram.parse_mode, imessage.styles).
The bubble rule (for any language)
Without the SDK, apply this rule to the model’s text and send each bubble as a basic message (POST /v0/conversations/{conversation_id}/basic with {"text": ...}), one after another, showing typing (POST .../typing with {}) before you start and every 4 seconds until you finish.
- A bubble ends at a paragraph break (a blank line), except after a lead-in line that ends with
:and between items of one list, unless the bubble is already past the channel’s soft length. - Past the soft length, a bubble ends at the next sentence end (
.,!,?or…followed by a space). - Never cut inside a fenced code block, unless the bubble would pass the channel’s hard limit; then cut at the last line break or space before it.
Use the event’s ID plus the bubble’s index as each send’s
Idempotency-Key (evt_...:0, evt_...:1), so retrying a failed reply never sends a bubble twice.
Showing work while the agent thinks
For tool calls, retrieval or anything slow before the first word:Related
- Message kinds: typing, read receipts and text styles per channel.
- Agent frameworks: full examples per framework.