@@ -1008,3 +1008,114 @@ func TestAnthropicToResponses_ImageEmptyMediaType(t *testing.T) {
10081008 // Should default to image/png when media_type is empty.
10091009 assert .Equal (t , "data:image/png;base64,iVBOR" , parts [0 ].ImageURL )
10101010}
1011+
1012+ // ---------------------------------------------------------------------------
1013+ // normalizeToolParameters tests
1014+ // ---------------------------------------------------------------------------
1015+
1016+ func TestNormalizeToolParameters (t * testing.T ) {
1017+ tests := []struct {
1018+ name string
1019+ input json.RawMessage
1020+ expected string
1021+ }{
1022+ {
1023+ name : "nil input" ,
1024+ input : nil ,
1025+ expected : `{"type":"object","properties":{}}` ,
1026+ },
1027+ {
1028+ name : "empty input" ,
1029+ input : json .RawMessage (`` ),
1030+ expected : `{"type":"object","properties":{}}` ,
1031+ },
1032+ {
1033+ name : "null input" ,
1034+ input : json .RawMessage (`null` ),
1035+ expected : `{"type":"object","properties":{}}` ,
1036+ },
1037+ {
1038+ name : "object without properties" ,
1039+ input : json .RawMessage (`{"type":"object"}` ),
1040+ expected : `{"type":"object","properties":{}}` ,
1041+ },
1042+ {
1043+ name : "object with properties" ,
1044+ input : json .RawMessage (`{"type":"object","properties":{"city":{"type":"string"}}}` ),
1045+ expected : `{"type":"object","properties":{"city":{"type":"string"}}}` ,
1046+ },
1047+ {
1048+ name : "non-object type" ,
1049+ input : json .RawMessage (`{"type":"string"}` ),
1050+ expected : `{"type":"string"}` ,
1051+ },
1052+ {
1053+ name : "object with additional fields preserved" ,
1054+ input : json .RawMessage (`{"type":"object","required":["name"]}` ),
1055+ expected : `{"type":"object","required":["name"],"properties":{}}` ,
1056+ },
1057+ {
1058+ name : "invalid JSON passthrough" ,
1059+ input : json .RawMessage (`not json` ),
1060+ expected : `not json` ,
1061+ },
1062+ }
1063+
1064+ for _ , tt := range tests {
1065+ t .Run (tt .name , func (t * testing.T ) {
1066+ result := normalizeToolParameters (tt .input )
1067+ if tt .name == "invalid JSON passthrough" {
1068+ assert .Equal (t , tt .expected , string (result ))
1069+ } else {
1070+ assert .JSONEq (t , tt .expected , string (result ))
1071+ }
1072+ })
1073+ }
1074+ }
1075+
1076+ func TestAnthropicToResponses_ToolWithoutProperties (t * testing.T ) {
1077+ req := & AnthropicRequest {
1078+ Model : "gpt-5.2" ,
1079+ MaxTokens : 1024 ,
1080+ Messages : []AnthropicMessage {
1081+ {Role : "user" , Content : json .RawMessage (`"Hello"` )},
1082+ },
1083+ Tools : []AnthropicTool {
1084+ {Name : "mcp__pencil__get_style_guide_tags" , Description : "Get style tags" , InputSchema : json .RawMessage (`{"type":"object"}` )},
1085+ },
1086+ }
1087+
1088+ resp , err := AnthropicToResponses (req )
1089+ require .NoError (t , err )
1090+
1091+ require .Len (t , resp .Tools , 1 )
1092+ assert .Equal (t , "function" , resp .Tools [0 ].Type )
1093+ assert .Equal (t , "mcp__pencil__get_style_guide_tags" , resp .Tools [0 ].Name )
1094+
1095+ // Parameters must have "properties" field after normalization.
1096+ var params map [string ]json.RawMessage
1097+ require .NoError (t , json .Unmarshal (resp .Tools [0 ].Parameters , & params ))
1098+ assert .Contains (t , params , "properties" )
1099+ }
1100+
1101+ func TestAnthropicToResponses_ToolWithNilSchema (t * testing.T ) {
1102+ req := & AnthropicRequest {
1103+ Model : "gpt-5.2" ,
1104+ MaxTokens : 1024 ,
1105+ Messages : []AnthropicMessage {
1106+ {Role : "user" , Content : json .RawMessage (`"Hello"` )},
1107+ },
1108+ Tools : []AnthropicTool {
1109+ {Name : "simple_tool" , Description : "A tool" },
1110+ },
1111+ }
1112+
1113+ resp , err := AnthropicToResponses (req )
1114+ require .NoError (t , err )
1115+
1116+ require .Len (t , resp .Tools , 1 )
1117+ var params map [string ]json.RawMessage
1118+ require .NoError (t , json .Unmarshal (resp .Tools [0 ].Parameters , & params ))
1119+ assert .JSONEq (t , `"object"` , string (params ["type" ]))
1120+ assert .JSONEq (t , `{}` , string (params ["properties" ]))
1121+ }
0 commit comments