From 50529c5e66ca5da79c47e479540bff87849d2aa4 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Sun, 27 Apr 2025 09:56:35 +0200 Subject: [PATCH 1/2] Set `use_attribute_docstrings=True` by default on tools --- pydantic_ai_slim/pydantic_ai/_pydantic.py | 2 +- tests/test_tools.py | 45 +++++++++++++++++++---- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/pydantic_ai_slim/pydantic_ai/_pydantic.py b/pydantic_ai_slim/pydantic_ai/_pydantic.py index 901556a1b7..8f5f0ee73a 100644 --- a/pydantic_ai_slim/pydantic_ai/_pydantic.py +++ b/pydantic_ai_slim/pydantic_ai/_pydantic.py @@ -58,7 +58,7 @@ def function_schema( # noqa: C901 Returns: A `FunctionSchema` instance. """ - config = ConfigDict(title=function.__name__) + config = ConfigDict(title=function.__name__, use_attribute_docstrings=True) config_wrapper = ConfigWrapper(config) gen_schema = _generate_schema.GenerateSchema(config_wrapper) diff --git a/tests/test_tools.py b/tests/test_tools.py index 69864a040d..946641ec11 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -9,16 +9,10 @@ from pydantic import BaseModel, Field, WithJsonSchema from pydantic.json_schema import GenerateJsonSchema, JsonSchemaValue from pydantic_core import PydanticSerializationError, core_schema +from typing_extensions import TypedDict from pydantic_ai import Agent, RunContext, Tool, ToolOutput, UserError -from pydantic_ai.messages import ( - ModelMessage, - ModelRequest, - ModelResponse, - TextPart, - ToolCallPart, - ToolReturnPart, -) +from pydantic_ai.messages import ModelMessage, ModelRequest, ModelResponse, TextPart, ToolCallPart, ToolReturnPart from pydantic_ai.models.function import AgentInfo, FunctionModel from pydantic_ai.models.test import TestModel from pydantic_ai.tools import ToolDefinition @@ -926,3 +920,38 @@ def my_tool(x: Annotated[Union[str, None], WithJsonSchema({'type': 'string'})] = }, ] ) + + +def test_tool_parameters_with_attribute_docstrings(): + agent = Agent(FunctionModel(get_json_schema)) + + class Data(TypedDict): + a: int + """The first parameter""" + b: int + """The second parameter""" + + @agent.tool_plain + def get_score(data: Data) -> int: + return data['a'] + data['b'] + + result = agent.run_sync('Hello') + json_schema = json.loads(result.output) + assert json_schema == snapshot( + { + 'name': 'get_score', + 'description': None, + 'parameters_json_schema': { + 'additionalProperties': False, + 'properties': { + 'a': {'description': 'The first parameter', 'type': 'integer'}, + 'b': {'description': 'The second parameter', 'type': 'integer'}, + }, + 'required': ['a', 'b'], + 'title': 'Data', + 'type': 'object', + }, + 'outer_typed_dict_key': None, + 'strict': None, + } + ) From 126b869cc50a8ba36ae8f1f399da9ef8ecfa1009 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Sun, 27 Apr 2025 10:07:25 +0200 Subject: [PATCH 2/2] fix coverage --- tests/test_tools.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_tools.py b/tests/test_tools.py index 946641ec11..887274a83a 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -932,8 +932,7 @@ class Data(TypedDict): """The second parameter""" @agent.tool_plain - def get_score(data: Data) -> int: - return data['a'] + data['b'] + def get_score(data: Data) -> int: ... result = agent.run_sync('Hello') json_schema = json.loads(result.output)