Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit eafd8df

Browse files
authored
Fix openai#968 by upgrading openai package to the latest (openai#1034)
This pull request resolves openai#968
1 parent aab7bdd commit eafd8df

File tree

8 files changed

+55
-16
lines changed

8 files changed

+55
-16
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>=1.87.0",
10+
"openai>=1.93.1, <2",
1111
"pydantic>=2.10, <3",
1212
"griffe>=1.5.6, <2",
1313
"typing-extensions>=4.12.2, <5",

src/agents/model_settings.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,14 @@ def validate_from_none(value: None) -> _Omit:
4242
serialization=core_schema.plain_serializer_function_ser_schema(lambda instance: None),
4343
)
4444

45+
@dataclass
46+
class MCPToolChoice:
47+
server_label: str
48+
name: str
4549

4650
Omit = Annotated[_Omit, _OmitTypeAnnotation]
4751
Headers: TypeAlias = Mapping[str, Union[str, Omit]]
48-
ToolChoice: TypeAlias = Union[Literal["auto", "required", "none"], str, None]
49-
52+
ToolChoice: TypeAlias = Union[Literal["auto", "required", "none"], str, MCPToolChoice, None]
5053

5154
@dataclass
5255
class ModelSettings:

src/agents/models/chatcmpl_converter.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,20 @@
4444
from ..exceptions import AgentsException, UserError
4545
from ..handoffs import Handoff
4646
from ..items import TResponseInputItem, TResponseOutputItem
47+
from ..model_settings import MCPToolChoice
4748
from ..tool import FunctionTool, Tool
4849
from .fake_id import FAKE_RESPONSES_ID
4950

5051

5152
class Converter:
5253
@classmethod
5354
def convert_tool_choice(
54-
cls, tool_choice: Literal["auto", "required", "none"] | str | None
55+
cls, tool_choice: Literal["auto", "required", "none"] | str | MCPToolChoice | None
5556
) -> ChatCompletionToolChoiceOptionParam | NotGiven:
5657
if tool_choice is None:
5758
return NOT_GIVEN
59+
elif isinstance(tool_choice, MCPToolChoice):
60+
raise UserError("MCPToolChoice is not supported for Chat Completions models")
5861
elif tool_choice == "auto":
5962
return "auto"
6063
elif tool_choice == "required":

src/agents/models/openai_responses.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from ..handoffs import Handoff
2626
from ..items import ItemHelpers, ModelResponse, TResponseInputItem
2727
from ..logger import logger
28+
from ..model_settings import MCPToolChoice
2829
from ..tool import (
2930
CodeInterpreterTool,
3031
ComputerTool,
@@ -303,10 +304,16 @@ class ConvertedTools:
303304
class Converter:
304305
@classmethod
305306
def convert_tool_choice(
306-
cls, tool_choice: Literal["auto", "required", "none"] | str | None
307+
cls, tool_choice: Literal["auto", "required", "none"] | str | MCPToolChoice | None
307308
) -> response_create_params.ToolChoice | NotGiven:
308309
if tool_choice is None:
309310
return NOT_GIVEN
311+
elif isinstance(tool_choice, MCPToolChoice):
312+
return {
313+
"server_label": tool_choice.server_label,
314+
"type": "mcp",
315+
"name": tool_choice.name,
316+
}
310317
elif tool_choice == "required":
311318
return "required"
312319
elif tool_choice == "auto":
@@ -334,9 +341,9 @@ def convert_tool_choice(
334341
"type": "code_interpreter",
335342
}
336343
elif tool_choice == "mcp":
337-
return {
338-
"type": "mcp",
339-
}
344+
# Note that this is still here for backwards compatibility,
345+
# but migrating to MCPToolChoice is recommended.
346+
return { "type": "mcp" } # type: ignore [typeddict-item]
340347
else:
341348
return {
342349
"type": "function",

tests/model_settings/test_serialization.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from pydantic import TypeAdapter
66
from pydantic_core import to_json
77

8-
from agents.model_settings import ModelSettings
8+
from agents.model_settings import MCPToolChoice, ModelSettings
99

1010

1111
def verify_serialization(model_settings: ModelSettings) -> None:
@@ -29,6 +29,17 @@ def test_basic_serialization() -> None:
2929
verify_serialization(model_settings)
3030

3131

32+
def test_mcp_tool_choice_serialization() -> None:
33+
"""Tests whether ModelSettings with MCPToolChoice can be serialized to a JSON string."""
34+
# First, lets create a ModelSettings instance
35+
model_settings = ModelSettings(
36+
temperature=0.5,
37+
tool_choice=MCPToolChoice(server_label="mcp", name="mcp_tool"),
38+
)
39+
# Now, lets serialize the ModelSettings instance to a JSON string
40+
verify_serialization(model_settings)
41+
42+
3243
def test_all_fields_serialization() -> None:
3344
"""Tests whether ModelSettings can be serialized to a JSON string."""
3445

tests/test_items_helpers.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
)
1212
from openai.types.responses.response_function_tool_call import ResponseFunctionToolCall
1313
from openai.types.responses.response_function_tool_call_param import ResponseFunctionToolCallParam
14-
from openai.types.responses.response_function_web_search import ResponseFunctionWebSearch
14+
from openai.types.responses.response_function_web_search import (
15+
ActionSearch,
16+
ResponseFunctionWebSearch,
17+
)
1518
from openai.types.responses.response_function_web_search_param import ResponseFunctionWebSearchParam
1619
from openai.types.responses.response_output_message import ResponseOutputMessage
1720
from openai.types.responses.response_output_message_param import ResponseOutputMessageParam
@@ -225,14 +228,20 @@ def test_to_input_items_for_file_search_call() -> None:
225228

226229
def test_to_input_items_for_web_search_call() -> None:
227230
"""A web search tool call output should produce the same dict as a web search input."""
228-
ws_call = ResponseFunctionWebSearch(id="w1", status="completed", type="web_search_call")
231+
ws_call = ResponseFunctionWebSearch(
232+
id="w1",
233+
action=ActionSearch(type="search", query="query"),
234+
status="completed",
235+
type="web_search_call",
236+
)
229237
resp = ModelResponse(output=[ws_call], usage=Usage(), response_id=None)
230238
input_items = resp.to_input_items()
231239
assert isinstance(input_items, list) and len(input_items) == 1
232240
expected: ResponseFunctionWebSearchParam = {
233241
"id": "w1",
234242
"status": "completed",
235243
"type": "web_search_call",
244+
"action": {"type": "search", "query": "query"},
236245
}
237246
assert input_items[0] == expected
238247

tests/test_run_step_processing.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
ResponseFunctionWebSearch,
88
)
99
from openai.types.responses.response_computer_tool_call import ActionClick
10+
from openai.types.responses.response_function_web_search import ActionSearch
1011
from openai.types.responses.response_reasoning_item import ResponseReasoningItem, Summary
1112
from pydantic import BaseModel
1213

@@ -306,7 +307,12 @@ async def test_file_search_tool_call_parsed_correctly():
306307
@pytest.mark.asyncio
307308
async def test_function_web_search_tool_call_parsed_correctly():
308309
agent = Agent(name="test")
309-
web_search_call = ResponseFunctionWebSearch(id="w1", status="completed", type="web_search_call")
310+
web_search_call = ResponseFunctionWebSearch(
311+
id="w1",
312+
action=ActionSearch(type="search", query="query"),
313+
status="completed",
314+
type="web_search_call",
315+
)
310316
response = ModelResponse(
311317
output=[get_text_message("hello"), web_search_call],
312318
usage=Usage(),

uv.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)