Skip to content

Commit 86b3db5

Browse files
authored
docs: document v0.21.1 runtime behavior (#4460)
1 parent b01ea1d commit 86b3db5

8 files changed

Lines changed: 90 additions & 8 deletions

File tree

docs/models/index.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,21 @@ english_agent = Agent(
494494
)
495495
```
496496

497+
## Model-call timeouts
498+
499+
Set [`ModelSettings.timeout`][agents.model_settings.ModelSettings.timeout] to a positive number of seconds to bound each model-call attempt. The timeout applies to streaming and non-streaming calls and covers the complete attempt, including transport waits. It does not limit the full agent run, function-tool execution, or retry backoff.
500+
501+
```python
502+
from agents import Agent, ModelSettings
503+
504+
agent = Agent(
505+
name="Assistant",
506+
model_settings=ModelSettings(timeout=30.0),
507+
)
508+
```
509+
510+
If an attempt exceeds the limit, the SDK cancels the attempt and waits for its cleanup to finish before raising [`ModelTimeoutError`][agents.exceptions.ModelTimeoutError]. When runner-managed retries are enabled, the SDK passes the timeout failure to the retry policy with `context.normalized.is_timeout` set to `True`; for example, `retry_policies.network_error()` matches that classification. Each permitted retry receives a new per-attempt timeout. The SDK still applies the normal [replay-safety rules](#safety-boundaries) before retrying.
511+
497512
## Runner-managed retries
498513

499514
Retries are runtime-only and opt in. The SDK does not retry general model requests unless you set `ModelSettings(retry=...)` and your retry policy chooses to retry.

docs/realtime/guide.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ Unlike text-only runs, `runner.run()` does not produce a final result immediatel
3232

3333
By default, `RealtimeRunner` uses `OpenAIRealtimeWebSocketModel`, so the default Python path is a server-side WebSocket connection to the Realtime API. If you pass a different `RealtimeModel`, the same session lifecycle and agent features still apply, while the connection mechanics can change.
3434

35+
When the Realtime API server closes the default WebSocket connection normally, the model transport emits a `disconnected` [`RealtimeModelConnectionStatusEvent`][agents.realtime.model_events.RealtimeModelConnectionStatusEvent] followed by a [`RealtimeModelEndOfStreamEvent`][agents.realtime.model_events.RealtimeModelEndOfStreamEvent]. `RealtimeSession` forwards both inside `raw_model_event`, drains events that are already queued, and then ends asynchronous iteration without raising an exception. A caller-initiated `session.close()` does not synthesize these server-disconnect events. Unexpected WebSocket failures continue through the session's exception path instead of ending iteration as a normal server close.
36+
3537
## Agent and session configuration
3638

3739
`RealtimeAgent` is intentionally narrower than the regular `Agent` type:

docs/running_agents.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ The SDK raises exceptions in certain cases. The full list is in [`agents.excepti
589589

590590
- [`AgentsException`][agents.exceptions.AgentsException]: This is the base class for all exceptions that the SDK raises. It serves as a generic type from which all other specific exceptions are derived.
591591
- [`MaxTurnsExceeded`][agents.exceptions.MaxTurnsExceeded]: This exception is raised when the agent's run exceeds the `max_turns` limit passed to the `Runner.run`, `Runner.run_sync`, or `Runner.run_streamed` methods. It indicates that the agent could not complete its task within the specified number of agent-loop turns (LLM calls). Set `max_turns=None` to disable the limit.
592+
- [`ModelTimeoutError`][agents.exceptions.ModelTimeoutError]: This exception is raised when a model-call attempt exceeds [`ModelSettings.timeout`][agents.model_settings.ModelSettings.timeout]. See [Model-call timeouts](models/index.md#model-call-timeouts) for scope and retry behavior.
592593
- [`ModelBehaviorError`][agents.exceptions.ModelBehaviorError]: This exception occurs when the underlying model (LLM) produces unexpected or invalid outputs. This can include:
593594
- Malformed JSON: When the model provides a malformed JSON structure for tool calls or in its direct output, especially if a specific `output_type` is defined.
594595
- Unexpected tool-related failures: When the model fails to use tools in an expected manner

docs/sandbox/clients.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,19 @@ run_config = RunConfig(
5454

5555
Use this when you want container isolation or want the sandbox image to match the image used in another environment. See [examples/sandbox/docker/docker_runner.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docker/docker_runner.py).
5656

57+
### Disable Docker networking
58+
59+
Set `network_mode="none"` when a Docker sandbox must not have network access:
60+
61+
```python
62+
options = DockerSandboxClientOptions(
63+
image="python:3.14-slim",
64+
network_mode="none",
65+
)
66+
```
67+
68+
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.
69+
5770
## Mounts and remote storage
5871

5972
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.
@@ -102,6 +115,22 @@ For provider-specific setup notes and links for the checked-in extension example
102115

103116
</div>
104117

118+
### Size Modal sandboxes
119+
120+
Use `ModalSandboxClientOptions.cpu` and `ModalSandboxClientOptions.memory` to request resources for a new Modal sandbox. A single value requests that amount. A two-item `(request, limit)` tuple uses the first item as the request and the second item as the limit. Memory values are in MiB.
121+
122+
```python
123+
from agents.extensions.sandbox import ModalSandboxClientOptions
124+
125+
options = ModalSandboxClientOptions(
126+
app_name="agents-sandbox",
127+
cpu=(1.0, 4.0),
128+
memory=(2048, 8192),
129+
)
130+
```
131+
132+
Leave `cpu`, `memory`, or both as `None` to use Modal's default for each omitted resource. The selected values are preserved in sandbox session state so replacement sandboxes use the same resource configuration.
133+
105134
Hosted sandbox clients expose provider-specific mount strategies. Choose the backend and mount strategy that best fit your storage provider:
106135

107136
<div class="sandbox-nowrap-first-column-table" markdown="1">

docs/sandbox/guide.md

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ Good uses for `instructions` include:
169169
- [examples/sandbox/unix_local_pty.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/unix_local_pty.py) keeps the agent in one interactive process when PTY state matters.
170170
- [examples/sandbox/handoffs.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/handoffs.py) forbids the sandbox reviewer from answering the user directly after inspection.
171171
- [examples/sandbox/tax_prep.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/tax_prep.py) requires the final filled files to actually land in `output/`.
172-
- [examples/sandbox/docs/coding_task.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docs/coding_task.py) pins the exact verification command and clarifies workspace-root-relative patch paths.
172+
- [examples/sandbox/docs/coding_task.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/docs/coding_task.py) pins the exact verification command and clarifies that patch paths are workspace-root relative when `SandboxRunConfig.cwd` is unset.
173173

174174
Avoid copying the user's one-off task into `instructions`, embedding long reference material that belongs in the manifest, restating tool docs that built-in capabilities already inject, or mixing in local installation notes the model does not need at run time.
175175

@@ -186,7 +186,7 @@ Built-in capabilities include:
186186
| Capability | Add it when | Notes |
187187
| --- | --- | --- |
188188
| `Shell` | The agent needs shell access. | Adds `exec_command`, plus `write_stdin` when the sandbox client supports PTY interaction. |
189-
| `Filesystem` | The agent needs to edit files or inspect local images. | Adds `apply_patch` and `view_image`; patch paths are workspace-root-relative. |
189+
| `Filesystem` | The agent needs to edit files or inspect local images. | Adds `apply_patch` and `view_image`; relative paths use the workspace root by default and `SandboxRunConfig.cwd` when configured. |
190190
| `Skills` | You want skill discovery and materialization in the sandbox. | Prefer this over manually mounting `.agents` or `.agents/skills`; `Skills` indexes and materializes skills into the sandbox for you. |
191191
| `Memory` | Follow-on runs should read or generate memory artifacts. | Requires `Shell`; updating memory artifacts during a run also requires `Filesystem`. |
192192
| `Compaction` | Long-running flows need context trimming after compaction items. | Adjusts model sampling and input handling. |
@@ -195,6 +195,8 @@ Built-in capabilities include:
195195

196196
By default, `SandboxAgent.capabilities` uses `Capabilities.default()`, which includes `Filesystem()`, `Shell()`, and `Compaction()`. If you pass `capabilities=[...]`, that list replaces the default, so include any default capabilities you still want.
197197

198+
The `view_image` tool identifies PNG, JPEG, GIF, WebP, BMP, and TIFF raster images from their file content, not from the filename extension. A filename with a raster-image extension is rejected when its content is unsupported, while supported raster content can be loaded even when the filename has no image extension. For `.svg` and `.svgz` files, the tool retains filename-based compatibility in addition to recognizing SVG markup from file content.
199+
198200
For skills, choose the source based on how you want them materialized:
199201

200202
- `Skills(lazy_from=LocalDirLazySkillSource(...))` is a good default for larger local skill directories because the model can discover the index first and load only what it needs.
@@ -235,7 +237,7 @@ Use manifest entries for the material the agent needs before work begins:
235237

236238
Mount entries describe what storage to expose; mount strategies describe how a sandbox backend attaches that storage. See [Sandbox clients](clients.md#mounts-and-remote-storage) for mount options and provider support.
237239

238-
Good manifest design usually means keeping the workspace contract narrow, putting long task recipes in workspace files such as `repo/task.md`, and using relative workspace paths in instructions, for example `repo/task.md` or `output/report.md`. If the agent edits files with the `Filesystem` capability's `apply_patch` tool, remember that patch paths are relative to the sandbox workspace root, not the shell `workdir`.
240+
Good manifest design usually means keeping the workspace contract narrow, putting long task recipes in workspace files such as `repo/task.md`, and using relative workspace paths in instructions, for example `repo/task.md` or `output/report.md`. If the agent edits files with the `Filesystem` capability's `apply_patch` tool, remember that patch paths use the sandbox workspace root by default or `SandboxRunConfig.cwd` when configured; they do not use the shell `workdir`.
239241

240242
Use `extra_path_grants` only when the agent needs a concrete absolute path outside the workspace or the manifest needs to copy a trusted local source outside the SDK process working directory. Examples include `/tmp` for temporary tool output, `/opt/toolchain` for a read-only runtime, or a generated skills directory that should be materialized into the sandbox. A grant applies to local source materialization and SDK file APIs. It also applies to shell execution when the backend can enforce filesystem policy:
241243

@@ -472,6 +474,31 @@ These options only matter when the runner is creating a fresh sandbox session:
472474

473475
</div>
474476

477+
### Model-facing working directory
478+
479+
Set `cwd` to a POSIX workspace-relative directory when several runs should share one sandbox session but operate in separate subdirectories. The directory must exist and be accessible to the configured sandbox user when the runner validates `cwd`. For a fresh session, the runner materializes the manifest first, so the manifest can create the directory before this validation.
480+
481+
```python
482+
from agents import Runner
483+
from agents.run import RunConfig
484+
from agents.sandbox import SandboxRunConfig
485+
486+
result = await Runner.run(
487+
agent,
488+
"Work only on task A.",
489+
run_config=RunConfig(
490+
sandbox=SandboxRunConfig(
491+
session=shared_sandbox,
492+
cwd="tasks/task-a",
493+
),
494+
),
495+
)
496+
```
497+
498+
Relative paths used by the built-in `exec_command`, `view_image`, and `apply_patch` tools resolve from `cwd`. For the `cwd` value itself, absolute paths, parent segments such as `..`, and empty values are rejected. String values must use forward slashes. Relative `PurePath` values are normalized to POSIX form, while absolute `PurePath` values remain invalid. Direct `BaseSandboxSession` file APIs remain workspace-root relative, so `cwd` does not change `Manifest.root` or the session's underlying workspace boundary. The setting changes relative-path resolution only: it does not confine the run to `cwd` or prevent access to other paths allowed by the shared session's workspace policy.
499+
500+
Custom path-bearing capabilities must apply their bound [`SandboxWorkspaceScope`][agents.sandbox.workspace_paths.SandboxWorkspaceScope] when resolving model-provided relative paths. See [examples/sandbox/shared_session_workdirs.py](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/shared_session_workdirs.py) for two concurrent runs that share one sandbox session while keeping their model-facing working directories separate.
501+
475502
### Materialization controls
476503

477504
`concurrency_limits` controls how much sandbox materialization work can run in parallel. Use `SandboxConcurrencyLimits(manifest_entries=..., local_dir_files=...)` when large manifests or local directory copies need tighter resource control. Set either value to `None` to disable that specific limit.
@@ -520,9 +547,9 @@ def build_agent(model: str) -> SandboxAgent[None]:
520547
"and summarize the file changes and risks. "
521548
"Read `repo/task.md` before editing files. Stay grounded in the repository, preserve "
522549
"existing behavior, and mention the exact verification command you ran. "
523-
"Use the `$credit-note-fixer` skill before editing files. If the repo lives under "
524-
"`repo/`, remember that `apply_patch` paths stay relative to the sandbox workspace "
525-
"root, so edits still target `repo/...`."
550+
"Use the `$credit-note-fixer` skill before editing files. "
551+
"This example leaves `SandboxRunConfig.cwd` unset, so `apply_patch` paths stay "
552+
"relative to the sandbox workspace root and edits still target `repo/...`."
526553
),
527554
# Put repos and task files in the manifest.
528555
default_manifest=Manifest(

docs/sessions/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ print(result.final_output)
276276

277277
By default, after each turn, the SDK checks whether the compaction candidate meets the threshold and compacts only if it does.
278278

279+
When automatic compaction runs, the SDK waits for it before `Runner.run(...)` returns or the streamed event iterator closes. Usage reported by the compaction request contributes to that run's [`Usage`](../usage.md) totals. By default, a manual `run_compaction()` call made later has no enclosing run context and does not update the completed run's usage object.
280+
279281
`compaction_mode="previous_response_id"` uses Responses API response IDs retained by the compaction session and works best while that response chain remains available. `compaction_mode="input"` rebuilds the compaction request from the current session items instead, which is useful when the response chain is unavailable or you want the session contents to be the source of truth. The default `"auto"` chooses the safest available option.
280282

281283
If your agent runs with `ModelSettings(store=False)`, the Responses API does not retain the last response for later lookup. In that stateless setup, the default `"auto"` mode falls back to input-based compaction instead of relying on `previous_response_id`. See [`examples/memory/compaction_session_stateless_example.py`](https://github.com/openai/openai-agents-python/tree/main/examples/memory/compaction_session_stateless_example.py) for a complete example.

docs/usage.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ print("Total tokens:", usage.total_tokens)
3030

3131
Usage is aggregated across all model calls during the run, including model calls that produce tool calls or handoffs.
3232

33+
When an [`OpenAIResponsesCompactionSession`][agents.memory.openai_responses_compaction_session.OpenAIResponsesCompactionSession] automatically compacts history before the run finishes, usage reported by that `responses.compact` request is also added to the same run totals. A manual `run_compaction()` call made outside a run has no enclosing run context, so it does not update the usage object returned by an earlier run. See [OpenAI Responses compaction sessions](sessions/index.md#openai-responses-compaction-sessions).
34+
3335
### Enabling usage with third-party adapters
3436

3537
Usage reporting varies across third-party adapters and provider backends. If you access models through third-party adapters and need accurate `result.context_wrapper.usage` values:

src/agents/run_config.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,12 @@ class SandboxRunConfig:
224224
225225
Relative paths used by the built-in `exec_command`, `view_image`, and `apply_patch` tools
226226
resolve from this directory. Custom path-bearing capabilities must apply their bound
227-
`SandboxWorkspaceScope` explicitly. The directory must already exist when the run starts.
228-
This setting does not change `Manifest.root` or direct `BaseSandboxSession` path behavior.
227+
`SandboxWorkspaceScope` explicitly. The directory must exist and be accessible to the
228+
configured sandbox user when the runner validates `cwd`; for a fresh session, the runner
229+
materializes the manifest before that validation.
230+
This setting changes relative-path resolution only. It does not confine the run to `cwd`,
231+
prevent access to other paths allowed by the shared session's workspace policy, change
232+
`Manifest.root`, or change direct `BaseSandboxSession` path behavior.
229233
"""
230234

231235
if TYPE_CHECKING:

0 commit comments

Comments
 (0)