导出 Word 后只显示 Mermaid 源码,未生成流程图
用户在 AI 对话里得到一段含 Mermaid 流程图的 Markdown,导出成 Word 后图变成了一段代码文本。Agent 判定这是后端转换缺陷,在隔离沙箱里选用「DOCX 中至少出现 1 个图形」这条已登记断言写出复现测试,第二轮复现成功,随后一轮修复即通过目标测试。独立验证重跑了基线、目标测试、53 项全量后端测试与 DOCX 结构检查,全部通过后创建了 Pull Request。过程中 PR 创建连续失败三次,第四次成功——这类重试在真实运行里很常见,站点如实展示而不做修饰。
总耗时
23m 05s
2026-08-12 14:54
Token
57,403
4 次模型调用
代码改动
+24 −1
3 个文件
工具调用
21
恢复 4 次
- RUN REF
- 7ec99c1ea8c6
- 类别
- docx_structure
- Provider
- openai_compatible
- 模型
- deepseek-ai/DeepSeek-V4-Flash
- Graph
- agent-graph-v7
- Policy
- publication-policy-v5
- 扩展版本
- 0.3.0
- 基线 commit
- b50187fc7003
阶段 7 / 7
创建 PR14m 16s重试 3 次
只有四道验证全部通过才会创建 Pull Request。Agent 到此为止 —— 绝不自动合并、绝不自动部署,是否采纳由维护者决定。
- 补丁哈希
- 04024526609e28a6fd56c401bc2e50381e126a647c1cda00c962093f9b06485b
- Pull Request
- https://github.com/yyqqCoding/MDToWord/pull/1
本阶段调用4
publication_failed
- base_sha
- b50187fc70031b13fcef3bedc0c459c3a9f634b0
- feedback_id_prefix
- 892ff98b
- validated_patch_sha256
- [REDACTED_PHONE]e28a6fd56c401bc2e50381e126a647c1cda00c962093f9b06485b
- error_code
- publication_failed
- error_type
- PublicationError
publication_failed
- base_sha
- b50187fc70031b13fcef3bedc0c459c3a9f634b0
- feedback_id_prefix
- 892ff98b
- validated_patch_sha256
- [REDACTED_PHONE]e28a6fd56c401bc2e50381e126a647c1cda00c962093f9b06485b
- error_code
- publication_failed
- error_type
- PublicationError
publication_failed
- base_sha
- b50187fc70031b13fcef3bedc0c459c3a9f634b0
- feedback_id_prefix
- 892ff98b
- validated_patch_sha256
- [REDACTED_PHONE]e28a6fd56c401bc2e50381e126a647c1cda00c962093f9b06485b
- error_code
- publication_failed
- error_type
- PublicationError
- base_sha
- b50187fc70031b13fcef3bedc0c459c3a9f634b0
- feedback_id_prefix
- 892ff98b
- validated_patch_sha256
- [REDACTED_PHONE]e28a6fd56c401bc2e50381e126a647c1cda00c962093f9b06485b
- branch
- agent/feedback-892ff98b-docx_structure
- reused
- false
- pr_number
- 1
- disposition
- pr_opened
代码改动
取自公开仓库中已合并的 Pull Request,不是 Agent 的受控产物
@@ -9,6 +9,7 @@
| 9 | 9 | |
| 10 | 10 | from app.normalizer import normalize_markdown |
| 11 | 11 | from app.settings import settings |
| 12 | +from app.mermaid_renderer import render_mermaid_blocks, MermaidRenderError | |
| 12 | 13 | |
| 13 | 14 | logger = logging.getLogger(__name__) |
| 14 | 15 |
@@ -70,7 +71,12 @@ def convert_markdown_to_docx(markdown: str, work_dir: Path | None = None) -> byt
| 70 | 71 | def _convert(markdown: str, work_dir: Path) -> bytes: |
| 71 | 72 | input_path = work_dir / "input.md" |
| 72 | 73 | output_path = work_dir / "result.docx" |
| 73 | - input_path.write_text(normalize_markdown(markdown), encoding="utf-8") | |
| 74 | + try: | |
| 75 | + rendered_markdown = render_mermaid_blocks(markdown, work_dir) | |
| 76 | + except MermaidRenderError as exc: | |
| 77 | + raise ConversionError(exc.message, exc.details) | |
| 78 | + normalized = normalize_markdown(rendered_markdown) | |
| 79 | + input_path.write_text(normalized, encoding="utf-8") | |
| 74 | 80 | |
| 75 | 81 | command = [ |
| 76 | 82 | _resolve_pandoc_binary(), |
@@ -0,0 +1,7 @@
| 1 | +graph TD | |
| 2 | + A([起床]) --> B{看窗外天气} | |
| 3 | + B -- 下雨 --> C[带伞] | |
| 4 | + B -- 晴天 --> D[涂防晒] | |
| 5 | + C --> E[出门上班] | |
| 6 | + D --> E | |
| 7 | + E --> F([到达公司]) |
@@ -0,0 +1,10 @@
| 1 | +def test_feedback_892ff98b_mermaid_not_rendered(tmp_path): | |
| 2 | + from pathlib import Path | |
| 3 | + | |
| 4 | + from app.pandoc_runner import convert_markdown_to_docx | |
| 5 | + from docx_assertions import assert_minimum_drawing_count | |
| 6 | + | |
| 7 | + fixture = Path(__file__).parent / "fixtures" / "feedback" / "test_feedback_892ff98b_mermaid_not_rendered.md" | |
| 8 | + markdown = fixture.read_text(encoding="utf-8") | |
| 9 | + docx_bytes = convert_markdown_to_docx(markdown, tmp_path) | |
| 10 | + assert_minimum_drawing_count(docx_bytes, 1) |
独立验证
全量后端测试 53 项
- 通过
基线复现
修复前目标测试确实以预期方式失败
- 通过
目标测试
修复后目标测试通过
- 通过
全量回归
失败 0 · 跳过 0(与基线一致)
- 通过
DOCX 结构
assert_minimum_drawing_count
补丁策略检查
patch-policy-v2
- 通过
改动均在可写范围内
1 个产品文件 · 2 个测试文件
- 通过
产品代码仅限修复目标
pandoc_runner.py
- 通过
未触及扩展与依赖
Dockerfile、依赖清单与 extension/ 不在可写范围内
- 通过
改动文件数
3 / 上限 5
- 通过
改动行数
+24 / 300 · −1 / 150