core[patch]: Correct type casting of annotations in _infer_arg_descriptions (#31181)

- **Description:** 
- In _infer_arg_descriptions, the annotations dictionary contains string
representations of types instead of actual typing objects. This causes
_is_annotated_type to fail, preventing the correct description from
being generated.
- This is a simple fix using the get_type_hints method, which resolves
the annotations properly and is supported across all Python versions.

  - **Issue:** #31051

---------

Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
This commit is contained in:
Mohammad Mohtashim 2025-06-05 20:58:36 +05:00 committed by GitHub
parent dea43436ea
commit ae3551c96b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 6 deletions

View File

@ -5,6 +5,7 @@ from __future__ import annotations
import functools import functools
import inspect import inspect
import json import json
import typing
import warnings import warnings
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from inspect import signature from inspect import signature
@ -80,7 +81,7 @@ class SchemaAnnotationError(TypeError):
def _is_annotated_type(typ: type[Any]) -> bool: def _is_annotated_type(typ: type[Any]) -> bool:
return get_origin(typ) is Annotated return get_origin(typ) is typing.Annotated
def _get_annotation_description(arg_type: type) -> str | None: def _get_annotation_description(arg_type: type) -> str | None:
@ -143,11 +144,7 @@ def _infer_arg_descriptions(
error_on_invalid_docstring: bool = False, error_on_invalid_docstring: bool = False,
) -> tuple[str, dict]: ) -> tuple[str, dict]:
"""Infer argument descriptions from a function's docstring.""" """Infer argument descriptions from a function's docstring."""
if hasattr(inspect, "get_annotations"): annotations = typing.get_type_hints(fn, include_extras=True)
# This is for python < 3.10
annotations = inspect.get_annotations(fn)
else:
annotations = getattr(fn, "__annotations__", {})
if parse_docstring: if parse_docstring:
description, arg_descriptions = _parse_python_function_docstring( description, arg_descriptions = _parse_python_function_docstring(
fn, annotations, error_on_invalid_docstring=error_on_invalid_docstring fn, annotations, error_on_invalid_docstring=error_on_invalid_docstring

View File

@ -2711,3 +2711,24 @@ def test_tool_invoke_does_not_mutate_inputs() -> None:
"id": "call_0_82c17db8-95df-452f-a4c2-03f809022134", "id": "call_0_82c17db8-95df-452f-a4c2-03f809022134",
"type": "tool_call", "type": "tool_call",
} }
def test_tool_args_schema_with_annotated_type() -> None:
@tool
def test_tool(
query_fragments: Annotated[
list[str],
"A list of query fragments",
],
) -> list[str]:
"""Search the Internet and retrieve relevant result items."""
return []
assert test_tool.args == {
"query_fragments": {
"description": "A list of query fragments",
"items": {"type": "string"},
"title": "Query Fragments",
"type": "array",
}
}