DirectProject 流式正文被逐 delta 脱敏写坏:Markdown 表格/段落/列表整体失效(#384 引入) #532
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
现象
AGC 项目对话里 agent 的汇报正文渲染错位:段落并进同一行、序号项挤成一段、Markdown 表格整块不渲染(表头
| 素材 | 用途 | 路径 |、|---|---|---|与数据行以纯文本连在同一行里);同一段文本里的路径还出现game<absolute-path>ame.js、assets<absolute-path>anvas-generated/...这种被切坏的占位符。重开项目读历史时同一段话渲染正常,因此很容易被当成渲染器偶发或模型写坏了 Markdown。原因(定位到行)
#384(30c377d0f,2026-09-18)把 DirectProject 流式正文改成每个 delta 各自脱敏(本意正确:前端不得接触原始增量),但脱敏函数不满足拼接不变性,而前端是裸拼接。apps/ai-game-creator-shell/src-tauri/src/agent/codex_app_server/mod.rsdirect_codex_thread_delta_event→.../agent/direct_thread_wire.rsdirect_thread_delta_text=bounded(sanitize_detail_text(root, delta), 8000),即每个item.delta只拿到自己那一段。.../agent/generation/prompt_context.rs的sanitize_error_context旧实现用value.lines()遍历、join("\n")回填:以换行结尾的段,末尾换行被吃掉("a\n"→"a"、"\n"→"")。apps/ai-game-creator-shell/src/view/project-development/chat/conversation/directThreadChat.ts的appendLiveText直接拼接各段,于是段落空行、列表项换行、表格行换行全部消失。redact_absolute_path_tokens把index == 0当文本边界,delta 从/开头时片段被误判成绝对路径:"assets" + "/c" + "anvas-generated"→assets<absolute-path>anvas-generated,而它的整段形式assets/canvas-generated/...不会被命中——同一段文本两种结果。复现与证据
%APPDATA%\world.genarrative.ai-game-creator\projects\gameagent-cfc64e7f\.agent\conversations\project.jsonl里这条汇报原文完整((项目相对路径):\n\n| 素材 | 用途 | 路径 |\n|---|---|---|),turn-stream.jsonl同样是完整文本 → 文本没坏,坏在展示链路。direct_thread_delta_text再拼接:1445 字符 / 38 个换行 → 1435 字符 / 0 个换行;送进ChatMarkdownMessage渲染得table:0 th:0 li:0 h2:0 p:1(就是截图形态)。同一文本走整段脱敏(item.completed/ 历史读回)仍是table:1 th:3 h2:4 p:8。git log -S direct_thread_delta_text→30c377d0f;其父提交里这条分支直接发原始 delta(payload: {"delta": delta.clone()}),当时渲染正常。影响
<absolute-path>(15) 替换 2 字符会让流式正文比完成态更长,mergeDirectChatEntry于是保留被搞坏的正文,item.completed的正确快照覆盖不回界面。project.jsonl原文、历史读回、工具卡片。计划
sanitize_error_context改为split_inclusive('\n')逐段处理、原样保留行终止符,令「逐段脱敏 == 整段脱敏」,并补回归测试。/开头的 delta 片段被判成绝对路径(上面第 4 点)。修它需要把「上一个字符」带进边界判定(正文增量可从DirectProjectHistoryAccumulator::accumulated_text_for取;思考增量目前没有累计器),属于跨 delta 状态的取舍,单独处理。