Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Treat the parameter and dataclass field order of exported runtime APIs as a comp

- Documentation is published to the live site, so coordinate SDK behavior changes and docs carefully. If docs describe behavior that is not released yet, either delay the docs change until the SDK release is available or split it into a follow-up PR.
- Treat runnable docs snippets as API compatibility checks. Before adding OpenAI API, provider, Responses, Realtime, WebSocket, or SDK constructor examples, verify the shown arguments and call shape against the actual implementation.
- When adding or updating code in `examples/` or runnable `docs/` snippets, import Agents SDK decorators from `agents.decorators`. Prefer `tool` over `function_tool`; keep non-decorator SDK imports on their existing public import paths.
- Do not let untrusted sandbox manifests opt themselves out of host filesystem or base-directory boundaries. Escape hatches for local source materialization must be controlled by trusted application code at the call site, not by serialized manifest data.
- When documenting sandbox or security grants, verify the actual implementation path enforces the grant or boundary. Do not claim a grant applies to `LocalDir`, `LocalFile`, archive extraction, or other materialization paths unless those paths actually consult it.
- When redacting OpenAI tool, MCP, model, or provider payloads, consider traceback display, exception chaining, `__context__`, logs, and telemetry. Suppressing display with `raise ... from None` is not enough if the original exception object still carries sensitive input data.
Expand Down
4 changes: 2 additions & 2 deletions examples/agent_patterns/agents_as_tools_conditional.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from pydantic import BaseModel

from agents import Agent, AgentBase, ModelSettings, RunContextWrapper, Runner, trace
from agents.tool import function_tool
from agents.decorators import tool
from examples.auto_mode import confirm_with_fallback, input_with_fallback, is_auto_mode

"""
Expand All @@ -27,7 +27,7 @@ def european_enabled(ctx: RunContextWrapper[AppContext], agent: AgentBase) -> bo
return ctx.context.language_preference == "european"


@function_tool(needs_approval=True)
@tool(needs_approval=True)
async def get_user_name() -> str:
print("Getting the user's name...")
return "Kaz"
Expand Down
11 changes: 9 additions & 2 deletions examples/agent_patterns/agents_as_tools_streaming.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import asyncio

from agents import Agent, AgentToolStreamEvent, ModelSettings, Runner, function_tool, trace
from agents import (
Agent,
AgentToolStreamEvent,
ModelSettings,
Runner,
trace,
)
from agents.decorators import tool


@function_tool(
@tool(
name_override="billing_status_checker",
description_override="Answer questions about customer billing status.",
)
Expand Down
4 changes: 2 additions & 2 deletions examples/agent_patterns/forcing_tool_use.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
Runner,
ToolsToFinalOutputFunction,
ToolsToFinalOutputResult,
function_tool,
)
from agents.decorators import tool
from examples.auto_mode import is_auto_mode

"""
Expand Down Expand Up @@ -43,7 +43,7 @@ class Weather(BaseModel):
conditions: str


@function_tool
@tool
def get_weather(city: str) -> Weather:
print("[debug] get_weather called")
return Weather(city=city, temperature_range="14-20C", conditions="Sunny with wind")
Expand Down
8 changes: 6 additions & 2 deletions examples/agent_patterns/hosted_multi_agent_beta.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
from collections.abc import Mapping
from typing import Any

from agents import Agent, Runner, function_tool
from agents import (
Agent,
Runner,
)
from agents.decorators import tool
from agents.extensions.experimental.hosted_multi_agent import (
OpenAIHostedMultiAgentModel,
get_hosted_agent_metadata,
Expand All @@ -19,7 +23,7 @@
}


@function_tool
@tool
def get_proposal(ctx: ToolContext[Any], proposal: str) -> dict[str, object]:
"""Return deterministic details for one proposal."""
metadata = get_hosted_agent_metadata(ctx)
Expand Down
11 changes: 8 additions & 3 deletions examples/agent_patterns/human_in_the_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@
import json
from pathlib import Path

from agents import Agent, Runner, RunState, function_tool
from agents import (
Agent,
Runner,
RunState,
)
from agents.decorators import tool
from examples.auto_mode import confirm_with_fallback


@function_tool
@tool
async def get_weather(city: str) -> str:
"""Get the weather for a given city.

Expand All @@ -33,7 +38,7 @@ async def _needs_temperature_approval(_ctx, params, _call_id) -> bool:
return "Oakland" in params.get("city", "")


@function_tool(
@tool(
# Dynamic approval: only require approval for Oakland
needs_approval=_needs_temperature_approval
)
Expand Down
4 changes: 2 additions & 2 deletions examples/agent_patterns/human_in_the_loop_custom_rejection.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
RunConfig,
Runner,
ToolErrorFormatterArgs,
function_tool,
)
from agents.decorators import tool
from examples.auto_mode import confirm_with_fallback


Expand All @@ -29,7 +29,7 @@ async def tool_error_formatter(args: ToolErrorFormatterArgs[None]) -> str | None
return "Publish action was canceled because approval was rejected."


@function_tool(needs_approval=True)
@tool(needs_approval=True)
async def publish_announcement(title: str, body: str) -> str:
"""Simulate publishing an announcement to users."""
return f"Published announcement '{title}' with body: {body}"
Expand Down
10 changes: 7 additions & 3 deletions examples/agent_patterns/human_in_the_loop_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@

import asyncio

from agents import Agent, Runner, function_tool
from agents import (
Agent,
Runner,
)
from agents.decorators import tool
from examples.auto_mode import confirm_with_fallback


Expand All @@ -19,7 +23,7 @@ async def _needs_temperature_approval(_ctx, params, _call_id) -> bool:
return "Oakland" in params.get("city", "")


@function_tool(
@tool(
# Dynamic approval: only require approval for Oakland
needs_approval=_needs_temperature_approval
)
Expand All @@ -35,7 +39,7 @@ async def get_temperature(city: str) -> str:
return f"The temperature in {city} is 20° Celsius"


@function_tool
@tool
async def get_weather(city: str) -> str:
"""Get the weather for a given city.

Expand Down
2 changes: 1 addition & 1 deletion examples/agent_patterns/input_guardrails.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
RunContextWrapper,
Runner,
TResponseInputItem,
input_guardrail,
)
from agents.decorators import input_guardrail
from examples.auto_mode import input_with_fallback, is_auto_mode

"""
Expand Down
2 changes: 1 addition & 1 deletion examples/agent_patterns/output_guardrails.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
OutputGuardrailTripwireTriggered,
RunContextWrapper,
Runner,
output_guardrail,
)
from agents.decorators import output_guardrail

"""
This example shows how to use output guardrails.
Expand Down
6 changes: 3 additions & 3 deletions examples/basic/agent_lifecycle_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
RunContextWrapper,
Runner,
Tool,
function_tool,
)
from agents.decorators import tool
from examples.auto_mode import input_with_fallback, is_auto_mode


Expand Down Expand Up @@ -62,7 +62,7 @@ async def on_tool_end(
###


@function_tool
@tool
def random_number(max: int) -> int:
"""
Generate a random number from 0 to max (inclusive).
Expand All @@ -79,7 +79,7 @@ def random_number(max: int) -> int:
return random.randint(0, max)


@function_tool
@tool
def multiply_by_two(x: int) -> int:
"""Simple multiplication by two."""
return x * 2
Expand Down
10 changes: 8 additions & 2 deletions examples/basic/image_tool_output.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import asyncio

from agents import Agent, Runner, ToolOutputImage, ToolOutputImageDict, function_tool
from agents import (
Agent,
Runner,
ToolOutputImage,
ToolOutputImageDict,
)
from agents.decorators import tool

return_typed_dict = True

URL = "https://images.unsplash.com/photo-1505761671935-60b3a7427bad?auto=format&fit=crop&w=400&q=80"


@function_tool
@tool
def fetch_random_image() -> ToolOutputImage | ToolOutputImageDict:
"""Fetch a random image."""

Expand Down
6 changes: 3 additions & 3 deletions examples/basic/lifecycle_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
Runner,
Tool,
Usage,
function_tool,
)
from agents.decorators import tool
from agents.items import ModelResponse, TResponseInputItem
from agents.tool_context import ToolContext
from examples.auto_mode import input_with_fallback
Expand Down Expand Up @@ -112,13 +112,13 @@ async def on_handoff(
###


@function_tool
@tool
def random_number(max: int) -> int:
"""Generate a random number from 0 to max (inclusive)."""
return random.randint(0, max)


@function_tool
@tool
def multiply_by_two(x: int) -> int:
"""Return x times two."""
return x * 2
Expand Down
10 changes: 7 additions & 3 deletions examples/basic/stream_function_call_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@

from openai.types.responses import ResponseFunctionCallArgumentsDeltaEvent

from agents import Agent, Runner, function_tool
from agents import (
Agent,
Runner,
)
from agents.decorators import tool


@function_tool
@tool
def write_file(filename: Annotated[str, "Name of the file"], content: str) -> str:
"""Write content to a file."""
return f"File {filename} written successfully"


@function_tool
@tool
def create_config(
project_name: Annotated[str, "Project name"],
version: Annotated[str, "Project version"],
Expand Down
9 changes: 7 additions & 2 deletions examples/basic/stream_items.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import asyncio
import random

from agents import Agent, ItemHelpers, Runner, function_tool
from agents import (
Agent,
ItemHelpers,
Runner,
)
from agents.decorators import tool


@function_tool
@tool
def how_many_jokes() -> int:
"""Return a random integer of jokes to tell between 1 and 10 (inclusive)."""
return random.randint(1, 10)
Expand Down
6 changes: 3 additions & 3 deletions examples/basic/stream_ws.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@
Agent,
ModelSettings,
ResponsesWebSocketSession,
function_tool,
responses_websocket_session,
trace,
)
from agents.decorators import tool
from examples.auto_mode import confirm_with_fallback


@function_tool
@tool
def lookup_order(order_id: str) -> dict[str, Any]:
"""Return deterministic order data for the demo."""
orders = {
Expand Down Expand Up @@ -69,7 +69,7 @@ def lookup_order(order_id: str) -> dict[str, Any]:
)


@function_tool(needs_approval=True)
@tool(needs_approval=True)
def submit_refund(order_id: str, amount: float, reason: str) -> dict[str, Any]:
"""Create a refund request. This tool requires approval."""
ticket = "RF-1001" if order_id == "ORD-1001" else f"RF-{order_id[-4:]}"
Expand Down
10 changes: 6 additions & 4 deletions examples/basic/tool_guardrails.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@
ToolInputGuardrailData,
ToolOutputGuardrailData,
ToolOutputGuardrailTripwireTriggered,
function_tool,
)
from agents.decorators import (
tool,
tool_input_guardrail,
tool_output_guardrail,
)


@function_tool
@tool
def send_email(to: str, subject: str, body: str) -> str:
"""Send an email to the specified recipient."""
return f"Email sent to {to} with subject '{subject}'"


@function_tool
@tool
def get_user_data(user_id: str) -> dict[str, str]:
"""Get user data by ID."""
# Simulate returning sensitive data
Expand All @@ -33,7 +35,7 @@ def get_user_data(user_id: str) -> dict[str, str]:
}


@function_tool
@tool
def get_contact_info(user_id: str) -> dict[str, str]:
"""Get contact info by ID."""
return {
Expand Down
8 changes: 6 additions & 2 deletions examples/basic/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@

from pydantic import BaseModel, Field

from agents import Agent, Runner, function_tool
from agents import (
Agent,
Runner,
)
from agents.decorators import tool


class Weather(BaseModel):
Expand All @@ -12,7 +16,7 @@ class Weather(BaseModel):
conditions: str = Field(description="The weather conditions")


@function_tool
@tool
def get_weather(city: Annotated[str, "The city to get the weather for"]) -> Weather:
"""Get the current weather information for a specified city."""
print("[debug] get_weather called")
Expand Down
Loading