In deep agent workflows, each sub‐agent automatically performs an LLM
step to summarize its tool calls before returning to its parent. This
leads to:
1. Excessive latency: every nested agent invokes the LLM, compounding
delays.
2. Loss of raw tool data: summaries may strip out details the top‐level
agent needs.
We discovered that `Agent.as_tool(...)` already accepts an
(undocumented) `custom_output_extractor` parameter. By providing a
callback, a parent agent can override what the sub‐agent returns e.g.
hand back raw tool outputs or a custom slice so that only the final
agent does summarization.
---
This PR adds a “Custom output extraction” section to the Markdown docs
under “Agents as tools,” with a minimal code example.
The documentation in `docs/mcp.md` listed three server types (stdio,
HTTP over SSE, Streamable HTTP) but incorrectly stated "two kinds of
servers" in the heading. This PR fixes the numerical discrepancy.
**Changes:**
- Modified from "two kinds of servers" to "three kinds of servers".
- File: `docs/mcp.md` (line 11).
This PR adds Portkey AI as a tracing provider. Portkey helps you take
your OpenAI agents from prototype to production.
Portkey turns your experimental OpenAI Agents into production-ready
systems by providing:
- Complete observability of every agent step, tool use, and interaction
- Built-in reliability with fallbacks, retries, and load balancing
- Cost tracking and optimization to manage your AI spend
- Access to 1600+ LLMs through a single integration
- Guardrails to keep agent behavior safe and compliant
- Version-controlled prompts for consistent agent performance
Towards #786
## Summary
- mention MCPServerStreamableHttp in MCP server docs
- document CodeInterpreterTool, HostedMCPTool, ImageGenerationTool and
LocalShellTool
- update Japanese translations
Only the file name is needed since graphviz's `render()` automatically
adds the file extension.
Also, unnecessary .gv (.dot) files are output, so the `cleanup=True`
option has been modified to prevent them from being saved.
Here is a similar modification, but in a different content.
- https://github.com/openai/openai-agents-python/pull/451
This pull request introduces the following changes:
1. **Exclude translated pages from search**: I explored ways to make the
search plugin work with the i18n plugin, but it would require extensive
custom JavaScript hacks. So for now, I’m holding off on this work.
2. **Switch from GPT-4.1 to o3 for even better translation quality**:
While 4.1 performs well, o3 shows even greater quality for this task,
and there’s no reason to avoid using it.
This pull request enhances the document translation workflow by
switching to the new GPT-4.1 model. The generator script’s prompt now
includes a “workflow” section that guides the model to iterate
self-reviews on its outputs to autonomously achieve the highest quality.
This addition has noticeably improved the naturalness and consistency of
the wording in the translated outputs.
Detected typos using typos-cli (https://crates.io/crates/typos-cli). It
detected "occured" in a string constant "handoff_occured" too, but I
didn't change the part this time because it could be a minor breaking
change.
Full outputs:
```
% typos .
error: `Supresses` should be `Suppresses`
--> ./src/agents/function_schema.py:134:7
|
134 | # Supresses warnings about missing annotations for params
| ^^^^^^^^^
|
error: `typ` should be `typo`, `type`
--> ./src/agents/strict_schema.py:51:5
|
51 | typ = json_schema.get("type")
| ^^^
|
error: `typ` should be `typo`, `type`
--> ./src/agents/strict_schema.py:52:8
|
52 | if typ == "object" and "additionalProperties" not in json_schema:
| ^^^
|
error: `typ` should be `typo`, `type`
--> ./src/agents/strict_schema.py:55:9
|
55 | typ == "object"
| ^^^
|
error: `occured` should be `occurred`
--> ./src/agents/stream_events.py:34:18
|
34 | "handoff_occured",
| ^^^^^^^
|
error: `occured` should be `occurred`
--> ./src/agents/_run_impl.py:723:69
|
723 | event = RunItemStreamEvent(item=item, name="handoff_occured")
| ^^^^^^^
|
error: `desitnation` should be `destination`
--> ./src/agents/tracing/span_data.py:171:25
|
171 | Includes source and desitnation agents.
| ^^^^^^^^^^^
|
error: `exmaples` should be `examples`
--> ./docs/scripts/translate_docs.py:71:145
|
71 | "* The term 'examples' must be code examples when the page mentions the code examples in the repo, it can be translated as either 'code exmaples' or 'sample code'.",
| ^^^^^^^^
|
error: `structed` should be `structured`
--> ./tests/test_agent_hooks.py:227:16
|
227 | async def test_structed_output_non_streamed_agent_hooks():
| ^^^^^^^^
|
error: `structed` should be `structured`
--> ./tests/test_agent_hooks.py:298:16
|
298 | async def test_structed_output_streamed_agent_hooks():
| ^^^^^^^^
|
```
This is a pretty minor improvement to the docs: `model_settings`
parameter is only mentioned on the agent doc page, but first-time
visitors may want to know it’s also available on the models page.
This pull request introduces functionality for visualizing agent
structures using Graphviz. The changes include adding a new dependency,
implementing functions to generate and draw graphs, and adding tests for
these functions.
New functionality for visualizing agent structures:
* Added `graphviz` as a new dependency in `pyproject.toml`.
* Implemented functions in `src/agents/visualizations.py` to generate
and draw graphs for agents using Graphviz. These functions include
`get_main_graph`, `get_all_nodes`, `get_all_edges`, and `draw_graph`.
Testing the new visualization functionality:
* Added tests in `tests/test_visualizations.py` to verify the
correctness of the graph generation and drawing functions. The tests
cover `get_main_graph`, `get_all_nodes`, `get_all_edges`, and
`draw_graph`.
For example, given the following code:
```python
from agents import Agent, function_tool
from agents.visualizations import draw_graph
@function_tool
def get_weather(city: str) -> str:
return f"The weather in {city} is sunny."
spanish_agent = Agent(
name="Spanish agent",
instructions="You only speak Spanish.",
)
english_agent = Agent(
name="English agent",
instructions="You only speak English",
)
triage_agent = Agent(
name="Triage agent",
instructions="Handoff to the appropriate agent based on the language of the request.",
handoffs=[spanish_agent, english_agent],
tools=[get_weather],
)
draw_graph(triage_agent)
```
Generates the following image:
<img width="614" alt="Screenshot 2025-03-13 at 18 36 23"
src="https://github.com/user-attachments/assets/d01fe502-6886-4efb-aaf8-c92e4524b0fe"
/>
## Summary:
#263 added this behavior. The goal was to prevent infinite loops when tool choice was set. The key change I'm making is:
1. Making it configurable on the agent.
2. Doing bookkeeping in the Runner to track this, to prevent mutating agents.
3. Not resetting the global tool choice in RunConfig.
## Test Plan:
Unit tests.
.
# Fix potential infinite tool call loop by resetting tool_choice after
tool execution
## Summary
This PR fixes an issue where setting `tool_choice` to "required" or a
specific function name could cause models to get stuck in an infinite
tool call loop.
When `tool_choice` is set to force tool usage, this setting persists
across model invocations. This PR automatically resets `tool_choice` to
"auto" after tool execution, allowing the model to decide whether to
make additional tool calls in subsequent turns.
Unlike using `tool_use_behavior="stop_on_first_tool"`, this approach
lets the model continue processing tool results while preventing forced
repeated tool calls.
## Test plan
- Added tests to verify tool_choice reset behavior for both agent and
run_config settings
- Added integration test to verify the solution prevents infinite loops
- All tests pass
## Checks
- [x] I've added new tests for the fix
- [x] I've updated the relevant documentation (added comment in code)
- [x] I've run `make lint` and `make format`
- [x] I've made sure tests pass