Files
Agent-System-Documents/docs/proposals/2026-10-06-ext-5-host-parse-document.md
T
weichen 5825cd35f2 Propose EXT-5 host document parse and tighten the surface snapshot
Why: downstream parsers are unreachable through the Host handle and the base lacks xlsx/pptx parsers; MS1 needs both. The snapshot also missed interface methods, so adding one was undetectable.

Evidence: request follows compat-policy sect.6 four elements; behavior contract and limits in the proposal body (documents has no CI; verified via git diff --check recorded on the Dev task card).

Impact: docs only; compat-policy sect.3 gains one sentence, usage.md format list gains xlsx/pptx.

Refs: docs/proposals/2026-10-06-ext-5-host-parse-document.md
2026-10-06 14:44:17 +00:00

5.9 KiB
Raw Blame History

EXT-5:宿主句柄开放内置文档解析(含 xlsx/pptx 内置解析器)

状态:实施中(2026-10-06);owner:weichen;主任务:Dev 仓 feature/ext-5-host-parse。 规范依据:扩展面兼容与演进(§6 扩展点申请模板);前序 EXT-1(Host 最小集)。相关:EXT-4(下游注册 inproc 解析器,备选、未提交)——方向相反,本申请不依赖它。 撰写日期:2026-10-06。

1. 申请四要素(compat-policy §6)

  • 场景:Agent-System-RDM 的 F1 上传主链(rdm.upload,PR #103)需要解析用户上传的文档;基座 internal/ingest 有内置解析器但没有经 extension.Host 开放——下游拿到的只有 ArtifactGet/ArtifactContent(原件字节),要解析就得自带一份解析代码(RDM 现状:自带 md/txt/docx 解析器,pdf/pptx/xlsx 一律回「不支持」)。MS1(W4,11-01)验收第 4 条要求「报价单 Excel + 图文混排 PPT 解析完整性核对」,当前两条路都走不通:句柄没有解析方法,基座自身也没有 xlsx/pptx 解析器。

  • 希望符号:pkg/extension 的 Host 新增一个方法:

    // ParseDocument 用基座内置解析器把文档字节解析为 ParsedDocument(EXT-5)。
    ParseDocument(ctx context.Context, filename, mime string, content []byte) (core.ParsedDocument, error)
    

    同时 internal/ingest 新增 builtin:xlsx(xlsx/xlsm)与 builtin:pptx(pptx/pptm/ppsx)两个内置解析器——这两个是基座能力补齐,不依赖 EXT-5,上传/附件路径同步受益。

  • 为何现有注册点组合不出来:ParsersDescription 只是注册表描述(设置页/文档用),没有执行入口;PluginParserDecl.Tool 仅接受内置名或 sidecar 工具名(core/plugin_v2.go 注释明示);Host 最小集里与文档相关的只有工件只读两个方法。下游唯一替代是复制基座解析代码进自己仓库——违背「引擎在基座」的接缝表裁定。

  • 兼容:只加符号。实验窗口内给 Host 接口加方法会破坏第三方 fake 的编译(compat-policy §1 允许,须改快照并在提案里写一句);SurfaceVersion 保持 2.0.0-experimental。本次同时把契约快照升级为记录导出接口的方法(此前只记顶层名,加方法这类变更检测不到)。

2. 接口语义

  • 分派按文件扩展名,与 ingest.Parse 完全一致(同一实现,hostcaps.parse 委托)。
  • 返回 error 的只有两种情况:ctx 已取消;输入超过 100 MiB(与上传端点 io.LimitReader(file, 100<<20) 同口径)。除此之外的「不可解析」都返回带 Warnings 的文档(显式失败,不静默),Meta.Confidence 相应降低。
  • 纯计算:不读写 owner 数据、不走存储。要解析工件原件,先调 ArtifactContent(owner 作用域由它保证),把字节传进来——不另造句柄、不新增凭证面。
  • 参数为位置参数(filename/mime/content),与 Host 既有方法风格一致;不引入 options 结构。

3. 新解析器格式与限制

xlsx/xlsm(builtin:xlsx):工作表顺序取 workbook.xml 的 sheets 列表(不按文件名),target 经 rels 解析(相对/绝对路径);共享字符串含富文本 run(排除注音 rPh);单元格覆盖 t=inlineStr/str/b/e/n(布尔输出 TRUE/FALSE、错误值原样)、公式取缓存值(无缓存输出 =公式)、日期按内置格式 ID 与含 y/m/d/h/s 记号的自定义格式转 ISO(1900/1904 双日期系统);稀疏列按单元格引用就位,去行尾空与全空行;隐藏工作表标题标「(隐藏)」;每个工作表产出一个 heading 块 + 一个 table 块,空表跳过。

pptx/pptm/ppsx(builtin:pptx):幻灯片顺序取 presentation.xml 的 sldIdLst;标题占位符(title/ctrTitle)产「幻灯片 N:标题」heading 块;正文形状每形状一个 para 块(a:br 换行);组合形状递归;mc:AlternateContent 只取 Choice 分支;graphicFrame 表格产 table 块(合并单元格位置留空以保持列对齐);备注页正文产「备注:…」;跳过页码/日期/页脚占位符。图片、SmartArt 不解析(无 OCR/图形理解,属远期档)。

旧二进制格式 doc/xls/ppt:不做解析,Warnings 给可操作提示(请转存 docx/xlsx/pptx 后重传)。

上限(包级变量,测试可覆盖):单元格总数 200000、列数 1024、zip 内单部件解压 64 MiB(zip 炸弹防护,docx 一并受益);超限保留已解析部分 + Warnings + Confidence 降 0.6,原件不受影响。

4. 验证

  • 手工构造 OOXML zip 的单元测试:xlsx(表序/富文本/公式/日期/稀疏列/隐藏表)、pptx(sldIdLst 序/标题/组合/AlternateContent/表格/备注)、失败路径(损坏 zip/缺 workbook.xml/部件超限/超上限)。
  • openpyxl 与 python-pptx 现场生成真实文件的轮测(依赖缺失时 t.Skip;CI 已装这两个包)。
  • internal/app 走真实 applyCompiled → cmdbus.Dispatch → inprocHost 链路:alice 解析自己的 xlsx 工件成功、bob 同 ID 被拒(owner 作用域不因新方法放宽);ctx 取消与超限两条 error 路径。
  • 上传端点 e2e:xlsx 上传返回 parser=builtin:xlsx 且无 Warnings,知识检索命中单元格文本。
  • surface 快照按「顶层名 + 接口方法」新口径重建并通过。

5. 不在本文范围

  • sidecar /host/v1 的 HTTP 解析路由(sidecar 形态可继续读字节走自己的解析;出现真实需求再申请)。
  • MinerU 交叉验证、OCR、SmartArt、旧 OLE 格式解析。
  • 上传超过 100 MiB 被静默截断的问题、kindOf 与 artifactKindOf 口径不一致——已登记为 EXT-5 盘点发现的缺陷,另行修复。
  • 下游把上传链路切到 Host 解析、RDM pin 升级到 v0.2.0:RDM 仓自己的任务卡。