7.8 KiB
7.8 KiB
3-27 MinerU OCR 后端 runtime 已落地但缺前端任务链
状态
- 状态:process
- Owner:03-rust-web / local-folder OCR / MinerU sidecar
- 发现时间:2026-05-31
现象
P2 目标中包含 MinerU OCR 能力收口。当前已补后端 mock route、真实 MinerU HTTP client、sidecar 写入、.mnote/ocr-index.json、includeOcr=true 搜索命中、resource tab 图片/PDF OCR 工具条、附件/File Tree 资源菜单入口和浏览器 UI smoke。但 active job store、realtime job event、全局任务栏/任务抽屉和 AI 资源上下文仍未落地。
证据
rust/crates/mnote-web/src/routes/local_ocr.rs已注册jobs/status/read/insert,provider=mock能写入{pageStem}.ocr/*.ocr.md和.mnote/ocr-index.json。provider=mineru在有 token 时会走真实 HTTP client:申请上传 URL、PUT 上传、轮询结果、下载 zip、提取 Markdown,并写入{pageStem}.ocr/*.ocr.md/.mnote/ocr-index.json。该路径已有本地 HTTP mock 单测覆盖,不访问外网。local_search_index已支持includeOcr=true命中 OCR owner page;增量刷新也已排除 hash 后缀 OCR sidecar,不再把*.ocr.md当普通页面命中。task526-local-folder-ocr-api-smoke.js已覆盖浏览器上下文调用 mock OCR API、图片 resource tab 手动 OCR、工具条状态、打开 OCR、搜索命中和显式 insert 链接。- 设计中的活动任务生命周期、
local_ocr.job.updated和浏览器可见入口仍未完成。
影响
- 用户已能从本地图片/PDF resource tab、附件菜单和 File Tree 资源菜单触发 OCR;但离开当前资源后的全局任务抽屉仍缺。
- 搜索的
includeOcr=true已能命中 OCR sidecar,includeOcr=false不应命中普通 OCR sidecar;本轮补了增量索引过滤测试。 - AI 资源上下文无法优先读取已有 OCR Markdown。
下一步
- 已完成后端 mock 最小闭环:路径规划、sidecar frontmatter、
.mnote/ocr-index.json、mock OCR job route、status/read、Page Tree 过滤和includeOcr=true搜索 owner page。 - 已补浏览器 API smoke:mock OCR、status/read/jobs、
includeOcr=true搜索 owner page 和显式 insert link。 - 下一步接长任务状态、
local_ocr.job.updatedrealtime 事件、全局 OCR 任务栏/任务抽屉和 AI 资源上下文读取 OCR sidecar。
验收
- Rust route/helper 测试覆盖 sidecar 路径/frontmatter、index stale/error redaction、mock OCR job 写入、status/read、无 token、越界拒绝、非图片/PDF 拒绝、mock 失败 response 脱敏和显式 insert link。
- local search 测试覆盖 OCR 命中返回 owner page,普通与 hash 后缀 OCR sidecar 不作为普通页面。
- Page Tree 测试覆盖 OCR sidecar 可在 File Tree 作为资源文件可见,但不作为普通页面进入 Page Tree。
- Rust route 测试覆盖无 token response 形态。
- Rust route 测试覆盖
provider=mineru后端成功路径:申请上传 URL、PUT 上传、轮询结果、下载 zip、提取 Markdown、写 sidecar/index。 - [~] 浏览器 smoke 覆盖图片/PDF 手动 OCR、任务栏状态、打开 OCR、搜索 OCR 命中和插入 OCR 链接。(当前
task526覆盖图片 resource tab 手动 OCR、工具条状态、mock OCR API、搜索命中、显式 insert link 和 OCR sidecar resource tab 打开;全局任务栏/任务抽屉待做)
2026-06-01 后端 mock 闭环记录
新增 rust/crates/mnote-web/src/routes/local_ocr.rs,注册:
POST /api/local-folder/ocr/jobsGET /api/local-folder/ocr/jobsGET /api/local-folder/ocr/statusGET /api/local-folder/ocr/readPOST /api/local-folder/ocr/insert
当前真实 MinerU HTTP client 仍未接入;provider=mock 用于本地后端闭环和测试,provider=mineru 在缺少 token 时返回 mineru_token_missing,有 token 时返回 mineru_runtime_not_enabled,避免伪装真实能力已完成。
已通过验证:
cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1cargo test --manifest-path rust/Cargo.toml -p mnote-web local_search_ocr -- --test-threads=1
2026-06-01 续补 route 边界测试:
- 越界来源路径拒绝:
local_ocr_path_escape - 非图片/PDF 来源拒绝:
local_ocr_source_type_unsupported - provider
mineru且缺 token 时拒绝:mineru_token_missing - mock 失败响应与
.mnote/ocr-index.json失败条目统一脱敏为provider_error_redacted - 显式
ocr/insertlink 模式把[OCR:photo.png](./Page.ocr/photo.png.ocr.md)追加进 owner Markdown;未调用 insert 时不改正文
本文继续保持 process:全局任务栏、active job store / realtime event 和 AI 资源上下文尚未完成。
2026-06-01 只读复核更新:
- Subagent 复核确认:route/mock/search 测试已落地,早期“没有实际 OCR route”的描述已经过时。
- 本 bug 不归档的阻塞点更新为:active job store /
local_ocr.job.updated、全局任务栏/任务抽屉、AI 资源上下文读取 OCR sidecar 和完整 UI browser smoke。
2026-06-01 浏览器 API smoke 续补:
- 新增
scripts/task526-local-folder-ocr-api-smoke.js,在真实浏览器登录态页面内通过 UI 和fetch串起图片 resource tab OCR 工具条、POST /api/local-folder/ocr/jobs、status、read、jobs、/api/search/documents includeOcr=true和POST /api/local-folder/ocr/insert。 - 已验证
provider=mock会生成docs/Page.ocr/photo.png.ocr.md,resource tab 工具条显示 OCR 完成并可打开/插入;includeOcr=false不命中 OCR 文本,includeOcr=true返回 owner page 且带hasOcr/ocrEvidence,显式 insert 才向 owner Markdown 追加[OCR:photo.png](...)。 - 续补后已验证 OCR sidecar 可作为 Markdown resource tab 打开,截图写入
tmp/task526-local-folder-ocr-api-smoke/03-ocr-resource-tab.png;OCR 工具条截图写入tmp/task526-local-folder-ocr-api-smoke/02-ocr-toolbar.png。 - 已通过:
node --check scripts/task526-local-folder-ocr-api-smoke.jsMNOTE_UI_BASE_URL=http://127.0.0.1:3301 MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3301 node scripts/task526-local-folder-ocr-api-smoke.jscargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1cargo test --manifest-path rust/Cargo.toml -p mnote-web local_search_ocr -- --test-threads=1
2026-06-01 MinerU API 口径复核:
- 官方文档当前仍以
https://mineru.net/api/v4/extract/task或https://mineru.net/api/v4/file-urls/batch作为精准解析入口;model_version支持pipeline/vlm/MinerU-HTML,Markdown/JSON 为默认结果格式,图片/PDF/Office 等文档受文件大小与页数限制。 - 当前设计稿中的“申请上传地址 -> PUT 上传 -> 轮询批量结果 -> 下载 zip -> 提取 Markdown”方向仍成立。
- 旧回归测试曾要求
MNOTE_MINERU_API_TOKEN存在且 provider 为mineru时返回mineru_runtime_not_enabled;该口径已被真实后端 runtime 合同测试替代。
2026-06-01 后端 MinerU runtime 补齐记录
rust/crates/mnote-web/src/routes/local_ocr.rs已补mineru_api_base_url、mineru_poll_interval、mineru_max_polls配置函数。provider=mineru后端路径已接入run_mineru_ocr,执行申请上传 URL、PUT 上传、轮询 batch 结果、下载 zip、提取 Markdown。- 新增本地 HTTP mock 测试
local_ocr_jobs_route_runs_mineru_runtime_against_http_mock,不访问外网,验证真实 client 合同和 sidecar/index 写入。 - 已通过:
cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1
本文继续保持 process 的剩余原因:
- OCR jobs 仍是同步请求 +
.mnote/ocr-index.json历史状态,没有 active job store。 - 缺少
local_ocr.job.updatedrealtime event 与全局任务栏 UI。 - AI 资源上下文还没有优先读取 OCR sidecar。