Approval Backends
Choose how tool approvals reach a human — console prompt, plan mode, accept-edits, or a chat channel
Pick who (or what) approves a tool call — the terminal, a coding-mode fast path, or a chat channel that fans out to Slack/Telegram/Discord.
from praisonaiagents import Agent
agent = Agent(
name="coder",
instructions="Edit files carefully.",
tools=["write_file"],
approval="console",
)
agent.start("Refactor utils.py")The user triggers a risky tool; the chosen approval backend prompts or routes the decision to a human.
Available Backends
How It Works
A risky tool call pauses until the chosen backend collects a human decision.
Diff preview
The console backend renders a coloured unified diff for file-mutating tools — edit_file, acp_edit_file, write_file, acp_create_file, and apply_patch — so the reviewer sees the concrete change, not truncated arguments.
The diff rides on ApprovalRequest.context["diff"], a stable public field. Wrapper backends (slack, telegram, discord, webhook, http) can read it and render or attach it in their channel — this is where custom-backend authors should look.
# Inside a custom backend
def request_approval_sync(self, request, timeout=None):
diff = request.context.get("diff")
if diff:
... # render as a code block, attachment, or on-request expandSee Approval › Diff preview in approval prompts for the full tool contract and safety rules.
Backend Matrix
| Backend | Where it runs | One-line meaning |
|---|---|---|
console (also true/yes/1) | Standalone | Ask on the terminal, y/N — shows a rendered diff for file-mutating tools |
none (also false/no/0) | Standalone | Auto-approve everything (unsafe) |
auto | Standalone | Auto-approve safe read-only tools |
plan | Standalone | Coding-mode plan approval |
accept-edits | Standalone | Auto-accept file-edit tools |
bypass | Standalone | Approve without prompting (dev) |
agent | Standalone | Delegate to a reviewer agent (see below) |
slack | Wrapper | Approvals routed to Slack |
telegram | Wrapper | Approvals routed to Telegram |
discord | Wrapper | Approvals routed to Discord |
webhook | Wrapper | Custom outbound HTTP webhook |
http | Wrapper | Inbound HTTP approval endpoint |
secure | Wrapper | Secure-mode policy (audit-logged) |
presentation | Wrapper | Presentation/demo-safe policy |
CLI opt-outs register a registry backend
praisonai code --no-safe and --dangerously-skip-approval do two things, not one:
- Set env vars —
PRAISON_APPROVAL_MODE=auto,PRAISONAI_TOOL_SAFETY=off— consumed by the CLI’s own tool wiring. - Register
AutoApproveBackendon the approval registry — consumed by the core@require_approvaldecorator that gates critical tools likeacp_execute_command. Without this the flag was a no-op for any registry-decorated tool.
A safe-mode run removes the AutoApproveBackend a prior --no-safe installed in the same process, and removes only that backend — a caller-supplied backend or one installed by --plan is preserved. A per-agent backend still wins, since the core consults Agent(approval=…) before the global registry. See Approval → Bypassing safety for the full resolution order.
Without an opt-out, --safe writes PRAISON_APPROVAL_MODE=prompt. Known values are auto, prompt, manual, scoped; anything else is logged and treated as prompt. In auto, the edit-tool standing approval is granted only when the edit group is in the requested tool list.
Quick Start
from praisonaiagents import Agent
agent = Agent(
name="Code assistant",
instructions="Help refactor code files.",
)
agent.start("Refactor utils.py")- Choose your approval mode
Terminal
Ask the user on the terminal before each risky tool call:
bash praisonai-code run --approval console "Refactor utils.py"Coding fast path
Use plan/accept-edits mode (Claude Code-style flow) for unattended coding runs:
bash praisonai-code run --approval plan "Refactor utils.py"accept-editsauto-accepts file edits;planrequires explicit plan approval before execution.Chat channel (wrapper)
Route approvals to a Slack channel:
bash praisonai run --approval slack --approval-timeout 300 "Refactor utils.py"
--approval-timeout
--approval-timeout takes seconds. Pass none to wait indefinitely.
praisonai-code run --approval console --approval-timeout 60 "..."
praisonai-code run --approval slack --approval-timeout none "..."Reviewer-Agent Mode (--approval agent)
When you pass --approval agent, a built-in LLM reviewer gates every tool call. The default reviewer instructions frame the tool name and arguments as UNTRUSTED input from a possibly-compromised agent, forbid obeying any directive that appears inside, and offer three verdicts.
praisonai-code run --approval agent "List all files and summarise the project"The reviewer replies with one of APPROVE, DENY, or ESCALATE for each pending tool call. Parsing is fail-closed: empty, ambiguous, mixed, or negated (“DO NOT APPROVE”) responses deny; ESCALATE defers the call to a human. You can override the default instruction by passing a custom reviewer prompt via the API:
from praisonaiagents import Agent
from praisonaiagents.approval import AgentApproval
reviewer = Agent(
name="strict-reviewer",
instructions="Only approve file reads. Deny everything else. Reply APPROVE, DENY, or ESCALATE if uncertain.",
)
agent = Agent(
name="Assistant",
instructions="Help with coding tasks.",
approval=AgentApproval(approver_agent=reviewer),
)
agent.start("Read and summarise main.py")Unknown-Backend Error
If you pass an unrecognised backend name, the CLI raises:
Unknown approval backend: '<value>'. Valid options: console, plan, accept-edits, bypass, auto, agent, none, discord, http, presentation, secure, slack, telegram, webhookUse this to trap typos — the valid list is alphabetically sorted within the wrapper group.
Best Practices
Use console in interactive dev, agent for unattended runs
Use console in interactive dev, agent for unattended runs where a reviewer LLM can gate tools.
Pair accept-edits and plan with praisonai-code code
accept-edits and plan are the coding-mode fast paths — pair them with praisonai-code code.
Never use none outside throwaway sandboxes
none disables approval entirely; only use it in throwaway sandboxes.
Related
The same backends for the TypeScript SDK.
Approval ProtocolCross-SDK backend matrix and request/decision shapes.
Local Tools LoadingApproval decides who says yes to your local tools.
ApprovalThe full approval system — dangerous tool gating, TTY detection, and safe defaults.
Approval Cache BoundsPer-context cache cap and automatic cleanup of closed agents.