From d209c58b5dcae255d971fd28802d4ea3e6a2fe3a Mon Sep 17 00:00:00 2001 From: Wenjie Zhang Date: Wed, 8 Apr 2026 15:21:20 +0800 Subject: [PATCH] =?UTF-8?q?fix(parser):=20=E4=BF=AE=E5=A4=8D=20DOCX=20?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=9B=9E=E6=8F=92=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../package/yuxi/plugins/parser/unified.py | 2 +- .../test/unit/plugins/test_parser_facade.py | 46 +++++++++++++++++++ docs/develop-guides/roadmap.md | 1 + 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/backend/package/yuxi/plugins/parser/unified.py b/backend/package/yuxi/plugins/parser/unified.py index f0c72bf6..7e263256 100644 --- a/backend/package/yuxi/plugins/parser/unified.py +++ b/backend/package/yuxi/plugins/parser/unified.py @@ -149,7 +149,7 @@ def _convert_with_docling(file_path: Path, params: dict | None = None) -> str: markdown = doc.export_to_markdown() - for url in reversed(image_urls): + for url in image_urls: markdown = re.sub(r"", url, markdown, count=1) return markdown diff --git a/backend/test/unit/plugins/test_parser_facade.py b/backend/test/unit/plugins/test_parser_facade.py index e6b54ded..21857308 100644 --- a/backend/test/unit/plugins/test_parser_facade.py +++ b/backend/test/unit/plugins/test_parser_facade.py @@ -1,7 +1,9 @@ from __future__ import annotations import asyncio +import base64 from pathlib import Path +from types import SimpleNamespace import fitz import pytest @@ -63,6 +65,50 @@ def test_parser_parse_docx_file_returns_markdown_text(tmp_path: Path, monkeypatc assert len(markdown.strip()) > 0 +def test_convert_with_docling_reinserts_image_links_in_document_order( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +): + file_path = tmp_path / "parser_test.docx" + file_path.write_bytes(b"fake docx") + first_image = base64.b64encode(b"first image").decode() + second_image = base64.b64encode(b"second image").decode() + fake_doc = SimpleNamespace( + pictures=[ + SimpleNamespace(image=SimpleNamespace(uri=f"data:image/png;base64,{first_image}")), + SimpleNamespace(image=SimpleNamespace(uri=f"data:image/png;base64,{second_image}")), + ], + export_to_markdown=lambda: "before\n\nbetween\n\nafter", + ) + fake_result = SimpleNamespace(status=SimpleNamespace(name="SUCCESS"), document=fake_doc) + uploaded_images: list[bytes] = [] + + class FakeConverter: + def convert(self, path: Path): + assert path == file_path + return fake_result + + def _fake_upload_image_to_minio(image_data, filename, bucket_name, object_prefix): + uploaded_images.append(image_data) + return f"https://example.test/{len(uploaded_images)}.png" + + monkeypatch.setattr(parser_unified, "_get_docling_converter", lambda: FakeConverter()) + monkeypatch.setattr(parser_unified, "_upload_image_to_minio", _fake_upload_image_to_minio) + image_timestamps = iter([1.0, 2.0]) + monkeypatch.setattr(parser_unified.time, "time", lambda: next(image_timestamps)) + + markdown = parser_unified._convert_with_docling(file_path) + + assert uploaded_images == [b"first image", b"second image"] + assert markdown == ( + "before\n" + "![image_1000000.png](https://example.test/1.png)\n" + "between\n" + "![image_2000000.png](https://example.test/2.png)\n" + "after" + ) + + def test_parser_parse_png_file_returns_markdown_text_with_mocked_ocr( tmp_path: Path, monkeypatch: pytest.MonkeyPatch, diff --git a/docs/develop-guides/roadmap.md b/docs/develop-guides/roadmap.md index 577ee4f2..0f82268f 100644 --- a/docs/develop-guides/roadmap.md +++ b/docs/develop-guides/roadmap.md @@ -47,6 +47,7 @@ - 重构 MCP 运行时配置加载模型:移除 `MCP_SERVERS` 作为运行正确性前提的设计,改为每次直接从数据库读取最新 MCP 配置,并用 `server_name:config_hash` 作为本地工具缓存 key;同时将内置 MCP 初始化职责收敛为仅同步数据库默认项,前端 MCP 选项改为直接使用实时资源列表,解决 `api`/`worker` 分进程下的配置不一致与缓存失效问题 - 为知识库检索工具补充 `metadata.filepath` 注入:在 `query_kb` 统一出口基于会话可见知识库构建 `file_id -> /home/gem/kbs/...` 映射并回填检索结果,注入逻辑复用知识库只读后端命名规则;并将工具调用范围收敛为 Milvus(仅支持 Milvus chunks 列表且要求显式 `file_id`),不再兼容无显式 `file_id` 的推断注入,新增单测覆盖该约束 - 调整 Milvus 混合检索实现:集合 schema 增加 Milvus 内置 BM25 稀疏向量字段、BM25 函数和中文 analyzer 配置,`keyword` 模式改为 BM25 全文检索,`hybrid` 模式改为 Milvus 原生向量 + BM25 混合检索,并同步更新检索参数说明。 +- 修复 DOCX 解析中的图片回插顺序:Docling 导出的多个 `` 占位符现在按文档图片顺序替换,避免多图文档中的图片链接前后颠倒。 - 修复前端依赖安全告警:通过 `pnpm.overrides` 将传递依赖 `flatted` 锁定到 `3.4.2`、`lodash-es` 锁定到 `4.18.1`,并同步更新 `pnpm-lock.yaml` 以消除 DriftGuard 报告的高危 CVE - 重写界面设计规范:参考 `DESIGN.md` 写法补充视觉气质、颜色 token、组件状态、布局层级、响应式与 Agent Prompt Guide,并基于该规范收敛首页视觉表现,移除装饰性渐变、重阴影、hover 位移和入场动画。