@@ -803,6 +803,124 @@ def test_fix_enum_empty_strings():
803803 assert input_schema ["properties" ]["user_agent_type" ]["description" ] == "Device type for user agent"
804804
805805
806+ def test_fix_enum_types ():
807+ """
808+ Test _fix_enum_types function removes enum fields when type is not string.
809+
810+ This test verifies the fix for the issue where Gemini rejects cached content
811+ with function parameter enums on non-string types, causing API failures.
812+
813+ Relevant issue: Gemini only allows enums for string-typed fields
814+ """
815+ from litellm .llms .vertex_ai .common_utils import _fix_enum_types
816+
817+ # Input: Schema with enum on non-string type (the problematic case)
818+ input_schema = {
819+ "type" : "object" ,
820+ "properties" : {
821+ "truncateMode" : {
822+ "enum" : ["auto" , "none" , "start" , "end" ],
823+ "type" : "string" , # This should keep the enum
824+ "description" : "How to truncate content"
825+ },
826+ "maxLength" : {
827+ "enum" : [100 , 200 , 500 ], # This should be removed
828+ "type" : "integer" ,
829+ "description" : "Maximum length"
830+ },
831+ "enabled" : {
832+ "enum" : [True , False ], # This should be removed
833+ "type" : "boolean" ,
834+ "description" : "Whether feature is enabled"
835+ },
836+ "nested" : {
837+ "type" : "object" ,
838+ "properties" : {
839+ "innerEnum" : {
840+ "enum" : ["a" , "b" , "c" ], # This should be kept
841+ "type" : "string"
842+ },
843+ "innerNonStringEnum" : {
844+ "enum" : [1 , 2 , 3 ], # This should be removed
845+ "type" : "integer"
846+ }
847+ }
848+ },
849+ "anyOfField" : {
850+ "anyOf" : [
851+ {"type" : "string" , "enum" : ["option1" , "option2" ]}, # This should be kept
852+ {"type" : "integer" , "enum" : [1 , 2 , 3 ]} # This should be removed
853+ ]
854+ }
855+ }
856+ }
857+
858+ # Expected output: Non-string enums removed, string enums kept
859+ expected_output = {
860+ "type" : "object" ,
861+ "properties" : {
862+ "truncateMode" : {
863+ "enum" : ["auto" , "none" , "start" , "end" ], # Kept - string type
864+ "type" : "string" ,
865+ "description" : "How to truncate content"
866+ },
867+ "maxLength" : { # enum removed
868+ "type" : "integer" ,
869+ "description" : "Maximum length"
870+ },
871+ "enabled" : { # enum removed
872+ "type" : "boolean" ,
873+ "description" : "Whether feature is enabled"
874+ },
875+ "nested" : {
876+ "type" : "object" ,
877+ "properties" : {
878+ "innerEnum" : {
879+ "enum" : ["a" , "b" , "c" ], # Kept - string type
880+ "type" : "string"
881+ },
882+ "innerNonStringEnum" : { # enum removed
883+ "type" : "integer"
884+ }
885+ }
886+ },
887+ "anyOfField" : {
888+ "anyOf" : [
889+ {"type" : "string" , "enum" : ["option1" , "option2" ]}, # Kept - has string type
890+ {"type" : "integer" } # enum removed
891+ ]
892+ }
893+ }
894+ }
895+
896+ # Apply the transformation
897+ _fix_enum_types (input_schema )
898+
899+ # Verify the transformation
900+ assert input_schema == expected_output
901+
902+ # Verify specific transformations:
903+ # 1. String enums are preserved
904+ assert "enum" in input_schema ["properties" ]["truncateMode" ]
905+ assert input_schema ["properties" ]["truncateMode" ]["enum" ] == ["auto" , "none" , "start" , "end" ]
906+
907+ assert "enum" in input_schema ["properties" ]["nested" ]["properties" ]["innerEnum" ]
908+ assert input_schema ["properties" ]["nested" ]["properties" ]["innerEnum" ]["enum" ] == ["a" , "b" , "c" ]
909+
910+ # 2. Non-string enums are removed
911+ assert "enum" not in input_schema ["properties" ]["maxLength" ]
912+ assert "enum" not in input_schema ["properties" ]["enabled" ]
913+ assert "enum" not in input_schema ["properties" ]["nested" ]["properties" ]["innerNonStringEnum" ]
914+
915+ # 3. anyOf with string type keeps enum, non-string removes it
916+ assert "enum" in input_schema ["properties" ]["anyOfField" ]["anyOf" ][0 ]
917+ assert "enum" not in input_schema ["properties" ]["anyOfField" ]["anyOf" ][1 ]
918+
919+ # 4. Other properties preserved
920+ assert input_schema ["properties" ]["maxLength" ]["type" ] == "integer"
921+ assert input_schema ["properties" ]["enabled" ]["type" ] == "boolean"
922+
923+
806924def test_get_token_url ():
807925 from litellm .llms .vertex_ai .gemini .vertex_and_google_ai_studio_gemini import (
808926 VertexLLM ,
0 commit comments