diff --git a/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java b/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java index a78600af1..a8b76a1a6 100644 --- a/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java +++ b/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java @@ -6,10 +6,12 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -1072,9 +1074,24 @@ public record CreateMessageResult(// @formatter:off @JsonProperty("stopReason") StopReason stopReason) { public enum StopReason { - @JsonProperty("endTurn") END_TURN, - @JsonProperty("stopSequence") STOP_SEQUENCE, - @JsonProperty("maxTokens") MAX_TOKENS + @JsonProperty("endTurn") END_TURN("endTurn"), + @JsonProperty("stopSequence") STOP_SEQUENCE("stopSequence"), + @JsonProperty("maxTokens") MAX_TOKENS("maxTokens"), + @JsonProperty("unknown") UNKNOWN("unknown"); + + private final String value; + + StopReason(String value) { + this.value = value; + } + + @JsonCreator + private static StopReason of(String value) { + return Arrays.stream(StopReason.values()) + .filter(stopReason -> stopReason.value.equals(value)) + .findFirst() + .orElse(StopReason.UNKNOWN); + } } public static Builder builder() { diff --git a/mcp/src/test/java/io/modelcontextprotocol/spec/McpSchemaTests.java b/mcp/src/test/java/io/modelcontextprotocol/spec/McpSchemaTests.java index 6d027b55b..8520ed51a 100644 --- a/mcp/src/test/java/io/modelcontextprotocol/spec/McpSchemaTests.java +++ b/mcp/src/test/java/io/modelcontextprotocol/spec/McpSchemaTests.java @@ -829,6 +829,23 @@ void testCreateMessageResult() throws Exception { {"role":"assistant","content":{"type":"text","text":"Assistant response"},"model":"gpt-4","stopReason":"endTurn"}""")); } + @Test + void testCreateMessageResultUnknownStopReason() throws Exception { + String input = """ + {"role":"assistant","content":{"type":"text","text":"Assistant response"},"model":"gpt-4","stopReason":"arbitrary value"}"""; + + McpSchema.CreateMessageResult value = mapper.readValue(input, McpSchema.CreateMessageResult.class); + + McpSchema.TextContent expectedContent = new McpSchema.TextContent("Assistant response"); + McpSchema.CreateMessageResult expected = McpSchema.CreateMessageResult.builder() + .role(McpSchema.Role.ASSISTANT) + .content(expectedContent) + .model("gpt-4") + .stopReason(McpSchema.CreateMessageResult.StopReason.UNKNOWN) + .build(); + assertThat(value).isEqualTo(expected); + } + // Elicitation Tests @Test