Tool confirmation blocks selected tool calls until a user approves them. The agent identifies approval-required tools, creates pending calls with human-readable messages, and resumes execution after decisions arrive. This prevents irreversible actions from running before review. section 6.3.6 section 6.3.7
A practical implementation separates tool metadata from the agent’s internal execution flow:
- Add requires_confirmation and confirmation_message_template to BaseTool; generate approval text with the tool name and arguments. section 6.3.6
- Extend the tool decorator so each tool can declare whether approval is required and customize the request shown to the user. section 6.3.6
- Make act() collect pending calls instead of executing them, while immediately running tools that do not require confirmation. section 6.3.7
- Let run() pause when pending calls exist, then let _prepare_llm_request() process returned approvals and add the resulting ToolResults to the conversation. section 6.3.7
- Use whitelist approval: execute only approved tool_call_id values and reject pending calls absent from the approval list. section 6.3.7
Destructive versus read-only tools
Configure delete_file with requires_confirmation=True and a message naming the target file and warning that deletion cannot be undone. Leave get_weather without confirmation so it executes immediately. section 6.3.6
Listing 6.20 Modified act() method with confirmation check
async def act(
self,
context: ExecutionContext,
tool_calls: List[ToolCall]
) -> List[ToolResult]:
tools_dict = {tool.name: tool for tool in self.tools}
pending_calls = []
results = []
for tool_call in tool_calls:
tool = tools_dict.get(tool_call.name)
# Check if confirmation is required
if tool.requires_confirmation:
pending = PendingToolCall(
tool_call=tool_call,
confirmation_message=tool.get_confirmation_message(
tool_call.arguments
)
)
pending_calls.append(pending)
continue # Do not execute, do not create ToolResult
# Execute tools that don't require confirmation
# ... existing tool execution logic ...
# Store pending calls in session state
if pending_calls:
context.state["pending_tool_calls"] = [
p.model_dump() for p in pending_calls
]
return results
Inspect the act() implementation that separates pending approval-required calls from immediately executable tools. section 6.3.7
