Skip to content

Merge allOf subtypes so required fields sit next to their properties - #21

Open
Mohith26 wants to merge 1 commit into
cortexapps:masterfrom
Mohith26:fix/flatten-allof-subtypes
Open

Mohith26 wants to merge 1 commit into
cortexapps:masterfrom
Mohith26:fix/flatten-allof-subtypes

Conversation

@Mohith26

@Mohith26 Mohith26 commented Nov 3, 2026

Copy link
Copy Markdown

Fixes #13.

springdoc emits each subtype as {"required": [...], "allOf": [<parent>, {<own fields>}]}. After resolve_refs inlines the parent, the comparison schema of queryPointInTimeMetrics ends up with required: [alias, name, ordinal, windowSize] on an object that has no properties of its own, which is what Gemini/Vertex AI rejects in the issue.

This merges a plain allOf of object schemas into the schema that holds it while resolving: properties and required are unioned, so the constraints are the same, just on one object. It only does this when every branch is a plain object (type/properties/required/description/title/discriminator) and the branches agree on any property they both define (apart from description/title); otherwise the allOf is left alone. The base class's discriminator is dropped from the merged subtype, since there is no oneOf left for it to apply to.

Against the bundled swagger.json, queryPointInTimeMetrics is the only MCP tool whose input schema changes. I built the server with create_mcp_server() and checked the schemas from tools/list: before, comparison.anyOf[0] is {allOf, required, type} with the required names only inside the allOf; after, it is one object with required: [alias, name, ordinal, type, windowSize] and all of those in properties, and no tool input schema has a required name missing from its own properties. I haven't run it against Gemini itself.

Tests: added a test for the springdoc subtype shape and one for conflicting branches staying as allOf, and updated test_resolve_polymorphic_refs, which asserted the old allOf shape. pytest (40 passed), ruff check, black --check on the resolver, and mypy on the resolver are clean.

springdoc emits each subtype as a required list next to an allOf of the
parent schema and the subtype's own fields. After $ref resolution the
queryPointInTimeMetrics comparison schema therefore lists required fields
that are not in that object's properties, which Gemini/Vertex AI reject.

Fold plain object allOf branches into one object (union of properties and
required) while resolving. Branches with other keywords, or that define a
property differently, are left as they are.

Fixes cortexapps#13
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.

queryPointInTimeMetrics: comparison schema declares required properties outside its properties block, breaking Gemini/Vertex AI tool validation

1 participant