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.
On Telegram and Discord, every command below appears in the native / autocomplete menu automatically. See Slash Command Menu.
from praisonaiagents import Agent

agent = Agent(name="assistant", instructions="You are a helpful assistant.")
agent.start("What commands are available?")
The user types a slash command in chat; the bot runs built-in handlers for status, model, usage, and session control.

Command Picker

Every PraisonAI bot comes with built-in chat commands. Just type a command in your chat — no setup required.

Built-in Commands

/status

Shows agent name, model, platform, and uptime.

/new

Resets the conversation session. Starts a fresh chat with the agent.

/stop

Cancels the current agent task. Requires run control to be enabled.

/sethome

Mark this chat as the platform home channel for scheduled deliveries.

/help

Lists all available commands (built-in + custom) with descriptions. Output is filtered to commands the caller is allowed to run.

/whoami

Shows your user ID, role, and the commands you are allowed to run.

/model

Switch the LLM model for this conversation (session-scoped).

/usage

Show token usage and estimated cost for this session.

/compress

Summarise older messages to free context window space.

/queue

Queue a follow-up message to run after the current task.

/learn

Distil a grounded skill from sources you describe (repo, docs, PDFs, or this chat). Privileged — admin-only by default when a policy is configured. Authored via skill_manage with the same approval gate as other agent-created skills. See Learn a Skill from Sources and Command Access Control.

/undo

Undo the last turn’s file changes. Requires the agent to track changes (autonomy with track_changes).

/sessions

List the caller’s saved sessions/checkpoints. Scoped to the requesting user — never enumerates other users’ sessions.

/resume

Switch to a saved session: /resume <id>. Use /sessions to list available IDs.

/retry

Re-run your last message through the normal chat path.

/reasoning

Toggle whether extended-thinking output is shown in this conversation (per user).

Per-Command Access Control

Restrict which commands each user may run with admin_users and user_allowed_commands on Telegram, Slack, and Discord — admins get full access, regular users only run commands you list. All built-in commands, including the new runtime controls, are gated by this policy.

Command Access Control

Admin users, per-command allowlists, and /whoami

Quick Start

1

Install PraisonAI

pip install praisonai
2

Set Your Bot Token

export TELEGRAM_BOT_TOKEN=your_token_here
3

Start the Bot

praisonai bot telegram --token $TELEGRAM_BOT_TOKEN
4

Send a Command

Open your bot chat and type:
/status
You’ll see the agent name, model, platform, and uptime.

Platform Examples

praisonai bot telegram --token $TELEGRAM_BOT_TOKEN
praisonai bot discord --token $DISCORD_BOT_TOKEN
praisonai bot slack --token $SLACK_BOT_TOKEN --app-token $SLACK_APP_TOKEN
Voice notes are transcribed automatically — see Voice Notes.

Command Details

/status

Shows current bot information:
FieldDescription
AgentName of the AI agent
ModelLLM model being used
Platformtelegram, discord, slack, or whatsapp
UptimeHow long the bot has been running
RunningWhether the bot is currently active

/whoami

Shows permission information for the caller:
FieldDescription
User IDPlatform-native user ID
UsernameDisplay name when available
RoleAdmin or User
Allowed commandsCommands this user may run
Example output:
User Information
User ID: 456
Username: alice
Role: User
Allowed commands: help, status, whoami

/new

Resets the conversation:
  • Clears all previous messages from the agent’s session
  • Replies with a confirmation message
  • Next message starts a completely new conversation

/stop

Cancels the current agent task immediately:
  • Immediately interrupts the current agent processing
  • Clears any pending messages in the queue
  • Replies with confirmation that the task was cancelled
  • Next message starts a fresh task
/stop works out of the box on any bot using the default BotSessionManager — Telegram, Discord, Slack, and WhatsApp all register it. Enabling Bot Run Control with busy_mode adds mid-run interruption plus pending-message handling on top of basic cancellation.

/sethome

Mark this chat as the platform’s home channel for scheduled deliveries. Jobs using --deliver <platform> or --deliver all land here. Persists to ~/.praisonai/state/home_channels.json. See Proactive Delivery.

/help

Lists all available commands — both built-in and custom — with their descriptions.
Commands work the same way on all platforms — Telegram, Discord, Slack, and WhatsApp. The / prefix is the default command prefix.

/model

Switches the LLM model for your conversation, or reports which model is currently active. Show current model/model with no argument:
Current model: gpt-4o-mini
Use /model <name> to switch (e.g., /model gpt-4o)
Switch model/model <name>:
/model gpt-4o
✅ Model switched to gpt-4o for this conversation.
Restart-required guard — when the gateway’s code on disk has changed since the process started (e.g. you ran git pull or pip install -U against the running checkout), /model <name> refuses the switch instead of risking a half-loaded module:
/model gpt-4o
⚠️ Gateway code changed on disk since it started (2aa28d1 → def5678). Restart the gateway to apply updates before switching models.
Restart the gateway/bot process and try again. The check is best-effort: when the fingerprint can’t be determined (no git checkout, unreadable files) the switch proceeds normally. To disable the guard (e.g. on a sandboxed CI runner where in-place updates are deliberate):
session_manager.code_skew_guard = False
The override is scoped to your conversation only — other users keep their own model. On each turn the original model is restored after your message is processed, so a shared agent never leaks one user’s model to another concurrent user.
Code-skew guard. After an in-place update (git pull / pip install -U), /model detects that the running gateway code differs from the installed code and replies with a “restart required” message instead of switching the model. This prevents stale-code model switches that could produce inconsistent behaviour.To disable the guard (e.g. in development):
session_manager.code_skew_guard = False
Power users can also call the guard helpers directly:
from praisonaiagents.gateway import detect_code_skew, read_code_fingerprint

fingerprint = read_code_fingerprint()
skewed = detect_code_skew(fingerprint)

/usage

Reports token usage and a rough estimated cost for the session.
FieldDescription
TotalTotal tokens used in the session
PromptTokens spent on prompts (when tracked)
CompletionTokens generated by the model (when tracked)
Est. costApproximate cost using a flat per-token rate — not model-specific
Example output:
📊 Token Usage
Total: 18,204 tokens
Prompt: 12,800 | Completion: 5,404
Est. cost: $0.0036
The cost estimate uses a flat $0.00002 / token rate — it is not model-specific pricing. Treat it as a rough order-of-magnitude guide, not a billing figure.

/compress

Compresses your conversation history to free context-window space.
  • Requires at least 10 messages — shorter histories get: "ℹ️ Conversation too short to compress (need at least 10 messages)."
  • Targets ~50% token reduction, always preserving the most recent 10 messages and all system messages
  • Reports messages removed and tokens freed:
✅ Compressed 32 messages, freed ~12,400 tokens.
  • If the context optimizer library is unavailable, falls back to keeping system messages and the last 10 messages
  • On failure the history is left untouched: "❌ Compression failed: {error}"
Run /compress before a long research task to reclaim context window space without losing your conversation thread.

/queue

Adds a follow-up message that runs after the current task completes. Check pending queue/queue with no argument:
📝 Pending follow-up: summarise the key findings
Or if nothing is pending:
No follow-up queued. Use /queue <message> to add one while a task is running.
Queue a message — three possible outcomes depending on bot state:
OutcomeWhenBot reply
Nothing to queueNo task running"ℹ️ No task is currently running, so there's nothing to queue behind. Send your message normally to run it now."
MergedTask running, message parked in pending slot"⏳ Added to your pending follow-up — it will run after the current task completes."
SteeredTask running, message injected as live guidance"🧭 Injected into the running task as live guidance."
/queue requires Bot Run Control to be enabled with busy_mode. Without it, the bot replies: "ℹ️ Message queuing isn't enabled for this bot. Just send your message and it will be processed."

/undo

Rewinds the last turn’s file changes via Agent.undo().
  • Requires change tracking — enable autonomy with track_changes on the agent
  • Returns "✅ Reverted the last turn." when files were restored, "ℹ️ Nothing to undo." when there is nothing to revert
  • Degrades gracefully when undo is unavailable: "❌ This agent does not support undo (change tracking not enabled)."

/sessions

Lists recent saved sessions for the requesting user only. Session lookups are scoped via the per-user storage key so one caller cannot enumerate another user’s sessions. Example output:
📁 Recent sessions:
• telegram:123456789
• telegram:123456789:project-a

Use /resume <id> to switch to one.
Returns "No saved sessions yet." when nothing is stored.

/resume

Switches to a previously saved session.
/resume telegram:123456789:project-a
✅ Resumed session telegram:123456789:project-a.
  • Usage: /resume <id> — run /sessions first to see IDs
  • Returns "❌ Session {id} not found." when the ID is unknown
  • When the session manager lacks a resume_session primitive, the bot reports honestly rather than claiming a switch succeeded

/retry

Re-runs your most recent user message through the normal session.chat(...) path.
🔁 Retrying your last message:
Summarise the deployment runbook in three bullets.
Returns "ℹ️ Nothing to retry — no previous message found." when the history is empty.

/reasoning

Toggles whether extended-thinking output is shown for this user in this conversation. The preference is stored per user on the session manager.
/reasoning
🧠 Reasoning output will be shown for this conversation.
Run again to hide:
/reasoning
🙈 Reasoning output will be hidden for this conversation.
Defaults to hidden when no preference is set. Adapters consult is_reasoning_visible() when rendering responses.

/learn

Authors a grounded, reusable SKILL.md from sources you name — a codebase, API docs, PDFs, configs, or the current chat.
/learn deploy steps from this repo and the runbook PDF
  • Calls agent.learn_skill(request) which gathers the named sources with the agent’s existing tools and writes one grounded SKILL.md via skill_manage
  • Admin-only by default when a CommandAccessPolicy is configured (admin_users or user_allowed_commands set) — it belongs to PRIVILEGED_COMMANDS because it reads host sources and alters future agent behaviour
  • Available to all users when no policy is configured (backward-compatible)

Learn Skill

Full guide: sources, grounding rules, async API, bot usage

Custom Commands

Register your own commands using register_command(). Available on all bot adapters.
from praisonai.bots import TelegramBot
from praisonaiagents import Agent

agent = Agent(name="assistant", instructions="Be helpful")
bot = TelegramBot(token="YOUR_TOKEN", agent=agent)

# Register a custom command
async def handle_ping(message):
    return "Pong! Bot is alive."

bot.register_command("ping", handle_ping, description="Check if bot is alive")

import asyncio
asyncio.run(bot.start())
# Now /ping is available alongside /status, /new, /stop, /help

register_command() API

bot.register_command(
    name="mycommand",           # Command name (without /)
    handler=my_handler,          # Async or sync callable
    description="What it does",  # Shown in /help
    usage="/mycommand <arg>",    # Optional usage string
    channels=["telegram"],       # Optional: restrict to specific platforms
)
ParameterTypeRequiredDescription
namestrYesCommand name without / prefix
handlerCallableYesFunction to call. Receives a BotMessage argument
descriptionstrNoHuman-readable description (shown in /help)
usagestrNoUsage example string
channelslist[str]NoRestrict to specific platforms (e.g., ["telegram", "slack"]). Empty = all platforms
The description you pass here IS the label users see in the native / menu on Telegram and Discord. See Slash Command Menu.

list_commands()

Get all registered commands:
commands = bot.list_commands()
# Returns: [ChatCommandInfo(name="status", ...), ChatCommandInfo(name="new", ...), ...]

# Filter by platform
telegram_commands = bot.list_commands(platform="telegram")

Security & Allowlists

Built-in commands (/status, /new, /help) and custom commands registered via register_command() go through the same security pipeline as regular text messages. If allowed_users is set and the sender is not in it, the command is silently dropped with no reply. If unknown_user_policy="pair", unknown senders get the pairing flow before the command runs. If group_policy="mention_only", commands in groups still need a mention.
from praisonai.bots import TelegramBot
from praisonaiagents import BotConfig
from praisonaiagents import Agent

agent = Agent(name="assistant", instructions="Be helpful")
bot = TelegramBot(
    token="YOUR_TOKEN",
    agent=agent,
    config=BotConfig(allowed_users=["123456789"]),  # Only this user
)

# /help, /status, /new from any other user are now silently ignored
For full allowlist setup, see the Bot Security guide. This security hardening was implemented in PR #1835.

Python Usage

Start bots programmatically — built-in commands are always available:
from praisonai.bots import TelegramBot
from praisonaiagents import Agent

agent = Agent(name="assistant", instructions="Be helpful")
bot = TelegramBot(token="YOUR_TOKEN", agent=agent)

import asyncio
asyncio.run(bot.start())
# /status, /new, /stop, /model, /usage, /compress, /queue, /help available automatically
from praisonai.bots import DiscordBot
from praisonaiagents import Agent

agent = Agent(name="assistant", instructions="Be helpful")
bot = DiscordBot(token="YOUR_TOKEN", agent=agent)

import asyncio
asyncio.run(bot.start())
from praisonai.bots import SlackBot
from praisonaiagents import Agent

agent = Agent(name="assistant", instructions="Be helpful")
bot = SlackBot(token="YOUR_TOKEN", app_token="YOUR_APP_TOKEN", agent=agent)

import asyncio
asyncio.run(bot.start())
from praisonai.bots import WhatsAppBot
from praisonaiagents import Agent

agent = Agent(name="assistant", instructions="Be helpful")
bot = WhatsAppBot(mode="web", agent=agent)
# /stop, /status, /new, /help registered automatically

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

Native / Autocomplete (Telegram + Discord)

Typing / in Telegram or Discord surfaces the bot’s commands with descriptions through each platform’s native menu — no configuration needed. The bot publishes the menu automatically on startup — no user code required:
from praisonai.bots import TelegramBot
from praisonaiagents import Agent

agent = Agent(name="Support", instructions="Answer customer questions.")
bot = TelegramBot(token="YOUR_TOKEN", agent=agent)

import asyncio
asyncio.run(bot.start())  # /-menu appears in Telegram automatically
Custom commands flow through the same registry, so they appear alongside the built-ins on the next restart:
from praisonai.bots import TelegramBot
from praisonaiagents import Agent

agent = Agent(name="Support", instructions="Answer customer questions.")
bot = TelegramBot(token="YOUR_TOKEN", agent=agent)

async def summary(message):
    return "Latest summary..."

bot.register_command("summary", summary, description="Get the latest summary")

import asyncio
asyncio.run(bot.start())  # /summary appears alongside /status, /model, /usage in the / menu

Design Guarantees

The menu is a discoverability layer that never changes how commands run.
Additive. The native menu sits on top of the existing text-command path. on_message still dispatches every command exactly as before — the menu only makes commands easier to find.
Zero-config. Menu publishing fires at startup: Telegram after the bot is running, Discord on on_ready. New custom commands appear on the next restart.
Best-effort. Publishing is wrapped in try/except. A missing SDK, network error, or unsupported platform is logged at debug and swallowed, so startup is never blocked.
Policy-filtered. When a CommandAccessPolicy is set, build_command_menu_entries(user_id) returns only the commands that user may run, so restricted commands stay hidden from users who cannot run them. See Command Access Control.

Per-Platform Behaviour

PlatformAPIName rulesDescription limit
Telegramset_my_commands(BotCommand(...))[a-z0-9_]{1,32}≤ 256 chars
DiscordCommandTree.sync() (application commands)[a-z0-9_-]{1,32}≤ 100 chars
Out-of-range names are skipped; over-length descriptions are truncated.
Discord shim caveat. Registered Discord slash commands are thin shims. Tapping /status in Discord replies with Type /status as a message to run this command. — the text-command path remains the execution route. This is intentional so the change stays additive; the slash menu never runs the handler directly.

Best Practices

Configure admin_users and user_allowed_commands before enabling /learn, /stop, or /queue in production. See Command Access Control.
/stop and /queue need Bot Run Control with busy_mode for mid-run cancellation and follow-up queuing — without it, users get informational fallbacks only.
Run /compress when conversations exceed ~20 turns. It preserves recent context whilst reclaiming window space for research or coding tasks.
Always pass a description to register_command(). Users discover extensions through /help, which filters to commands they are allowed to run.
Bot tokens should never be hardcoded. Use environment variables or a .env file to store them securely.

Connect your agent to Telegram, Discord, Slack, and WhatsApp.

Understand per-platform message limits, editing, and rate-limit behaviour.

Slash Command Menu

Native / autocomplete for Telegram and Discord.

Command Access Control

Restrict who can run which commands.

Transcribe inbound voice messages on Telegram, Slack, and WhatsApp.