Media Albums

Coalesce a Telegram media album into a single multimodal agent turn

Set one config knob and a Telegram media album — several photos or files sent together — becomes one multimodal agent turn instead of one turn per part.

Diagram

Media Album Coalescing

📷 Update 1

⏳ AlbumCoalescer

📷 Update 2

📷 Update 3

✅ Single Turn

A user taps three receipt photos, hits Send once, and the agent sees all three attachments in a single turn — so it can compare them.

python
from praisonaiagents import Agent
from praisonai.bots import Bot, BotConfig

agent = Agent(
    name="Receipt Reviewer",
    instructions="Compare the receipts the user sends and highlight the highest total.",
)

bot = Bot(
    "telegram",
    agent=agent,
    config=BotConfig(
        token="YOUR_BOT_TOKEN",
        metadata={"media_group_window_ms": 1200},  # enable album coalescing
    ),
)
bot.run()

Quick Start

  1. Enable album coalescing

    Set media_group_window_ms on BotConfig.metadata to switch coalescing on. 0 (the default) keeps every album part as its own turn.

    python
    from praisonaiagents import Agent
    from praisonai.bots import Bot, BotConfig
    
    agent = Agent(
        name="Receipt Reviewer",
        instructions="Compare the receipts the user sends.",
    )
    
    bot = Bot(
        "telegram",
        agent=agent,
        config=BotConfig(
            token="YOUR_BOT_TOKEN",
            metadata={"media_group_window_ms": 1200},  # 1200 ms silence = flush
        ),
    )
    bot.run()
  2. Tune the album size cap

    Add media_group_max to bound how many attachments buffer per album before a forced flush. The default (10) covers a full Telegram album.

    python
    bot = Bot(
        "telegram",
        agent=agent,
        config=BotConfig(
            token="YOUR_BOT_TOKEN",
            metadata={
                "media_group_window_ms": 1200,
                "media_group_max": 6,  # split larger albums into multiple turns
            },
        ),
    )
    bot.run()

How It Works

Telegram delivers each album part as its own update sharing one media_group_id. The coalescer buffers the parts and flushes them once, after a short window of silence.

Diagram
BotSessionManagerAlbumCoalescerTelegramBot.handle_messageTelegramUserBotSessionManagerAlbumCoalescerTelegramBot.handle_messageTelegramUserSend 3 photos (one album)Update 1 (media_group_id=X)collect(X, [p1])Update 2 (media_group_id=X)collect(X, [p2]) → NoneUpdate 3 (media_group_id=X)collect(X, [p3]) → NoneMergedAlbum([p1, p2, p3]) (owner only)chat(attachments=[p1, p2, p3])One reply over all three

Exactly one caller per group receives the MergedAlbum; sibling handle_message calls return None because their media was folded into the owner’s turn. A standalone (non-album) message has no media_group_id, so it returns its own parts immediately — no debounce added.

BehaviourResult
Album parts within windowMerged into one turn
Sibling updatesReturn None (already folded in)
Standalone messageReturns immediately, unaffected
media_group_max reachedForced flush, remaining parts start a new turn
Owning update cancelledBuffered temp files reclaimed via on_orphan

Configuration Options

Both knobs live on BotConfig.metadata (passthrough — there are no dedicated BotConfig fields).

KeyTypeDefaultDescription
media_group_window_msint0Debounce window in ms. 0 = feature off. 1200 covers Telegram’s inter-part gap.
media_group_maxint10Max attachments buffered per album. Once reached, flush is forced immediately (bounds latency and memory). A full Telegram album fits under the default; lower it only on purpose.

Common Patterns

Compare several images in one turn:

python
agent = Agent(
    name="Receipt Reviewer",
    instructions="Compare the receipts the user sends and highlight the highest total.",
)
# User: sends 3 receipt photos as one album, caption "which is highest?"
# Agent sees one turn with 3 attachments → "Receipt #2 has the highest total: $84.20."

Split very large albums into multiple turns by lowering the cap:

python
bot = Bot(
    "telegram",
    agent=agent,
    config=BotConfig(
        token="YOUR_BOT_TOKEN",
        metadata={"media_group_window_ms": 1200, "media_group_max": 4},
    ),
)
# An album of 9 photos is delivered as turns of 4, 4, then 1.
bot.run()

Best Practices

Start with 1200 ms

1200 ms covers Telegram’s typical inter-part gap. Raise it only if slow phones trickle parts across more than a second.

Keep media_group_max at the default

The default (10) fits a full Telegram album. Lower it only when you have a specific latency or memory target — doing so splits a single album across multiple turns.

The feature is opt-in

Clean deployments stay byte-for-byte unchanged until you set media_group_window_ms. Enabling it never affects existing behaviour for other message types.

Standalone media is unaffected

Single-photo messages have no media_group_id, so they return immediately with no added debounce — album coalescing only touches multi-part albums.


Related