@@ -936,6 +936,17 @@ fn build_contents(
936936 // [FIX #752] Strict signature validation
937937 // Only use signatures that are cached and compatible with the target model
938938 if let Some ( sig) = signature {
939+ // Check signature length first - if it's too short, it's definitely invalid
940+ if sig. len ( ) < MIN_SIGNATURE_LENGTH {
941+ tracing:: warn!(
942+ "[Thinking-Signature] Signature too short (len: {} < {}), downgrading to text." ,
943+ sig. len( ) , MIN_SIGNATURE_LENGTH
944+ ) ;
945+ parts. push ( json ! ( { "text" : thinking} ) ) ;
946+ saw_non_thinking = true ;
947+ continue ;
948+ }
949+
939950 let cached_family = crate :: proxy:: SignatureCache :: global ( ) . get_signature_family ( sig) ;
940951
941952 match cached_family {
@@ -966,14 +977,31 @@ fn build_contents(
966977 parts. push ( part) ;
967978 }
968979 None => {
969- // Unknown signature origin: downgrade to text for safety
970- tracing:: warn!(
971- "[Thinking-Signature] Unknown signature origin (len: {}). Downgrading to text for safety." ,
972- sig. len( )
973- ) ;
974- parts. push ( json ! ( { "text" : thinking} ) ) ;
975- saw_non_thinking = true ;
976- continue ;
980+ // For JSON tool calling compatibility, if signature is long enough but unknown,
981+ // we should trust it rather than downgrade to text
982+ if sig. len ( ) >= MIN_SIGNATURE_LENGTH {
983+ tracing:: debug!(
984+ "[Thinking-Signature] Unknown signature origin but valid length (len: {}), using as-is for JSON tool calling." ,
985+ sig. len( )
986+ ) ;
987+ * last_thought_signature = Some ( sig. clone ( ) ) ;
988+ let mut part = json ! ( {
989+ "text" : thinking,
990+ "thought" : true ,
991+ "thoughtSignature" : sig
992+ } ) ;
993+ crate :: proxy:: common:: json_schema:: clean_json_schema ( & mut part) ;
994+ parts. push ( part) ;
995+ } else {
996+ // Unknown and too short: downgrade to text for safety
997+ tracing:: warn!(
998+ "[Thinking-Signature] Unknown signature origin and too short (len: {}). Downgrading to text for safety." ,
999+ sig. len( )
1000+ ) ;
1001+ parts. push ( json ! ( { "text" : thinking} ) ) ;
1002+ saw_non_thinking = true ;
1003+ continue ;
1004+ }
9771005 }
9781006 }
9791007 } else {
@@ -1088,8 +1116,13 @@ fn build_contents(
10881116 if is_retry && signature. is_none ( ) {
10891117 tracing:: warn!( "[Tool-Signature] Skipping signature backfill for tool_use: {} during retry." , id) ;
10901118 } else {
1091- // Check signature length
1092- if sig. len ( ) >= MIN_SIGNATURE_LENGTH {
1119+ // Check signature length first - if it's too short, it's definitely invalid
1120+ if sig. len ( ) < MIN_SIGNATURE_LENGTH {
1121+ tracing:: warn!(
1122+ "[Tool-Signature] Signature too short for tool_use: {} (len: {} < {}), skipping." ,
1123+ id, sig. len( ) , MIN_SIGNATURE_LENGTH
1124+ ) ;
1125+ } else {
10931126 // Check signature compatibility (optional for tool_use)
10941127 let cached_family = crate :: proxy:: SignatureCache :: global ( )
10951128 . get_signature_family ( & sig) ;
@@ -1108,27 +1141,32 @@ fn build_contents(
11081141 }
11091142 }
11101143 None => {
1111- // Unknown origin: only use in non-thinking mode
1112- if is_thinking_enabled {
1113- tracing:: warn!(
1114- "[Tool-Signature] Unknown signature origin for tool_use: {} (len: {}). Dropping in thinking mode." ,
1115- id, sig. len( )
1144+ // For JSON tool calling compatibility, if signature is long enough but unknown,
1145+ // we should trust it rather than drop it
1146+ if sig. len ( ) >= MIN_SIGNATURE_LENGTH {
1147+ tracing:: debug!(
1148+ "[Tool-Signature] Unknown signature origin but valid length (len: {}) for tool_use: {}, using as-is for JSON tool calling." ,
1149+ sig. len( ) , id
11161150 ) ;
1117- false
1118- } else {
1119- // In non-thinking mode, allow unknown signatures
11201151 true
1152+ } else {
1153+ // Unknown and too short: only use in non-thinking mode
1154+ if is_thinking_enabled {
1155+ tracing:: warn!(
1156+ "[Tool-Signature] Unknown signature origin and too short for tool_use: {} (len: {}). Dropping in thinking mode." ,
1157+ id, sig. len( )
1158+ ) ;
1159+ false
1160+ } else {
1161+ // In non-thinking mode, allow unknown signatures
1162+ true
1163+ }
11211164 }
11221165 }
11231166 } ;
11241167 if should_use_sig {
11251168 part[ "thoughtSignature" ] = json ! ( sig) ;
11261169 }
1127- } else {
1128- tracing:: warn!(
1129- "[Tool-Signature] Signature too short for tool_use: {} (len: {})" ,
1130- id, sig. len( )
1131- ) ;
11321170 }
11331171 }
11341172 } else {
0 commit comments