@@ -387,11 +387,9 @@ impl From<Context> for Request {
387387 } ) ,
388388 response_schema : context. response_format . and_then ( |rf| match rf {
389389 forge_domain:: ResponseFormat :: JsonSchema ( schema) => {
390- // Convert schema to JSON and strip $schema field (Google API doesn't accept it)
391390 let mut schema_value = serde_json:: to_value ( * schema) . ok ( ) ?;
392- if let Some ( obj) = schema_value. as_object_mut ( ) {
393- obj. remove ( "$schema" ) ;
394- }
391+ // Sanitize schema for Gemini API compatibility
392+ crate :: utils:: sanitize_gemini_schema ( & mut schema_value) ;
395393 Some ( schema_value)
396394 }
397395 _ => None ,
@@ -452,14 +450,13 @@ impl From<forge_domain::ToolChoice> for ToolConfig {
452450
453451impl From < forge_domain:: ToolDefinition > for FunctionDeclaration {
454452 fn from ( tool : forge_domain:: ToolDefinition ) -> Self {
455- // Convert input_schema to JSON value and strip $schema field
456453 let mut parameters =
457454 serde_json:: to_value ( tool. input_schema ) . unwrap_or ( serde_json:: json!( { } ) ) ;
458455
459- // Remove $ schema field if present (Google API doesn't accept it)
460- if let Some ( obj ) = parameters . as_object_mut ( ) {
461- obj . remove ( "$schema" ) ;
462- }
456+ // Sanitize schema for Gemini API compatibility (strips $schema,
457+ // removes additionalProperties, converts integer enums, ensures
458+ // arrays have items, removes properties from non-objects, etc.)
459+ crate :: utils :: sanitize_gemini_schema ( & mut parameters ) ;
463460
464461 FunctionDeclaration {
465462 name : tool. name . to_string ( ) ,
@@ -830,11 +827,18 @@ mod tests {
830827 assert_eq ! ( decl. name, "test_tool" ) ;
831828 assert_eq ! ( decl. description. unwrap( ) , "A test tool" ) ;
832829
833- // Check schema stripping
830+ // Check Gemini schema sanitization
834831 let params = decl. parameters ;
835832 assert ! ( params. is_object( ) ) ;
836833 assert ! ( !params. as_object( ) . unwrap( ) . contains_key( "$schema" ) ) ;
837834 assert ! ( params. as_object( ) . unwrap( ) . contains_key( "type" ) ) ;
835+ // additionalProperties should be removed by Gemini sanitization
836+ assert ! (
837+ !params
838+ . as_object( )
839+ . unwrap( )
840+ . contains_key( "additionalProperties" )
841+ ) ;
838842 }
839843
840844 #[ test]
@@ -934,6 +938,12 @@ mod tests {
934938 || obj. contains_key( "title" ) ,
935939 "Schema should still contain other properties"
936940 ) ;
941+
942+ // Verify additionalProperties is also removed by Gemini sanitization
943+ assert ! (
944+ !obj. contains_key( "additionalProperties" ) ,
945+ "additionalProperties should be removed by Gemini sanitization"
946+ ) ;
937947 } else {
938948 panic ! ( "response_schema should be an object" ) ;
939949 }
0 commit comments