修复: 协议层与体验缺陷六件

- temperature 按模型适配,仅收 1 的模型不再 400
- 流式 error 帧不再被 choices 必填整帧丢弃
- 只读缓存写后失效
- git diff 中文截断撞 UTF-8 边界 panic
- 非视觉模型纯图片直接拒绝
- 全局快捷键补输入焦点守卫
This commit is contained in:
lxy
2026-10-04 16:27:31 +08:00
parent 01d231c39d
commit 7aa0da32f2
28 changed files with 491 additions and 52 deletions
+27 -1
View File
@@ -262,12 +262,23 @@ impl AnthropicCompatProvider {
.collect()
});
// 模型不支持 temperature(如商汤 sensenova 仅接受 1.0)→ 省略该字段,避免上游 HTTP 400。
// 判定走 model_probe(命中 presets 表;未命中默认支持,保持原样透传零回归)。
let temperature = if req.temperature.is_some()
&& !crate::model_probe::probe(&model).temperature_supported
{
tracing::debug!(model = %model, "模型不支持 temperature,已省略该参数");
None
} else {
req.temperature
};
AnthropicRequest {
model,
messages,
max_tokens: req.max_tokens.unwrap_or(DEFAULT_MAX_TOKENS),
system,
temperature: req.temperature,
temperature,
stream: req.stream,
tools,
tool_choice: req.tool_choice,
@@ -927,6 +938,21 @@ mod tests {
assert_eq!(a.total_tokens, 15);
}
/// stop_reason=max_tokens(message_delta 帧携带)必须置截断标志;end_turn 不置。
/// 终态 finished 在后续 message_stop 帧,消费方跨帧 OR 累积标志。
#[test]
fn anthropic_max_tokens_stop_reason_sets_truncation_flag() {
let mut acc: Option<TokenUsage> = None;
let data = r#"{"type":"message_delta","delta":{"stop_reason":"max_tokens"},"usage":{"output_tokens":9}}"#;
let c = apply_anthropic_event(data, &mut acc);
assert!(!c.finished, "message_delta 非终态帧");
assert!(c.truncated_by_max_tokens, "max_tokens 必须置截断标志");
let mut acc2: Option<TokenUsage> = None;
let c2 = apply_anthropic_event(&message_delta(5), &mut acc2);
assert!(!c2.truncated_by_max_tokens, "end_turn 不置截断标志");
}
/// message_delta 的 output_tokens 必须是累计覆盖(非累加):连续两个 delta 5 和 8,结果应是 8 不是 13
#[test]
fn anthropic_message_delta_output_is_cumulative_not_incremental() {