Skip to content
Open
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
4 changes: 4 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ set_default_openai_client(custom_client)

When you pass an explicit client to [`OpenAIProvider`][agents.models.openai_provider.OpenAIProvider], that client owns its connection and account settings. Do not also pass `api_key`, `base_url`, `websocket_base_url`, `organization`, or `project` to `OpenAIProvider`; combining `openai_client` with any of those arguments raises [`UserError`][agents.exceptions.UserError] instead of silently ignoring the duplicate value. Set the intended values when constructing `AsyncOpenAI`.

When `openai_client` is omitted, `OpenAIProvider` reuses the SDK-wide default client only if `api_key`, `base_url`, `websocket_base_url`, `organization`, and `project` are all `None`. Passing any of those options, including an empty string, makes the provider create its own client and gives the provider option precedence over the SDK-wide default client. Leave every provider option as `None` when the provider should inherit the client installed by `set_default_openai_client()`.

[`OpenAIVoiceModelProvider`][agents.voice.models.openai_model_provider.OpenAIVoiceModelProvider] uses the same ownership and precedence rules for `api_key`, `base_url`, `organization`, and `project`. Its explicit `openai_client` cannot be combined with any of those four options.

### Custom HTTP clients with `openai` v3

Version 0.21.0 requires `openai>=3.0.0,<4`. The default OpenAI provider uses HTTPX2, so most applications do not need to configure an HTTP client directly. If your application passes `http_client=` to `AsyncOpenAI`, use HTTPX2 types for the custom client and its transport-facing options:
Expand Down
15 changes: 14 additions & 1 deletion docs/guardrails.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,20 @@ Output guardrails run in 3 steps:

An output tripwire and an exception raised by the guardrail function have different session behavior. A tripwire rejects the candidate final output. When a tripwire fires, the runner asks the configured session to persist already-completed tool call and tool output items, together with any reasoning context required to replay those calls, while excluding the rejected candidate final output. The runner applies this tripwire rule to both streaming and non-streaming runs. When the guardrail function raises an exception instead of returning a tripwire result, the runner treats the verdict as unknown and asks the configured session to persist the completed final-turn items before surfacing the guardrail exception. If that session write also fails, the session write error takes precedence. Streaming runs use the same persistence ordering as non-streaming runs and raise the terminal exception from `stream_events()`. An immediate [`RunResultStreaming.cancel()`][agents.result.RunResultStreaming.cancel] call while the output guardrail is running cancels the in-flight guardrail and does not start a final-turn session write.

Terminal function-tool output needs additional handling because the tool has already run before the agent-level output guardrail checks the value. When [`Agent.tool_use_behavior`][agents.agent.Agent.tool_use_behavior] makes that tool result the final output and an output tripwire rejects it, the SDK retains a replay-valid function call/output pair only when it can rebuild the pair from validated fields. The retained `function_call_output` payload is replaced with the fixed text `"Output withheld by an output guardrail."`; the original tool-output payload is not retained in the session, `RunState`, streamed result state, or sandbox memory input. The SDK does retain validated function-call metadata required for replay, including the function arguments, so that metadata can contain data that also appeared in the rejected output. Current-response [`OutputGuardrailResult`][agents.guardrail.OutputGuardrailResult] objects also replace `agent_output` with the fixed text and clear `output_info`. Current-response [`ToolOutputGuardrailResult`][agents.tool_guardrails.ToolOutputGuardrailResult] objects preserve the allow/reject behavior type but replace payload-bearing `output_info` and rejection messages with the same text. Earlier accepted turns and guardrail results remain unchanged. If the response contains reasoning or another shape that the SDK cannot sanitize safely, the SDK discards the complete current-response suffix instead of retaining the rejected output payload. A guardrail function that raises an exception has not returned a rejection verdict, so the completed terminal-tool turn follows the exception persistence behavior described above.
Terminal function-tool output needs additional handling because the tool has already run before the agent-level output guardrail checks the value. When [`Agent.tool_use_behavior`][agents.agent.Agent.tool_use_behavior] makes that tool result the final output and an output tripwire rejects it, the SDK retains a replay-valid function call/output pair only when it can rebuild the pair from validated fields. The retained `function_call_output` payload is replaced with the default text `"Output withheld by an output guardrail."`; the original tool-output payload is not retained in the session, `RunState`, streamed result state, or sandbox memory input. The SDK does retain validated function-call metadata required for replay, including the function arguments, so that metadata can contain data that also appeared in the rejected output. Current-response [`OutputGuardrailResult`][agents.guardrail.OutputGuardrailResult] objects also replace `agent_output` with the resolved placeholder and clear `output_info`. Current-response [`ToolOutputGuardrailResult`][agents.tool_guardrails.ToolOutputGuardrailResult] objects preserve the allow/reject behavior type but replace payload-bearing `output_info` and rejection messages with the same placeholder. Earlier accepted turns and guardrail results remain unchanged. If the response contains reasoning or another shape that the SDK cannot sanitize safely, the SDK discards the complete current-response suffix instead of retaining the rejected output payload. A guardrail function that raises an exception has not returned a rejection verdict, so the completed terminal-tool turn follows the exception persistence behavior described above.

Set [`RunConfig.output_guardrail_blocked_message`][agents.run.RunConfig.output_guardrail_blocked_message] to a non-empty string or a synchronous formatter when your application needs a different data-free placeholder. The formatter receives [`OutputGuardrailBlockedMessageArgs`][agents.run.OutputGuardrailBlockedMessageArgs] with the SDK default, the guardrail name, the agent, and the active run context. It never receives the rejected tool output or guardrail `output_info`. The returned text is persisted and replayed wherever the SDK retains the sanitized terminal-tool turn, so keep it free of sensitive data and do not copy secrets from the run context. If the formatter raises, returns `None`, returns an empty or non-string value, or produces an awaitable, the SDK uses the default placeholder. Async formatter functions are rejected when `RunConfig` is constructed.

```python
from agents import OutputGuardrailBlockedMessageArgs, RunConfig


def blocked_message(args: OutputGuardrailBlockedMessageArgs[dict[str, str]]) -> str:
return f"Output blocked by policy: {args.guardrail_name}."


run_config = RunConfig(output_guardrail_blocked_message=blocked_message)
```

## Tool guardrails

Expand Down
2 changes: 1 addition & 1 deletion docs/human_in_the_loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This page focuses on the manual approval flow via `interruptions`. If your app c

Set `needs_approval` to `True` to always require approval or provide an async function that decides per call. The callable receives the run context, parsed tool parameters, and the tool call ID.

Callable approval rules fail closed when the SDK cannot safely inspect the arguments. If the arguments are malformed JSON, are valid JSON but not an object (for example, `null` or a list), or contain non-standard constants such as `NaN`, `Infinity`, or `-Infinity`, the callable is not invoked and the call requires manual approval. This behavior is the same for Runner and Realtime tool calls.
Callable approval rules fail closed when the SDK cannot safely inspect the arguments. If the arguments are missing, empty, contain only whitespace, are malformed JSON, are valid JSON but not an object (for example, `null` or a list), or contain non-standard constants such as `NaN`, `Infinity`, or `-Infinity`, the callable is not invoked and the call requires manual approval. This behavior is the same for Runner and Realtime tool calls.

```python
from agents import Agent
Expand Down
3 changes: 3 additions & 0 deletions docs/mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ async with MCPServerManager(servers) as manager:
Key behaviors:

- `active_servers` includes only successfully connected servers when `drop_failed_servers=True` (the default).
- If the input iterable repeats the same server object, the manager owns that server once: `all_servers` and `active_servers` contain one entry, and connection and cleanup run once for that server.
- Failures are tracked in `failed_servers` and `errors`.
- Set `strict=True` to raise on the first connection failure.
- Call `reconnect(failed_only=True)` to retry failed servers, or `reconnect(failed_only=False)` to restart all servers.
Expand Down Expand Up @@ -486,6 +487,8 @@ Resources remain explicitly paginated. Pass the `nextCursor` from `list_resource

Every agent run calls `list_tools()` on each MCP server. Remote servers can introduce noticeable latency, so all of the MCP server classes expose a `cache_tools_list` option. Set it to `True` only if you are confident that the tool definitions do not change frequently. To force a fresh list later, call `invalidate_tools_cache()` on the server instance.

When caching is enabled, each `list_tools()` result contains detached copies of the cached tool definitions, including nested input schemas. Dynamic tool-filter callbacks also inspect detached copies. Mutating a returned tool or a tool received by a filter therefore does not change the server's cached schema or later `list_tools()` results.

## Tracing

[Tracing](./tracing.md) automatically captures MCP activity, including:
Expand Down
8 changes: 6 additions & 2 deletions docs/models/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ When using `context="all_turns"`, preserve the conversation through `previous_re

#### ComputerTool model selection

If an agent includes [`ComputerTool`][agents.tool.ComputerTool], the effective model on the actual Responses request determines which computer-tool payload the SDK sends. Explicit `gpt-5.5` requests use the GA built-in `computer` tool, while explicit `computer-use-preview` requests keep the older `computer_use_preview` payload.
If an agent includes [`ComputerTool`][agents.tool.ComputerTool], the effective model on the actual Responses request determines which computer-tool payload the SDK sends. When the agent does not set `model`, normal SDK model-selection precedence applies. The built-in SDK default, currently [`gpt-5.6-luna`](https://developers.openai.com/api/docs/models/gpt-5.6-luna), supports the GA built-in `computer` tool. If `OPENAI_DEFAULT_MODEL` or `RunConfig.model` overrides that default, select a model that supports computer use. Set `model` on the agent when you want to choose a different capability and cost profile for the computer-use workload; for example, `model="gpt-5.6"` uses the alias that OpenAI routes to GPT-5.6 Sol. Explicit `computer-use-preview` requests keep the older `computer_use_preview` payload.

Prompt-managed calls are the main exception. If a prompt template specifies the model and the SDK omits `model` from the request, the SDK defaults to the preview-compatible computer payload so it does not guess which model the prompt pins. To keep the GA path in that flow, either make `model="gpt-5.5"` explicit on the request or force the GA selector with `ModelSettings(tool_choice="computer")` or `ModelSettings(tool_choice="computer_use")`.
Prompt-managed calls are the main exception. If a prompt template specifies the model and the SDK omits `model` from the request, the SDK defaults to the preview-compatible computer payload so it does not guess which model the prompt pins. To keep the GA path in that flow, either make a supported GA model such as `model="gpt-5.6"` explicit on the request or force the GA selector with `ModelSettings(tool_choice="computer")` or `ModelSettings(tool_choice="computer_use")`.

With a registered [`ComputerTool`][agents.tool.ComputerTool], `tool_choice="computer"`, `"computer_use"`, and `"computer_use_preview"` are normalized to the built-in selector that matches the effective request model. If no `ComputerTool` is registered, those strings continue to behave like ordinary function names.

Expand Down Expand Up @@ -644,6 +644,8 @@ If you use [`MultiProvider`][agents.MultiProvider], pass `openai_strict_feature_

The OpenAI Chat Completions API can return audio output, but [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel] does not currently convert audio output into Agents SDK run items. If a non-streaming message or streaming delta contains audio output, the adapter raises `AgentsException("Audio is not currently supported")` instead of returning a partial or empty result. Use [Realtime agents](../realtime/guide.md) or [Voice agents](../voice/quickstart.md) for SDK-managed audio workflows.

If a streaming or non-streaming Chat Completions response ends with `finish_reason="length"` before producing assistant text, a tool call, or a refusal, the adapter raises [`ModelBehaviorError`][agents.exceptions.ModelBehaviorError]. The SDK treats this empty result as token- or reasoning-budget exhaustion, not as a content-policy refusal, so model-refusal handlers do not run for it.

Some OpenAI-compatible Chat Completions providers stream tool-call deltas in chunks that are not reliable enough for incremental SDK processing. In that case, enable streamed tool-call buffering so the SDK emits tool calls only after the provider stream finishes:

```python
Expand Down Expand Up @@ -689,6 +691,8 @@ Depending on the upstream provider path, Any-LLM may use the Responses API, Chat

If you need Any-LLM, install `openai-agents[any-llm]`, then start from [`examples/model_providers/any_llm_auto.py`](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/any_llm_auto.py) or [`examples/model_providers/any_llm_provider.py`](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/any_llm_provider.py). You can use `any-llm/...` model names with [`MultiProvider`][agents.MultiProvider], instantiate `AnyLLMModel` directly, or use `AnyLLMProvider` at run scope. If you need to pin the model surface explicitly, pass `api="responses"` or `api="chat_completions"` when constructing `AnyLLMModel`.

On the Any-LLM Chat Completions path, [`ModelSettings.extra_body`][agents.model_settings.ModelSettings.extra_body] remains a nested `extra_body` argument. The Agents SDK does not merge that mapping into Any-LLM's top-level call arguments, so keep provider-specific request-body fields inside the `extra_body` mapping.

Any-LLM remains a third-party adapter layer, so provider dependencies and capability gaps are defined upstream by Any-LLM rather than by the SDK. Usage metrics are propagated automatically when the upstream provider returns them, but streamed Chat Completions backends may require `ModelSettings(include_usage=True)` before they emit usage chunks. Validate the exact provider backend you plan to deploy if you depend on structured outputs, tool calling, usage reporting, or Responses-specific behavior.

### LiteLLM
Expand Down
2 changes: 1 addition & 1 deletion docs/realtime/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ main_agent = RealtimeAgent(

### Guardrails

Realtime agents support output guardrails on agent responses and input guardrails on function-tool calls. Output guardrail checks are debounced: each check runs on accumulated output-text and audio-transcript deltas rather than on every partial delta, and emits `guardrail_tripped` instead of raising an exception.
Realtime agents support output guardrails on agent responses and input guardrails on function-tool calls. Output guardrail checks are debounced: each check runs on accumulated output-text and audio-transcript deltas rather than on every partial delta, and emits `guardrail_tripped` instead of raising an exception. A single delta schedules at most one check. If that delta crosses multiple `debounce_text_length` boundaries, the SDK advances the next boundary past all of them instead of scheduling catch-up checks after later small deltas.

```python
from agents.guardrail import GuardrailFunctionOutput, OutputGuardrail
Expand Down
2 changes: 2 additions & 0 deletions docs/results.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ In practice:

When SDK-default nested handoff history preserves a message item verbatim, Sessions, `RunState`, and `to_input_list()` track the exact owned occurrence rather than deduplicating by content. Identical messages that occurred separately remain separate; only the already-owned occurrence is kept from being appended a second time.

When model output is converted into replayable input, `to_input_list()`, [`ModelResponse.to_input_items()`][agents.items.ModelResponse.to_input_items], and each [`RunItemBase.to_input_item()`][agents.items.RunItemBase.to_input_item] call remove provider output-only `created_by` metadata. This includes `created_by` on nested `shell_call_output` chunks. The conversion rebuilds the affected mappings and does not mutate the original raw item.

Unlike the JavaScript SDK, Python does not expose a separate `output` property containing only the model-format items newly generated during the run. Use `new_items` when you need SDK metadata, or inspect `raw_responses` when you need the raw model payloads.

Resubmitting computer-tool items as conversation input uses the raw Responses payload shape. Preview-model `computer_call` items preserve a single `action`, while `gpt-5.5` computer calls can preserve batched `actions[]`. [`to_input_list()`][agents.result.RunResultBase.to_input_list] and [`RunState`][agents.run_state.RunState] keep whichever shape the model produced, so manually resubmitting those items as conversation input, pause/resume flows, and stored transcripts continue to work across both preview and GA computer-tool calls. Local execution results still appear as `computer_call_output` items in `new_items`.
Expand Down
16 changes: 16 additions & 0 deletions docs/sandbox/clients.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,22 @@ options = DockerSandboxClientOptions(

The only supported explicit network mode is `"none"`; omit `network_mode` to preserve Docker's default behavior. A network-disabled sandbox cannot expose ports, so combining `network_mode="none"` with a non-empty `exposed_ports` tuple fails during option validation. The setting is stored in sandbox session state and reapplied if the SDK must create a replacement container while resuming that state.

### Label Docker containers

Set `labels` when an application needs to identify or manage the Docker containers created for sandbox sessions:

```python
options = DockerSandboxClientOptions(
image="python:3.14-slim",
labels={
"com.example.owner": "agents-sdk",
"com.example.environment": "development",
},
)
```

The SDK passes these key-value pairs to Docker when it creates the container and stores them in [`DockerSandboxSessionState`][agents.sandbox.sandboxes.docker.DockerSandboxSessionState]. When a resumed session reconnects to an existing container, the SDK verifies that every persisted label still has the expected value and raises `ValueError` if the labels do not match. When the SDK creates a replacement container from the saved state, it reapplies the persisted labels.

## Mounts and remote storage

Mount entries describe what storage to expose; mount strategies describe how a sandbox backend attaches that storage. Import the built-in mount entries and generic strategies from `agents.sandbox.entries`. Hosted-provider strategies are available from `agents.extensions.sandbox` or the provider-specific extension package.
Expand Down
Loading