Commit graph

146 commits

Author SHA1 Message Date
westhood
775d3e237e
Ensure item.model_dump only contains JSON serializable types (#801)
The EmbeddedResource from MCP tool call contains a field with type
AnyUrl that is not JSON-serializable. To avoid this exception, use
item.model_dump(mode="json") to ensure a JSON-serializable return value.
2025-06-02 11:10:21 -04:00
Kazuhiro Sera
3e7b2863e9
Fix #777 by handling MCPCall events in RunImpl (#799)
This pull request resolves #777; If you think we should introduce a new
item type for MCP call output, please let me know. As other hosted tools
use this event, I believe using the same should be good to go tho.
2025-06-02 11:10:07 -04:00
Rohan Mehta
cfe9099f3f
Add comment to handoff_occured misspelling (#792)
People keep trying to fix this, but its a breaking change.
2025-05-30 14:41:54 -04:00
Rehan Ul Haq
64383502dd
docs: fix typo in docstring for is_strict_json_schema method (#775)
### Overview

This PR fixes a small typo in the docstring of the
`is_strict_json_schema` abstract method of the `AgentOutputSchemaBase`
class in `agent_output.py`.

### Changes

- Corrected the word “valis” to “valid” in the docstring.

### Motivation

Clear and correct documentation improves code readability and reduces
confusion for users and contributors.

### Checklist

- [x] I have reviewed the docstring after making the change.
- [x] No functionality is affected.
- [x] The change follows the repository’s contribution guidelines.
2025-05-30 12:14:10 -04:00
Rehan Ul Haq
16fb29c1f0
Fix typo in assertion message for handoff function (#780)
### Overview

This PR fixes a typo in the assert statement within the `handoff`
function in `handoffs.py`, changing `'on_input'` to `'on_handoff`' for
accuracy and clarity.

### Changes

- Corrected the word “on_input” to “on_handoff” in the docstring.

### Motivation

Clear and correct documentation improves code readability and reduces
confusion for users and contributors.

### Checklist

- [x] I have reviewed the docstring after making the change.
- [x] No functionality is affected.
- [x] The change follows the repository’s contribution guidelines.
2025-05-30 11:53:15 -04:00
rob-openai
b699d9a533
Small fix for litellm model (#789)
Small fix:

Removing `import litellm.types` as its outside the try except block for
importing litellm so the import error message isn't displayed, and the
line actually isn't needed. I was reproducing a GitHub issue and came
across this in the process.
2025-05-30 10:32:25 -04:00
Daniele Morotti
71968625cc
Added RunErrorDetails object for MaxTurnsExceeded exception (#743)
### Summary

Introduced the `RunErrorDetails` object to get partial results from a
run interrupted by `MaxTurnsExceeded` exception. In this proposal the
`RunErrorDetails` object contains all the fields from `RunResult` with
`final_output` set to `None` and `output_guardrail_results` set to an
empty list. We can decide to return less information.

@rm-openai At the moment the exception doesn't return the
`RunErrorDetails` object for the streaming mode. Do you have any
suggestions on how to deal with it? In the `_check_errors` function of
`agents/result.py` file.

### Test plan

I have not implemented any tests currently, but if needed I can
implement a basic test to retrieve partial data.

### Issue number

This PR is an attempt to solve issue #719 

### Checks

- [ ] I've added new tests (if relevant)
- [ ] I've added/updated the relevant documentation
- [ ] I've run `make lint` and `make format`
- [ ] I've made sure tests pass
2025-05-29 16:11:33 -04:00
Rohan Mehta
6e078bf7a9
Fix Gemini API content filter handling (#746)
## Summary
- avoid AttributeError when Gemini API returns `None` for chat message
- return empty output if message is filtered
- add regression test

## Testing
- `make format`
- `make lint`
- `make mypy`
- `make tests`

Towards #744
2025-05-23 13:00:30 -04:00
Rohan Mehta
db462e32a3
Fix visualization recursion with cycle detection (#737)
## Summary
- avoid infinite recursion in visualization by tracking visited agents
- test cycle detection in graph utility

## Testing
- `make mypy`
- `make tests` 

Resolves #668
2025-05-23 13:00:10 -04:00
Andrew Han
1364f4408e
fix Gemini token validation issue with LiteLLM (#735)
Fix for #734
2025-05-21 17:59:47 -04:00
Rohan Mehta
079764f0ab
Add support for local shell, image generator, code interpreter tools (#732) 2025-05-21 15:26:22 -04:00
Rohan Mehta
9fa5c39d69
Hosted MCP support (#731)
---
[//]: # (BEGIN SAPLING FOOTER)
* #732
* __->__ #731
2025-05-21 15:21:37 -04:00
Rohan Mehta
ce2e2a4571
Upgrade openAI sdk version (#730)
---
[//]: # (BEGIN SAPLING FOOTER)
* #732
* #731
* __->__ #730
2025-05-21 15:17:58 -04:00
WJPBProjects
466b44df18
Dev/add usage details to Usage class (#726)
PR to enhance the `Usage` object and related logic, to support more
granular token accounting, matching the details available in the [OpenAI
Responses API](https://platform.openai.com/docs/api-reference/responses)
. Specifically, it:

- Adds `input_tokens_details` and `output_tokens_details` fields to the
`Usage` dataclass, storing detailed token breakdowns (e.g.,
`cached_tokens`, `reasoning_tokens`).
- Flows this change through
- Updates and extends tests to match
- Adds a test for the Usage.add method

### Motivation
- Aligns the SDK’s usage with the latest OpenAI responses API Usage
object
- Supports downstream use cases that require fine-grained token usage
data (e.g., billing, analytics, optimization) requested by startups

---------

Co-authored-by: Wulfie Bain <wulfie@openai.com>
2025-05-20 18:23:56 +01:00
Daniele Morotti
003cbfe5f5
Added mcp 'instructions' attribute to the server (#706)
Added the `instructions` attribute to the MCP servers to solve #704 .

Let me know if you want to add an example to the documentation.
2025-05-18 13:25:08 -04:00
Akshit97
1847008e0f
feat: Streamable HTTP support (#643)
Co-authored-by: aagarwal25 <akshit_agarwal@intuit.com>
2025-05-14 14:45:14 -04:00
Ashok Saravanan
1994f9d4c4
feat: pass extra_body through to LiteLLM acompletion (#638)
**Purpose**  
Allow arbitrary `extra_body` parameters (e.g. `cached_content`) to be
forwarded into the LiteLLM call. Useful for context caching in Gemini
models
([docs](https://ai.google.dev/gemini-api/docs/caching?lang=python)).

**Example usage**  
```python
import os
from agents import Agent, ModelSettings
from agents.extensions.models.litellm_model import LitellmModel

cache_name = "cachedContents/34jopukfx5di"  # previously stored context

gemini_model = LitellmModel(
    model="gemini/gemini-1.5-flash-002",
    api_key=os.getenv("GOOGLE_API_KEY")
)

agent = Agent(
    name="Cached Gemini Agent",
    model=gemini_model,
    model_settings=ModelSettings(
        extra_body={"cached_content": cache_name}
    )
)
2025-05-14 12:34:27 -04:00
Daniele Morotti
2c46dae377
Fixed a bug for "detail" attribute in input image (#685)
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.
2025-05-14 11:31:42 -04:00
Stefano Baccianella
aa197e1e14
Make the TTS voices type exportable (#577)
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>
2025-04-24 19:11:25 -04:00
Rohan Mehta
8fd7773a5e
Add usage to context in streaming (#595) 2025-04-24 18:20:35 -04:00
Daniele Morotti
e11b822d5f
Fix stream error using LiteLLM (#589)
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>
2025-04-24 12:53:39 -04:00
Nathan Brake
af80e3a971
Prevent MCP ClientSession hang (#580)
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
2025-04-24 12:12:46 -04:00
Rohan Mehta
3755ea8658
Create to_json_dict for ModelSettings (#582)
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.
2025-04-23 20:39:07 -04:00
Andrew Han
a113fea0ee
Allow cancel out of the streaming result (#579)
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())
````
2025-04-23 19:51:10 -04:00
Jonny Kalambay
111fc9ee66
Adding extra_headers parameters to ModelSettings (#550) 2025-04-22 22:26:47 -04:00
Steven Heidel
2bdf9b7b11
Pass through organization/project headers to tracing backend, fix speech_group enum (#562) 2025-04-21 16:59:46 -04:00
Rohan Mehta
a0254b0b74
RFC: automatically use litellm if possible (#534)
## 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>
2025-04-21 15:03:06 -04:00
Yuya Haruna
0a3dfa071a
Fix visualize graph filename to without extension. (#554)
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
2025-04-21 13:47:51 -04:00
Rohan Mehta
616d8e7f4b
Start and finish streaming trace in impl metod (#540)
Closes #435 and closes #538.

Unit tests.
2025-04-21 13:08:38 -04:00
Rohan Mehta
e3698f32b1
Enable non-strict output types (#539)
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=...)`
2025-04-21 11:58:36 -04:00
Rohan Mehta
472e8c13bd
Docs for LiteLLM integration (#532) 2025-04-16 18:54:22 -04:00
Rohan Mehta
bd404e0f87
Litellm integration (#524)
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
2025-04-16 18:48:41 -04:00
Rohan Mehta
65cae71b14
Extract chat completions streaming helpers (#523)
Small refactor.

---
[//]: # (BEGIN SAPLING FOOTER)
* #524
* __->__ #523
2025-04-15 18:42:09 -04:00
Rohan Mehta
80de53e879
Extract chat completions conversion code into helper (#522)
Small refactor for rest of stack.

---
[//]: # (BEGIN SAPLING FOOTER)
* #524
* #523
* __->__ #522
2025-04-15 18:31:17 -04:00
Rohan Mehta
e625cb495e
Only include stream_options when streaming (#519)
Closes #518
2025-04-15 12:48:27 -04:00
RonaldChungHueyWu
b978b4382e
Support parallel_tool_calls=False for ChatCompletion API (#513)
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.
2025-04-14 22:48:01 -04:00
Rohan Mehta
92d6e3e66c
Previous response id (#509)
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
2025-04-14 22:02:47 -04:00
Rohan Mehta
d6f5190d53
Replace referencable_id with response_id (#508)
Minor change - naming. So that it doesn't pollute the next PR.

---
[//]: # (BEGIN SAPLING FOOTER)
* #509
* __->__ #508
2025-04-14 21:37:18 -04:00
Rohan Mehta
36f5b72449
Don't run tracing shutdown behavior if disabled (#503)
Towards #502
2025-04-14 12:46:00 -04:00
Rohan Mehta
5727a1c73a
Example for streaming guardrails (#505)
An example for the question in the issue attached - how to run
guardrails during streaming.

Towards #495.
2025-04-14 12:40:41 -04:00
Kazuhiro Sera
25f97f979b
Fix typos and misspellings (#486)
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():
    |                ^^^^^^^^
    |
```
2025-04-14 10:37:13 -04:00
Daniele Morotti
e04d87cb1f
Add extra request parameters extra_query and extra_body (#500)
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.
2025-04-14 10:37:00 -04:00
LouisShark
d0693a192e
fix: ensure metadata is non-null in response handling (#483)
ensure metadata is non-null in response handling
2025-04-11 18:20:59 -04:00
Ddper
8ded8a9981
add overwrite mechanism for stream_options (#465)
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)
        ),
    )
```
2025-04-10 16:54:00 -04:00
Dmitry Pimenov
84fb734ba0
Adding scope and span_data doc strings (#463)
Built docs and tested outputs locally
2025-04-09 14:59:07 -04:00
nikkie
ccff74dcfa
docs: Make default model clear (#457)
close https://github.com/openai/openai-agents-python/issues/440
2025-04-08 11:47:23 -04:00
Rohan Mehta
2bcc864b81
Don't send the "store" param unless its hitting OpenAI (#455)
Summary: See #443. Causes issues with Gemini.

Test Plan: Tests. Also tested with Gemini to ensure it works.
2025-04-07 19:13:08 -04:00
Rohan Mehta
50bbfdd8be
Ensure MCP works when inputSchema.properties is missing (#454)
Resolves #449 - TLDR, [OpenAI's
API](https://platform.openai.com/docs/api-reference/responses/create)
expects the properties field to be present, whereas the MCP schema
explicitly allows omitting the properties field. [MCP
Spec](https://github.com/modelcontextprotocol/specification/blob/main/schema/2025-03-26/schema.json)
2025-04-07 18:38:36 -04:00
Suveen Ellawela
07a627e8eb
Add reasoning parameter to ModelSettings (#388)
fixes #189 

@rm-openai Would really appreciate if this can get a quick review.

---------

Co-authored-by: Rohan Mehta <rm@openai.com>
2025-04-03 19:35:59 -04:00
Drew Youngwerth
0110f3ad96
Add metadata to ModelSettings (#431) 2025-04-03 17:50:24 -04:00