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

- 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.
- Add default implementation that returns the appropriate type string based on the implementing class (text, image, or resource)
- Added comprehensive unit tests for McpSchema to validate serialization/deserialization behavior of all schema components.
- Add deserialization tests for all content types
- Add json-unit-assertj for flexible JSON testing -  ignores array order and extra array items, reducing test brittleness while
maintaining functional validation.

Resolves #26
Resolve https://github.com/spring-projects/spring-ai/issues/2350

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
This commit is contained in:
Christian Tzolov 2025-03-03 13:57:41 +01:00 • committed by GitHub
commit 1bee8d4744
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -964,7 +964,18 @@ public final class McpSchema {
@JsonSubTypes.Type(value = EmbeddedResource.class, name = "resource") })
public sealed interface Content permits TextContent, ImageContent, EmbeddedResource {
String type();
default String type() {
if (this instanceof TextContent) {
return "text";
}
else if (this instanceof ImageContent) {
return "image";
}
else if (this instanceof EmbeddedResource) {
return "resource";
}
throw new IllegalArgumentException("Unknown content type: " + this);
}
}
@ -972,19 +983,10 @@ public final class McpSchema {
public record TextContent( // @formatter:off
@JsonProperty("audience") List<Role> audience,
@JsonProperty("priority") Double priority,
@JsonProperty("type") String type,
@JsonProperty("text") String text) implements Content { // @formatter:on
public TextContent {
type = "text";
}
public String type() {
return type;
}
public TextContent(String content) {
this(null, null, "text", content);
this(null, null, content);
}
}
@ -992,33 +994,15 @@ public final class McpSchema {
public record ImageContent( // @formatter:off
@JsonProperty("audience") List<Role> audience,
@JsonProperty("priority") Double priority,
@JsonProperty("type") String type,
@JsonProperty("data") String data,
@JsonProperty("mimeType") String mimeType) implements Content { // @formatter:on
public ImageContent {
type = "image";
}
public String type() {
return type;
}
}
@JsonInclude(JsonInclude.Include.NON_ABSENT)
public record EmbeddedResource( // @formatter:off
@JsonProperty("audience") List<Role> audience,
@JsonProperty("priority") Double priority,
@JsonProperty("type") String type,
@JsonProperty("resource") ResourceContents resource) implements Content { // @formatter:on
public EmbeddedResource {
type = "resource";
}
public String type() {
return type;
}
}
// ---------------------------