fix(mcp): handle inline nested objects in McpToolSpec.create_model_from_json_schema#22143
fix(mcp): handle inline nested objects in McpToolSpec.create_model_from_json_schema#22143anishesg wants to merge 1 commit into
Conversation
…om_json_schema The `McpToolSpec.create_model_from_json_schema` method in `llama_index/tools/mcp/tool_spec_mixins.py` was not handling inline nested objects correctly. When a property had `type: "object"` with its own `properties` and `required` fields (not via `$ref`), the method treated it as a bare `Dict` type, losing the nested schema structure. Signed-off-by: anish <anishesg@users.noreply.github.com>
gyx09212214-prog
left a comment
There was a problem hiding this comment.
Nice fix for inline object schemas. One more schema shape would be worth covering: two inline nested object properties with the same property key set but different field types/required sets. _create_nested_model derives the fallback model name only from sorted property names, so {value: string} and {value: integer} both become the same NestedModel_<hash>.
Pydantic's JSON schema generation may then reuse/collide $defs names and one nested schema can overwrite or alias the other. Could the hash include the full nested schema, e.g. canonical JSON with sorted keys, or the property path, plus a regression with two same-key inline objects?
|
good catch, yeah that's a real collision risk. updated the hash to include the full schema definition, not just the keys. added a test with two nested objects that have the same keys but different types to make sure they don't collide. |
The
McpToolSpec.create_model_from_json_schemamethod inllama_index/tools/mcp/tool_spec_mixins.pywas not handling inline nested objects correctly. When a property hadtype: "object"with its ownpropertiesandrequiredfields (not via$ref), the method treated it as a bareDicttype, losing the nested schema structure.The root cause was in the
_resolve_basic_typemethod, which only checked for simple objects (those withadditionalProperties) but not for inline nested objects (those withproperties). This caused inline nested objects to fall through to the default type mapping, returning a bareDictinstead of recursively creating a nested Pydantic model.The fix adds a new helper method
_is_inline_nested_objectto detect schemas with inline nested properties, and a new method_create_nested_modelto recursively build Pydantic models for these nested objects. The logic is inserted before the default type mapping fallback in_resolve_basic_type, ensuring inline nested objects are properly handled. The fix also includes a regression test to verify that both inline nested objects and referenced nested objects (via$ref) work correctly.Fixes #22141