Quick Start
- CLI (No Code)
- Python SDK
Set Environment Variables
Start the Bot
praisonai bot linear, bot email, bot agentmail, bot webhook, and WhatsApp cloud mode now stay running correctly. Previously these non-blocking adapters exited 0 in about a second, so systemd Restart=on-failure never restarted them. The CLI now holds the loop open while the adapter reports is_running.(Optional) Custom Agent
Supported Platforms
Bot Runtimes (Bidirectional β Send + Receive)
Outbound Tools (Send-Only β Bot Runtime Coming Soon)
Durable Outbound Delivery β All Channels
config.outbound_resilience β the same config block applies to every adapter:
dlq_path, the adapter retries but never silently drops β it raises after exhausting attempts. With a dlq_path, a permanent failure parks the message to disk for manual inspection or replay.
Durable Delivery
_outbound_platform labels- Durable Delivery with
mark_recovered=True(opt-in) ββ»οΈ Recovered reply β the gateway restarted during delivery, so this may be a duplicate.See Durable Delivery. - Outbound DLQ boot recovery (on by default) β
β»οΈ Recovered after restart β this reply may be a duplicate.See Outbound Resilience β Automatic crash-recovery on start.
Inbound Media β Vision
Both WhatsApp and Telegram bots forward photos and documents directly to your agentβs vision capability. On Telegram, a media album is coalesced into a single turn β see Media Albums.attachments, the bot skips the file and forwards only the caption text. Text-only agents need zero changes.WhatsApp Inbound Media
max_inbound_media_bytes configBot Inbound Media
Outbound Media Delivery
How It Works
Wiring Button Clicks
Buttons and select menus rendered by your bot can be wired to your own async handlers β slash-command buttons work out of the box, and you can register custom namespaces for things like approvals, menus, or multi-step flows. Agents can also run a group vote with a poll block and get the aggregated tally back as a typedPollResult β see Poll Blocks.
See Interactive Bot Actions.
AIUI Dashboard Integration
When bots are connected through PraisonAI UI (praisonai chat), channel messages appear in the Chat dashboard with full visibility into agent processing steps β tool calls, reasoning, and intermediate responses stream in real-time.
What You See in the Dashboard
StreamEventEmitter used by the web chat, so channel messages get identical step visibility as messages typed directly in the dashboard.Smart Defaults
Bots ship with sensible defaults so you can start chatting immediately β no tool wiring required. Bothpraisonai bot start and praisonai gateway start apply the same defaults:
Opting out
auto_approve_tools used to default to False. If your bot relied on manual approval, set auto_approve_tools: false explicitly.ApprovalStore β late Allow/Deny taps still resolve after a deploy.Telegram-native durable approvals. On Telegram, setting Agent(approval="presentation") is enough β the bot auto-wires the durable backend to the chat on start and rehydrates pending approvals across restarts. See Telegram Durable Approval.Platform Awareness
Every bot automatically tells the agent which platform itβs on, what kind of chat itβs in, and which channels it can reach.inject_session_context=True on BotSessionManager. The agent receives a ## Session Context block in its system prompt each turn β for example: βYou are replying on telegram (group βProject Alphaβ) in thread 123. Reachable delivery targets: slack:home, team (slack:C0123).βTo suppress the visible block (context still flows to tools), set inject_session_context=False. See Platform-Aware Agents for the full configuration reference.Socket Mode vs Webhook
PraisonAI bots support two connection modes:Configuration Options
praisonai bot start? The same admission options apply in a single-bot bot.yaml (PR #5111):
- Default: Inline replies in the channel
- Auto-thread: Responses > 500 chars are automatically threaded
- Force thread: Set
reply_in_thread=Trueto always use threads
mention_onlyβ Bot only responds when @mentioned (default, safest)respond_allβ Bot responds to every message in the groupcommand_onlyβ Bot only responds to/commandsobserveβ Bot stays silent likemention_only, but keeps unmentioned group messages as passive context so it can answer with full awareness when next mentioned (Telegram only). Seeobserve: passive group context.
group_policy per channel in gateway.yaml. See Bot Gateway β Channel Security.[{sender}] attribution prefix, so a hostile name canβt masquerade as a fake system directive. See Sender Attribution Sanitisation for details.Access-check methods
BotConfig exposes two allowlist checks with distinct purposes:
is_explicitly_allowed() so a policy-allowed unknown user still gets pairing/deny semantics β PR #2856.CLI Capabilities
Enable powerful agent features directly from the command line:Memory
Knowledge/RAG
Skills
Extended Thinking
Full CLI Options Reference
Full CLI Options Reference
Platform Setup
- Telegram
- Discord
- Slack
- WhatsApp
- WhatsApp Web Mode
- Message @BotFather on Telegram
- Send
/newbotand follow prompts - Copy the bot token
Troubleshooting: Bot silently stops replying / 409 Conflict
Troubleshooting: Bot silently stops replying / 409 Conflict
telegram channel, Claw, or an orphaned process) is using the same token. Telegramβs getUpdates API allows only one active consumer per bot token, so every extra poller receives HTTP 409 Conflict.Fix.- Find and stop duplicate processes:
ps aux | grep -i praisonai | grep -v grep, thenkill <PID>. - Confirm no webhook is set:
curl "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getWebhookInfo". - Restart exactly one bot.
Bot Commands
Built-in commands available on all platforms:/automations and /blueprint for consent-first scheduled automations β see Automation Suggestions. Other adapters donβt register these yet.Common Patterns
- Restricted Access
- Webhook Mode
- Group Settings
CLI Commands
WhatsApp Message Filtering (Web Mode)
By default, WhatsApp Web mode responds only to self-chat messages β when you message your own number. This prevents the bot from replying to every conversation on your account, including messages you send in other peopleβs chats.CLI Flags
- Self-Only (Default)
- Allowed Numbers
- Allowed Groups
- Combined
- Respond to All
Python SDK
YAML Config
Filtering Behavior Matrix
+1-234-567-890, 1234567890, and (123) 456-7890 all match the same number. Group IDs use WhatsAppβs JID format (e.g., 120363123456@g.us).Stale message guard: Messages older than when the bot connected are always dropped, even with --respond-to-all. This prevents replaying old conversations on reconnect.Docker Deployment
Deploy bots using Docker for production environments:- Slack
- Discord
- Telegram
Production (Webhook Mode)
For production deployments with a public URL, use webhook mode instead of Socket Mode:- Slack
- Discord
- Telegram
- Event Subscriptions β Enable Events
- Set Request URL:
https://your-domain.com/slack/events - Subscribe to bot events:
app_mention,message.im
Multi-Channel Gateway
Run all bots simultaneously with a single gateway config: gateway.yaml:webhook_port unset and every mode: webhook channel serves behind one gateway URL at /webhooks/<channel> β no port collisions. See Shared Webhook Ingress.channels: (e.g. telegram, telegram_cfo) is just an identifier you choose. When the key is not a platform name, set platform: telegram (or whichever) inside the block so the gateway can pick the right protocol. This enables running multiple bots on the same platform. Note: bot.yaml requires channel keys to be platform names.
Bot() β agents get the same safe tools and auto-approval in both entry points.
Multiple bots on the same platform
For role-specific bots on the same platform (e.g., multiple Telegram bots), use this pattern:praisonai doctor.Zero-Code Mode (YAML Config)
Run a bot with a single YAML file β no Python code needed: bot.yaml:Tip: You can omittools:entirely β the bot auto-injects safe defaults (search_web, schedule, memory, learning). Keeptools: []only if you want the bot to run with zero tools.
Token is optional
Omittoken: entirely β the declared platform: resolves the platformβs own documented env var (for example TELEGRAM_BOT_TOKEN for Telegram, DISCORD_BOT_TOKEN for Discord):
The declared platform wins
Theplatform: you declare always wins. If other platform credentials happen to be exported in the environment, bot start refuses to auto-enable them behind your back and logs a warning naming each one it skipped:
Inbound Platform Events (opt-in)
Add anevents: list under a channel to hear reactions, edits, deletions, member changes, and thread creations β not just text.
reactionsβREACTION_RECEIVEDeditsβMESSAGE_EDITED+MESSAGE_DELETEDmembersβMEMBER_JOINED+MEMBER_LEFT(requires the privileged Discordmembersintent)threadsβTHREAD_CREATED
events: and nothing new is subscribed. Currently wired on the Discord adapter.
Inbound Platform Events
Registered but verb-less platforms β praisonai bot run
bot run starts any registered platform by name β including signal, webhook, local, entry-point plugin channels, and adapter: drop-ins that donβt have their own verb.
Local channel (REPL-style)
Signal via signal-cli-bridge
Generic webhook receiver
Plugin / drop-in channel
Flags
bot run (and bot start for platform: local, signal, webhook) forwards adapter-specific extras from the validated channel schema β such as the Webhook adapterβs verify signature verifier or Signalβs account / bridge_url. Previously the start path dropped these, silently replacing a configured Webhook verifier with the adapterβs unverified default.Which command should I use?
Bot startup exit codes
praisonai bot ... now exits 1 on any startup failure β bad config path, missing token, unknown platform, or adapter import failure:
systemd Restart=on-failure and shell if praisonai bot ... ; then scripting work as expected.
Token Types β When to Use What
Different platforms use different types of tokens. Hereβs when to use each:Telegram
Discord
Slack
bot.yaml shorthand, place app_token: at the top level β see Standalone Bot YAML.- Cloud API (default)
- Web Mode (experimental)
Best Practices
Secure your bot token
Secure your bot token
Use allowlists in production
Use allowlists in production
allowed_users and allowed_channels to prevent unauthorized access to your bot.Enable mention requirement for groups
Enable mention requirement for groups
mention_required=True to prevent the bot from responding to every message in group chats.Handle rate limits gracefully
Handle rate limits gracefully
Retry-After / retry_after automatically β both on live retries (deliver_with_retry) and on durable drains (OutboundQueue). To make the limiter widen the lane for the rest of your botβs concurrent sends, pass a shared RateLimiter into deliver_with_retry(rate_limiter=...). See Bot Rate Limiting and Durable Delivery.Safe default tools only
Safe default tools only
search_web, schedule_*, memory/learning). Tools like execute_command require explicit opt-in and should be paired with an approval backend. See Approval Protocol.Set approval flow for auto-approve disabled
Set approval flow for auto-approve disabled
auto_approve_tools: false if youβve wired a chat-level approval flow (e.g. SlackApproval). Otherwise tool calls will hang silently waiting for a CLI prompt the user cannot see.New: gateway does this for you
New: gateway does this for you
channels.<platform>.allow_shell: true with auto_approve_shell: false, the gateway now wires SlackApproval / TelegramApproval / DiscordApproval automatically β no Python glue required. And auto_approve_shell: true is automatically downgraded to the same wiring on externally-bound gateways or channels with a group_policy, unless auto_approve_shell_acknowledge_exposed: true opts in. See Bot Shell Execution.Multi-Agent Configuration
You can also define multiple agents in anagents.yaml file for complex workflows:
agents.yaml:
Inbound Message Debounce
When users send multiple rapid messages (e.g. βheyβ β βcan youβ β βsearch for AI newsβ), debounce coalesces them into a single agent call β saving tokens and preventing duplicate responses.- Python
- YAML
Smart Message Chunking
Long agent responses are split at paragraph boundaries while preserving code fences β no more broken code blocks mid-message.How splitting works
How splitting works
Paragraph boundaries
\n\n) first β keeps ideas together.Sentence boundaries
. ).Hard split
Code fence protection
Code fence protection
max_message_length. This ensures your users always see complete, copyable code.max_message_length in BotConfig to change the split threshold (default: 4096).length_unit="utf16"), matching Telegramβs own 4096 limit. An emoji counts as two units, so emoji- and CJK-heavy replies are chunked at the point Telegram actually enforces rather than being rejected as βmessage too longβ. See Reply Delivery.Session History
Bot agents automatically remember the last 20 messages per conversation β no extra dependencies required.- Automatic (default)
- Custom memory
Ack Reactions
Acknowledge inbound messages with an emoji reaction (e.g. β³) so users know the bot is processing, then swap to a done emoji (e.g. β ) when the response is sent.- Python
- YAML
Ack Scope
Control which inbound messages get acked so busy group channels arenβt flooded with β³ on ambient chatter the bot wonβt answer.- Small team DMs / 1:1 bots β default (
group-mentions) is fine. - Bot lives in a busy group and only answers when mentioned β keep the default; ambient traffic stays silent.
- Bot answers everything in the group β
group-all. - You want the pre-scope-gate behaviour back β
all. - You never want reactions β
off(equivalent toack_emoji="").
group-mentions or group_mentions) β unknown strings fall back to the group-mentions default. Use the dash form to match the YAML default.Long-Running Agent Feedback
RAG-enabled agents commonly take 20β30 seconds to answer (vector search + tool calls + LLM). PraisonAI Telegram bots give users continuous feedback throughout, with no extra code on your side.What the user sees
Why this matters
Session Reset Policy
Per-channel YAML policies automatically clear a userβs conversation history after idle time or at a scheduled hour β configured undersession.reset on each channel.
Bot Session Reset
Session Reaper
Automatically prune stale sessions to free memory on long-running bots. Sessions idle longer thansession_ttl seconds are reaped.
session_ttl: 0 (default) to disable automatic reaping.
You can also call bot._session.reap_stale(max_age_seconds) manually.YAML Configuration
Deploy bots entirely from YAML β including agent memory, tools, roles, and multi-platform config.- Full YAML
- Python loader
Supported agent fields
Supported agent fields
Environment variable syntax
Environment variable syntax
${ENV_VAR} in YAML values β resolved at load time.Tool Approval via Messaging
When your bot agent uses dangerous tools (e.g.execute_command), you can route approval requests to Slack:

