Tool Calls
Handle tool calls automatically or manually.
Flows may invoke external tools (e.g., web search, API calls). You can handle them automatically with a handler function or manually by pausing and resuming the iterator.
Automatic mode (tool_handler)
Pass a tool_handler function to execute() or steps() to auto-handle all tool calls:
With tool_handler, the flow executes to completion without pausing. If a tool call fails or returns invalid data, the flow retries automatically (up to 1 retry by default).
Manual mode (event.resume())
Without a tool_handler, the iterator yields ToolCallsRequired when the flow needs tools. Resume manually from inside the iterator loop:
Manual mode is useful when:
- Tool execution is expensive (e.g., real API calls) and you want custom caching/batching
- You need to validate or transform tool results before returning them
- You're integrating with external orchestration systems
Tool call structure
Tool calls follow OpenAI's format:
Tool results use the same message format:
Defining tools
Pass tool definitions to execute() or steps() in OpenAI function-calling format:
Error handling
If a tool call fails or returns an error, the flow automatically retries with exponential backoff (1 retry by default). If all retries are exhausted, a ToolCallLimitError is raised.
Comparing modes
| Aspect | Automatic (tool_handler) | Manual (resume()) |
|---|---|---|
| Simplicity | Very simple — set and forget | Requires loop management |
| Control | Limited — handler is stateless | Full control over execution |
| Tool latency | Transparent to your code | You observe and can optimize |
| Error handling | Automatic retries | You handle errors |
| Use case | Quick scripts, most flows | Complex logic, real APIs |
For most use cases, automatic mode is recommended. Use manual mode when you need advanced control.
Next steps
- Iteration patterns: See Step-by-step iteration
- Tracing tool calls: See Tracing & debugging
- Error handling: See Errors & retries