Skip to content

Commit 557b97e

Browse files
committed
docs: update pages to include recent changes
1 parent b99d186 commit 557b97e

5 files changed

Lines changed: 41 additions & 0 deletions

File tree

docs/agents.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ The most common properties of an agent are:
3333
| `model_settings` | no | Model tuning parameters such as `temperature`, `top_p`, and `tool_choice`. |
3434
| `tools` | no | Tools the agent can call. See [Tools](tools.md). |
3535
| `mcp_servers` | no | MCP-backed tools for the agent. See the [MCP guide](mcp.md). |
36+
| `mcp_config` | no | Fine-tune how MCP tools are prepared, such as strict schema conversion and MCP failure formatting. See the [MCP guide](mcp.md#agent-level-mcp-configuration). |
3637
| `input_guardrails` | no | Guardrails that run on the first user input for this agent chain. See [Guardrails](guardrails.md). |
3738
| `output_guardrails` | no | Guardrails that run on the final output for this agent. See [Guardrails](guardrails.md). |
3839
| `output_type` | no | Structured output type instead of plain text. See [Output types](#output-types). |
40+
| `hooks` | no | Agent-scoped lifecycle callbacks. See [Lifecycle events (hooks)](#lifecycle-events-hooks). |
3941
| `tool_use_behavior` | no | Control whether tool results loop back to the model or end the run. See [Tool use behavior](#tool-use-behavior). |
4042
| `reset_tool_choice` | no | Reset `tool_choice` after a tool call (default: `True`) to avoid tool-use loops. See [Forcing tool use](#forcing-tool-use). |
4143

docs/examples.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Check out a variety of sample implementations of the SDK in the examples section
1515
- LLM as a judge
1616
- Routing
1717
- Streaming guardrails
18+
- Custom rejection messages for approval flows (`examples/agent_patterns/human_in_the_loop_custom_rejection.py`)
1819

1920
- **[basic](https://github.com/openai/openai-agents-python/tree/main/examples/basic):**
2021
These examples showcase foundational capabilities of the SDK, such as
@@ -64,6 +65,7 @@ Check out a variety of sample implementations of the SDK in the examples section
6465
- Encrypted session storage
6566
- OpenAI Conversations session storage
6667
- Responses compaction session storage
68+
- Stateless Responses compaction with `ModelSettings(store=False)` (`examples/memory/compaction_session_stateless_example.py`)
6769

6870
- **[model_providers](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers):**
6971
Explore how to use non-OpenAI models with the SDK, including custom providers and LiteLLM integration.

docs/human_in_the_loop.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,36 @@ Sticky decisions created with `always_approve=True` or `always_reject=True` are
5151

5252
You do not need to resolve every pending approval in the same pass. `interruptions` can contain a mix of regular function tools, hosted MCP approvals, and nested `Agent.as_tool()` approvals. If you rerun after approving or rejecting only some items, those resolved calls can continue while unresolved ones remain in `interruptions` and pause the run again.
5353

54+
## Custom rejection messages
55+
56+
By default, a rejected tool call returns the SDK's standard rejection text back into the run. You can customize that message in two layers:
57+
58+
- Run-wide fallback: set [`RunConfig.tool_error_formatter`][agents.run.RunConfig.tool_error_formatter] to control the default model-visible message for approval rejections across the whole run.
59+
- Per-call override: pass `rejection_message=...` to `state.reject(...)` when you want one specific rejected tool call to surface a different message.
60+
61+
If both are provided, the per-call `rejection_message` takes precedence over the run-wide formatter.
62+
63+
```python
64+
from agents import RunConfig, ToolErrorFormatterArgs
65+
66+
67+
def format_rejection(args: ToolErrorFormatterArgs[None]) -> str | None:
68+
if args.kind != "approval_rejected":
69+
return None
70+
return "Publish action was canceled because approval was rejected."
71+
72+
73+
run_config = RunConfig(tool_error_formatter=format_rejection)
74+
75+
# Later, while resolving a specific interruption:
76+
state.reject(
77+
interruption,
78+
rejection_message="Publish action was canceled because the reviewer denied approval.",
79+
)
80+
```
81+
82+
See [`examples/agent_patterns/human_in_the_loop_custom_rejection.py`](https://github.com/openai/openai-agents-python/tree/main/examples/agent_patterns/human_in_the_loop_custom_rejection.py) for a complete example that shows both layers together.
83+
5484
## Automatic approval decisions
5585

5686
Manual `interruptions` are the most general pattern, but they are not the only one:
@@ -140,6 +170,7 @@ To stream output while waiting for approvals, call `Runner.run_streamed`, consum
140170
## Repository patterns and examples
141171

142172
- **Streaming approvals**: `examples/agent_patterns/human_in_the_loop_stream.py` shows how to drain `stream_events()` and then approve pending tool calls before resuming with `Runner.run_streamed(agent, state)`.
173+
- **Custom rejection text**: `examples/agent_patterns/human_in_the_loop_custom_rejection.py` shows how to combine run-level `tool_error_formatter` with per-call `rejection_message` overrides when approvals are rejected.
143174
- **Agent as tool approvals**: `Agent.as_tool(..., needs_approval=...)` applies the same interruption flow when delegated agent tasks need review. Nested interruptions still surface on the outer run, so resume the original top-level agent rather than the nested one.
144175
- **Local shell and apply_patch tools**: `ShellTool` and `ApplyPatchTool` also support `needs_approval`. Use `state.approve(interruption, always_approve=True)` or `state.reject(..., always_reject=True)` to cache the decision for future calls. For automatic decisions, provide `on_approval` (see `examples/tools/shell.py`); for manual decisions, handle interruptions (see `examples/tools/shell_human_in_the_loop.py`). Hosted shell environments do not support `needs_approval` or `on_approval`; see the [tools guide](tools.md).
145176
- **Local MCP servers**: Use `require_approval` on `MCPServerStdio` / `MCPServerSse` / `MCPServerStreamableHttp` to gate MCP tool calls (see `examples/mcp/get_all_mcp_tools_example/main.py` and `examples/mcp/tool_filter_example/main.py`).

docs/models/index.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ When you are using the OpenAI Responses API, several request fields already have
265265
| --- | --- |
266266
| `parallel_tool_calls` | Allow or forbid multiple tool calls in the same turn. |
267267
| `truncation` | Set `"auto"` to let the Responses API drop the oldest conversation items instead of failing when context would overflow. |
268+
| `store` | Control whether the generated response is stored server-side for later retrieval. This matters for follow-up workflows that rely on response IDs, and for session compaction flows that may need to fall back to local input when `store=False`. |
268269
| `prompt_cache_retention` | Keep cached prompt prefixes around longer, for example with `"24h"`. |
269270
| `response_include` | Request richer response payloads such as `web_search_call.action.sources`, `file_search_call.results`, or `reasoning.encrypted_content`. |
270271
| `top_logprobs` | Request top-token logprobs for output text. The SDK also adds `message.output_text.logprobs` automatically. |
@@ -279,13 +280,16 @@ research_agent = Agent(
279280
model_settings=ModelSettings(
280281
parallel_tool_calls=False,
281282
truncation="auto",
283+
store=True,
282284
prompt_cache_retention="24h",
283285
response_include=["web_search_call.action.sources"],
284286
top_logprobs=5,
285287
),
286288
)
287289
```
288290

291+
When you set `store=False`, the Responses API does not keep that response available for later server-side retrieval. This is useful for stateless or zero-data-retention style flows, but it also means features that would otherwise reuse response IDs need to rely on locally managed state instead. For example, [`OpenAIResponsesCompactionSession`][agents.memory.openai_responses_compaction_session.OpenAIResponsesCompactionSession] switches its default `"auto"` compaction path to input-based compaction when the last response was not stored. See the [Sessions guide](../sessions/index.md#openai-responses-compaction-sessions).
292+
289293
#### Runner-managed retries
290294

291295
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/sessions/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,8 @@ By default, compaction runs after each turn once the candidate threshold is reac
277277

278278
`compaction_mode="previous_response_id"` works best when you are already chaining turns with Responses API response IDs. `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.
279279

280+
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.
281+
280282
#### auto-compaction can block streaming
281283

282284
Compaction clears and rewrites the session history, so the SDK waits for compaction to finish before considering the run complete. In streaming mode, this means `run.stream_events()` can stay open for a few seconds after the last output token if compaction is heavy.

0 commit comments

Comments
 (0)