When an input image is given as input, the code tries to access the
'detail' key, that may not be present as noted in #159.
With this pull request, now it tries to access the key, otherwise set
the value to `None`.
@pakrym-oai or @rm-openai let me know if you want any changes.
When using the voice agent in typed code, it is suboptimal and error
prone to type the TTS voice variables in your code independently.
With this commit we are making the type exportable so that developers
can just use that and be future-proof.
Example of usage in code:
```
DEFAULT_TTS_VOICE: TTSModelSettings.TTSVoice = "alloy"
...
tts_voice: TTSModelSettings.TTSVoice = DEFAULT_TTS_VOICE
...
output = await VoicePipeline(
workflow=workflow,
config=VoicePipelineConfig(
tts_settings=TTSModelSettings(
buffer_size=512,
transform_data=transform_data,
voice=tts_voice,
instructions=tts_instructions,
))
).run(audio_input)
```
---------
Co-authored-by: Rohan Mehta <rm@openai.com>
In response to issue #587 , I implemented a solution to first check if
`refusal` and `usage` attributes exist in the `delta` object.
I added a unit test similar to `test_openai_chatcompletions_stream.py`.
Let me know if I should change something.
---------
Co-authored-by: Rohan Mehta <rm@openai.com>
Per
https://modelcontextprotocol.io/specification/draft/basic/lifecycle#timeouts
"Implementations SHOULD establish timeouts for all sent requests, to
prevent hung connections and resource exhaustion. When the request has
not received a success or error response within the timeout period, the
sender SHOULD issue a cancellation notification for that request and
stop waiting for a response.
SDKs and other middleware SHOULD allow these timeouts to be configured
on a per-request basis."
I picked 5 seconds since that's the default for SSE
Now that `ModelSettings` has `Reasoning`, a non-primitive object,
`dataclasses.as_dict()` wont work. It will raise an error when you try
to serialize (e.g. for tracing). This ensures the object is actually
serializable.
Fix for #574
@rm-openai I'm not sure how to add a test within the repo but I have
pasted a test script below that seems to work
```python
import asyncio
from openai.types.responses import ResponseTextDeltaEvent
from agents import Agent, Runner
async def main():
agent = Agent(
name="Joker",
instructions="You are a helpful assistant.",
)
result = Runner.run_streamed(agent, input="Please tell me 5 jokes.")
num_visible_event = 0
async for event in result.stream_events():
if event.type == "raw_response_event" and isinstance(event.data, ResponseTextDeltaEvent):
print(event.data.delta, end="", flush=True)
num_visible_event += 1
print(num_visible_event)
if num_visible_event == 3:
result.cancel()
if __name__ == "__main__":
asyncio.run(main())
````
## Summary
This replaces the default model provider with a `MultiProvider`, which
has the logic:
- if the model name starts with `openai/` or doesn't contain "/", use
OpenAI
- if the model name starts with `litellm/`, use LiteLLM to use the
appropriate model provider.
It's also extensible, so users can create their own mappings. I also
imagine that if we natively supported Anthropic/Gemini etc, we can add
it to MultiProvider to make it work.
The goal is that it should be really easy to use any model provider.
Today if you pass `model="gpt-4.1"`, it works great. But
`model="claude-sonnet-3.7"` doesn't. If we can make it that easy, it's a
win for devx.
I'm not entirely sure if this is a good idea - is it too magical? Is the
API too reliant on litellm? Comments welcome.
## Test plan
For now, the example. Will add unit tests if we agree its worth mergin.
---------
Co-authored-by: Steven Heidel <steven@heidel.ca>
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
See #528, some folks are having issues because their output types are
not strict-compatible.
My approach was:
1. Create `AgentOutputSchemaBase`, which represents the base methods for
an output type - the json schema + validation
2. Make the existing `AgentOutputSchema` subclass
`AgentOutputSchemaBase`
3. Allow users to pass a `AgentOutputSchemaBase` to
`Agent(output_type=...)`
litellm is a library that abstracts away details/differences for a lot
of model providers. Adding an extension, so that any provider can easily
be integrated.
---
[//]: # (BEGIN SAPLING FOOTER)
* #532
* __->__ #524
The current ChatCompletion API supports only `parallel_tool_calls=True`
or `parallel_tool_calls=NOT_GIVEN`
This PR is to support setting `parallel_tool_calls=False`, a common
requirement in controlling agent tool use patterns (e.g. ensuring one
tool call at the time, to facilitate desired tool calling sequence).
I followed the merged
[PR#333](https://github.com/openai/openai-agents-python/pull/333) for
consistency.
Allows passing in the previous_response_id to reduce sending the same
data again and again.
Test plan:
Examples. Adding tests in next PR shortly.
---
[//]: # (BEGIN SAPLING FOOTER)
* __->__ #509
* #508
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():
| ^^^^^^^^
|
```
Added the possibility to pass `extra_query` and `extra_body` parameters
when sending a request.
In this implementation I added the attributes to `ModelSettings` as
suggested by @rm-openai in #487 .
I'll be happy to add some tests if you have any suggestions.
fix issue https://github.com/openai/openai-agents-python/issues/442
below is an example to overwrite include_usage
```
result = Runner.run_streamed(
agent,
"Write a haiku about recursion in programming.",
run_config=RunConfig(
model_provider=CUSTOM_MODEL_PROVIDER,
model_settings=ModelSettings(include_usage=True)
),
)
```
Summary:
1. Use <2 for MCP version so it doesn't break if the MCP sdk upgrades.
2. Test the func schema extraction logic.
3. Fix the logic to get the version nuber of the framework
Test Plan:
unit tests
## Summary:
Towards #404. I made this configurable because it's not clear this is
always a good thing to do. I also made it default to False because I'm
not sure if this could cause errors.
If it works out well, we can switch the default in the future as a small
breaking changes
## Test Plan:
Unit tests
### **Summary**
This pull request fixes docstring in `ToolsToFinalOutputFunction`, where
`ToolToFinalOutputResult` was incorrectly referenced instead of
`ToolsToFinalOutputResult`.
### **Changes Made**
- Updated the docstring of `ToolsToFinalOutputFunction` to correctly
reference `ToolsToFinalOutputResult`.
### **Before**
```python
"""A function that takes a run context and a list of tool results, and returns a
`ToolToFinalOutputResult`.
"""
```
### **After**
```python
"""A function that takes a run context and a list of tool results, and returns a
`ToolsToFinalOutputResult`.
"""
```
### **Why This Change?**
- The incorrect reference could cause confusion for developers reading
the code.
- This aligns the documentation with the actual return type of the
function.
### **Checklist**
- [x] Verify correct reference to `ToolsToFinalOutputResult`
- [x] Ensure no functionality is affected
### **Testing**
This is a documentation-only change and does not affect runtime
behavior.
### **Reviewer Notes**
- Please review for accuracy in documentation.
- No additional tests are needed since this is a non-functional change.
Towards #345
## Summary:
Using a `dict` or `Mapping` isn't strict-mode compliant. But we were
checking for the literal `True` whereas the value can also be an array,
for example. Fix that.
## Test Plan:
Unit tests
## Summary:
Adds tracing and tests for tracing.
- Tools are added to the agents
- Theres a span for the mcp tools lookup
- Functions have MCP data
## Test Plan:
Unit tests
.
## Summary:
Adds tracing and tests for tracing.
- Tools are added to the agents
- Theres a span for the mcp tools lookup
- Functions have MCP data
## Test Plan:
Unit tests
.
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"
/>