Skip to content

Commit 10514ca

Browse files
authored
fix: #2038 openai==2.7.0 compatibility (#2039)
1 parent d659a73 commit 10514ca

15 files changed

+83
-33
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ requires-python = ">=3.9"
77
license = "MIT"
88
authors = [{ name = "OpenAI", email = "[email protected]" }]
99
dependencies = [
10-
"openai>=2.6.1,<3",
10+
"openai>=2.7.1,<3",
1111
"pydantic>=2.12.3, <3",
1212
"griffe>=1.5.6, <2",
1313
"typing-extensions>=4.12.2, <5",

src/agents/models/chatcmpl_converter.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
from ..tool import FunctionTool, Tool
5252
from .fake_id import FAKE_RESPONSES_ID
5353

54+
ResponseInputContentWithAudioParam = Union[ResponseInputContentParam, ResponseInputAudioParam]
55+
5456

5557
class Converter:
5658
@classmethod
@@ -136,7 +138,9 @@ def message_to_output_items(cls, message: ChatCompletionMessage) -> list[TRespon
136138
)
137139
if message.content:
138140
message_item.content.append(
139-
ResponseOutputText(text=message.content, type="output_text", annotations=[])
141+
ResponseOutputText(
142+
text=message.content, type="output_text", annotations=[], logprobs=[]
143+
)
140144
)
141145
if message.refusal:
142146
message_item.content.append(
@@ -246,7 +250,7 @@ def maybe_reasoning_message(cls, item: Any) -> ResponseReasoningItemParam | None
246250

247251
@classmethod
248252
def extract_text_content(
249-
cls, content: str | Iterable[ResponseInputContentParam]
253+
cls, content: str | Iterable[ResponseInputContentWithAudioParam]
250254
) -> str | list[ChatCompletionContentPartTextParam]:
251255
all_content = cls.extract_all_content(content)
252256
if isinstance(all_content, str):
@@ -259,7 +263,7 @@ def extract_text_content(
259263

260264
@classmethod
261265
def extract_all_content(
262-
cls, content: str | Iterable[ResponseInputContentParam]
266+
cls, content: str | Iterable[ResponseInputContentWithAudioParam]
263267
) -> str | list[ChatCompletionContentPartParam]:
264268
if isinstance(content, str):
265269
return content
@@ -535,7 +539,7 @@ def ensure_assistant_message() -> ChatCompletionAssistantMessageParam:
535539
elif func_output := cls.maybe_function_tool_call_output(item):
536540
flush_assistant_message()
537541
output_content = cast(
538-
Union[str, Iterable[ResponseInputContentParam]], func_output["output"]
542+
Union[str, Iterable[ResponseInputContentWithAudioParam]], func_output["output"]
539543
)
540544
msg: ChatCompletionToolMessageParam = {
541545
"role": "tool",

src/agents/models/chatcmpl_stream_handler.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ async def handle_stream(
231231
text="",
232232
type="output_text",
233233
annotations=[],
234+
logprobs=[],
234235
),
235236
)
236237
# Start a new assistant message stream
@@ -258,6 +259,7 @@ async def handle_stream(
258259
text="",
259260
type="output_text",
260261
annotations=[],
262+
logprobs=[],
261263
),
262264
type="response.content_part.added",
263265
sequence_number=sequence_number.get_and_increment(),

tests/extensions/memory/test_sqlalchemy_session.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def _make_message_item(item_id: str, text_value: str) -> TResponseInputItem:
3636
"type": "output_text",
3737
"text": text_value,
3838
"annotations": [],
39+
"logprobs": [],
3940
}
4041
message: ResponseOutputMessageParam = {
4142
"id": item_id,

tests/test_agent_as_tool.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ async def test_agent_as_tool_returns_concatenated_text(monkeypatch: pytest.Monke
240240
annotations=[],
241241
text="Hello world",
242242
type="output_text",
243-
logprobs=None,
243+
logprobs=[],
244244
)
245245
],
246246
)
@@ -304,7 +304,7 @@ async def test_agent_as_tool_custom_output_extractor(monkeypatch: pytest.MonkeyP
304304
annotations=[],
305305
text="Original text",
306306
type="output_text",
307-
logprobs=None,
307+
logprobs=[],
308308
)
309309
],
310310
)

tests/test_agent_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,7 @@ async def echo_tool(text: str) -> str:
12261226
"content": [
12271227
{
12281228
"annotations": [],
1229+
"logprobs": [],
12291230
"text": "Summary: Echoed foo and bar",
12301231
"type": "output_text",
12311232
}

tests/test_call_model_input_filter_unit.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ async def test_call_model_input_filter_sync_non_streamed_unit() -> None:
2828
id="1",
2929
type="message",
3030
role="assistant",
31-
content=[ResponseOutputText(text="ok", type="output_text", annotations=[])],
31+
content=[
32+
ResponseOutputText(text="ok", type="output_text", annotations=[], logprobs=[])
33+
],
3234
status="completed",
3335
)
3436
]
@@ -64,7 +66,9 @@ async def test_call_model_input_filter_async_streamed_unit() -> None:
6466
id="1",
6567
type="message",
6668
role="assistant",
67-
content=[ResponseOutputText(text="ok", type="output_text", annotations=[])],
69+
content=[
70+
ResponseOutputText(text="ok", type="output_text", annotations=[], logprobs=[])
71+
],
6872
status="completed",
6973
)
7074
]

tests/test_extension_filters.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ def _get_message_output_run_item(content: str) -> MessageOutputItem:
4242
agent=fake_agent(),
4343
raw_item=ResponseOutputMessage(
4444
id="1",
45-
content=[ResponseOutputText(text=content, annotations=[], type="output_text")],
45+
content=[
46+
ResponseOutputText(text=content, annotations=[], type="output_text", logprobs=[])
47+
],
4648
role="assistant",
4749
status="completed",
4850
type="message",

tests/test_handoff_tool.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ def message_item(content: str, agent: Agent[Any]) -> MessageOutputItem:
2727
status="completed",
2828
role="assistant",
2929
type="message",
30-
content=[ResponseOutputText(text=content, type="output_text", annotations=[])],
30+
content=[
31+
ResponseOutputText(text=content, type="output_text", annotations=[], logprobs=[])
32+
],
3133
),
3234
)
3335

tests/test_items_helpers.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,18 @@ def make_message(
5757

5858
def test_extract_last_content_of_text_message() -> None:
5959
# Build a message containing two text segments.
60-
content1 = ResponseOutputText(annotations=[], text="Hello ", type="output_text")
61-
content2 = ResponseOutputText(annotations=[], text="world!", type="output_text")
60+
content1 = ResponseOutputText(annotations=[], text="Hello ", type="output_text", logprobs=[])
61+
content2 = ResponseOutputText(annotations=[], text="world!", type="output_text", logprobs=[])
6262
message = make_message([content1, content2])
6363
# Helpers should yield the last segment's text.
6464
assert ItemHelpers.extract_last_content(message) == "world!"
6565

6666

6767
def test_extract_last_content_of_refusal_message() -> None:
6868
# Build a message whose last content entry is a refusal.
69-
content1 = ResponseOutputText(annotations=[], text="Before refusal", type="output_text")
69+
content1 = ResponseOutputText(
70+
annotations=[], text="Before refusal", type="output_text", logprobs=[]
71+
)
7072
refusal = ResponseOutputRefusal(refusal="I cannot do that", type="refusal")
7173
message = make_message([content1, refusal])
7274
# Helpers should extract the refusal string when last content is a refusal.
@@ -87,8 +89,8 @@ def test_extract_last_content_non_message_returns_empty() -> None:
8789

8890
def test_extract_last_text_returns_text_only() -> None:
8991
# A message whose last segment is text yields the text.
90-
first_text = ResponseOutputText(annotations=[], text="part1", type="output_text")
91-
second_text = ResponseOutputText(annotations=[], text="part2", type="output_text")
92+
first_text = ResponseOutputText(annotations=[], text="part1", type="output_text", logprobs=[])
93+
second_text = ResponseOutputText(annotations=[], text="part2", type="output_text", logprobs=[])
9294
message = make_message([first_text, second_text])
9395
assert ItemHelpers.extract_last_text(message) == "part2"
9496
# Whereas when last content is a refusal, extract_last_text returns None.
@@ -116,9 +118,9 @@ def test_input_to_new_input_list_deep_copies_lists() -> None:
116118
def test_text_message_output_concatenates_text_segments() -> None:
117119
# Build a message with both text and refusal segments, only text segments are concatenated.
118120
pieces: list[ResponseOutputText | ResponseOutputRefusal] = []
119-
pieces.append(ResponseOutputText(annotations=[], text="a", type="output_text"))
121+
pieces.append(ResponseOutputText(annotations=[], text="a", type="output_text", logprobs=[]))
120122
pieces.append(ResponseOutputRefusal(refusal="denied", type="refusal"))
121-
pieces.append(ResponseOutputText(annotations=[], text="b", type="output_text"))
123+
pieces.append(ResponseOutputText(annotations=[], text="b", type="output_text", logprobs=[]))
122124
message = make_message(pieces)
123125
# Wrap into MessageOutputItem to feed into text_message_output.
124126
item = MessageOutputItem(agent=Agent(name="test"), raw_item=message)
@@ -131,8 +133,12 @@ def test_text_message_outputs_across_list_of_runitems() -> None:
131133
that only MessageOutputItem instances contribute any text. The non-message
132134
(ReasoningItem) should be ignored by Helpers.text_message_outputs.
133135
"""
134-
message1 = make_message([ResponseOutputText(annotations=[], text="foo", type="output_text")])
135-
message2 = make_message([ResponseOutputText(annotations=[], text="bar", type="output_text")])
136+
message1 = make_message(
137+
[ResponseOutputText(annotations=[], text="foo", type="output_text", logprobs=[])]
138+
)
139+
message2 = make_message(
140+
[ResponseOutputText(annotations=[], text="bar", type="output_text", logprobs=[])]
141+
)
136142
item1: RunItem = MessageOutputItem(agent=Agent(name="test"), raw_item=message1)
137143
item2: RunItem = MessageOutputItem(agent=Agent(name="test"), raw_item=message2)
138144
# Create a non-message run item of a different type, e.g., a reasoning trace.
@@ -171,7 +177,9 @@ def test_tool_call_output_item_constructs_function_call_output_dict():
171177

172178
def test_to_input_items_for_message() -> None:
173179
"""An output message should convert into an input dict matching the message's own structure."""
174-
content = ResponseOutputText(annotations=[], text="hello world", type="output_text")
180+
content = ResponseOutputText(
181+
annotations=[], text="hello world", type="output_text", logprobs=[]
182+
)
175183
message = ResponseOutputMessage(
176184
id="m1", content=[content], role="assistant", status="completed", type="message"
177185
)
@@ -184,6 +192,7 @@ def test_to_input_items_for_message() -> None:
184192
"content": [
185193
{
186194
"annotations": [],
195+
"logprobs": [],
187196
"text": "hello world",
188197
"type": "output_text",
189198
}
@@ -305,6 +314,7 @@ def test_input_to_new_input_list_copies_the_ones_produced_by_pydantic() -> None:
305314
type="output_text",
306315
text="Hey, what's up?",
307316
annotations=[],
317+
logprobs=[],
308318
)
309319
],
310320
role="assistant",

0 commit comments

Comments
 (0)