Skip to content

Commit e5a2e69

Browse files
committed
Merge branch 'pr-1009'
2 parents 9e0c5b3 + 617650a commit e5a2e69

2 files changed

Lines changed: 65 additions & 26 deletions

File tree

src-tauri/src/proxy/mappers/claude/request.rs

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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 {

src-tauri/src/proxy/mappers/claude/thinking_utils.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,13 @@ pub fn filter_invalid_thinking_blocks_with_family(
188188
let original_len = blocks.len();
189189
blocks.retain(|block| {
190190
if let ContentBlock::Thinking { signature, .. } = block {
191-
// 1. Basic length check
191+
// 1. Basic length check - allow empty signatures to pass through for compatibility
192192
let sig = match signature {
193-
Some(s) if s.len() >= MIN_SIGNATURE_LENGTH => s,
193+
Some(s) if s.len() >= MIN_SIGNATURE_LENGTH || s.is_empty() => s,
194+
None => return true, // Allow None signatures to pass through
194195
_ => {
195196
stripped_count += 1;
196-
return false;
197+
return false;
197198
}
198199
};
199200

0 commit comments

Comments
 (0)