Implementation:Openai Openai agents python Tool Approval Config
Overview
This page documents the concrete API signatures and configuration patterns for enabling tool approval in the OpenAI Agents Python SDK.
ShellTool Signature
The ShellTool dataclass is defined in src/agents/tool.py (lines 679-699):
@dataclass
class ShellTool:
"""Next-generation shell tool. LocalShellTool will be deprecated in favor of this."""
executor: ShellExecutor
name: str = "shell"
needs_approval: bool | ShellApprovalFunction = False
on_approval: ShellOnApprovalFunction | None = None
Fields
- executor: A callable that receives a
ShellCommandRequestand returns either a string or aShellResult. This is the function that actually executes the shell commands. - name: The tool name exposed to the model. Defaults to
"shell". - needs_approval: Controls whether execution requires human approval. Accepts a
bool(always/never) or aShellApprovalFunctioncallable for dynamic per-call decisions. - on_approval: Optional callback invoked immediately when approval is needed. Can auto-approve or auto-reject without manual intervention.
FunctionTool.needs_approval Field
The FunctionTool dataclass defines needs_approval in src/agents/tool.py (lines 253-264):
needs_approval: (
bool | Callable[[RunContextWrapper[Any], dict[str, Any], str], Awaitable[bool]]
) = False
The callable receives three arguments:
RunContextWrapper[Any]: The current run context wrapperdict[str, Any]: The tool's input parameters for this callstr: The call ID identifying this specific tool invocation
It must return an Awaitable[bool] indicating whether this particular call needs approval.
Import
from agents import ShellTool, function_tool
Example: Function Tool with Static Approval
from agents import Agent, function_tool, ShellTool
@function_tool(needs_approval=True)
def delete_file(path: str) -> str:
"""Delete a file at the given path."""
import os
os.remove(path)
return f"Deleted {path}"
agent = Agent(
name="file_manager",
instructions="Manage files as requested.",
tools=[delete_file],
)
Setting needs_approval=True on the @function_tool decorator causes every invocation of delete_file to pause execution and produce a ToolApprovalItem for human review.
Example: Shell Tool with Approval
from agents import Agent, ShellTool
async def my_executor(request):
import asyncio
proc = await asyncio.create_subprocess_shell(
" ".join(request.data.action.commands),
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await proc.communicate()
return stdout.decode()
shell = ShellTool(executor=my_executor, needs_approval=True)
agent = Agent(
name="admin",
instructions="Execute commands.",
tools=[shell],
)
Example: Dynamic Approval with a Callable
from agents import Agent, function_tool, RunContextWrapper
async def check_if_dangerous(
ctx: RunContextWrapper, params: dict, call_id: str
) -> bool:
"""Only require approval for paths outside the safe directory."""
path = params.get("path", "")
return not path.startswith("/tmp/safe/")
@function_tool(needs_approval=check_if_dangerous)
def delete_file(path: str) -> str:
"""Delete a file at the given path."""
import os
os.remove(path)
return f"Deleted {path}"
In this example, calls targeting paths under /tmp/safe/ execute immediately, while all other paths trigger an approval interruption.
Source References
src/agents/tool.pylines 253-264:FunctionTool.needs_approvalfieldsrc/agents/tool.pylines 679-699:ShellTooldataclass