- clarify Rust SSR shell, WS/SSE transport status, and Next legacy role - add Reasonix block edit workflow empty block ops bug record Verification: - git diff --check -- CURRENT_ARCHITECTURE.md design/10-review/process/11-current-full-architecture-review-v1.md bugs/07-ai/process/7-25-reasonix-block-edit-workflow-empty-block-ops-after-markdown-match-v1.md
4.6 KiB
4.6 KiB
7-25 [process][bug] ACP Reasonix 页面 AI block_edit_workflow 在 markdown 命中后生成空 block_ops v1
发现时间:2026-05-17
状态:
[process]关联主线:
07-ai关联缺陷:
7-24 在线 markdown_edit 写回不以最终 Markdown 为真源
1. 用户可见症状
在页面 AI 中切换到 ACP · Reasonix,输入:
你
检查你是否能读取到本页第一段,同时请修改第二段为:测试123
工具调用失败:
mnote.page_ai.block_edit_workflow 失败 · page-ai-fast-mp9wm0qo
结果 mnote.doc.apply_block_ops operations 不能为空
2. 问题定义
page_ai.block_edit_workflow 当前已切到:
模型输出 search/replace
-> mnote.doc.markdown_edit
-> 在线文档再转换为 mnote.doc.apply_block_ops
但在线写回层没有以最终 Markdown 为真源。它在 markdown 字符串中 search/replace 成功后,又用原始 operations 去原始 blocks 中反查目标块。如果反查不到块,就生成空 block_ops,随后仍调用 mnote.doc.apply_block_ops,最终抛出“operations 不能为空”。
3. 证据
- page_ai_workflow.rs 调用模型生成 markdown operations。
- page_ai_workflow.rs 构造
mnote.doc.markdown_edit输入。 - doc.rs 在
md字符串上执行 search/replace。 - doc.rs 调用
build_block_ops_from_markdown_edit。 - doc.rs 只用
block.text.contains(search)反查 block。 - doc.rs 可能返回空
block_ops。 - doc.rs 即使
block_ops为空,也继续调用doc_apply_block_ops。 - block.rs 对空 operations 报错:
mnote.doc.apply_block_ops operations 不能为空。
4. 根因判断
这条错误不是最终 root cause,只是下游暴露出来的症状。
真正根因是 markdown 层与 block ops 写回层存在二次定位:
search_replace(&md, search, replace)可以通过精确、归一化或 fuzzy 匹配成功。build_block_ops_from_markdown_edit却只支持block.text.contains(search)。- 两套匹配规则不一致时,markdown 层显示已命中,block 层却生成空 operations。
- 空 operations 没有在
markdown_edit层转成语义化错误,而是继续传给apply_block_ops。
5. 影响
- ACP Reasonix 的页面编辑会向用户暴露底层
apply_block_ops错误,而不是说明“markdown 命中但无法映射到块”。 - “读取第一段 + 修改第二段”这类混合任务可能进入 fast workflow,但该 workflow 只能表达写入,不保证先读后答。
- 如果模型给出的
search是段落序号、fuzzy 片段、带格式文本或跨块文本,markdown 层可能成功,block 写回层仍失败。
6. 建议修复
短期:
doc_markdown_edit在调用doc_apply_block_ops前,如果applied > 0但block_ops.is_empty(),应返回明确错误,例如mnote_doc_markdown_edit_block_mapping_empty,并包含 failed operation 的 search 摘要。page_ai_workflow应把该错误翻译为用户可理解的提示,不要暴露apply_block_ops operations 不能为空。
中期:
build_block_ops_from_markdown_edit必须复用search_replace的定位结果,或让search_replace返回原始命中范围 / paragraph / block 映射。- 对“第一段/第二段”等序号型指令,应由模型输出对应段落原文作为
search,并增加回读校验。
长期:
- 按
7-24收口:在线markdown_edit应以最终 Markdown 为写回真源,或明确限制只支持可安全映射的单块精确替换。
7. 复现 / 验证建议
- 浏览器 smoke:ACP Reasonix,页面含至少两段正文,输入“检查第一段并修改第二段为:测试123”。
- 断言失败时错误码不能是
mnote.doc.apply_block_ops operations 不能为空,应是 markdown 到 block 映射失败的明确错误。 - 修复后回读 Page Aggregate,断言第二段实际变为
测试123,同时 AI 回复能正常说明已读取到第一段。
8. 状态
已按用户反馈与源码路径确认缺陷,尚未修复。