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.
The user types a slash command in chat; the bot runs built-in handlers for status, model, usage, and session control.

Command Picker

File-based (.praisonai/commands/*.md) and entry-point commands surface alongside built-ins — see File-based & Entry-point Commands. 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.

/recap

Show a read-only “where were we” summary of the session. Never mutates history or triggers compaction.

/queue

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

/tasks

List background tasks (/tasks), inspect one (/tasks <id>), or cancel (/tasks cancel <id>). Per-user scoped.

/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 &lt;id&gt;. 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).

/automations

List pending automation suggestions with inline Accept/Dismiss buttons. Telegram only today.

/blueprint

Create an automation from a template: /blueprint <name> [slot=value ...]. Telegram only today.

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

2

Set Your Bot Token

3

Start the Bot

4

Send a Command

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

Platform Examples

Voice notes are transcribed automatically — see Voice Notes.

Command Details

/status

Shows current bot information:

/whoami

Shows permission information for the caller: Example output:

/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.
When your bot routes through the gateway (Telegram, Discord, Slack, WhatsApp with praisonai_bot), /stop is handled server-side by the gateway’s abort path introduced in PraisonAI#3472 — it cancels the in-flight turn cooperatively without requiring busy_mode. The busy_mode path is still what enables pending-message handling and mid-run steering; /stop alone works with any gateway-routed bot. See Gateway Abort and Per-Turn Timeout.

/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:
Switch model/model <name>:
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:
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):
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):
Power users can also call the guard helpers directly:

/usage

Reports token usage and a rough estimated cost for the session. Example output:
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:
  • 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.
/compress is destructive — it shrinks context. For a non-destructive “where were we” view that changes nothing, use /recap instead.

/recap

Renders a read-only “where were we” summary of the session without changing anything. Example output:
  • Read-only. Never mutates the transcript and never triggers compaction — safe to run mid-conversation.
  • Reuses a persisted summary when present. If /compress has already produced a compaction summary, /recap shows it verbatim instead of re-summarising.
  • Otherwise it runs the naive summariser over a copy of the history, so the original is untouched and no compaction event is emitted.
  • Always preserves the recent tail — the last few messages are appended verbatim.
  • Output is bounded to ~3500 characters so Telegram deliveries never overflow the 4096-char message limit; when trimming is needed the older summary is truncated, never the recent tail.
Empty history returns:
When the access policy denies the command, the bot replies:
Returning to a long session (a bot chat or --continue)? Run /recap first as a cheap re-entry aid — unlike /compress it costs nothing against your context window.
The same recap is available as a Python primitive when you build a custom surface:

/queue

Adds a follow-up message that runs after the current task completes. Check pending queue/queue with no argument:
Or if nothing is pending:
Queue a message — three possible outcomes depending on bot state:
/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:
Returns "No saved sessions yet." when nothing is stored.

/resume

Switches to a previously saved session.
  • 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.
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.
Run again to hide:
Defaults to hidden when no preference is set. Adapters consult is_reasoning_visible() when rendering responses.

/tasks

Inspect background tasks from inside the chat — no need to switch to a terminal. Example output:
Per-user scoping. /tasks only shows tasks whose metadata["user_id"] matches the caller. Tasks submitted from the CLI or REPL without a user_id are hidden from bot users. One user can never enumerate or cancel another user’s work through /tasks.
Handler strings:

/learn

Authors a grounded, reusable SKILL.md from sources you name — a codebase, API docs, PDFs, configs, or the current chat.
  • 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

/automations

Lists pending automation suggestions, one message per suggestion, each with its own ✓ Accept / ✕ Dismiss inline keyboard. Telegram only today.
  • Header when suggestions exist: 💡 You have 1 pending automation suggestion: (pluralised by count)
  • Header when empty: You have no pending automation suggestions.\nUse /blueprint to create one from a template.
  • Each Accept button carries sug:accept:<id>; each Dismiss carries sug:dismiss:<id>
  • The automations permission is re-checked on every button tap. A denied user sees ⛔ You are not permitted to manage automations appended to the message
  • When the scheduler extra isn’t installed: ❌ Automations are not available (scheduler not installed).

/blueprint

Creates an automation directly from a blueprint template. Telegram only today. Three call shapes:
  1. /blueprint (no args) → lists available blueprints + usage:
  1. /blueprint <name> → creates a job with blueprint defaults
  2. /blueprint <name> hour=8 weekdays=mon-fri → slot overrides
Slot overrides use key=value grammar. Integer-looking values are coerced to int, so hour, minute, and interval_minutes resolve correctly (_parse_slot_args). Success and error strings from _automations.create_from_blueprint:
/automations and /blueprint are generic names, so if your app registers a custom @bot.on_command handler of the same name, that handler wins and the built-in steps aside — unlike every other built-in, which always takes precedence. See Automation Suggestions.

Custom Commands

Register your own commands using register_command(). Available on all bot adapters.

register_command() API

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:

File-based and Entry-point Commands in Bot Chats

One .praisonai/commands/{name}.md file authored once runs in praisonai code and in every bot chat — no duplication, no per-platform wiring.

Quick Start — one file, every chat

Author a single command file:
Start the bot — nothing new to wire. The resolver discovers the file automatically once bot commands are enabled in config:
The user runs it in chat:

One command source, every surface

The same .praisonai/commands/*.md files already documented for Custom Agents & Commands now reach bot chats too — the resolver reuses that loader through the sanctioned _code_bridge seam instead of reimplementing it.

Configuration — BotCommandsConfigSchema

Enable and tune the bridge with a commands block on each channel.

Safety posture: double opt-in for shell

Shell substitution needs both the deployment and the command to say yes. When either is false, the resolver drops the ! marker so the segment becomes plain backticks — the safe $ARGUMENTS and @file parts still interpolate normally instead of the whole command failing.
A shell-carrying command whose deployment forbids shell renders that segment inert rather than erroring. This safe-by-default degradation keeps the rest of the command working. See Bot Shell Execution for the wider shell-approval model.

Precedence & collision rules

When two sources define the same command name, one wins. /help and the native / menu are populated through the shared ChatCommandMixin, so file and entry-point commands appear in both automatically — no per-adapter wiring.

Packaged commands via entry-point

Installed packages add bot commands through the praisonai.bot_commands entry-point group — no forking.
The loader accepts three spec shapes per command:

User interaction flow

  1. A teammate authors .praisonai/commands/deploy.md with description: "Run the deploy checklist" and opens a PR.
  2. After merge, everyone using praisonai code gets /deploy — no restart of code.
  3. On the next bot restart, /deploy also appears in Telegram’s native / menu with the same description, and running it in chat replies with the interpolated template through the normal session.chat path.
  4. Same file. Two surfaces. No duplication.
File and entry-point commands pass through the same Command Access Control policy as built-in and Python-registered commands — admin_users and user_allowed_commands gate them identically, and restricted commands stay hidden from the / menu for users who cannot run them.

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. observe behaves like mention_only for command dispatch — slash-commands in groups still need a mention; only free-form messages are passively recorded.
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:

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:
Custom commands flow through the same registry, so they appear alongside the built-ins on the next restart:

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

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.
/recap never changes your history. Run it first to see the state of the conversation; only reach for /compress when you actually need to free window space.
Always pass a description to register_command(). Users discover extensions through /help, which filters to commands they are allowed to run.
Author .praisonai/commands/{name}.md once and commit it. It runs in praisonai code and — once a channel’s commands block is enabled — in every bot chat, with no per-platform duplication. See File-based & Entry-point Commands.
Live !`cmd` substitution runs only when both the deployment (commands.allow_shell: true) and the command’s own allow_shell: true frontmatter agree. Leave both off unless a specific command genuinely needs shell — the segment degrades to inert backticks otherwise, so the rest of the command still works.
The scheduler’s suggestion store supports per-user isolation via a principal owner key (see Automation Suggestions → Multi-tenant isolation and Per-User Scheduler Isolation). When your bot passes the resolved chat identity to the store, each user sees and can accept/dismiss only their own suggestions, and one tenant cannot exhaust another’s pending cap or dedup window.Until the adapter you use threads that identity through (or if you prefer a simpler policy), gate the whole command behind an admin allowlist by adding automations and blueprint to admin_users (not user_allowed_commands) in CommandAccessPolicy.
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.

Custom Agents & Commands

Author .praisonai/commands/*.md files once — they run in praisonai code and bot chats.

Bot Shell Execution

The double-opt-in shell rule and the wider shell-approval model.
How tasks get submitted, configured, and made durable — the substrate /tasks inspects.