Skip to main content
Declare a tool needs human approval directly on the @tool decorator; every runtime honours it.
The tool carries its own approval requirement — the agent pauses and asks a human before delete_account runs.
One vocabulary: approval= is the same word you already use on the agent — Agent(name="…", approval="high"). See Agent Approval. requires_approval= still works as a deprecated alias (below).

Quick Start

1

One-line, high-risk default

approval=True registers the tool at "high" risk:
2

Explicit risk level

Pass a string to choose the level explicitly:
3

Renamed tool

Registration keys off the resolved tool name — not the function name:

How It Works

Registration happens once at import time; enforcement happens on every call.

Choose your level


Configuration Options

Accepted values for approval (canonical):

Deprecated alias: requires_approval

requires_approval= is the old spelling. It still works but emits a DeprecationWarning — migrate to approval=.
Attributes on the returned FunctionTool:
Fail-closed: If the registry cannot install the requirement, the decorator raises RuntimeError and does not hand back an executable tool. A tool you asked to gate never runs ungated.
Misspelled levels are caught early. @tool(approval="critial") raises ValueError at decoration time, not silently at runtime.

Common Patterns

Mark one tool critical alongside safe tools

Rename a tool and keep it gated

Compose with agent-level approval config

The decorator declares what needs approval; the agent config decides how to ask.

User interaction flow

A real run looks like this:
  1. You run the agent: agent.start("Delete account u_42").
  2. The LLM decides to call delete_account.
  3. The console approval prompt appears with four choices: [o] once, [s] session, [a] always, [n] no.
  4. You pick — the tool runs, or is skipped.
See Interactive Tool Approval for the full prompt semantics.

Best Practices

Prefer approval=True for any tool that writes, mutates, or deletes state. True registers at "high" — safe default for destructive actions.
Use 'critical' only for irreversible operations. Critical tools always re-prompt regardless of the argument cache, so they never slip through a cached grant. See the approval cache.
Declare approval on the tool itself. The tool then travels safely between agents — no agent can accidentally use it ungated.
approval on the decorator does not wire a backend — console stays the default. For async agents, combine with Agent(approval={"backend": "slack"}) or another non-console backend.

Approval

Agent-level approval config and the dangerous-tools registry

Interactive Approval

The console prompt UX and scope choices

Approval Backends

Slack, HTTP, webhook, and other channels

Tool Retry Policy

A sibling decorator-level knob for retries