Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(mcp): remove redundant type field from Content implementations #27

Merged
merged 3 commits into from
Mar 3, 2025

Conversation

tzolov
Copy link
Contributor

@tzolov tzolov commented Mar 1, 2025

  • The type field and associated methods were redundant in Content implementations (TextContent, ImageContent, EmbeddedResource) as the type information is already handled by Jackson's polymorphic type handling via @JsonSubTypes annotation.
  • Added comprehensive unit tests for McpSchema to validate serialization/deserialization behavior of all schema components.

Resolves #26
Resolve spring-projects/spring-ai#2350

- The type field and associated methods were redundant in Content implementations (TextContent, ImageContent, EmbeddedResource)
  as the type information is already handled by Jackson's polymorphic type handling via @JsonSubTypes annotation.
- Added comprehensive unit tests for McpSchema to validate serialization/deserialization behavior of all schema components.

Resolves #26
Resolve spring-projects/spring-ai#2350

Signed-off-by: Christian Tzolov <[email protected]>
Copy link
Member

@chemicL chemicL left a comment

Choose a reason for hiding this comment

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

Despite the triviality of the fix, the tests are comprehensive and useful so I reviewed them carefully. I left a few comments.

@@ -964,61 +965,34 @@ public record CompleteCompletion(// @formatter:off
@JsonSubTypes.Type(value = EmbeddedResource.class, name = "resource") })
public sealed interface Content permits TextContent, ImageContent, EmbeddedResource {

String type();
// String type();
Copy link
Member

Choose a reason for hiding this comment

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

It should be removed I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I've decided to add a default String type() implementation to comply with the MCP Schema, were the type in the content exist.

String value = mapper.writeValueAsString(request);
assertEquals(
"""
{"protocolVersion":"2024-11-05","capabilities":{"roots":{"listChanged":true},"sampling":{}},"clientInfo":{"name":"test-client","version":"1.0.0"}}""",
Copy link
Member

Choose a reason for hiding this comment

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

This will break as soon as we update McpSchema.LATEST_PROTOCOL_VERSION. It should embed that value in the expected string.

Copy link
Member

Choose a reason for hiding this comment

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

Same comment applies to the other tests with the version.

Copy link
Member

Choose a reason for hiding this comment

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

Alternatively, instead of using the constant, specify a value inside the test and then the tests will work regardless of the versioning evolution.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

you're right. I will remove the constant from the fixture.

Comment on lines 312 to 314
// Use Jackson to parse both the expected and actual JSON to compare them as
// objects
// This ignores the order of properties in JSON objects
Copy link
Member

Choose a reason for hiding this comment

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

Why is there a need for this in one test and not in others?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It shouldn't. will remove the comment

- Enhance Content interface with type() implementation:
   - Add default implementation that returns the appropriate type string
     based on the implementing class (text, image, or resource)
   - Remove unused JsonIgnore import
- Improve test assertions and coverage:
   - Replace JUnit Jupiter assertions with AssertJ for more readable assertions
   - Add comprehensive deserialization tests for all content types
   - Add negative test case for invalid content type deserialization

Signed-off-by: Christian Tzolov <[email protected]>
@@ -964,61 +964,45 @@ public record CompleteCompletion(// @formatter:off
@JsonSubTypes.Type(value = EmbeddedResource.class, name = "resource") })
public sealed interface Content permits TextContent, ImageContent, EmbeddedResource {

String type();
default String type() {
Copy link
Member

Choose a reason for hiding this comment

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

Since you are dealing with a sealed interface, you can use a pattern switch on this and have a complete coverage without the default case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

pattern matching is available in Java 21+. The MCP project at the moment is configured for 17.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, it was a preview feature back then. My bad, sorry!

Replace direct string assertions with json-unit-assertj in McpSchemaTests to make tests more robust
against non-functional changes in JSON formatting.
The new approach ignores array order and extra array items, reducing test brittleness while
maintaining functional validation.

Signed-off-by: Christian Tzolov <[email protected]>
@tzolov
Copy link
Contributor Author

tzolov commented Mar 3, 2025

Addressed review comments

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.

Improve MchSchema JSON consistency Duplicate "type" field in JSON output of McpSchema.TextContent
2 participants