修复: AI 消息卡片友好展示

- update_task 卡片后端补返 title + 前端 title 优先 + i18n 文案对齐(UX-260619-04,防裸 UUID id 辨识度低)
- anthropic_compat 合并连续 user 块,修 GLM 1214 协议交替违规(B-260619-03)
This commit is contained in:
2026-06-19 18:58:49 +08:00
parent 8da6bdcec2
commit db129fd78f
5 changed files with 47 additions and 4 deletions

View File

@@ -216,6 +216,12 @@ impl AnthropicCompatProvider {
}
Self::flush_tool_results(&mut messages, &mut pending_tool_results);
// B-260619-03: 合并相邻 user 块。Anthropic 协议要求 user/assistant 严格交替,连续 user
// 触发 GLM 1214。场景:drainQueue 续发(前一轮以 tool_result 结尾 + 新 user)→ flush 把
// tool_result 转成 user 后紧跟 push 新 user → 连续两 user。合并成一条 user 含
// [tool_result..., text] blocks(Anthropic 允许一条 user 多 blocks),打破恶性循环。
Self::merge_consecutive_users(&mut messages);
let tools = req.tools.map(|defs| {
defs.into_iter()
.map(|d| AnthropicToolDef {
@@ -256,6 +262,39 @@ impl AnthropicCompatProvider {
messages.push(serde_json::json!({ "role": "user", "content": blocks }));
}
/// B-260619-03: 合并相邻 user 消息为一条(content 拼成 blocks 数组)。
/// Anthropic 协议要求 user/assistant 严格交替,连续 user 触发 1214。
/// 触发场景:flush_tool_results 把 tool_result 转 user 后紧跟新 user(drainQueue 续发,
/// 前一轮以 tool_result 结尾)。合并成一条 user 含 [tool_result..., text] blocks,合法。
/// content 形态:string(简写)或 array(blocks),统一规范化为 array 后拼接。
fn merge_consecutive_users(messages: &mut Vec<serde_json::Value>) {
let is_user = |m: &serde_json::Value| m.get("role").and_then(|r| r.as_str()) == Some("user");
let mut i = 0;
while i + 1 < messages.len() {
if is_user(&messages[i]) && is_user(&messages[i + 1]) {
let next_content = messages[i + 1].get("content").cloned().unwrap_or(serde_json::Value::Null);
let cur = &mut messages[i];
// 当前 user content 规范化为 array
let mut blocks: Vec<serde_json::Value> = match cur.get("content").cloned() {
Some(serde_json::Value::String(s)) => vec![serde_json::json!({ "type": "text", "text": s })],
Some(serde_json::Value::Array(a)) => a,
_ => vec![],
};
// 并入下一个 user content
match next_content {
serde_json::Value::String(s) => blocks.push(serde_json::json!({ "type": "text", "text": s })),
serde_json::Value::Array(a) => blocks.extend(a),
_ => {}
}
cur["content"] = serde_json::Value::Array(blocks);
messages.remove(i + 1);
// 不增 i:继续合并 i 与新 i+1(可能多个连续 user)
} else {
i += 1;
}
}
}
/// 生成 messages 诊断摘要(每条 role + content 形态 + tool 标记),不含敏感数据。
/// B-260618-27: 1214 类错误时随 bail 文案直达前端 raw,定位哪条/字段非法。
fn summarize_messages(messages: &[serde_json::Value]) -> String {