Skip to main content
Bot platform adapters now ship in the praisonai-bot package. praisonai bot serve still works exactly as documented here; for a standalone install see praisonai-bot Migration.
Bot adapters forward inbound photos and documents to your agent’s vision capability — validated, size-capped, and SSRF-safe.
from praisonaiagents import Agent

agent = Agent(
    name="Assistant",
    instructions="Describe photos and documents users send in chat.",
)

agent.start("What is in this image?")
The user sends a photo or document in WhatsApp or Telegram; the bot validates the file and passes it to the agent vision model.

Quick Start

1

Simple — works with any vision model

No configuration needed. Point a vision-capable agent at your bot.
from praisonaiagents import Agent
from praisonai.bots import TelegramBot

agent = Agent(
    name="vision-assistant",
    instructions="Describe images and answer questions about them.",
    llm="gpt-4o",
)

bot = TelegramBot(token="your-telegram-bot-token", agent=agent)

import asyncio
asyncio.run(bot.start())
Send the bot a photo (with or without a caption). The agent sees the image and responds.
2

With size limit

Cap media size for public-facing bots to avoid processing large files.
from praisonaiagents import Agent
from praisonai.bots import WhatsAppBot
from praisonaiagents import BotConfig

agent = Agent(
    name="assistant",
    instructions="Help users with their images and questions.",
    llm="gpt-4o",
)

bot = WhatsAppBot(
    agent=agent,
    config=BotConfig(
        max_inbound_media_bytes=5 * 1024 * 1024,  # 5 MiB cap
    ),
)

import asyncio
asyncio.run(bot.start())
3

Disable inbound media

Set max_inbound_media_bytes=0 for text-only agents.
from praisonaiagents import Agent
from praisonai.bots import TelegramBot
from praisonaiagents import BotConfig

agent = Agent(name="text-only", instructions="Answer text questions only.")

bot = TelegramBot(
    token="your-token",
    agent=agent,
    config=BotConfig(max_inbound_media_bytes=0),
)

import asyncio
asyncio.run(bot.start())

How It Works

StepWhat happens
DownloadWhatsApp: fetches via Graph API by media id. Telegram: uses get_file()download_to_drive()
Size capFile rejected if size exceeds max_inbound_media_bytes. Default: 20 MiB
Magic-byte checkFile header bytes checked against declared content-type — prevents type confusion
SSRF guardURL must use http/https and resolve to a public IP — rejects loopback, link-local, and RFC-1918 ranges
ForwardValidated path passed to agent.chat(attachments=[path])

Platform Coverage

PlatformMedia typesCaption support
WhatsApp (Cloud API)Photos, documents✅ Caption forwarded as prompt
TelegramPhotos, all documents✅ Caption forwarded as prompt
Telegram registers a PHOTO | Document.ALL handler — both photos and any document type (PDF, DOCX, etc.) flow through the same validation pipeline.

Configuration

OptionTypeDefaultDescription
max_inbound_media_bytesint20971520Maximum file size in bytes. 0 = disable inbound media.
Set via BotConfig:
from praisonaiagents import BotConfig

config = BotConfig(
    max_inbound_media_bytes=10 * 1024 * 1024,  # 10 MiB
)
Or via YAML:
agent:
  name: vision-bot
  instructions: Describe images.
  llm: gpt-4o

platforms:
  telegram:
    token: ${TELEGRAM_BOT_TOKEN}
    max_inbound_media_bytes: 10485760  # 10 MiB

Common Patterns

Photo + question (most common)

The user sends a photo with a caption asking a question. The caption becomes the prompt; the image is the attachment.
User: [photo of a chart] → "What does this chart show?"
Agent: "The chart shows quarterly revenue growth from Q1 to Q4..."

Document analysis

Send a PDF or Word document. The agent reads the content via vision.
User: [report.pdf] → "Summarize the key findings"
Agent: "The report covers three main findings..."

Oversized file rejected

Files above max_inbound_media_bytes are silently dropped. Only the caption text is forwarded.
User: [50 MB video] → "Describe this"
Agent: (receives only "Describe this", no attachment)

Non-vision agent (backward compatible)

If agent.chat() does not accept attachments, the adapter skips the file gracefully.
agent = Agent(name="text-only", instructions="Answer text questions.")
# Agent chat() has no attachments parameter — attachments are skipped automatically

Best Practices

The default 20 MiB is generous. For public-facing bots, set 2–5 MiB to reduce processing time and storage use.
config = BotConfig(max_inbound_media_bytes=2 * 1024 * 1024)
If your agent doesn’t use vision, set max_inbound_media_bytes=0. Users still get a response — just from the caption text alone.
config = BotConfig(max_inbound_media_bytes=0)
The SSRF guard logs rejections at WARNING level. If you see unexpected rejections in production, check that the platform’s media CDN URLs resolve to public IPs.
WARNING: SSRF guard rejected URL: https://internal-cdn.example.com/...
Not all models support vision. Pass a vision-capable model to see image attachments.
agent = Agent(llm="gpt-4o")          # OpenAI vision
agent = Agent(llm="claude-3-7-sonnet-20250219")  # Anthropic vision
agent = Agent(llm="gemini/gemini-2.0-flash")      # Google vision

WhatsApp Bot

WhatsApp setup, Cloud API, Web mode, and message filtering

Messaging Bots

All supported platforms: Telegram, Discord, Slack, WhatsApp

Platform-Aware Agents

Session context, channel directory, and BotSessionManager parameters

Bot Streaming Replies

Live streaming responses for Telegram, Slack, and Discord