Skip to content

Python: fix(claude): preserve $defs in JSON schema for nested Pydantic models#3655

Merged
moonbox3 merged 3 commits intomicrosoft:mainfrom
droideronline:fix/claude-agent-preserve-schema-defs
Feb 4, 2026
Merged

Python: fix(claude): preserve $defs in JSON schema for nested Pydantic models#3655
moonbox3 merged 3 commits intomicrosoft:mainfrom
droideronline:fix/claude-agent-preserve-schema-defs

Conversation

@droideronline
Copy link
Contributor

Summary

This PR fixes a bug where _function_tool_to_sdk_mcp_tool() dropped the $defs section from Pydantic JSON schemas, breaking any tool that uses nested Pydantic models.

Problem

When converting a FunctionTool to an SDK MCP tool, the code was only extracting properties and required from the Pydantic model's JSON schema, but dropping the $defs section which contains definitions for nested types:

input_schema: dict[str, Any] = {
    "type": "object",
    "properties": schema.get("properties", {}),
    "required": schema.get("required", []),
}
# $defs was not being preserved!

This caused tools with nested Pydantic models to produce invalid/unresolvable JSON schemas. The schema would contain $ref references like "$ref": "#/$defs/SomeNestedType" but the $defs section was missing, so Claude could not resolve the type and refused to call the tool.

Changes

_agent.py

  • Preserve $defs section from Pydantic JSON schema when present:
    if "$defs" in schema:
        input_schema["$defs"] = schema["$defs"]

test_claude_agent.py

  • Added test_function_tool_to_sdk_mcp_tool_preserves_defs_for_nested_types - verifies that nested Pydantic models generate schemas with $defs preserved

Testing

All 45 tests pass:

pytest tests/test_claude_agent.py -v
============================== 45 passed in 0.31s ==============================

Fixes #3654

Copilot AI review requested due to automatic review settings February 3, 2026 20:28
@github-actions github-actions bot changed the title fix(claude): preserve $defs in JSON schema for nested Pydantic models Python: fix(claude): preserve $defs in JSON schema for nested Pydantic models Feb 3, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes the Claude agent’s FunctionTool → SDK MCP conversion so that Pydantic nested models produce valid JSON schemas by preserving the $defs section, and adds a regression test to prevent regressions for nested types.

Changes:

  • Updated _function_tool_to_sdk_mcp_tool to carry over the $defs section from the Pydantic model’s model_json_schema() into the MCP tool input schema.
  • Added a dedicated test ensuring that tools with nested Pydantic models have $defs preserved and that the top-level property referencing the nested model is present.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
python/packages/claude/agent_framework_claude/_agent.py Extends the generated MCP input schema to include $defs from the underlying Pydantic schema so nested $ref types resolve correctly.
python/packages/claude/tests/test_claude_agent.py Adds a regression test using nested Pydantic models to verify that $defs is preserved and that the nested model reference appears in properties.

@markwallace-microsoft
Copy link
Member

markwallace-microsoft commented Feb 4, 2026

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/core/agent_framework
   _tools.py7697690%226, 272, 323, 325, 353, 523, 558–559, 661, 663, 683, 701, 715, 727, 732, 734, 741, 774, 845–847, 888, 913–922, 928–937, 973, 981, 1222, 1559, 1646–1650, 1672–1673, 1789, 1791, 1857, 1949, 1955, 1997–1998, 2011–2012, 2055, 2139, 2177–2178, 2217–2219, 2257–2258, 2268, 2325–2326, 2333–2334
TOTAL16338198287% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
3822 221 💤 0 ❌ 0 🔥 1m 9s ⏱️

@dmytrostruk dmytrostruk enabled auto-merge February 4, 2026 01:46
@moonbox3 moonbox3 disabled auto-merge February 4, 2026 01:52
@droideronline
Copy link
Contributor Author

@moonbox3 - Can we have please have a look at this ?

- Preserve $defs section from Pydantic JSON schema when converting FunctionTool to SDK MCP tool
- This fixes tools with nested Pydantic models that use $ref references
- Add test for nested type schema preservation

Fixes microsoft#3654
@moonbox3
Copy link
Contributor

moonbox3 commented Feb 4, 2026

I need to get another PR merged that fixes a bug, and thus allows the failing unit test to pass.

@droideronline droideronline force-pushed the fix/claude-agent-preserve-schema-defs branch from b33d823 to e8d3930 Compare February 4, 2026 05:46
@droideronline
Copy link
Contributor Author

I need to get another PR merged that fixes a bug, and thus allows the failing unit test to pass.

sure, I just cherry-picked your test failure fixes here

@moonbox3 moonbox3 added this pull request to the merge queue Feb 4, 2026
Merged via the queue into microsoft:main with commit 5c6cf4f Feb 4, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: _function_tool_to_sdk_mcp_tool drops $defs from Pydantic JSON schemas, breaking tools with nested types

5 participants