Approval
Route tool approvals to Slack, Discord, Telegram, or any channel before agents execute dangerous operations
Route tool approvals to Slack, Discord, Telegram, a webhook, or a local dashboard. Agents pause before executing dangerous tools and wait for human approval via your chosen platform.
from praisonaiagents import Agent
from praisonai.bots import SlackApproval
agent = Agent(
name="assistant",
instructions="Help users with system tasks",
tools=["execute_command"],
approval=SlackApproval(channel="#approvals"),
)
agent.start("Delete old log files")Quick Start
- Pick a backend
Choose your approval channel. Each backend reads its token from an environment variable:
Backend Command Required Env Vars Slack --approval slackSLACK_BOT_TOKEN,SLACK_CHANNELDiscord --approval discordDISCORD_BOT_TOKEN,DISCORD_CHANNEL_IDTelegram --approval telegramTELEGRAM_BOT_TOKEN,TELEGRAM_CHAT_ID - Set environment variables
bash # Slack export SLACK_BOT_TOKEN=xoxb-your-token export SLACK_CHANNEL=C0123456789 # or #channel-name # Discord export DISCORD_BOT_TOKEN=your-bot-token export DISCORD_CHANNEL_ID=123456789 # Telegram export TELEGRAM_BOT_TOKEN=123456:ABC-DEF export TELEGRAM_CHAT_ID=your-chat-id - Run with –approval
bash praisonai "deploy to production" --approval slack praisonai "delete old logs" --approval discord praisonai "clean up temp files" --approval telegram
CLI Commands
The --approval flag works with all CLI commands:
# Direct prompt
praisonai "task" --approval slack
praisonai "task" --approval telegram
praisonai "task" --approval discordAll CLI Approval Flags
| Flag | Description | Example |
|---|---|---|
--approval <backend> | Route approvals to a platform | --approval slack |
--trust | Auto-approve all tools (skip prompts) | --trust |
--approve-level <level> | Auto-approve up to a risk level | --approve-level high |
--approve-all-tools | Require approval for all tools, not just dangerous ones | --approve-all-tools |
--approval-timeout <sec> | Override backend timeout | --approval-timeout 60 |
Available Backends
| Value | What Happens | Env Vars |
|---|---|---|
console | Interactive terminal prompt (default) | — |
slack | Slack Block Kit message → reply “yes”/”no” | SLACK_BOT_TOKEN, SLACK_CHANNEL |
telegram | Telegram inline keyboard buttons | TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID |
discord | Discord embed → text reply “yes”/”no” | DISCORD_BOT_TOKEN, DISCORD_CHANNEL_ID |
webhook | POST to HTTP endpoint → poll for decision | APPROVAL_WEBHOOK_URL |
http | Local web dashboard (browser) | — |
agent | Delegate to an AI reviewer agent | — |
auto | Auto-approve everything (same as --trust) | — |
none | Disable approval entirely | — |
Programmatic Usage
Slack
from praisonaiagents import Agent
from praisonai.bots import SlackApproval
agent = Agent(
name="assistant",
instructions="Help users with system tasks",
tools=["execute_command"],
approval=SlackApproval(channel="#approvals"),
)
agent.start("Delete old log files")The Slack bot token needs chat:write and channels:history (or im:history for DMs) scopes.
| Parameter | Default | Description |
|---|---|---|
token | SLACK_BOT_TOKEN env | Slack bot token (xoxb-...) |
channel | SLACK_CHANNEL env, or bot’s own DM | Channel ID, #name, or user ID |
timeout | 300 (5 min) | Seconds to wait for response |
poll_interval | 3.0 | Seconds between reply polls |
Discord
from praisonaiagents import Agent
from praisonai.bots import DiscordApproval
agent = Agent(
name="assistant",
instructions="Help users with system tasks",
tools=["execute_command"],
approval=DiscordApproval(channel_id="YOUR_CHANNEL_ID"),
)
agent.start("Delete old log files")| Parameter | Default | Description |
|---|---|---|
token | DISCORD_BOT_TOKEN env | Discord bot token |
channel_id | _(required)_ | Channel ID to send approvals to |
timeout | 300 (5 min) | Seconds to wait for response |
poll_interval | 3.0 | Seconds between polls |
Telegram
from praisonaiagents import Agent
from praisonai.bots import TelegramApproval
agent = Agent(
name="assistant",
instructions="Help users with system tasks",
tools=["execute_command"],
approval=TelegramApproval(chat_id="YOUR_CHAT_ID"),
)
agent.start("Delete old log files")| Parameter | Default | Description |
|---|---|---|
token | TELEGRAM_BOT_TOKEN env | Telegram bot token |
chat_id | _(required)_ | Chat ID to send approvals to |
timeout | 300 (5 min) | Seconds to wait for response |
poll_interval | 2.0 | Seconds between polls |
Webhook
from praisonaiagents import Agent
from praisonai.bots import WebhookApproval
agent = Agent(
name="assistant",
tools=["execute_command"],
approval=WebhookApproval(
webhook_url="https://your-app.com/api/approvals",
headers={"Authorization": "Bearer sk-xxx"},
),
)| Parameter | Default | Description |
|---|---|---|
webhook_url | APPROVAL_WEBHOOK_URL env | URL to POST requests to |
status_url | webhook_url/{request_id} | URL template for polling |
headers | {} | Extra HTTP headers (e.g. auth) |
timeout | 300 (5 min) | Seconds to wait |
poll_interval | 5.0 | Seconds between polls |
HTTP Dashboard
from praisonaiagents import Agent
from praisonai.bots import HTTPApproval
agent = Agent(
name="assistant",
tools=["execute_command"],
approval=HTTPApproval(host="127.0.0.1", port=8899),
)
# Open http://127.0.0.1:8899/approve/<request_id> in your browser| Parameter | Default | Description |
|---|---|---|
host | 127.0.0.1 | Bind address |
port | 8899 | Port to listen on |
timeout | 300 (5 min) | Seconds to wait for response |
Agent
from praisonaiagents import Agent
from praisonaiagents.approval import AgentApproval
reviewer = Agent(
name="security-reviewer",
instructions="Only approve low-risk read operations. Deny anything destructive.",
)
worker = Agent(
name="assistant",
tools=["execute_command"],
approval=AgentApproval(approver_agent=reviewer),
)| Parameter | Default | Description |
|---|---|---|
approver_agent | Auto-created | Agent instance to evaluate requests |
llm | gpt-4o-mini | LLM for default approver agent |
Approval Keywords
All messaging backends (Slack, Discord, Telegram) understand these keywords:
| Action | Keywords |
|---|---|
| Approve | yes, y, approve, approved, ok, allow, go, proceed, confirm |
| Deny | no, n, deny, denied, reject, block, stop, cancel, refuse |
How It Works
| Step | What Happens |
|---|---|
| Agent backend | approval=True or custom backend on the Agent is checked first |
| Required? | Only tools in the dangerous-tools set need approval |
| Env check | PRAISONAI_AUTO_APPROVE=true skips all prompts |
| YAML check | Tools listed in YAML approve field are auto-approved |
| Already approved | Once approved in a session, no re-prompt |
| Backend | ConsoleBackend (default), AutoApproveBackend, or your custom |
Configuration Options
Agent Parameter (Recommended)
| Value | Behavior |
|---|---|
approval=True | Auto-approve all dangerous tools for this agent |
approval=False / None | Use registry fallback (default: console prompt) |
approval=SlackApproval(...) | Route approvals to Slack |
approval=TelegramApproval(...) | Route approvals to Telegram |
approval=DiscordApproval(...) | Route approvals to Discord |
Other Methods
| Method | Scope | Use Case |
|---|---|---|
PRAISONAI_AUTO_APPROVE=true | All agents | CI/CD, testing |
get_approval_registry().set_backend(backend) | All agents | Global policy |
get_approval_registry().set_backend(backend, agent_name="x") | Single agent | Registry-level control |
YAML approve: [tool1, tool2] | Per-task | Declarative configs |
Multi-Agent Example
Different agents can have different approval policies:
from praisonaiagents import Agent
from praisonaiagents.approval import AgentApproval
from praisonai.bots import SlackApproval, TelegramApproval
# Bot agent: auto-approve everything
bot = Agent(name="bot", approval=True)
# Interactive: console prompt (default)
interactive = Agent(name="interactive")
# Critical ops: approved via Slack
deployer = Agent(
name="deployer",
approval=SlackApproval(channel="#deploy-approvals"),
)
# Data ops: approved via Telegram
data_agent = Agent(
name="data-processor",
approval=TelegramApproval(chat_id="123456"),
)
# AI-reviewed: no human needed
reviewer = Agent(name="reviewer", instructions="Only approve safe read operations")
ai_agent = Agent(name="ai-reviewed", approval=AgentApproval(approver_agent=reviewer))Dangerous Tools (Default)
These tools require approval by default:
| Tool | Risk Level |
|---|---|
execute_command | critical |
kill_process | critical |
execute_code | critical |
write_file | high |
delete_file | high |
move_file | high |
execute_query | high |
crawl | medium |
scrape_page | medium |
Add or remove requirements:
from praisonaiagents.approval import get_approval_registry
registry = get_approval_registry()
registry.add_requirement("my_dangerous_tool", risk_level="high")
registry.remove_requirement("crawl")Best Practices
Use approval=True for bot agents
Set approval=True directly on agent constructors for unattended bots. This is the simplest, most agent-centric approach.
Use –approval slack for team oversight
Route dangerous tool approvals to a shared Slack channel so your team can review and approve in real time. Works across timezones — the agent waits up to 5 minutes by default.
Cross-platform: Telegram bot → Slack approval
Users can chat with your agent via Telegram while dangerous tool approvals are routed to a Slack admin channel. Just set approval=SlackApproval(...) on the agent powering the Telegram bot.
Use environment variable for CI/CD
Set PRAISONAI_AUTO_APPROVE=true in your CI environment to avoid blocking on prompts during automated testing.
Use per-agent backends for multi-agent systems
Different agents may need different approval policies. Pass different backends to each agent’s approval= parameter.