Skip to content

[codex] fix nested MCP schema conversion#130

Open
117503445 wants to merge 1 commit into
Serverless-Devs:mainfrom
117503445:codex/fix-nested-mcp-schema-downgrade
Open

[codex] fix nested MCP schema conversion#130
117503445 wants to merge 1 commit into
Serverless-Devs:mainfrom
117503445:codex/fix-nested-mcp-schema-downgrade

Conversation

@117503445

@117503445 117503445 commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Preserve nested MCP object schemas when converting through the LangChain adapter path.
  • Thread the root JSON schema through _json_schema_to_pydantic / _json_type_to_python so deep anyOf / $ref wrappers can resolve $defs.
  • Add regression coverage for nested optional object fields, direct anyOf + $ref schemas, and recursive $ref schemas that should not crash.

Root Cause

Optional nested object fields are represented by Pydantic as anyOf: [{"$ref": ...}, {"type": "null"}]. The second JSON Schema to Pydantic conversion in the LangChain adapter previously passed those nested field schemas into _json_type_to_python without the root schema, and _json_type_to_python defaulted schemas without a top-level type to string. That downgraded nested MCP objects into string | null.

The fix resolves wrapped schema fragments against the root schema and tracks active $ref entries while recursively constructing Pydantic models, so self-referential schemas degrade to dict at the recursive edge instead of raising RecursionError.

Validation

  • .venv/bin/python -m pytest tests/unittests/integration/test_tool_utils.py::TestNestedObjectRoundTrip -q
  • .venv/bin/python -m pytest tests/unittests/integration/test_tool_utils.py -q

@117503445 117503445 marked this pull request as ready for review July 4, 2026 06:58
@117503445 117503445 closed this Jul 4, 2026
@117503445 117503445 force-pushed the codex/fix-nested-mcp-schema-downgrade branch from 21e59b7 to 84dfaf2 Compare July 4, 2026 06:59
@117503445 117503445 reopened this Jul 4, 2026
@117503445 117503445 force-pushed the codex/fix-nested-mcp-schema-downgrade branch 11 times, most recently from f1b5947 to dbda29b Compare July 4, 2026 09:08
Signed-off-by: 黑曜 <haotian.qht@alibaba-inc.com>
@117503445 117503445 force-pushed the codex/fix-nested-mcp-schema-downgrade branch from dbda29b to 5e62dbd Compare July 4, 2026 09:27
@OhYee OhYee requested a review from Copilot July 4, 2026 12:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 JSON Schema → Pydantic conversion issues in the LangChain adapter path so that nested MCP object schemas (especially anyOf/$ref wrappers) remain objects after the second conversion, and recursive $ref graphs no longer crash during model construction.

Changes:

  • Thread the root schema and add $ref-tracking/caching to _json_schema_to_pydantic / _json_type_to_python to correctly resolve deep $defs references and avoid exponential expansion.
  • Add $ref-cycle protection so self-referential schemas degrade gracefully instead of raising recursion errors.
  • Add regression tests covering nested optional objects, anyOf + $ref wrappers, recursive and shared $ref topologies, and reachable-ref caching.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
agentrun/integration/utils/tool.py Threads root schema + adds ref-cycle guard and caching to preserve nested object typing across conversions.
tests/unittests/integration/test_tool_utils.py Adds regression coverage for nested object round-trips and multiple $ref recursion/caching scenarios.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +2035 to +2043
if root_schema is not None and (
"anyOf" in field_schema
or "oneOf" in field_schema
or "allOf" in field_schema
or "$ref" in field_schema
):
core_schema, _ = _extract_core_schema(field_schema, root_schema)
if core_schema:
field_schema = core_schema
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants