Outlook Index Fusion Workspace
outlook-index 现在不再只是静态票据 mock。当前实现已经把页面切到 canonical document-recognition API,并把 Fusion 收敛为底层 runtime 实现。
当前能力
- 当前 demo workspace 外壳仍会先校验 admin session;未登录时显示登录页,但底层
document-recognitionAPI 本身是公开的 - 支持通过
?agent_id=...&run_id=...深链打开指定单证识别 run - 地址栏现在会同步 canonical 路径
/operate、/doc-records、/manage、/maintain以及对应的agent_id/run_id/manage_run_id,刷新后会尽量恢复到相同 surface / agent / run 上下文,而不是回到首页默认态;旧的?surface=records查询参数仍兼容恢复到Doc Records - 顶部 Runtime 控件从
GET /api/document-recognition/runtime-agents加载可选 runtime,并以 agent name 作为主要选择入口 - Runtime selector 支持按 name、description 或
agent_id搜索;用户不需要手动复制内部 ID - 先读取
GET /api/document-recognition/runtime-agents/{runtime_agent_id},再根据upload_slot_resolution判断当前 runtime 是否可上传 - 通过
multipart/form-data调用POST /api/document-recognition/runs - 在页面内轮询
GET /api/document-recognition/runs/{run_id},并展示 canonicalworkspace_output Operate工作队列来源是GET /api/document-recognition/runs/pending-sync?runtime_agent_id=...,由后端基于 document-recognition 投影状态筛出仍需处理的 run,避免在浏览器里只过滤最近历史窗口- 历史记录来源改为
GET /api/document-recognition/runs/page?runtime_agent_id=...,服务Doc Records的服务端分页历史列表;裸的GET /api/document-recognition/runs仍保留给其他历史回看和 lookup 场景 - 点击字段或表格单元时,左侧 viewer 会切换到目标页并显示 bbox 高亮
- 字段修正现在会先进入 operate/footer 的待同步列表;用户点击
Approve & Sync后,会先看到一个简洁的确认弹窗,再通过PATCH /api/document-recognition/runs/{run_id}/field-reviews/{field_id}批量写回并重新拉取 run detail Doc Records现在是和Operate并列的独立 surface,通过/doc-records访问,并按当前 runtime 的 run list 渲染 document/run tableDoc Records首次加载会走/api/document-recognition/runs/page做服务端分页,表格只渲染当前页;搜索、排序和分页都由后端处理,不再依赖浏览器本地切页Doc Records每行展示 document/run、run status、review status、字段计数、低置信度/校验问题、更新时间,并保留源文档 preview/download actions;Edit Columns支持开关可选列、调整数据列顺序,表格与 CSV/Excel 导出会使用同一列顺序Doc Records对failedrun 和人工rejectedrun 使用后端 canonical rerun action;重跑会创建新的 run id 和 source/target lineage,页面停留在Doc Records并刷新列表Doc Records和OPERATE会在后端已经记录 rerun lineage 后禁用同一个 source run 的Rerun按钮,避免重复重跑同一条失败记录Doc Records的 rerun 可用性来自批量 lineage 预取,而不是逐行单独查询;当前页的 source run 会一次性计算是否已有 rerun targetDoc Records对 completed、unsynced 且尚未 rejected 的坏结果记录提供Reject操作;该操作只把review_status标记为rejected,不会把执行状态改成failedDoc Records表头支持点击排序,当前实现可以按 document/run name、ID、upload time、last edit time、sync status 和 document type 重新排序Doc Records的日期列使用紧凑的单行格式,避免同一列里因浏览器换行导致视觉高度不一致Doc Records的 document type 优先使用后端 canonicaldocument_type/summary.document_type,字段计数优先使用 run-level summary 与 review countersDoc Records行内Open会带上当前记录所属的run_id切回Operate,确保进入工作台后打开的是同一条 document/run 记录- 从
Operate切回Doc Records时会重新拉取当前 runtime 的 run 列表,避免Approve & Sync后继续展示旧的Synced/Unsynced状态 Doc Records搜索作用于 document/run rows,可匹配 document/run metadata、status、summary、计数和时间文本;empty state 会区分“当前没有 document runs”和“搜索无匹配”- 对于功能上线前没有 revision ledger 的旧 run,history 视图仍会展示 baseline 字段快照,并明确标记“未记录历史”
- 历史记录回看时,会先通过单证识别 run 的
source_document_url/source_pdf_url取回 blob,再在前端恢复 PDF / image 预览 - PDF 预览使用前端 canvas 渲染页图层,再叠加 bbox overlay;这样 bbox 坐标才能与 PDF 页面内容对齐
- PDF 预览改成渐进式页渲染:首次打开时优先渲染当前页(默认第一页),再按当前页附近逐步补页,而不是先把整份 PDF 全部 rasterize 完再显示
- PDF 页面在 viewer 内按真实页数连续纵向滚动,页码状态跟随滚动位置更新;字段联动时会滚动到目标页顶部
- viewer 会把远离当前页的已渲染 PDF 页图退回占位态,需要时再重渲染,以控制长文档的前端内存与 CPU 占用
- 历史 job 只有在对象存储中的源文件仍然存在时,才能恢复原文档预览;仅有 extraction job 列表记录并不等于原始文件一定还能下载
- 顶部导航已经拆成
OPERATE / MANAGE / DOC RECORDS / MAINTAIN四个 surface;DOC RECORDS通过独立的/doc-records页面显示 document/run 列表,MANAGE会进入独立的管理页面壳层,MAINTAIN目前仍是占位页 MANAGE现在是浏览器本地的布局编辑器:进入时会优先使用当前 completed run,未分组的稳定字段也会先显示在中央布局画布中;用户可以选择一条成功历史 run,创建 section,把稳定字段拖入 section,调整字段宽高、显示模式、label、chip 显示开关,以及 section 的flow / grid布局模式MANAGE使用浏览器localStorage保存布局,作用域按agent_id + version_id隔离;布局不会写回后端,也不会跨浏览器同步MANAGE的grid模式支持为字段设置显式的column start / row start,因此可以刻意留空某些网格位置;flow模式仍保持自动补位MANAGE只编辑 field layout;tables 继续保持OPERATE中的独立 pane 展示和 bbox 联动,不进入布局编辑器- 当字段身份无法稳定区分时,这些字段会以 ambiguous 状态展示给用户查看,但不会进入持久化布局
OPERATE现在按 sectioned form 渲染字段,未放入 section 的字段会进入 unplaced 区域;隐藏字段不会在OPERATE中展示OPERATE的字段值修正会先作为浏览器本地草稿按agent_id + run_id保存,刷新后可恢复;只有在 footer 中点击Approve & Sync并确认后,字段变更才会通过 canonical field-review PATCH 写回后端OPERATE顶部动作区提供Refresh,会重新拉取当前 run detail 和队列状态,按钮点击后会显示旋转态,避免用户重复触发OPERATE顶部动作区会对failed或rejectedrun 显示Rerun;重跑成功后工作台切换到新 run。completed 坏结果需要先Reject,再进入可 rerun 状态- footer 左侧现在是文件级 pager,序号优先对应当前 workspace 待审队列里的位置;该队列由后端
GET /document-recognition/runs/pending-sync基于 run status、review status 和last_reviewed_at推导,成功 sync 后如果当前 run 已无 pending 字段,会自动从工作区消失并切到下一个待审文件。如果当前打开的是从Doc Records跳回来的历史 run、它不在待审队列里,pager 会回退到完整 run history,避免只显示总数却没有可切换的当前项 - 表格单元编辑目前仍只有浏览器本地草稿,不会随
Approve & Sync一起提交;footer 会把这类 local-only 变更单独列出来 MANAGE仍不是全字段审阅工具;history inspector 会无视 layout 隐藏状态,单独承担“查看全部字段并继续修订”的职责
前端结构
outlook-index/src/components/fusion/FusionWorkspace.tsx- 工作台主状态:runtime agent、runtime detail、upload slot、run、polling、字段 timeline、bbox 选中态
outlook-index/src/components/fusion/FusionResultPane.tsx- 结果 pane:字段与表格布局、run 列表、字段修订入口
outlook-index/src/components/fusion/DocRecordsSurface.tsxDoc Records独立 surface:按agent_id调用分页 run API,再交给DocRecordsPage渲染 document/run table、搜索、源文档 preview/download 和回到Operate的 open actionoutlook-index/src/manage/ManagePage.tsx- 布局编辑器:section 管理、字段拖拽、字段展示设置、浏览器本地自动保存
outlook-index/src/manage/layout-schema.ts- 布局 schema 类型与默认规则
outlook-index/src/manage/layout-reconcile.ts- 选中 run 字段与本地 layout schema 的 reconciliation
outlook-index/src/manage/layout-storage.ts- 浏览器本地布局读写与容错
outlook-index/shared/api/documentRecognition.ts- canonical document-recognition runtime/run/field-review 的前端适配层;
listPendingSyncDocumentRecognitionRuns(...)专供Operate队列,listDocumentRecognitionRuns(...)保持历史列表语义 ai_service/document_recognition/interfaces/http/router.py- document-recognition HTTP 入口与 admin history 真相源
outlook-index/src/lib/fusion-output.tsworkspace_output输出规范化与字段 identity 生成outlook-index/src/components/fusion/FusionSectionedForm.tsxOPERATE字段 section 渲染outlook-index/src/components/fusion/FusionFieldRenderer.tsx- 单字段表单壳层渲染
outlook-index/src/components/viewer/*- 文档预览与 bbox overlay 组件
本地联调
开发模式下,Vite 会把 /api/* 代理到 VITE_API_PROXY_TARGET,默认是 http://localhost:3000,也就是 demo-backend。
由于 outlook-index 现在使用 multipart 上传,demo-backend 也同步支持把 multipart /document-recognition/runs 请求透传给 ai_service。同一代理层也覆盖 document-recognition 的 pending-sync queue、reject、rerun、field review、timeline 和下载路由。
同时,当前页面壳层仍使用 admin session 控制 demo 入口,但 /document-recognition/runtime-agents* 与 /document-recognition/runs* 自身不要求登录。
Runtime 选择语义
outlook-index 的 UI 以 agent name 帮助用户选择 runtime,但 API、深链、历史记录和本地布局作用域仍使用稳定的 agent_id。
如果 URL 或 localStorage 中保存的 agent_id 已不在 /document-recognition/runtime-agents 返回列表中,页面会提示该 runtime 已不可用,并要求用户重新按名称选择一个已注册 runtime 后再上传。