Skip to content

Fix recursive tool input schema by hoisting $defs to root#6035

Closed
jewoodev wants to merge 1 commit into
spring-projects:mainfrom
jewoodev:fix/gh-5888-tool-input-schema-defs
Closed

Fix recursive tool input schema by hoisting $defs to root#6035
jewoodev wants to merge 1 commit into
spring-projects:mainfrom
jewoodev:fix/gh-5888-tool-input-schema-defs

Conversation

@jewoodev

@jewoodev jewoodev commented May 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #5888.

  • Why: Spring AI currently inlines parameter schemas under properties.<param>, but their generated $refs still point to root-level $defs.

  • Fix: Move each parameter schema's $defs to the wrapper schema root before inlining the parameter. Reuse structurally equal definitions; rename conflicting simple names and rewrite refs within the hoisted schema.

Tests

Added regression coverage in both generators for:

  • transitive recursive parameter schemas
  • duplicate equal definitions
  • colliding simple-name definitions with ref rewrites
./mvnw -pl spring-ai-model,mcp/mcp-annotations test \
    -Dtest='JsonSchemaGeneratorTests,McpJsonSchemaGeneratorTests'

Scope

This PR covers the transitive $defs failure reported in #5888 for both JsonSchemaGenerator and McpJsonSchemaGenerator. Direct self-recursive $ref: "#" handling is outside this PR.

Signed-off-by: jewoodev <jewoos15@naver.com>
@jewoodev

Copy link
Copy Markdown
Contributor Author

Hi @danielvolovik96 and @jeanchristophecascade — apologies for going ahead without a check-in first. The issue had been quiet for ~18 days and I drafted this to keep it moving, but I want to be explicit: if either of you would prefer to lead the implementation, I'm happy to close this PR, hand the branch over, or co-author — just say the word. Same goes if maintainers prefer a different approach.

The diff covers the transitive $defs case described in #5888 (with rename + peer-ref rewrite for the same-simple-name corner case), applied to both spring-ai-model and mcp-annotations per @jeanchristophecascade's follow-up.

@tzolov

tzolov commented May 21, 2026

Copy link
Copy Markdown
Contributor

Thanks for addressing this issue @jewoodev !

tzolov added a commit that referenced this pull request May 21, 2026
Add hoistDefsToRoot into JsonSchemaUtils so both JsonSchemaGenerator and
McpJsonSchemaGenerator share the implementation.
Handles equal-definition reuse, name collisions with suffix renaming,
peer-ref rewriting, and correct $defs-before-properties ordering.
Add tests for both generators.

Signed-off-by: jewoodev <jewoos15@naver.com>
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>

Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com>
@tzolov

tzolov commented May 21, 2026

Copy link
Copy Markdown
Contributor

Rebased, clean the code and duplications, squashed and merged at 0f9c2a5

@tzolov tzolov closed this May 21, 2026
@jewoodev jewoodev deleted the fix/gh-5888-tool-input-schema-defs branch May 21, 2026 14:19
R3gardless pushed a commit to R3gardless/spring-ai that referenced this pull request May 21, 2026
…jects#6035)

Add hoistDefsToRoot into JsonSchemaUtils so both JsonSchemaGenerator and
McpJsonSchemaGenerator share the implementation.
Handles equal-definition reuse, name collisions with suffix renaming,
peer-ref rewriting, and correct $defs-before-properties ordering.
Add tests for both generators.

Signed-off-by: jewoodev <jewoos15@naver.com>
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>

Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com>
Signed-off-by: R3gardless <pidaoh@g.skku.edu>
@jeanchristophecascade

Copy link
Copy Markdown

Many thanks to both of you 😊

@jewoodev

Copy link
Copy Markdown
Contributor Author

Thank you @tzolov for the careful review, cleanup, and merge.

I really appreciate the refinements you made to the implementation. I learned from them and will keep that direction in mind for future contributions.

psilberk pushed a commit to psilberk/spring-ai that referenced this pull request May 22, 2026
…jects#6035)

Add hoistDefsToRoot into JsonSchemaUtils so both JsonSchemaGenerator and
McpJsonSchemaGenerator share the implementation.
Handles equal-definition reuse, name collisions with suffix renaming,
peer-ref rewriting, and correct $defs-before-properties ordering.
Add tests for both generators.

Signed-off-by: jewoodev <jewoos15@naver.com>
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>

Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com>
Signed-off-by: psilberk <psilberkasten@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working mcp tool calling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tool inputSchema with recursive parameter types emits unresolvable $ref (nested $defs, root-relative $ref)

3 participants