Skip to content

Commit ae06c9e

Browse files
Copiloteavanvalkenburgmoonbox3
authored
Add support for Pydantic BaseModel as function call result (#2606)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com>
1 parent f7a9005 commit ae06c9e

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

python/packages/core/agent_framework/_types.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,6 +1805,8 @@ def _prepare_function_call_results_as_dumpable(content: Contents | Any | list[Co
18051805
return [_prepare_function_call_results_as_dumpable(item) for item in content]
18061806
if isinstance(content, dict):
18071807
return {k: _prepare_function_call_results_as_dumpable(v) for k, v in content.items()}
1808+
if isinstance(content, BaseModel):
1809+
return content.model_dump()
18081810
if hasattr(content, "to_dict"):
18091811
return content.to_dict(exclude={"raw_representation", "additional_properties"})
18101812
return content

python/packages/core/tests/core/test_types.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
UsageContent,
3737
UsageDetails,
3838
ai_function,
39+
prepare_function_call_results,
3940
)
4041
from agent_framework.exceptions import AdditionItemMismatch, ContentError
4142

@@ -1965,3 +1966,75 @@ def test_text_content_with_multiple_annotations_serialization():
19651966
assert reconstructed.annotations[0].title == "Citation 1"
19661967
assert reconstructed.annotations[1].title == "Citation 2"
19671968
assert all(isinstance(ann.annotated_regions[0], TextSpanRegion) for ann in reconstructed.annotations)
1969+
1970+
1971+
# region prepare_function_call_results with Pydantic models
1972+
1973+
1974+
class WeatherResult(BaseModel):
1975+
"""A Pydantic model for testing."""
1976+
1977+
temperature: float
1978+
condition: str
1979+
1980+
1981+
class NestedModel(BaseModel):
1982+
"""A Pydantic model with nested structure."""
1983+
1984+
name: str
1985+
weather: WeatherResult
1986+
1987+
1988+
def test_prepare_function_call_results_pydantic_model():
1989+
"""Test that Pydantic BaseModel subclasses are properly serialized using model_dump()."""
1990+
result = WeatherResult(temperature=22.5, condition="sunny")
1991+
json_result = prepare_function_call_results(result)
1992+
1993+
# The result should be a valid JSON string
1994+
assert isinstance(json_result, str)
1995+
assert '"temperature": 22.5' in json_result or '"temperature":22.5' in json_result
1996+
assert '"condition": "sunny"' in json_result or '"condition":"sunny"' in json_result
1997+
1998+
1999+
def test_prepare_function_call_results_pydantic_model_in_list():
2000+
"""Test that lists containing Pydantic models are properly serialized."""
2001+
results = [
2002+
WeatherResult(temperature=20.0, condition="cloudy"),
2003+
WeatherResult(temperature=25.0, condition="sunny"),
2004+
]
2005+
json_result = prepare_function_call_results(results)
2006+
2007+
# The result should be a valid JSON string representing a list
2008+
assert isinstance(json_result, str)
2009+
assert json_result.startswith("[")
2010+
assert json_result.endswith("]")
2011+
assert "cloudy" in json_result
2012+
assert "sunny" in json_result
2013+
2014+
2015+
def test_prepare_function_call_results_pydantic_model_in_dict():
2016+
"""Test that dicts containing Pydantic models are properly serialized."""
2017+
results = {
2018+
"current": WeatherResult(temperature=22.0, condition="partly cloudy"),
2019+
"forecast": WeatherResult(temperature=24.0, condition="sunny"),
2020+
}
2021+
json_result = prepare_function_call_results(results)
2022+
2023+
# The result should be a valid JSON string representing a dict
2024+
assert isinstance(json_result, str)
2025+
assert "current" in json_result
2026+
assert "forecast" in json_result
2027+
assert "partly cloudy" in json_result
2028+
assert "sunny" in json_result
2029+
2030+
2031+
def test_prepare_function_call_results_nested_pydantic_model():
2032+
"""Test that nested Pydantic models are properly serialized."""
2033+
result = NestedModel(name="Seattle", weather=WeatherResult(temperature=18.0, condition="rainy"))
2034+
json_result = prepare_function_call_results(result)
2035+
2036+
# The result should be a valid JSON string
2037+
assert isinstance(json_result, str)
2038+
assert "Seattle" in json_result
2039+
assert "rainy" in json_result
2040+
assert "18.0" in json_result or "18" in json_result

0 commit comments

Comments
 (0)