@@ -941,18 +941,26 @@ func TestOpenAIToolsToGeminiTools(t *testing.T) {
941941 "required" : []any {"a" , "b" },
942942 }
943943 tests := []struct {
944- name string
945- openaiTools []openai.Tool
946- expected []genai.Tool
947- expectedError string
944+ name string
945+ openaiTools []openai.Tool
946+ parametersJSONSchemaAvailable bool
947+ expected []genai.Tool
948+ expectedError string
948949 }{
949950 {
950- name : "empty tools" ,
951- openaiTools : nil ,
952- expected : nil ,
951+ name : "empty tools with parametersJSONSchemaAvailable=false" ,
952+ openaiTools : nil ,
953+ parametersJSONSchemaAvailable : false ,
954+ expected : nil ,
953955 },
954956 {
955- name : "single function tool with parameters" ,
957+ name : "empty tools with parametersJSONSchemaAvailable=true" ,
958+ openaiTools : nil ,
959+ parametersJSONSchemaAvailable : true ,
960+ expected : nil ,
961+ },
962+ {
963+ name : "single function tool with parameters - parametersJSONSchemaAvailable=false" ,
956964 openaiTools : []openai.Tool {
957965 {
958966 Type : openai .ToolTypeFunction ,
@@ -963,6 +971,39 @@ func TestOpenAIToolsToGeminiTools(t *testing.T) {
963971 },
964972 },
965973 },
974+ parametersJSONSchemaAvailable : false ,
975+ expected : []genai.Tool {
976+ {
977+ FunctionDeclarations : []* genai.FunctionDeclaration {
978+ {
979+ Name : "add" ,
980+ Description : "Add two numbers" ,
981+ Parameters : & genai.Schema {
982+ Type : "object" ,
983+ Properties : map [string ]* genai.Schema {
984+ "a" : {Type : "integer" },
985+ "b" : {Type : "integer" },
986+ },
987+ Required : []string {"a" , "b" },
988+ },
989+ },
990+ },
991+ },
992+ },
993+ },
994+ {
995+ name : "single function tool with parameters - parametersJSONSchemaAvailable=true" ,
996+ openaiTools : []openai.Tool {
997+ {
998+ Type : openai .ToolTypeFunction ,
999+ Function : & openai.FunctionDefinition {
1000+ Name : "add" ,
1001+ Description : "Add two numbers" ,
1002+ Parameters : funcParams ,
1003+ },
1004+ },
1005+ },
1006+ parametersJSONSchemaAvailable : true ,
9661007 expected : []genai.Tool {
9671008 {
9681009 FunctionDeclarations : []* genai.FunctionDeclaration {
@@ -976,44 +1017,96 @@ func TestOpenAIToolsToGeminiTools(t *testing.T) {
9761017 },
9771018 },
9781019 {
979- name : "multiple function tools" ,
1020+ name : "multiple function tools with nil/empty parameters - parametersJSONSchemaAvailable=false " ,
9801021 openaiTools : []openai.Tool {
9811022 {
9821023 Type : openai .ToolTypeFunction ,
9831024 Function : & openai.FunctionDefinition {
9841025 Name : "foo" ,
9851026 Description : "Foo function" ,
1027+ Parameters : map [string ]any {}, // empty parameters
9861028 },
9871029 },
9881030 {
9891031 Type : openai .ToolTypeFunction ,
9901032 Function : & openai.FunctionDefinition {
9911033 Name : "bar" ,
9921034 Description : "Bar function" ,
1035+ Parameters : nil , // nil parameters
9931036 },
9941037 },
9951038 },
1039+ parametersJSONSchemaAvailable : false ,
9961040 expected : []genai.Tool {
9971041 {
9981042 FunctionDeclarations : []* genai.FunctionDeclaration {
9991043 {
1000- Name : "foo" ,
1001- Description : "Foo function" ,
1002- Parameters : nil ,
1003- ParametersJsonSchema : nil ,
1044+ Name : "foo" ,
1045+ Description : "Foo function" ,
1046+ Parameters : nil ,
10041047 },
10051048 {
1006- Name : "bar" ,
1007- Description : "Bar function" ,
1008- Parameters : nil ,
1009- ParametersJsonSchema : nil ,
1049+ Name : "bar" ,
1050+ Description : "Bar function" ,
1051+ Parameters : nil ,
10101052 },
10111053 },
10121054 },
10131055 },
10141056 },
10151057 {
1016- name : "tool with invalid parameters schema" ,
1058+ name : "multiple function tools with nil/empty parameters - parametersJSONSchemaAvailable=true" ,
1059+ openaiTools : []openai.Tool {
1060+ {
1061+ Type : openai .ToolTypeFunction ,
1062+ Function : & openai.FunctionDefinition {
1063+ Name : "foo" ,
1064+ Description : "Foo function" ,
1065+ },
1066+ },
1067+ {
1068+ Type : openai .ToolTypeFunction ,
1069+ Function : & openai.FunctionDefinition {
1070+ Name : "bar" ,
1071+ Description : "Bar function" ,
1072+ },
1073+ },
1074+ },
1075+ parametersJSONSchemaAvailable : true ,
1076+ expected : []genai.Tool {
1077+ {
1078+ FunctionDeclarations : []* genai.FunctionDeclaration {
1079+ {
1080+ Name : "foo" ,
1081+ Description : "Foo function" ,
1082+ ResponseJsonSchema : nil ,
1083+ },
1084+ {
1085+ Name : "bar" ,
1086+ Description : "Bar function" ,
1087+ ResponseJsonSchema : nil ,
1088+ },
1089+ },
1090+ },
1091+ },
1092+ },
1093+ {
1094+ name : "tool with invalid parameters schema - parametersJSONSchemaAvailable=false" ,
1095+ openaiTools : []openai.Tool {
1096+ {
1097+ Type : openai .ToolTypeFunction ,
1098+ Function : & openai.FunctionDefinition {
1099+ Name : "bad" ,
1100+ Description : "Bad function" ,
1101+ Parameters : "invalid-json" ,
1102+ },
1103+ },
1104+ },
1105+ parametersJSONSchemaAvailable : false ,
1106+ expectedError : "invalid JSON schema for parameters in tool bad: expected map[string]any" ,
1107+ },
1108+ {
1109+ name : "tool with invalid parameters schema - parametersJSONSchemaAvailable=true" ,
10171110 openaiTools : []openai.Tool {
10181111 {
10191112 Type : openai .ToolTypeFunction ,
@@ -1024,32 +1117,140 @@ func TestOpenAIToolsToGeminiTools(t *testing.T) {
10241117 },
10251118 },
10261119 },
1120+ parametersJSONSchemaAvailable : true ,
10271121 expected : []genai.Tool {
10281122 {
10291123 FunctionDeclarations : []* genai.FunctionDeclaration {
10301124 {
1031- Description : "Bad function" ,
1032- Name : "bad" ,
1125+ Description : "Bad function" ,
1126+ Name : "bad" ,
1127+ // ai-gateway does not validate schema, upstream will be expected to validate the bad json param
10331128 ParametersJsonSchema : "invalid-json" ,
10341129 },
10351130 },
10361131 },
10371132 },
10381133 },
10391134 {
1040- name : "non-function tool is ignored" ,
1135+ name : "complex nested schema - parametersJSONSchemaAvailable=false" ,
1136+ openaiTools : []openai.Tool {
1137+ {
1138+ Type : openai .ToolTypeFunction ,
1139+ Function : & openai.FunctionDefinition {
1140+ Name : "complex_tool" ,
1141+ Description : "Complex tool with nested parameters" ,
1142+ Parameters : map [string ]any {
1143+ "type" : "object" ,
1144+ "properties" : map [string ]any {
1145+ "user" : map [string ]any {
1146+ "type" : "object" ,
1147+ "properties" : map [string ]any {
1148+ "name" : map [string ]any {"type" : "string" },
1149+ "age" : map [string ]any {"type" : "integer" },
1150+ },
1151+ "required" : []any {"name" },
1152+ },
1153+ "items" : map [string ]any {
1154+ "type" : "array" ,
1155+ "items" : map [string ]any {
1156+ "type" : "object" ,
1157+ "properties" : map [string ]any {
1158+ "id" : map [string ]any {"type" : "integer" },
1159+ "name" : map [string ]any {"type" : "string" },
1160+ },
1161+ },
1162+ },
1163+ },
1164+ "required" : []any {"user" },
1165+ },
1166+ },
1167+ },
1168+ },
1169+ parametersJSONSchemaAvailable : false ,
1170+ expected : []genai.Tool {
1171+ {
1172+ FunctionDeclarations : []* genai.FunctionDeclaration {
1173+ {
1174+ Name : "complex_tool" ,
1175+ Description : "Complex tool with nested parameters" ,
1176+ Parameters : & genai.Schema {
1177+ Type : "object" ,
1178+ Properties : map [string ]* genai.Schema {
1179+ "user" : {
1180+ Type : "object" ,
1181+ Properties : map [string ]* genai.Schema {
1182+ "name" : {Type : "string" },
1183+ "age" : {Type : "integer" },
1184+ },
1185+ Required : []string {"name" },
1186+ },
1187+ "items" : {
1188+ Type : "array" ,
1189+ Items : & genai.Schema {
1190+ Type : "object" ,
1191+ Properties : map [string ]* genai.Schema {
1192+ "id" : {Type : "integer" },
1193+ "name" : {Type : "string" },
1194+ },
1195+ },
1196+ },
1197+ },
1198+ Required : []string {"user" },
1199+ },
1200+ },
1201+ },
1202+ },
1203+ },
1204+ },
1205+ {
1206+ name : "non-function tool is ignored - both modes" ,
10411207 openaiTools : []openai.Tool {
10421208 {
10431209 Type : "retrieval" ,
10441210 },
10451211 },
1046- expected : nil ,
1212+ parametersJSONSchemaAvailable : false ,
1213+ expectedError : "unsupported tool type: retrieval" ,
1214+ },
1215+ {
1216+ name : "mixed valid and invalid tools - parametersJSONSchemaAvailable=false" ,
1217+ openaiTools : []openai.Tool {
1218+ {
1219+ Type : "retrieval" , // Should be ignored
1220+ },
1221+ {
1222+ Type : openai .ToolTypeFunction ,
1223+ Function : & openai.FunctionDefinition {
1224+ Name : "valid_tool" ,
1225+ Description : "Valid function tool" ,
1226+ Parameters : map [string ]any {
1227+ "type" : "object" ,
1228+ "properties" : map [string ]any {
1229+ "param" : map [string ]any {"type" : "string" },
1230+ },
1231+ },
1232+ },
1233+ },
1234+ },
1235+ parametersJSONSchemaAvailable : false ,
1236+ expectedError : "unsupported tool type: retrieval" ,
1237+ },
1238+ {
1239+ name : "tool with nil function - should not panic" ,
1240+ openaiTools : []openai.Tool {
1241+ {
1242+ Type : openai .ToolTypeFunction ,
1243+ Function : nil ,
1244+ },
1245+ },
1246+ parametersJSONSchemaAvailable : false ,
1247+ expected : nil ,
10471248 },
10481249 }
10491250
10501251 for _ , tc := range tests {
10511252 t .Run (tc .name , func (t * testing.T ) {
1052- result , err := openAIToolsToGeminiTools (tc .openaiTools )
1253+ result , err := openAIToolsToGeminiTools (tc .openaiTools , tc . parametersJSONSchemaAvailable )
10531254 if tc .expectedError != "" {
10541255 require .ErrorContains (t , err , tc .expectedError )
10551256 } else {
0 commit comments