From a38410553659d5061101fc15d8aafb2986f890c6 Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Sat, 5 Jul 2025 11:23:23 +0400 Subject: [PATCH 01/22] Add get_prompt and list_prompts to MCPServer --- examples/mcp/streamablehttp_example/main.py | 6 ++++ examples/mcp/streamablehttp_example/server.py | 4 +++ src/agents/mcp/server.py | 35 ++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/examples/mcp/streamablehttp_example/main.py b/examples/mcp/streamablehttp_example/main.py index cc95e798b..88c8b164b 100644 --- a/examples/mcp/streamablehttp_example/main.py +++ b/examples/mcp/streamablehttp_example/main.py @@ -46,6 +46,12 @@ async def main(): ) as server: trace_id = gen_trace_id() with trace(workflow_name="Streamable HTTP Example", trace_id=trace_id): + # List available prompts + prompts = await server.list_prompts() + print(f"Prompts list -> {prompts}") + system_prompt = await server.get_prompt("system_prompt") + instructions = system_prompt.messages[0].content.text + print(f"instructions -> {instructions}") print(f"View trace: https://platform.openai.com/traces/trace?trace_id={trace_id}\n") await run(server) diff --git a/examples/mcp/streamablehttp_example/server.py b/examples/mcp/streamablehttp_example/server.py index d8f839652..41b087db3 100644 --- a/examples/mcp/streamablehttp_example/server.py +++ b/examples/mcp/streamablehttp_example/server.py @@ -28,6 +28,10 @@ def get_current_weather(city: str) -> str: response = requests.get(f"{endpoint}/{city}") return response.text +@mcp.prompt() +def system_prompt(): + return "Use the tools to answer the questions." + if __name__ == "__main__": mcp.run(transport="streamable-http") diff --git a/src/agents/mcp/server.py b/src/agents/mcp/server.py index f6c2b58ef..1c3850fe4 100644 --- a/src/agents/mcp/server.py +++ b/src/agents/mcp/server.py @@ -13,7 +13,7 @@ from mcp.client.sse import sse_client from mcp.client.streamable_http import GetSessionIdCallback, streamablehttp_client from mcp.shared.message import SessionMessage -from mcp.types import CallToolResult, InitializeResult +from mcp.types import CallToolResult, InitializeResult, GetPromptResult from typing_extensions import NotRequired, TypedDict from ..exceptions import UserError @@ -63,6 +63,21 @@ async def call_tool(self, tool_name: str, arguments: dict[str, Any] | None) -> C """Invoke a tool on the server.""" pass + @abc.abstractmethod + async def list_prompts( + self + ) -> list[GetPromptResult]: + """List the prompts available on the server.""" + pass + + @abc.abstractmethod + async def get_prompt( + self, name: str, + arguments: dict[str, str] | None = None + ) -> GetPromptResult: + """Returns an existing prompt from the server.""" + pass + class _MCPServerWithClientSession(MCPServer, abc.ABC): """Base class for MCP servers that use a `ClientSession` to communicate with the server.""" @@ -261,6 +276,24 @@ async def call_tool(self, tool_name: str, arguments: dict[str, Any] | None) -> C return await self.session.call_tool(tool_name, arguments) + async def list_prompts( + self, + ) -> list[GetPromptResult]: + """List the prompts available on the server.""" + if not self.session: + raise UserError("Server not initialized. Make sure you call `connect()` first.") + + return await self.session.list_prompts() + + async def get_prompt( + self, name: str, + arguments: dict[str, str] | None = None + ) -> GetPromptResult: + if not self.session: + raise UserError("Server not initialized. Make sure you call `connect()` first.") + + return await self.session.get_prompt(name, arguments) + async def cleanup(self): """Cleanup the server.""" async with self._cleanup_lock: From 2b8d62d8fc9fdc1703b57b3340c00c901558b4c6 Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Sat, 5 Jul 2025 11:30:38 +0400 Subject: [PATCH 02/22] Update example --- examples/mcp/streamablehttp_example/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/mcp/streamablehttp_example/main.py b/examples/mcp/streamablehttp_example/main.py index 88c8b164b..44b0c1eff 100644 --- a/examples/mcp/streamablehttp_example/main.py +++ b/examples/mcp/streamablehttp_example/main.py @@ -10,10 +10,10 @@ from agents.model_settings import ModelSettings -async def run(mcp_server: MCPServer): +async def run(mcp_server: MCPServer, instructions): agent = Agent( name="Assistant", - instructions="Use the tools to answer the questions.", + instructions=instructions, mcp_servers=[mcp_server], model_settings=ModelSettings(tool_choice="required"), ) @@ -53,7 +53,7 @@ async def main(): instructions = system_prompt.messages[0].content.text print(f"instructions -> {instructions}") print(f"View trace: https://platform.openai.com/traces/trace?trace_id={trace_id}\n") - await run(server) + await run(server, instructions) if __name__ == "__main__": From f47b04a16b3551122c9b91cd13e3ae767f7d1b63 Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Sat, 5 Jul 2025 11:43:31 +0400 Subject: [PATCH 03/22] Linting --- docs/scripts/translate_docs.py | 4 +++- examples/basic/hello_world_jupyter.ipynb | 2 +- examples/mcp/streamablehttp_example/server.py | 1 + examples/reasoning_content/main.py | 4 ++-- src/agents/agent.py | 4 +--- src/agents/mcp/server.py | 14 ++++---------- src/agents/model_settings.py | 13 +++++++------ src/agents/tool.py | 1 - tests/mcp/test_tool_filtering.py | 9 ++++++--- tests/model_settings/test_serialization.py | 2 +- tests/test_reasoning_content.py | 14 +++++--------- 11 files changed, 31 insertions(+), 37 deletions(-) diff --git a/docs/scripts/translate_docs.py b/docs/scripts/translate_docs.py index 5dada2681..ac40b6fa8 100644 --- a/docs/scripts/translate_docs.py +++ b/docs/scripts/translate_docs.py @@ -266,7 +266,9 @@ def translate_single_source_file(file_path: str) -> None: def main(): parser = argparse.ArgumentParser(description="Translate documentation files") - parser.add_argument("--file", type=str, help="Specific file to translate (relative to docs directory)") + parser.add_argument( + "--file", type=str, help="Specific file to translate (relative to docs directory)" + ) args = parser.parse_args() if args.file: diff --git a/examples/basic/hello_world_jupyter.ipynb b/examples/basic/hello_world_jupyter.ipynb index 42ee8e6a2..8dd3bb379 100644 --- a/examples/basic/hello_world_jupyter.ipynb +++ b/examples/basic/hello_world_jupyter.ipynb @@ -30,7 +30,7 @@ "agent = Agent(name=\"Assistant\", instructions=\"You are a helpful assistant\")\n", "\n", "# Intended for Jupyter notebooks where there's an existing event loop\n", - "result = await Runner.run(agent, \"Write a haiku about recursion in programming.\") # type: ignore[top-level-await] # noqa: F704\n", + "result = await Runner.run(agent, \"Write a haiku about recursion in programming.\") # type: ignore[top-level-await] # noqa: F704\n", "print(result.final_output)" ] } diff --git a/examples/mcp/streamablehttp_example/server.py b/examples/mcp/streamablehttp_example/server.py index 41b087db3..3d979fccf 100644 --- a/examples/mcp/streamablehttp_example/server.py +++ b/examples/mcp/streamablehttp_example/server.py @@ -28,6 +28,7 @@ def get_current_weather(city: str) -> str: response = requests.get(f"{endpoint}/{city}") return response.text + @mcp.prompt() def system_prompt(): return "Use the tools to answer the questions." diff --git a/examples/reasoning_content/main.py b/examples/reasoning_content/main.py index 5f67e1779..c23b04254 100644 --- a/examples/reasoning_content/main.py +++ b/examples/reasoning_content/main.py @@ -44,7 +44,7 @@ async def stream_with_reasoning_content(): handoffs=[], tracing=ModelTracing.DISABLED, previous_response_id=None, - prompt=None + prompt=None, ): if event.type == "response.reasoning_summary_text.delta": print( @@ -82,7 +82,7 @@ async def get_response_with_reasoning_content(): handoffs=[], tracing=ModelTracing.DISABLED, previous_response_id=None, - prompt=None + prompt=None, ) # Extract reasoning content and regular content from the response diff --git a/src/agents/agent.py b/src/agents/agent.py index 6c87297f1..2f77f5f2a 100644 --- a/src/agents/agent.py +++ b/src/agents/agent.py @@ -256,9 +256,7 @@ async def get_prompt( """Get the prompt for the agent.""" return await PromptUtil.to_model_input(self.prompt, run_context, self) - async def get_mcp_tools( - self, run_context: RunContextWrapper[TContext] - ) -> list[Tool]: + async def get_mcp_tools(self, run_context: RunContextWrapper[TContext]) -> list[Tool]: """Fetches the available tools from the MCP servers.""" convert_schemas_to_strict = self.mcp_config.get("convert_schemas_to_strict", False) return await MCPUtil.get_all_function_tools( diff --git a/src/agents/mcp/server.py b/src/agents/mcp/server.py index 1c3850fe4..93c97f80a 100644 --- a/src/agents/mcp/server.py +++ b/src/agents/mcp/server.py @@ -64,16 +64,13 @@ async def call_tool(self, tool_name: str, arguments: dict[str, Any] | None) -> C pass @abc.abstractmethod - async def list_prompts( - self - ) -> list[GetPromptResult]: + async def list_prompts(self) -> list[GetPromptResult]: """List the prompts available on the server.""" pass @abc.abstractmethod async def get_prompt( - self, name: str, - arguments: dict[str, str] | None = None + self, name: str, arguments: dict[str, str] | None = None ) -> GetPromptResult: """Returns an existing prompt from the server.""" pass @@ -133,9 +130,7 @@ async def _apply_tool_filter( return await self._apply_dynamic_tool_filter(tools, run_context, agent) def _apply_static_tool_filter( - self, - tools: list[MCPTool], - static_filter: ToolFilterStatic + self, tools: list[MCPTool], static_filter: ToolFilterStatic ) -> list[MCPTool]: """Apply static tool filtering based on allowlist and blocklist.""" filtered_tools = tools @@ -286,8 +281,7 @@ async def list_prompts( return await self.session.list_prompts() async def get_prompt( - self, name: str, - arguments: dict[str, str] | None = None + self, name: str, arguments: dict[str, str] | None = None ) -> GetPromptResult: if not self.session: raise UserError("Server not initialized. Make sure you call `connect()` first.") diff --git a/src/agents/model_settings.py b/src/agents/model_settings.py index 26af94ba3..f81f10989 100644 --- a/src/agents/model_settings.py +++ b/src/agents/model_settings.py @@ -17,9 +17,9 @@ class _OmitTypeAnnotation: @classmethod def __get_pydantic_core_schema__( - cls, - _source_type: Any, - _handler: GetCoreSchemaHandler, + cls, + _source_type: Any, + _handler: GetCoreSchemaHandler, ) -> core_schema.CoreSchema: def validate_from_none(value: None) -> _Omit: return _Omit() @@ -39,13 +39,14 @@ def validate_from_none(value: None) -> _Omit: from_none_schema, ] ), - serialization=core_schema.plain_serializer_function_ser_schema( - lambda instance: None - ), + serialization=core_schema.plain_serializer_function_ser_schema(lambda instance: None), ) + + Omit = Annotated[_Omit, _OmitTypeAnnotation] Headers: TypeAlias = Mapping[str, Union[str, Omit]] + @dataclass class ModelSettings: """Settings to use when calling an LLM. diff --git a/src/agents/tool.py b/src/agents/tool.py index 3aab47752..f2861b936 100644 --- a/src/agents/tool.py +++ b/src/agents/tool.py @@ -30,7 +30,6 @@ from .util._types import MaybeAwaitable if TYPE_CHECKING: - from .agent import Agent ToolParams = ParamSpec("ToolParams") diff --git a/tests/mcp/test_tool_filtering.py b/tests/mcp/test_tool_filtering.py index c1ffff4b8..0127df806 100644 --- a/tests/mcp/test_tool_filtering.py +++ b/tests/mcp/test_tool_filtering.py @@ -3,6 +3,7 @@ external dependencies (processes, network connections) and ensure fast, reliable unit tests. FakeMCPServer delegates filtering logic to the real _MCPServerWithClientSession implementation. """ + import asyncio import pytest @@ -27,6 +28,7 @@ def create_test_context() -> RunContextWrapper: # === Static Tool Filtering Tests === + @pytest.mark.asyncio async def test_static_tool_filtering(): """Test all static tool filtering scenarios: allowed, blocked, both, none, etc.""" @@ -55,7 +57,7 @@ async def test_static_tool_filtering(): # Test both filters together (allowed first, then blocked) server.tool_filter = { "allowed_tool_names": ["tool1", "tool2", "tool3"], - "blocked_tool_names": ["tool3"] + "blocked_tool_names": ["tool3"], } tools = await server.list_tools(run_context, agent) assert len(tools) == 2 @@ -68,8 +70,7 @@ async def test_static_tool_filtering(): # Test helper function server.tool_filter = create_static_tool_filter( - allowed_tool_names=["tool1", "tool2"], - blocked_tool_names=["tool2"] + allowed_tool_names=["tool1", "tool2"], blocked_tool_names=["tool2"] ) tools = await server.list_tools(run_context, agent) assert len(tools) == 1 @@ -78,6 +79,7 @@ async def test_static_tool_filtering(): # === Dynamic Tool Filtering Core Tests === + @pytest.mark.asyncio async def test_dynamic_filter_sync_and_async(): """Test both synchronous and asynchronous dynamic filters""" @@ -181,6 +183,7 @@ def error_prone_filter(context: ToolFilterContext, tool: MCPTool) -> bool: # === Integration Tests === + @pytest.mark.asyncio async def test_agent_dynamic_filtering_integration(): """Test dynamic filtering integration with Agent methods""" diff --git a/tests/model_settings/test_serialization.py b/tests/model_settings/test_serialization.py index 94d11def3..23ea5359c 100644 --- a/tests/model_settings/test_serialization.py +++ b/tests/model_settings/test_serialization.py @@ -135,8 +135,8 @@ def test_extra_args_resolve_both_none() -> None: assert resolved.temperature == 0.5 assert resolved.top_p == 0.9 -def test_pydantic_serialization() -> None: +def test_pydantic_serialization() -> None: """Tests whether ModelSettings can be serialized with Pydantic.""" # First, lets create a ModelSettings instance diff --git a/tests/test_reasoning_content.py b/tests/test_reasoning_content.py index 5160e09c2..69e9a7d0c 100644 --- a/tests/test_reasoning_content.py +++ b/tests/test_reasoning_content.py @@ -27,12 +27,8 @@ # Helper functions to create test objects consistently def create_content_delta(content: str) -> dict[str, Any]: """Create a delta dictionary with regular content""" - return { - "content": content, - "role": None, - "function_call": None, - "tool_calls": None - } + return {"content": content, "role": None, "function_call": None, "tool_calls": None} + def create_reasoning_delta(content: str) -> dict[str, Any]: """Create a delta dictionary with reasoning content. The Only difference is reasoning_content""" @@ -41,7 +37,7 @@ def create_reasoning_delta(content: str) -> dict[str, Any]: "role": None, "function_call": None, "tool_calls": None, - "reasoning_content": content + "reasoning_content": content, } @@ -188,7 +184,7 @@ async def test_get_response_with_reasoning_content(monkeypatch) -> None: "index": 0, "finish_reason": "stop", "message": msg_with_reasoning, - "delta": None + "delta": None, } chat = ChatCompletion( @@ -274,7 +270,7 @@ async def patched_fetch_response(self, *args, **kwargs): handoffs=[], tracing=ModelTracing.DISABLED, previous_response_id=None, - prompt=None + prompt=None, ): output_events.append(event) From 284898f0dcd301022dd2a31fb17e7f6f2eb04265 Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Sat, 5 Jul 2025 11:43:42 +0400 Subject: [PATCH 04/22] Linting --- src/agents/mcp/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agents/mcp/server.py b/src/agents/mcp/server.py index 93c97f80a..bf0989fe0 100644 --- a/src/agents/mcp/server.py +++ b/src/agents/mcp/server.py @@ -13,7 +13,7 @@ from mcp.client.sse import sse_client from mcp.client.streamable_http import GetSessionIdCallback, streamablehttp_client from mcp.shared.message import SessionMessage -from mcp.types import CallToolResult, InitializeResult, GetPromptResult +from mcp.types import CallToolResult, GetPromptResult, InitializeResult from typing_extensions import NotRequired, TypedDict from ..exceptions import UserError From 6bd974a8a7bc1b324f4dee0a70ad433ccfe26257 Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Sat, 5 Jul 2025 11:50:54 +0400 Subject: [PATCH 05/22] Fix FakeMCPServer --- tests/mcp/helpers.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/mcp/helpers.py b/tests/mcp/helpers.py index e0d8a813d..6286a7195 100644 --- a/tests/mcp/helpers.py +++ b/tests/mcp/helpers.py @@ -4,7 +4,7 @@ from typing import Any from mcp import Tool as MCPTool -from mcp.types import CallToolResult, TextContent +from mcp.types import CallToolResult, GetPromptResult, TextContent from agents.mcp import MCPServer from agents.mcp.server import _MCPServerWithClientSession @@ -57,10 +57,12 @@ def name(self) -> str: class FakeMCPServer(MCPServer): def __init__( self, + prompts: list[GetPromptResult] | None = None, tools: list[MCPTool] | None = None, tool_filter: ToolFilter = None, server_name: str = "fake_mcp_server", ): + self.prompts: list[GetPromptResult] = prompts or [] self.tools: list[MCPTool] = tools or [] self.tool_calls: list[str] = [] self.tool_results: list[str] = [] @@ -94,6 +96,19 @@ async def call_tool(self, tool_name: str, arguments: dict[str, Any] | None) -> C content=[TextContent(text=self.tool_results[-1], type="text")], ) + async def list_prompts( + self, + ) -> list[GetPromptResult]: + return self.prompts + + async def get_prompt( + self, name: str, arguments: dict[str, str] | None = None + ) -> GetPromptResult | None: + if self.prompts: + for prompt in self.prompts: + if prompt.name == name: + return prompt + @property def name(self) -> str: return self._server_name From 2188b9344ea2ff7976681191445d762fc23afa21 Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Sat, 5 Jul 2025 11:54:17 +0400 Subject: [PATCH 06/22] Fix ListPromptsResult --- src/agents/mcp/server.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/agents/mcp/server.py b/src/agents/mcp/server.py index bf0989fe0..54f4f20ac 100644 --- a/src/agents/mcp/server.py +++ b/src/agents/mcp/server.py @@ -13,7 +13,7 @@ from mcp.client.sse import sse_client from mcp.client.streamable_http import GetSessionIdCallback, streamablehttp_client from mcp.shared.message import SessionMessage -from mcp.types import CallToolResult, GetPromptResult, InitializeResult +from mcp.types import CallToolResult, GetPromptResult, InitializeResult, ListPromptsResult from typing_extensions import NotRequired, TypedDict from ..exceptions import UserError @@ -64,7 +64,7 @@ async def call_tool(self, tool_name: str, arguments: dict[str, Any] | None) -> C pass @abc.abstractmethod - async def list_prompts(self) -> list[GetPromptResult]: + async def list_prompts(self) -> ListPromptsResult: """List the prompts available on the server.""" pass @@ -273,7 +273,7 @@ async def call_tool(self, tool_name: str, arguments: dict[str, Any] | None) -> C async def list_prompts( self, - ) -> list[GetPromptResult]: + ) -> ListPromptsResult: """List the prompts available on the server.""" if not self.session: raise UserError("Server not initialized. Make sure you call `connect()` first.") From 8db2a6627184ea75e636a881f128a7f0374091f7 Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Sat, 5 Jul 2025 12:01:01 +0400 Subject: [PATCH 07/22] Fix ListPromptsResult --- tests/mcp/helpers.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/mcp/helpers.py b/tests/mcp/helpers.py index 6286a7195..4b85eed40 100644 --- a/tests/mcp/helpers.py +++ b/tests/mcp/helpers.py @@ -4,7 +4,7 @@ from typing import Any from mcp import Tool as MCPTool -from mcp.types import CallToolResult, GetPromptResult, TextContent +from mcp.types import CallToolResult, GetPromptResult, ListPromptsResult, TextContent from agents.mcp import MCPServer from agents.mcp.server import _MCPServerWithClientSession @@ -57,12 +57,12 @@ def name(self) -> str: class FakeMCPServer(MCPServer): def __init__( self, - prompts: list[GetPromptResult] | None = None, + prompts: ListPromptsResult | None = None, tools: list[MCPTool] | None = None, tool_filter: ToolFilter = None, server_name: str = "fake_mcp_server", ): - self.prompts: list[GetPromptResult] = prompts or [] + self.prompts: ListPromptsResult = prompts or [] self.tools: list[MCPTool] = tools or [] self.tool_calls: list[str] = [] self.tool_results: list[str] = [] @@ -98,7 +98,7 @@ async def call_tool(self, tool_name: str, arguments: dict[str, Any] | None) -> C async def list_prompts( self, - ) -> list[GetPromptResult]: + ) -> ListPromptsResult: return self.prompts async def get_prompt( From 08a8defeb3b0bd5c3ba0c386e0f513d675e02b1d Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Sat, 5 Jul 2025 12:03:44 +0400 Subject: [PATCH 08/22] Fix ListPromptsResult --- tests/mcp/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mcp/helpers.py b/tests/mcp/helpers.py index 4b85eed40..d1efb5b9b 100644 --- a/tests/mcp/helpers.py +++ b/tests/mcp/helpers.py @@ -62,7 +62,7 @@ def __init__( tool_filter: ToolFilter = None, server_name: str = "fake_mcp_server", ): - self.prompts: ListPromptsResult = prompts or [] + self.prompts: prompts self.tools: list[MCPTool] = tools or [] self.tool_calls: list[str] = [] self.tool_results: list[str] = [] From e6e9b74d7031708e276bb1ad5b0334a1c55f700f Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Sat, 5 Jul 2025 12:05:08 +0400 Subject: [PATCH 09/22] Fix ListPromptsResult --- tests/mcp/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mcp/helpers.py b/tests/mcp/helpers.py index d1efb5b9b..6539eb722 100644 --- a/tests/mcp/helpers.py +++ b/tests/mcp/helpers.py @@ -62,7 +62,7 @@ def __init__( tool_filter: ToolFilter = None, server_name: str = "fake_mcp_server", ): - self.prompts: prompts + self.prompts = prompts self.tools: list[MCPTool] = tools or [] self.tool_calls: list[str] = [] self.tool_results: list[str] = [] From bd7ab63c5ee663f620093b817dad0f9542a78b7b Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Sat, 5 Jul 2025 12:08:07 +0400 Subject: [PATCH 10/22] Fix ListPromptsResult --- src/agents/mcp/server.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/agents/mcp/server.py b/src/agents/mcp/server.py index 54f4f20ac..e68a4b8dd 100644 --- a/src/agents/mcp/server.py +++ b/src/agents/mcp/server.py @@ -64,7 +64,7 @@ async def call_tool(self, tool_name: str, arguments: dict[str, Any] | None) -> C pass @abc.abstractmethod - async def list_prompts(self) -> ListPromptsResult: + async def list_prompts(self) -> ListPromptsResult | None: """List the prompts available on the server.""" pass @@ -273,7 +273,7 @@ async def call_tool(self, tool_name: str, arguments: dict[str, Any] | None) -> C async def list_prompts( self, - ) -> ListPromptsResult: + ) -> ListPromptsResult | None: """List the prompts available on the server.""" if not self.session: raise UserError("Server not initialized. Make sure you call `connect()` first.") @@ -282,7 +282,7 @@ async def list_prompts( async def get_prompt( self, name: str, arguments: dict[str, str] | None = None - ) -> GetPromptResult: + ) -> GetPromptResult | None: if not self.session: raise UserError("Server not initialized. Make sure you call `connect()` first.") From 85a88e771587a58b53d5f56ce0121978c1dcf4eb Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Sat, 5 Jul 2025 12:10:27 +0400 Subject: [PATCH 11/22] Fix ListPromptsResult --- src/agents/mcp/server.py | 2 +- tests/mcp/helpers.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/agents/mcp/server.py b/src/agents/mcp/server.py index e68a4b8dd..ef1d290b0 100644 --- a/src/agents/mcp/server.py +++ b/src/agents/mcp/server.py @@ -71,7 +71,7 @@ async def list_prompts(self) -> ListPromptsResult | None: @abc.abstractmethod async def get_prompt( self, name: str, arguments: dict[str, str] | None = None - ) -> GetPromptResult: + ) -> GetPromptResult | None: """Returns an existing prompt from the server.""" pass diff --git a/tests/mcp/helpers.py b/tests/mcp/helpers.py index 6539eb722..102af0b1e 100644 --- a/tests/mcp/helpers.py +++ b/tests/mcp/helpers.py @@ -98,7 +98,7 @@ async def call_tool(self, tool_name: str, arguments: dict[str, Any] | None) -> C async def list_prompts( self, - ) -> ListPromptsResult: + ) -> ListPromptsResult | None: return self.prompts async def get_prompt( From 8603750b0dd03f9ce89c0ee512574eacf4ab6b29 Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Sat, 5 Jul 2025 12:12:16 +0400 Subject: [PATCH 12/22] Fix ListPromptsResult --- tests/mcp/helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/mcp/helpers.py b/tests/mcp/helpers.py index 102af0b1e..37a6c4877 100644 --- a/tests/mcp/helpers.py +++ b/tests/mcp/helpers.py @@ -108,6 +108,7 @@ async def get_prompt( for prompt in self.prompts: if prompt.name == name: return prompt + return None @property def name(self) -> str: From bee9f9eb9ade0f61f0bf6d01727562e0838cb31a Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Sat, 5 Jul 2025 12:49:13 +0400 Subject: [PATCH 13/22] Fix ListPromptsResult --- tests/mcp/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mcp/helpers.py b/tests/mcp/helpers.py index 37a6c4877..8f06ed366 100644 --- a/tests/mcp/helpers.py +++ b/tests/mcp/helpers.py @@ -104,7 +104,7 @@ async def list_prompts( async def get_prompt( self, name: str, arguments: dict[str, str] | None = None ) -> GetPromptResult | None: - if self.prompts: + if self.prompts.prompts: for prompt in self.prompts: if prompt.name == name: return prompt From 0c786fa2282de1c612336a7c7a6ef3625ef4f536 Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Sat, 5 Jul 2025 12:50:41 +0400 Subject: [PATCH 14/22] Fix ListPromptsResult --- tests/mcp/helpers.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/mcp/helpers.py b/tests/mcp/helpers.py index 8f06ed366..5a2365607 100644 --- a/tests/mcp/helpers.py +++ b/tests/mcp/helpers.py @@ -104,10 +104,6 @@ async def list_prompts( async def get_prompt( self, name: str, arguments: dict[str, str] | None = None ) -> GetPromptResult | None: - if self.prompts.prompts: - for prompt in self.prompts: - if prompt.name == name: - return prompt return None @property From 4e5ceb0a9915d80de0692bcec04f3363addccb73 Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Tue, 8 Jul 2025 16:33:43 +0400 Subject: [PATCH 15/22] Remove un-necessary changes --- docs/scripts/translate_docs.py | 6 ++---- examples/basic/hello_world_jupyter.ipynb | 2 +- examples/reasoning_content/main.py | 6 +++--- src/agents/agent.py | 6 ++++-- src/agents/mcp/server.py | 4 +++- src/agents/model_settings.py | 15 +++++++-------- src/agents/tool.py | 3 ++- tests/mcp/test_tool_filtering.py | 11 ++++------- tests/test_reasoning_content.py | 16 ++++++++++------ 9 files changed, 36 insertions(+), 33 deletions(-) diff --git a/docs/scripts/translate_docs.py b/docs/scripts/translate_docs.py index ac40b6fa8..2af4297d9 100644 --- a/docs/scripts/translate_docs.py +++ b/docs/scripts/translate_docs.py @@ -266,9 +266,7 @@ def translate_single_source_file(file_path: str) -> None: def main(): parser = argparse.ArgumentParser(description="Translate documentation files") - parser.add_argument( - "--file", type=str, help="Specific file to translate (relative to docs directory)" - ) + parser.add_argument("--file", type=str, help="Specific file to translate (relative to docs directory)") args = parser.parse_args() if args.file: @@ -310,4 +308,4 @@ def main(): if __name__ == "__main__": # translate_single_source_file("docs/index.md") - main() + main() \ No newline at end of file diff --git a/examples/basic/hello_world_jupyter.ipynb b/examples/basic/hello_world_jupyter.ipynb index 8dd3bb379..42ee8e6a2 100644 --- a/examples/basic/hello_world_jupyter.ipynb +++ b/examples/basic/hello_world_jupyter.ipynb @@ -30,7 +30,7 @@ "agent = Agent(name=\"Assistant\", instructions=\"You are a helpful assistant\")\n", "\n", "# Intended for Jupyter notebooks where there's an existing event loop\n", - "result = await Runner.run(agent, \"Write a haiku about recursion in programming.\") # type: ignore[top-level-await] # noqa: F704\n", + "result = await Runner.run(agent, \"Write a haiku about recursion in programming.\") # type: ignore[top-level-await] # noqa: F704\n", "print(result.final_output)" ] } diff --git a/examples/reasoning_content/main.py b/examples/reasoning_content/main.py index c23b04254..10f713835 100644 --- a/examples/reasoning_content/main.py +++ b/examples/reasoning_content/main.py @@ -44,7 +44,7 @@ async def stream_with_reasoning_content(): handoffs=[], tracing=ModelTracing.DISABLED, previous_response_id=None, - prompt=None, + prompt=None ): if event.type == "response.reasoning_summary_text.delta": print( @@ -82,7 +82,7 @@ async def get_response_with_reasoning_content(): handoffs=[], tracing=ModelTracing.DISABLED, previous_response_id=None, - prompt=None, + prompt=None ) # Extract reasoning content and regular content from the response @@ -121,4 +121,4 @@ async def main(): if __name__ == "__main__": - asyncio.run(main()) + asyncio.run(main()) \ No newline at end of file diff --git a/src/agents/agent.py b/src/agents/agent.py index 2f77f5f2a..1d2a8d85d 100644 --- a/src/agents/agent.py +++ b/src/agents/agent.py @@ -256,7 +256,9 @@ async def get_prompt( """Get the prompt for the agent.""" return await PromptUtil.to_model_input(self.prompt, run_context, self) - async def get_mcp_tools(self, run_context: RunContextWrapper[TContext]) -> list[Tool]: + async def get_mcp_tools( + self, run_context: RunContextWrapper[TContext] + ) -> list[Tool]: """Fetches the available tools from the MCP servers.""" convert_schemas_to_strict = self.mcp_config.get("convert_schemas_to_strict", False) return await MCPUtil.get_all_function_tools( @@ -281,4 +283,4 @@ async def _check_tool_enabled(tool: Tool) -> bool: results = await asyncio.gather(*(_check_tool_enabled(t) for t in self.tools)) enabled: list[Tool] = [t for t, ok in zip(self.tools, results) if ok] - return [*mcp_tools, *enabled] + return [*mcp_tools, *enabled] \ No newline at end of file diff --git a/src/agents/mcp/server.py b/src/agents/mcp/server.py index ef1d290b0..21ad20740 100644 --- a/src/agents/mcp/server.py +++ b/src/agents/mcp/server.py @@ -130,7 +130,9 @@ async def _apply_tool_filter( return await self._apply_dynamic_tool_filter(tools, run_context, agent) def _apply_static_tool_filter( - self, tools: list[MCPTool], static_filter: ToolFilterStatic + self, + tools: list[MCPTool], + static_filter: ToolFilterStatic ) -> list[MCPTool]: """Apply static tool filtering based on allowlist and blocklist.""" filtered_tools = tools diff --git a/src/agents/model_settings.py b/src/agents/model_settings.py index f81f10989..6e6d78988 100644 --- a/src/agents/model_settings.py +++ b/src/agents/model_settings.py @@ -17,9 +17,9 @@ class _OmitTypeAnnotation: @classmethod def __get_pydantic_core_schema__( - cls, - _source_type: Any, - _handler: GetCoreSchemaHandler, + cls, + _source_type: Any, + _handler: GetCoreSchemaHandler, ) -> core_schema.CoreSchema: def validate_from_none(value: None) -> _Omit: return _Omit() @@ -39,14 +39,13 @@ def validate_from_none(value: None) -> _Omit: from_none_schema, ] ), - serialization=core_schema.plain_serializer_function_ser_schema(lambda instance: None), + serialization=core_schema.plain_serializer_function_ser_schema( + lambda instance: None + ), ) - - Omit = Annotated[_Omit, _OmitTypeAnnotation] Headers: TypeAlias = Mapping[str, Union[str, Omit]] - @dataclass class ModelSettings: """Settings to use when calling an LLM. @@ -159,4 +158,4 @@ def to_json_dict(self) -> dict[str, Any]: else: json_dict[field_name] = value - return json_dict + return json_dict \ No newline at end of file diff --git a/src/agents/tool.py b/src/agents/tool.py index f2861b936..06805befb 100644 --- a/src/agents/tool.py +++ b/src/agents/tool.py @@ -30,6 +30,7 @@ from .util._types import MaybeAwaitable if TYPE_CHECKING: + from .agent import Agent ToolParams = ParamSpec("ToolParams") @@ -462,4 +463,4 @@ async def _on_invoke_tool(ctx: ToolContext[Any], input: str) -> Any: def decorator(real_func: ToolFunction[...]) -> FunctionTool: return _create_function_tool(real_func) - return decorator + return decorator \ No newline at end of file diff --git a/tests/mcp/test_tool_filtering.py b/tests/mcp/test_tool_filtering.py index 0127df806..5a55400d3 100644 --- a/tests/mcp/test_tool_filtering.py +++ b/tests/mcp/test_tool_filtering.py @@ -3,7 +3,6 @@ external dependencies (processes, network connections) and ensure fast, reliable unit tests. FakeMCPServer delegates filtering logic to the real _MCPServerWithClientSession implementation. """ - import asyncio import pytest @@ -28,7 +27,6 @@ def create_test_context() -> RunContextWrapper: # === Static Tool Filtering Tests === - @pytest.mark.asyncio async def test_static_tool_filtering(): """Test all static tool filtering scenarios: allowed, blocked, both, none, etc.""" @@ -57,7 +55,7 @@ async def test_static_tool_filtering(): # Test both filters together (allowed first, then blocked) server.tool_filter = { "allowed_tool_names": ["tool1", "tool2", "tool3"], - "blocked_tool_names": ["tool3"], + "blocked_tool_names": ["tool3"] } tools = await server.list_tools(run_context, agent) assert len(tools) == 2 @@ -70,7 +68,8 @@ async def test_static_tool_filtering(): # Test helper function server.tool_filter = create_static_tool_filter( - allowed_tool_names=["tool1", "tool2"], blocked_tool_names=["tool2"] + allowed_tool_names=["tool1", "tool2"], + blocked_tool_names=["tool2"] ) tools = await server.list_tools(run_context, agent) assert len(tools) == 1 @@ -79,7 +78,6 @@ async def test_static_tool_filtering(): # === Dynamic Tool Filtering Core Tests === - @pytest.mark.asyncio async def test_dynamic_filter_sync_and_async(): """Test both synchronous and asynchronous dynamic filters""" @@ -183,7 +181,6 @@ def error_prone_filter(context: ToolFilterContext, tool: MCPTool) -> bool: # === Integration Tests === - @pytest.mark.asyncio async def test_agent_dynamic_filtering_integration(): """Test dynamic filtering integration with Agent methods""" @@ -243,4 +240,4 @@ async def role_based_filter(context: ToolFilterContext, tool: MCPTool) -> bool: for t in all_tools if t.name in {"file_read", "file_write", "database_query", "network_request"} } - assert mcp_tool_names == {"file_read", "file_write"} + assert mcp_tool_names == {"file_read", "file_write"} \ No newline at end of file diff --git a/tests/test_reasoning_content.py b/tests/test_reasoning_content.py index 69e9a7d0c..94b6fc58f 100644 --- a/tests/test_reasoning_content.py +++ b/tests/test_reasoning_content.py @@ -27,8 +27,12 @@ # Helper functions to create test objects consistently def create_content_delta(content: str) -> dict[str, Any]: """Create a delta dictionary with regular content""" - return {"content": content, "role": None, "function_call": None, "tool_calls": None} - + return { + "content": content, + "role": None, + "function_call": None, + "tool_calls": None + } def create_reasoning_delta(content: str) -> dict[str, Any]: """Create a delta dictionary with reasoning content. The Only difference is reasoning_content""" @@ -37,7 +41,7 @@ def create_reasoning_delta(content: str) -> dict[str, Any]: "role": None, "function_call": None, "tool_calls": None, - "reasoning_content": content, + "reasoning_content": content } @@ -184,7 +188,7 @@ async def test_get_response_with_reasoning_content(monkeypatch) -> None: "index": 0, "finish_reason": "stop", "message": msg_with_reasoning, - "delta": None, + "delta": None } chat = ChatCompletion( @@ -270,7 +274,7 @@ async def patched_fetch_response(self, *args, **kwargs): handoffs=[], tracing=ModelTracing.DISABLED, previous_response_id=None, - prompt=None, + prompt=None ): output_events.append(event) @@ -282,4 +286,4 @@ async def patched_fetch_response(self, *args, **kwargs): assert len(response_event.response.output) == 1 assert isinstance(response_event.response.output[0], ResponseOutputMessage) assert isinstance(response_event.response.output[0].content[0], ResponseOutputText) - assert response_event.response.output[0].content[0].text == "The answer is 42" + assert response_event.response.output[0].content[0].text == "The answer is 42" \ No newline at end of file From ac4c042a30bba66c4bd64751eea7cb7bb2853bc9 Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Tue, 8 Jul 2025 16:34:27 +0400 Subject: [PATCH 16/22] Remove un-necessary changes --- docs/scripts/translate_docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/scripts/translate_docs.py b/docs/scripts/translate_docs.py index 2af4297d9..5dada2681 100644 --- a/docs/scripts/translate_docs.py +++ b/docs/scripts/translate_docs.py @@ -308,4 +308,4 @@ def main(): if __name__ == "__main__": # translate_single_source_file("docs/index.md") - main() \ No newline at end of file + main() From f47f88dc228f1113398b76ccc03293894adbf46c Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Tue, 8 Jul 2025 16:36:16 +0400 Subject: [PATCH 17/22] Remove un-necessary changes --- examples/reasoning_content/main.py | 2 +- src/agents/agent.py | 2 +- src/agents/model_settings.py | 2 +- tests/mcp/test_tool_filtering.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/reasoning_content/main.py b/examples/reasoning_content/main.py index 10f713835..5f67e1779 100644 --- a/examples/reasoning_content/main.py +++ b/examples/reasoning_content/main.py @@ -121,4 +121,4 @@ async def main(): if __name__ == "__main__": - asyncio.run(main()) \ No newline at end of file + asyncio.run(main()) diff --git a/src/agents/agent.py b/src/agents/agent.py index 1d2a8d85d..6c87297f1 100644 --- a/src/agents/agent.py +++ b/src/agents/agent.py @@ -283,4 +283,4 @@ async def _check_tool_enabled(tool: Tool) -> bool: results = await asyncio.gather(*(_check_tool_enabled(t) for t in self.tools)) enabled: list[Tool] = [t for t, ok in zip(self.tools, results) if ok] - return [*mcp_tools, *enabled] \ No newline at end of file + return [*mcp_tools, *enabled] diff --git a/src/agents/model_settings.py b/src/agents/model_settings.py index 6e6d78988..26af94ba3 100644 --- a/src/agents/model_settings.py +++ b/src/agents/model_settings.py @@ -158,4 +158,4 @@ def to_json_dict(self) -> dict[str, Any]: else: json_dict[field_name] = value - return json_dict \ No newline at end of file + return json_dict diff --git a/tests/mcp/test_tool_filtering.py b/tests/mcp/test_tool_filtering.py index 5a55400d3..c1ffff4b8 100644 --- a/tests/mcp/test_tool_filtering.py +++ b/tests/mcp/test_tool_filtering.py @@ -240,4 +240,4 @@ async def role_based_filter(context: ToolFilterContext, tool: MCPTool) -> bool: for t in all_tools if t.name in {"file_read", "file_write", "database_query", "network_request"} } - assert mcp_tool_names == {"file_read", "file_write"} \ No newline at end of file + assert mcp_tool_names == {"file_read", "file_write"} From 5467d21d9c02caf3eaf8bcb82e4653ca52f28c9e Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Tue, 8 Jul 2025 16:37:49 +0400 Subject: [PATCH 18/22] Remove un-necessary changes --- src/agents/mcp/server.py | 6 +++--- src/agents/tool.py | 2 +- tests/test_reasoning_content.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/agents/mcp/server.py b/src/agents/mcp/server.py index 21ad20740..31986b283 100644 --- a/src/agents/mcp/server.py +++ b/src/agents/mcp/server.py @@ -130,9 +130,9 @@ async def _apply_tool_filter( return await self._apply_dynamic_tool_filter(tools, run_context, agent) def _apply_static_tool_filter( - self, - tools: list[MCPTool], - static_filter: ToolFilterStatic + self, + tools: list[MCPTool], + static_filter: ToolFilterStatic ) -> list[MCPTool]: """Apply static tool filtering based on allowlist and blocklist.""" filtered_tools = tools diff --git a/src/agents/tool.py b/src/agents/tool.py index 06805befb..3aab47752 100644 --- a/src/agents/tool.py +++ b/src/agents/tool.py @@ -463,4 +463,4 @@ async def _on_invoke_tool(ctx: ToolContext[Any], input: str) -> Any: def decorator(real_func: ToolFunction[...]) -> FunctionTool: return _create_function_tool(real_func) - return decorator \ No newline at end of file + return decorator diff --git a/tests/test_reasoning_content.py b/tests/test_reasoning_content.py index 94b6fc58f..5160e09c2 100644 --- a/tests/test_reasoning_content.py +++ b/tests/test_reasoning_content.py @@ -286,4 +286,4 @@ async def patched_fetch_response(self, *args, **kwargs): assert len(response_event.response.output) == 1 assert isinstance(response_event.response.output[0], ResponseOutputMessage) assert isinstance(response_event.response.output[0].content[0], ResponseOutputText) - assert response_event.response.output[0].content[0].text == "The answer is 42" \ No newline at end of file + assert response_event.response.output[0].content[0].text == "The answer is 42" From 4c4559e2b28496dd1cae5d2a9ba7910715a7c5ee Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Tue, 8 Jul 2025 16:43:02 +0400 Subject: [PATCH 19/22] Remove un-necessary changes --- src/agents/tool.py | 2 +- tests/model_settings/test_serialization.py | 4 ++-- tests/test_reasoning_content.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/agents/tool.py b/src/agents/tool.py index 3aab47752..06805befb 100644 --- a/src/agents/tool.py +++ b/src/agents/tool.py @@ -463,4 +463,4 @@ async def _on_invoke_tool(ctx: ToolContext[Any], input: str) -> Any: def decorator(real_func: ToolFunction[...]) -> FunctionTool: return _create_function_tool(real_func) - return decorator + return decorator \ No newline at end of file diff --git a/tests/model_settings/test_serialization.py b/tests/model_settings/test_serialization.py index 23ea5359c..eac9b4e81 100644 --- a/tests/model_settings/test_serialization.py +++ b/tests/model_settings/test_serialization.py @@ -135,8 +135,8 @@ def test_extra_args_resolve_both_none() -> None: assert resolved.temperature == 0.5 assert resolved.top_p == 0.9 - def test_pydantic_serialization() -> None: + """Tests whether ModelSettings can be serialized with Pydantic.""" # First, lets create a ModelSettings instance @@ -162,4 +162,4 @@ def test_pydantic_serialization() -> None: json = to_json(model_settings) deserialized = TypeAdapter(ModelSettings).validate_json(json) - assert model_settings == deserialized + assert model_settings == deserialized \ No newline at end of file diff --git a/tests/test_reasoning_content.py b/tests/test_reasoning_content.py index 5160e09c2..94b6fc58f 100644 --- a/tests/test_reasoning_content.py +++ b/tests/test_reasoning_content.py @@ -286,4 +286,4 @@ async def patched_fetch_response(self, *args, **kwargs): assert len(response_event.response.output) == 1 assert isinstance(response_event.response.output[0], ResponseOutputMessage) assert isinstance(response_event.response.output[0].content[0], ResponseOutputText) - assert response_event.response.output[0].content[0].text == "The answer is 42" + assert response_event.response.output[0].content[0].text == "The answer is 42" \ No newline at end of file From 164fe61da8cf332f4d3139adebe15bd537693b49 Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Tue, 8 Jul 2025 16:45:05 +0400 Subject: [PATCH 20/22] Remove un-necessary changes --- src/agents/tool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agents/tool.py b/src/agents/tool.py index 06805befb..3aab47752 100644 --- a/src/agents/tool.py +++ b/src/agents/tool.py @@ -463,4 +463,4 @@ async def _on_invoke_tool(ctx: ToolContext[Any], input: str) -> Any: def decorator(real_func: ToolFunction[...]) -> FunctionTool: return _create_function_tool(real_func) - return decorator \ No newline at end of file + return decorator From dc5aea18b201bc840cf8a338a4b700dffcb0d12a Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Tue, 8 Jul 2025 16:50:35 +0400 Subject: [PATCH 21/22] Remove un-necessary changes --- tests/test_reasoning_content.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_reasoning_content.py b/tests/test_reasoning_content.py index 94b6fc58f..5160e09c2 100644 --- a/tests/test_reasoning_content.py +++ b/tests/test_reasoning_content.py @@ -286,4 +286,4 @@ async def patched_fetch_response(self, *args, **kwargs): assert len(response_event.response.output) == 1 assert isinstance(response_event.response.output[0], ResponseOutputMessage) assert isinstance(response_event.response.output[0].content[0], ResponseOutputText) - assert response_event.response.output[0].content[0].text == "The answer is 42" \ No newline at end of file + assert response_event.response.output[0].content[0].text == "The answer is 42" From 937da4b3075f91bbcf205b03455fa99a47f422f1 Mon Sep 17 00:00:00 2001 From: Mohamed Amri Date: Tue, 8 Jul 2025 16:50:59 +0400 Subject: [PATCH 22/22] Remove un-necessary changes --- tests/model_settings/test_serialization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/model_settings/test_serialization.py b/tests/model_settings/test_serialization.py index eac9b4e81..94d11def3 100644 --- a/tests/model_settings/test_serialization.py +++ b/tests/model_settings/test_serialization.py @@ -162,4 +162,4 @@ def test_pydantic_serialization() -> None: json = to_json(model_settings) deserialized = TypeAdapter(ModelSettings).validate_json(json) - assert model_settings == deserialized \ No newline at end of file + assert model_settings == deserialized