feat: organize tool schemas by category
All checks were successful
Deploy to OCIWP / deploy (push) Successful in 1m58s
All checks were successful
Deploy to OCIWP / deploy (push) Successful in 1m58s
This commit is contained in:
@@ -31,6 +31,6 @@ public @interface McpValidation {
|
|||||||
int maxLength() default -1;
|
int maxLength() default -1;
|
||||||
String[] allowedValues() default {};
|
String[] allowedValues() default {};
|
||||||
String format() default "";
|
String format() default "";
|
||||||
String defaultValue() default "";
|
boolean nullable() default false; String defaultValue() default "";
|
||||||
String[] examples() default {};
|
String[] examples() default {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,6 +103,14 @@ public class JsonSchemaGenerator {
|
|||||||
if (validation != null && validation.examples().length > 0) {
|
if (validation != null && validation.examples().length > 0) {
|
||||||
fieldSchema.put("examples", List.of(validation.examples()));
|
fieldSchema.put("examples", List.of(validation.examples()));
|
||||||
}
|
}
|
||||||
|
if (validation != null && validation.nullable()) {
|
||||||
|
Map<String, Object> nonNullSchema = new HashMap<>(fieldSchema);
|
||||||
|
fieldSchema = new HashMap<>();
|
||||||
|
fieldSchema.put("anyOf", List.of(
|
||||||
|
nonNullSchema,
|
||||||
|
Map.of("type", "null")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
properties.put(field.getName(), fieldSchema);
|
properties.put(field.getName(), fieldSchema);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,11 +43,11 @@ public class ClaimSearchResponse {
|
|||||||
private String statusLabel;
|
private String statusLabel;
|
||||||
|
|
||||||
@McpParameter(description = "Approved amount. Null before review; do not interpret null as zero.")
|
@McpParameter(description = "Approved amount. Null before review; do not interpret null as zero.")
|
||||||
@McpValidation(minimum = 0)
|
@McpValidation(minimum = 0, nullable = true)
|
||||||
private Long approvedAmount;
|
private Long approvedAmount;
|
||||||
|
|
||||||
@McpParameter(description = "Present only when status is REJECTED; otherwise null.")
|
@McpParameter(description = "Present only when status is REJECTED; otherwise null.")
|
||||||
@McpValidation(maxLength = 200)
|
@McpValidation(maxLength = 200, nullable = true)
|
||||||
private String rejectionReason;
|
private String rejectionReason;
|
||||||
|
|
||||||
@McpParameter(description = "Claim summaries, ordered by received date descending.")
|
@McpParameter(description = "Claim summaries, ordered by received date descending.")
|
||||||
@@ -82,7 +82,7 @@ public class ClaimSearchResponse {
|
|||||||
private String receivedDate;
|
private String receivedDate;
|
||||||
|
|
||||||
@McpParameter(description = "Approved amount. Null before review; do not interpret null as zero.")
|
@McpParameter(description = "Approved amount. Null before review; do not interpret null as zero.")
|
||||||
@McpValidation(minimum = 0)
|
@McpValidation(minimum = 0, nullable = true)
|
||||||
private Long approvedAmount;
|
private Long approvedAmount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,8 +17,8 @@ public interface ClaimSearchSchemaSampleUseCase {
|
|||||||
name = "sample.claim.search.resource",
|
name = "sample.claim.search.resource",
|
||||||
description = "Claim search Tool sample using input and output JSON Schema resources.",
|
description = "Claim search Tool sample using input and output JSON Schema resources.",
|
||||||
prompt = "Search an insurance claim by claim number or contract number.",
|
prompt = "Search an insurance claim by claim number or contract number.",
|
||||||
inputSchemaResource = "classpath:tool-schemas/claim-search-resource-input-schema.json",
|
inputSchemaResource = "classpath:tool-schemas/cmm/claim-search-resource-input-schema.json",
|
||||||
|
outputSchemaResource = "classpath:tool-schemas/cmm/claim-search-resource-output-schema.json",
|
||||||
readOnlyHint = true,
|
readOnlyHint = true,
|
||||||
idempotentHint = true
|
idempotentHint = true
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -69,6 +69,14 @@ class ClaimSearchRequestSchemaTest {
|
|||||||
|
|
||||||
assertTrue(validator.validateValue(schema, response).isEmpty());
|
assertTrue(validator.validateValue(schema, response).isEmpty());
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
|
void sampleResponseConformsToAutomaticallyGeneratedOutputSchema() throws Exception {
|
||||||
|
Map<String, Object> schema = JsonSchemaGenerator.generateSchema(ClaimSearchResponse.class);
|
||||||
|
ClaimSearchResponse response = new ClaimSearchSchemaSampleUseCaseImpl().search(new ClaimSearchRequest());
|
||||||
|
ToolArgumentSchemaValidator validator = new ToolArgumentSchemaValidator(new ObjectMapper());
|
||||||
|
|
||||||
|
assertTrue(validator.validateValue(schema, response).isEmpty());
|
||||||
|
}
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Map<String, Map<String, Object>> properties(Map<String, Object> schema) {
|
private Map<String, Map<String, Object>> properties(Map<String, Object> schema) {
|
||||||
return (Map<String, Map<String, Object>>) schema.get("properties");
|
return (Map<String, Map<String, Object>>) schema.get("properties");
|
||||||
|
|||||||
Reference in New Issue
Block a user