@@ -167,6 +167,48 @@ func TestMakeAllRequired_ArrayItems(t *testing.T) {
167167 assert .Contains (t , itemRequired , "name" )
168168}
169169
170+ func TestMakeAllRequired_AdditionalProperties (t * testing.T ) {
171+ // Reproduces the Notion MCP tool schema where additionalProperties
172+ // contains an object schema with its own properties (like bulleted_list_item).
173+ // OpenAI requires all properties in additionalProperties schemas to also
174+ // be listed in the required array.
175+ schema := shared.FunctionParameters {
176+ "type" : "object" ,
177+ "properties" : map [string ]any {
178+ "children" : map [string ]any {
179+ "type" : "object" ,
180+ "additionalProperties" : map [string ]any {
181+ "type" : "object" ,
182+ "properties" : map [string ]any {
183+ "bulleted_list_item" : map [string ]any {"type" : "string" },
184+ "numbered_list_item" : map [string ]any {"type" : "string" },
185+ },
186+ "required" : []any {"bulleted_list_item" },
187+ },
188+ },
189+ },
190+ "required" : []any {"children" },
191+ }
192+
193+ updated := makeAllRequired (schema )
194+
195+ // additionalProperties object: all properties must be required
196+ children := updated ["properties" ].(map [string ]any )["children" ].(map [string ]any )
197+ additionalProps := children ["additionalProperties" ].(map [string ]any )
198+ additionalRequired := additionalProps ["required" ].([]any )
199+ assert .Len (t , additionalRequired , 2 )
200+ assert .Contains (t , additionalRequired , "bulleted_list_item" )
201+ assert .Contains (t , additionalRequired , "numbered_list_item" )
202+
203+ // numbered_list_item was not originally required, so its type should be nullable
204+ numberedListItem := additionalProps ["properties" ].(map [string ]any )["numbered_list_item" ].(map [string ]any )
205+ assert .Equal (t , []string {"string" , "null" }, numberedListItem ["type" ])
206+
207+ // bulleted_list_item was originally required, so its type should be unchanged
208+ bulletedListItem := additionalProps ["properties" ].(map [string ]any )["bulleted_list_item" ].(map [string ]any )
209+ assert .Equal (t , "string" , bulletedListItem ["type" ])
210+ }
211+
170212func TestRemoveFormatFields (t * testing.T ) {
171213 schema := map [string ]any {
172214 "type" : "object" ,
0 commit comments