Lightweight framework for building multi-agent workflows with LLMs, supporting handoffs, guardrails, tools, and 100+ LLM providers
Tools enable agents to perform actions beyond text generation. The SDK supports function tools (Python functions), hosted tools (OpenAI-provided capabilities), shell tools, MCP tools, and custom tool implementations with guardrails and error handling.
Tool = Union[
FunctionTool,
FileSearchTool,
WebSearchTool,
ComputerTool,
HostedMCPTool,
ShellTool,
ApplyPatchTool,
LocalShellTool,
ImageGenerationTool,
CodeInterpreterTool
]Union of all supported tool types.
Python functions wrapped as agent tools with automatic schema generation.
class FunctionTool:
"""
Tool wrapping a Python function.
Attributes:
- name: str - Tool name (derived from function name)
- description: str - Tool description (from docstring)
- params_json_schema: dict[str, Any] - Parameter JSON schema
- on_invoke_tool: Callable - Function to invoke
- strict_json_schema: bool - Use strict mode
- is_enabled: bool | Callable - Tool enabled state
- tool_input_guardrails: list[ToolInputGuardrail] | None - Input guardrails
- tool_output_guardrails: list[ToolOutputGuardrail] | None - Output guardrails
"""
def function_tool(
func: ToolFunction | None = None,
*,
name_override: str | None = None,
description_override: str | None = None,
docstring_style: DocstringStyle | None = None,
use_docstring_info: bool = True,
failure_error_function: ToolErrorFunction | None = None,
strict_mode: bool = True,
is_enabled: bool | Callable = True
):
"""
Decorator to create FunctionTool from function.
Parameters:
- func: Function to wrap (when used as @function_tool())
- name_override: Custom tool name
- description_override: Custom description
- docstring_style: Docstring parsing style
- use_docstring_info: Extract info from docstring
- failure_error_function: Custom error handler
- strict_mode: Enable strict JSON schema
- is_enabled: Tool enabled state or function
Returns:
- FunctionTool or decorator
"""
class FunctionToolResult:
"""
Result of function tool execution.
Attributes:
- tool: FunctionTool - The tool that was executed
- output: Any - Tool output value
- run_item: RunItem - Associated run item
"""Usage example:
from agents import Agent, function_tool
@function_tool
def get_weather(city: str, units: str = "celsius") -> str:
"""
Get the weather for a city.
Args:
city: The city name
units: Temperature units (celsius or fahrenheit)
Returns:
Weather information as a string
"""
# Implementation
return f"Weather in {city}: 22°{units[0].upper()}"
@function_tool(
name_override="search_db",
description_override="Search the knowledge database",
strict_mode=True
)
def search_knowledge_base(query: str) -> dict:
"""Search for information."""
return {"results": [...]}
# Conditional tool enabling
def should_enable_tool(ctx):
return ctx.context.user.is_premium
@function_tool(is_enabled=should_enable_tool)
def premium_feature():
"""Premium-only feature."""
...
agent = Agent(
name="Assistant",
tools=[get_weather, search_knowledge_base, premium_feature]
)Hosted tool for searching vector stores with file content.
class FileSearchTool:
"""
Hosted tool for vector store search.
Attributes:
- vector_store_ids: list[str] - Vector store IDs to search
- max_num_results: int | None - Maximum number of results
- include_search_results: bool - Include results in output
- ranking_options: RankingOptions | None - Ranking configuration
- filters: Filters | None - Search filters
Properties:
- name: Returns "file_search"
"""Usage example:
from agents import Agent, FileSearchTool
file_search = FileSearchTool(
vector_store_ids=["vs_123", "vs_456"],
max_num_results=10,
include_search_results=True
)
agent = Agent(
name="Knowledge Agent",
instructions="Use file search to answer questions.",
tools=[file_search]
)Hosted tool for web search capabilities.
class WebSearchTool:
"""
Hosted tool for web search.
Attributes:
- user_location: UserLocation | None - User location for results
- filters: WebSearchToolFilters | None - Search filters
- search_context_size: Literal["low", "medium", "high"] - Context amount
Properties:
- name: Returns "web_search"
"""Usage example:
from agents import Agent, WebSearchTool
web_search = WebSearchTool(
search_context_size="high",
filters={
"recency": "recent",
"max_results": 5
}
)
agent = Agent(
name="Research Agent",
instructions="Search the web for current information.",
tools=[web_search]
)Hosted tool for computer control (UI automation).
class ComputerTool:
"""
Hosted tool for computer control.
Attributes:
- computer: Computer | AsyncComputer - Computer implementation
- on_safety_check: Callable | None - Safety check callback
Properties:
- name: Returns "computer_use_preview"
"""
class ComputerToolSafetyCheckData:
"""
Data for computer tool safety checks.
Attributes:
- ctx_wrapper: RunContextWrapper - Run context
- agent: Agent - Current agent
- tool_call: ToolCall - The tool call
- safety_check: SafetyCheck - Safety check details
"""Usage example:
from agents import Agent, ComputerTool, Computer
class MyComputer(Computer):
@property
def environment(self):
return "ubuntu"
@property
def dimensions(self):
return (1920, 1080)
def screenshot(self):
# Take screenshot
return "base64_image_data"
def click(self, x, y, button="left"):
# Click at position
...
# Implement other methods...
async def safety_check(data):
# Review action before execution
print(f"Agent wants to: {data.tool_call}")
return True # Allow action
computer_tool = ComputerTool(
computer=MyComputer(),
on_safety_check=safety_check
)
agent = Agent(
name="Automation Agent",
instructions="Control the computer to complete tasks.",
tools=[computer_tool]
)Modern shell command execution tool.
class ShellTool:
"""
Next-generation shell tool.
Attributes:
- executor: ShellExecutor - Executor function
- name: str - Tool name (default "shell")
"""
class ShellCommandRequest:
"""
Modern shell command request.
Attributes:
- ctx_wrapper: RunContextWrapper - Run context
- data: ShellCallData - Command data
"""
class ShellResult:
"""
Shell execution result.
Attributes:
- output: list[ShellCommandOutput] - Command outputs
- max_output_length: int | None - Max output length
- provider_data: dict[str, Any] | None - Provider-specific data
"""
class ShellCommandOutput:
"""
Output from single shell command.
Attributes:
- stdout: str - Standard output
- stderr: str - Standard error
- outcome: ShellCallOutcome - Terminal condition
- command: str - Executed command
- provider_data: dict[str, Any] | None - Provider data
Properties:
- exit_code: int | None - Exit code if available
- status: str - Status string
"""
class ShellCallOutcome:
"""
Terminal condition of shell command.
Attributes:
- type: str - Outcome type
- exit_code: int | None - Exit code
"""
class ShellCallData:
"""
Normalized shell call data.
Attributes:
- call_id: str - Call identifier
- action: ShellActionRequest - Action details
- status: str - Call status
- raw: dict - Raw call data
"""
class ShellActionRequest:
"""
Shell action payload.
Attributes:
- commands: list[str] - Commands to execute
- timeout_ms: int | None - Timeout in milliseconds
- max_output_length: int | None - Maximum output length
"""Type alias:
ShellExecutor = Callable[
[ShellCommandRequest],
MaybeAwaitable[str | ShellResult]
]Usage example:
from agents import Agent, ShellTool, ShellCommandRequest, ShellResult
import subprocess
async def execute_shell(request: ShellCommandRequest) -> ShellResult:
outputs = []
for cmd in request.data.action.commands:
result = subprocess.run(
cmd,
shell=True,
capture_output=True,
text=True
)
outputs.append(ShellCommandOutput(
stdout=result.stdout,
stderr=result.stderr,
outcome=ShellCallOutcome(
type="exited",
exit_code=result.returncode
),
command=cmd,
provider_data=None
))
return ShellResult(output=outputs, max_output_length=None, provider_data=None)
shell_tool = ShellTool(executor=execute_shell)
agent = Agent(
name="DevOps Agent",
instructions="Run shell commands to manage the system.",
tools=[shell_tool]
)Simple local shell command execution.
class LocalShellTool:
"""
Tool for local shell command execution.
Attributes:
- executor: LocalShellExecutor - Executor function
Properties:
- name: Returns "local_shell"
"""
class LocalShellCommandRequest:
"""
Local shell command request.
Attributes:
- ctx_wrapper: RunContextWrapper - Run context
- data: dict - Command data
"""Type alias:
LocalShellExecutor = Callable[
[LocalShellCommandRequest],
MaybeAwaitable[str]
]Usage example:
from agents import Agent, LocalShellTool
import subprocess
async def run_local_shell(request):
cmd = request.data["command"]
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
return f"stdout: {result.stdout}\nstderr: {result.stderr}"
local_shell = LocalShellTool(executor=run_local_shell)
agent = Agent(
name="Script Runner",
tools=[local_shell]
)Tool for applying diffs to files (code editing).
class ApplyPatchTool:
"""
Hosted apply_patch tool.
Attributes:
- editor: ApplyPatchEditor - Editor implementation
- name: str - Tool name (default "apply_patch")
"""Editor protocol:
class ApplyPatchEditor:
"""Protocol for editor implementation."""
def create_file(operation: ApplyPatchOperation) -> MaybeAwaitable[ApplyPatchResult | str | None]:
"""Create a new file."""
def update_file(operation: ApplyPatchOperation) -> MaybeAwaitable[ApplyPatchResult | str | None]:
"""Update existing file."""
def delete_file(operation: ApplyPatchOperation) -> MaybeAwaitable[ApplyPatchResult | str | None]:
"""Delete a file."""
class ApplyPatchOperation:
"""
Single apply_patch operation.
Attributes:
- type: ApplyPatchOperationType - Operation type
- path: str - File path
- diff: str | None - Diff content
"""
class ApplyPatchResult:
"""
Result of editor operation.
Attributes:
- status: Literal["completed", "failed"] | None - Operation status
- output: str | None - Operation output
"""Usage example:
from agents import Agent, ApplyPatchTool, ApplyPatchEditor, ApplyPatchOperation
class MyEditor(ApplyPatchEditor):
def create_file(self, op):
# Create file at op.path with op.diff
return ApplyPatchResult(status="completed", output="File created")
def update_file(self, op):
# Apply diff to existing file
return ApplyPatchResult(status="completed", output="File updated")
def delete_file(self, op):
# Delete file
return ApplyPatchResult(status="completed", output="File deleted")
apply_patch = ApplyPatchTool(editor=MyEditor())
agent = Agent(
name="Code Editor Agent",
instructions="Edit code files as requested.",
tools=[apply_patch]
)Tool for accessing hosted MCP servers.
class HostedMCPTool:
"""
Hosted MCP server tool.
Attributes:
- tool_config: Mcp - MCP configuration
- on_approval_request: MCPToolApprovalFunction | None - Approval handler
Properties:
- name: Returns "hosted_mcp"
"""
class MCPToolApprovalRequest:
"""
MCP tool approval request.
Attributes:
- ctx_wrapper: RunContextWrapper - Run context
- data: dict - Approval data
"""
class MCPToolApprovalFunctionResult:
"""
Result of MCP approval function.
Attributes:
- approve: bool - Whether to approve
- reason: str | None - Optional reason
"""Type alias:
MCPToolApprovalFunction = Callable[
[MCPToolApprovalRequest],
MaybeAwaitable[MCPToolApprovalFunctionResult]
]Usage example:
from agents import Agent, HostedMCPTool
async def approve_mcp_action(request):
# Review MCP action
if "dangerous" in request.data.get("action", ""):
return {"approve": False, "reason": "Potentially dangerous"}
return {"approve": True}
hosted_mcp = HostedMCPTool(
tool_config={"server": "mcp_server_id"},
on_approval_request=approve_mcp_action
)
agent = Agent(
name="MCP Agent",
tools=[hosted_mcp]
)Hosted tool for code execution.
class CodeInterpreterTool:
"""
Hosted code interpreter tool.
Attributes:
- tool_config: CodeInterpreter - Configuration
Properties:
- name: Returns "code_interpreter"
"""Usage example:
from agents import Agent, CodeInterpreterTool
code_interpreter = CodeInterpreterTool(
tool_config={"runtime": "python3"}
)
agent = Agent(
name="Data Analysis Agent",
instructions="Analyze data using Python code.",
tools=[code_interpreter]
)Hosted tool for generating images.
class ImageGenerationTool:
"""
Hosted image generation tool.
Attributes:
- tool_config: ImageGeneration - Configuration
Properties:
- name: Returns "image_generation"
"""Usage example:
from agents import Agent, ImageGenerationTool
image_gen = ImageGenerationTool(
tool_config={
"model": "dall-e-3",
"quality": "hd"
}
)
agent = Agent(
name="Creative Agent",
instructions="Generate images based on descriptions.",
tools=[image_gen]
)Structured output types for tools.
class ToolOutputText:
"""
Text tool output.
Attributes:
- type: Literal["text"]
- text: str - Text content
"""
class ToolOutputTextDict:
"""
TypedDict variant for text output.
Attributes:
- type: Literal["text"]
- text: str
"""
class ToolOutputImage:
"""
Image tool output.
Attributes:
- type: Literal["image"]
- image_url: str | None - Image URL
- file_id: str | None - File ID
- detail: str | None - Detail level
"""
class ToolOutputImageDict:
"""
TypedDict variant for image output.
Attributes:
- type: Literal["image"]
- image_url: str | None
- file_id: str | None
- detail: str | None
"""
class ToolOutputFileContent:
"""
File content tool output.
Attributes:
- type: Literal["file"]
- file_data: str | None - Base64 file data
- file_url: str | None - File URL
- file_id: str | None - File ID
- filename: str | None - Filename
"""
class ToolOutputFileContentDict:
"""
TypedDict variant for file output.
Attributes:
- type: Literal["file"]
- file_data: str | None
- file_url: str | None
- file_id: str | None
- filename: str | None
"""Usage example:
from agents import function_tool, ToolOutputImage
@function_tool
def generate_chart(data: list[float]) -> ToolOutputImage:
"""Generate a chart from data."""
# Create chart
chart_url = "https://example.com/chart.png"
return ToolOutputImage(
type="image",
image_url=chart_url,
detail="high"
)Error handling for tool failures.
def default_tool_error_function(ctx: RunContextWrapper, error: Exception) -> str:
"""
Default error handler for tool failures.
Parameters:
- ctx: Run context
- error: Exception that occurred
Returns:
- str: Error message for the LLM
"""Type alias:
ToolErrorFunction = Callable[
[RunContextWrapper, Exception],
MaybeAwaitable[str]
]Usage example:
from agents import function_tool
async def custom_error_handler(ctx, error):
# Log error
print(f"Tool error: {error}")
# Return user-friendly message
return "The tool encountered an error. Please try again."
@function_tool(failure_error_function=custom_error_handler)
def risky_operation(input: str) -> str:
"""An operation that might fail."""
# Potentially failing code
...Abstract interfaces for computer control implementations used with ComputerTool.
class Computer:
"""Synchronous computer control interface."""
@property
def environment(self) -> Environment:
"""
Get environment type.
Returns:
- Environment: One of "mac", "windows", "ubuntu", "browser"
"""
@property
def dimensions(self) -> tuple[int, int]:
"""
Get screen dimensions.
Returns:
- tuple[int, int]: Width and height in pixels
"""
def screenshot() -> str:
"""
Take screenshot.
Returns:
- str: Base64-encoded image
"""
def click(x: int, y: int, button: Button = "left") -> None:
"""
Click at position.
Parameters:
- x: X coordinate
- y: Y coordinate
- button: Mouse button ("left", "right", "wheel", "back", "forward")
"""
def double_click(x: int, y: int) -> None:
"""
Double click at position.
Parameters:
- x: X coordinate
- y: Y coordinate
"""
def scroll(x: int, y: int, scroll_x: int, scroll_y: int) -> None:
"""
Scroll at position.
Parameters:
- x: X coordinate
- y: Y coordinate
- scroll_x: Horizontal scroll amount
- scroll_y: Vertical scroll amount
"""
def type(text: str) -> None:
"""
Type text.
Parameters:
- text: Text to type
"""
def wait() -> None:
"""Wait for UI updates."""
def move(x: int, y: int) -> None:
"""
Move cursor.
Parameters:
- x: X coordinate
- y: Y coordinate
"""
def keypress(keys: str) -> None:
"""
Press keys.
Parameters:
- keys: Keys to press (e.g., "ctrl+c")
"""
def drag(path: list[tuple[int, int]]) -> None:
"""
Drag along path.
Parameters:
- path: List of (x, y) coordinates
"""class AsyncComputer:
"""Asynchronous computer control interface."""
@property
def environment(self) -> Environment:
"""Get environment type."""
@property
def dimensions(self) -> tuple[int, int]:
"""Get screen dimensions."""
async def screenshot() -> str:
"""Take screenshot."""
async def click(x: int, y: int, button: Button = "left") -> None:
"""Click at position."""
async def double_click(x: int, y: int) -> None:
"""Double click at position."""
async def scroll(x: int, y: int, scroll_x: int, scroll_y: int) -> None:
"""Scroll at position."""
async def type(text: str) -> None:
"""Type text."""
async def wait() -> None:
"""Wait for UI updates."""
async def move(x: int, y: int) -> None:
"""Move cursor."""
async def keypress(keys: str) -> None:
"""Press keys."""
async def drag(path: list[tuple[int, int]]) -> None:
"""Drag along path."""Environment = Literal["mac", "windows", "ubuntu", "browser"]
Button = Literal["left", "right", "wheel", "back", "forward"]Install with Tessl CLI
npx tessl i tessl/pypi-openai-agents