@@ -333,6 +333,45 @@ func TestRemoveFormatFields_NoProperties(t *testing.T) {
333333 assert .Equal (t , schema , updated )
334334}
335335
336+ func TestMakeAllRequired_TypeArrayWithObject (t * testing.T ) {
337+ // Reproduces the user_prompt tool schema where a property has
338+ // type: ["object", "null"] with nested properties. OpenAI requires
339+ // these nested properties to also have additionalProperties: false.
340+ schema := shared.FunctionParameters {
341+ "type" : "object" ,
342+ "properties" : map [string ]any {
343+ "schema" : map [string ]any {
344+ "type" : []string {"object" , "null" },
345+ "properties" : map [string ]any {
346+ "name" : map [string ]any {"type" : "string" },
347+ "age" : map [string ]any {"type" : "number" },
348+ },
349+ "required" : []any {"name" },
350+ },
351+ },
352+ "required" : []any {"schema" },
353+ }
354+
355+ updated := makeAllRequired (schema )
356+
357+ // Top-level should have additionalProperties: false
358+ assert .Equal (t , false , updated ["additionalProperties" ])
359+
360+ // The schema property should also have additionalProperties: false
361+ schemaProps := updated ["properties" ].(map [string ]any )["schema" ].(map [string ]any )
362+ assert .Equal (t , false , schemaProps ["additionalProperties" ])
363+
364+ // All properties in schema should be required
365+ schemaRequired := schemaProps ["required" ].([]any )
366+ assert .Len (t , schemaRequired , 2 )
367+ assert .Contains (t , schemaRequired , "name" )
368+ assert .Contains (t , schemaRequired , "age" )
369+
370+ // age was not originally required, so its type should be nullable
371+ age := schemaProps ["properties" ].(map [string ]any )["age" ].(map [string ]any )
372+ assert .Equal (t , []string {"number" , "null" }, age ["type" ])
373+ }
374+
336375func TestFixSchemaArrayItems (t * testing.T ) {
337376 schema := `{
338377 "properties": {
0 commit comments