From aa492e3696b34802d9c8a8e995d7a3d7a705e570 Mon Sep 17 00:00:00 2001 From: Harry Cruz Date: Tue, 25 Aug 2026 18:34:31 +0200 Subject: [PATCH] fix: add additionalProperties: false to response schema for test generation OpenAI structured outputs with strict mode requires every object node in the JSON schema to declare additionalProperties: false. Without it the API rejects the schema. Added at both the root and item levels. Signed-off-by: Harry Cruz Co-Authored-By: Claude Opus 4.6 --- .../sdk/synthesizers/SchemaBuilder.java | 10 +++-- .../unit/synthesizers/SchemaBuilderTest.java | 42 +++++++++++++++++++ 2 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 src/test/java/ai/rhesis/sdk/unit/synthesizers/SchemaBuilderTest.java diff --git a/src/main/java/ai/rhesis/sdk/synthesizers/SchemaBuilder.java b/src/main/java/ai/rhesis/sdk/synthesizers/SchemaBuilder.java index 7ca01a1..fb94a05 100644 --- a/src/main/java/ai/rhesis/sdk/synthesizers/SchemaBuilder.java +++ b/src/main/java/ai/rhesis/sdk/synthesizers/SchemaBuilder.java @@ -12,6 +12,7 @@ public static Map buildFlatTestsSchema( items.put("type", "object"); items.put("properties", properties); items.put("required", requiredFields); + items.put("additionalProperties", false); Map testsProp = new HashMap<>(); testsProp.put("type", "array"); @@ -22,9 +23,12 @@ public static Map buildFlatTestsSchema( Map jsonSchema = new HashMap<>(); jsonSchema.put("name", "FlatTests"); - jsonSchema.put( - "schema", - Map.of("type", "object", "properties", schemaProps, "required", List.of("tests"))); + Map schema = new HashMap<>(); + schema.put("type", "object"); + schema.put("properties", schemaProps); + schema.put("required", List.of("tests")); + schema.put("additionalProperties", false); + jsonSchema.put("schema", schema); jsonSchema.put("strict", true); Map rootSchema = new HashMap<>(); diff --git a/src/test/java/ai/rhesis/sdk/unit/synthesizers/SchemaBuilderTest.java b/src/test/java/ai/rhesis/sdk/unit/synthesizers/SchemaBuilderTest.java new file mode 100644 index 0000000..e56b3d3 --- /dev/null +++ b/src/test/java/ai/rhesis/sdk/unit/synthesizers/SchemaBuilderTest.java @@ -0,0 +1,42 @@ +package ai.rhesis.sdk.unit.synthesizers; + +import static org.junit.jupiter.api.Assertions.*; + +import ai.rhesis.sdk.synthesizers.SchemaBuilder; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class SchemaBuilderTest { + + @Test + @SuppressWarnings("unchecked") + void singleTurnSchemaHasAdditionalPropertiesFalseAtAllLevels() { + Map root = SchemaBuilder.buildSingleTurnSchema(); + Map jsonSchema = (Map) root.get("json_schema"); + Map schema = (Map) jsonSchema.get("schema"); + + assertEquals(false, schema.get("additionalProperties"), "root schema object"); + + Map props = (Map) schema.get("properties"); + Map tests = (Map) props.get("tests"); + Map items = (Map) tests.get("items"); + + assertEquals(false, items.get("additionalProperties"), "test item object"); + } + + @Test + @SuppressWarnings("unchecked") + void multiTurnSchemaHasAdditionalPropertiesFalseAtAllLevels() { + Map root = SchemaBuilder.buildMultiTurnSchema(); + Map jsonSchema = (Map) root.get("json_schema"); + Map schema = (Map) jsonSchema.get("schema"); + + assertEquals(false, schema.get("additionalProperties"), "root schema object"); + + Map props = (Map) schema.get("properties"); + Map tests = (Map) props.get("tests"); + Map items = (Map) tests.get("items"); + + assertEquals(false, items.get("additionalProperties"), "test item object"); + } +}