补齐历史失败气泡的正文缺失标记
覆盖等待模型回执、通道连接、流式协议等旧通用失败句 补充历史错误回归测试与排障口径
This commit is contained in:
+9
-7
@@ -513,16 +513,18 @@ export function sanitizeDirectThreadText(
|
||||
const withoutAbsolutePaths = redactAbsolutePaths(withoutProjectRoot);
|
||||
const withoutSecrets = redactSecretTokens(withoutAbsolutePaths);
|
||||
const sanitized = sanitizeSensitiveLines(withoutSecrets);
|
||||
// 旧版已经落盘的失败条目无法凭空恢复被删掉的原因;把它们明确标成“宿主未提供正文”,
|
||||
// 旧版已经落盘的失败条目无法凭空恢复被删掉的原因;把它们明确标成“历史事件未记录正文”,
|
||||
// 避免历史记录继续伪装成当前仍在吞错的完整兜底句。新事件带 detail 时不命中这里。
|
||||
const legacyGenericFailure =
|
||||
'陶泥儿智能创作 执行通道中断,本轮未完成;请重试,若持续失败请检查项目诊断';
|
||||
// 旧版本有的写入路径把连续空格 / 换行归一化方式不同;按空白折叠识别同一条历史
|
||||
// 兜底文案,避免截图里的旧消息继续以“完整原因”伪装展示。新事件带正文时不命中这里。
|
||||
// 旧版本把多个失败变体直接写成固定句,历史条目里没有可恢复的 detail。按空白折叠
|
||||
// 识别所有已知旧兜底句,避免“等待模型回执超时”这类截图继续伪装成完整原因;新事件
|
||||
// 带 typed failure/detail 时不经过这条历史兼容分支。
|
||||
const normalizedLegacyFailure = sanitized.trim().replace(/\s+/gu, ' ');
|
||||
const isLegacyGenericFailure =
|
||||
sanitized.trim().replace(/\s+/gu, ' ') === legacyGenericFailure;
|
||||
/^陶泥儿智能创作 (?:等待模型回执超时(?:(已尝试 \d+ 次))?,本轮未完成;请稍后重试|执行通道连接失败,本轮未完成;请重试,若持续失败请检查项目诊断|执行通道中断,本轮未完成;请重试,若持续失败请检查项目诊断|流式响应协议不可用,本轮未完成;请检查项目诊断后重试)$/u.test(
|
||||
normalizedLegacyFailure,
|
||||
);
|
||||
return isLegacyGenericFailure
|
||||
? `${sanitized}:宿主未提供具体错误正文`
|
||||
? `${sanitized}:历史错误事件未记录具体错误正文`
|
||||
: sanitized;
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ describe('directThreadSanitize', () => {
|
||||
'陶泥儿智能创作 执行通道中断,本轮未完成;请重试,若持续失败请检查项目诊断',
|
||||
),
|
||||
).toBe(
|
||||
'陶泥儿智能创作 执行通道中断,本轮未完成;请重试,若持续失败请检查项目诊断:宿主未提供具体错误正文',
|
||||
'陶泥儿智能创作 执行通道中断,本轮未完成;请重试,若持续失败请检查项目诊断:历史错误事件未记录具体错误正文',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -110,7 +110,18 @@ describe('directThreadSanitize', () => {
|
||||
'陶泥儿智能创作 执行通道中断,本轮未完成;请重试,若持续失败请检查项目诊断',
|
||||
),
|
||||
).toBe(
|
||||
'陶泥儿智能创作 执行通道中断,本轮未完成;请重试,若持续失败请检查项目诊断:宿主未提供具体错误正文',
|
||||
'陶泥儿智能创作 执行通道中断,本轮未完成;请重试,若持续失败请检查项目诊断:历史错误事件未记录具体错误正文',
|
||||
);
|
||||
});
|
||||
|
||||
it('旧版等待模型回执超时条目也明确标记历史正文缺失', () => {
|
||||
expect(
|
||||
sanitizeDirectThreadText(
|
||||
ROOT,
|
||||
'陶泥儿智能创作 等待模型回执超时,本轮未完成;请稍后重试',
|
||||
),
|
||||
).toBe(
|
||||
'陶泥儿智能创作 等待模型回执超时,本轮未完成;请稍后重试:历史错误事件未记录具体错误正文',
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
## 2026-10-06 AGC 失败终态与 CC/MCP 边界不能吞掉协议、清理和 I/O 错误
|
||||
|
||||
- **现象**:DirectProject 的 `turn.completed(status=failed)` 若跨 IPC 丢失 `failure` 载荷,前端会只收口回合而不显示任何说明;Claude Code sidecar 的非 UTF-8 stderr、进程树清理失败、会话表锁损坏,以及 MCP loopback 服务退出、插件能力桥超时、损坏 manifest,会分别被压成空 detail、继续成功取消、伪造 hash projectId 或静默不广告插件。
|
||||
- **现行口径**:失败载荷缺失显示明确的协议错误;CC 清理、stderr 解码、会话锁都保留原始正文;MCP server / capability bridge 失败写入统一应用日志,MCP manifest / journal / 时间 / metadata 读取失败返回具体错误;完成判定在把素材缺失归因于“未引用平台图”前先验证源码、manifest 和已登记图片的 I/O/PNG 错误。切片文件是可选投影,完整 spritesheet 不因无切片而误失败。
|
||||
- **现行口径**:失败载荷缺失显示明确的协议错误;旧历史里的已知通用失败句明确标成“历史错误事件未记录具体错误正文”,不伪装成当前仍在吞错;CC 清理、stderr 解码、会话锁都保留原始正文;MCP server / capability bridge 失败写入统一应用日志,MCP manifest / journal / 时间 / metadata 读取失败返回具体错误;完成判定在把素材缺失归因于“未引用平台图”前先验证源码、manifest 和已登记图片的 I/O/PNG 错误。切片文件是可选投影,完整 spritesheet 不因无切片而误失败。
|
||||
- **验证**:`cargo test agent::claude_code_cli::tests::` 14 passed;`cargo test agent::direct_tools_mcp::tests::` 34 passed;`cargo test agent::direct_runtime::tests::` 92 passed;`npx vitest run tests/directThreadChat.test.ts tests/directTurnFailure.test.ts` 64 passed;另有损坏 manifest 回归用例 1 passed。新失败正文仍经既有脱敏边界处理。
|
||||
- **关联**:`agent/claude_code_cli.rs`、`agent/direct_tools_mcp.rs`、`agent/direct_runtime/mod.rs`、`agent/thread_manager/dispatch.rs`、`chat/conversation/directThreadChat.ts`。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user