# DeepSeek Harness PDF 插件 - 功能 SPEC 版本:0.7;状态:随实现更新,阅读布局已实现、待交互验收;日期:2026-09-29。 本文件定义产品行为、功能范围和验收标准;具体 API、服务拆分、PDF 引擎和构建方式在后续设计中确定。 ## 0. 当前实现状态 以下状态依据当前插件源码、已完成构建及宿主激活记录;布局改动已通过类型检查和构建。**已实现不等于界面交互或全部验收用例已经通过**;尚未执行完整 UI 验收或性能基准,未提供实际加速比例。后文保留产品需求和后续设计,未交付项以本表为准。 | 能力 | 当前状态 | 范围与限制 | | --- | --- | --- | | 独立安装与宿主接入 | 已实现,Host 已激活 | 独立 `@local/dsh-pdf` bundle;已链接本地 Web / Desktop profile,注册 PDF 默认渲染器和设置页。无需修改 DSH 源码。 | | 阅读、选择、搜索与跳转 | 已实现,待交互验收 | 连续滚动、按需绘制近页、物理页码、缩放/适应宽度、显示旋转、文字/OCR 搜索、被动链接命中和独立返回栈。PDF 自带显示页标签尚未实现。 | | 原生标注编辑 | 已实现,待互操作验收 | Highlight、Underline、StrikeOut、Text 的读取与人工编辑,选区即时预览、页面直接选择、颜色/正文/删除、PDF 日期本地化。扁平化标记仍只是页面内容。 | | 工作副本、保存与丢弃 | 已实现,待交互验收 | 手动保存/另存为、版本冲突、撤销/重做、草稿恢复;一键丢弃恢复基线并清空草稿/历史;空白点击关闭上下文操作及未提交便笺。 | | 切换会话清理 | 已实现,待交互验收 | 关闭旧会话 PDF 并直接丢弃草稿;等待打开请求与清理完成。旧 Sidebar 未挂载的恢复标签保留精确关闭任务,下次挂载时关闭。 | | 区域截图与 OCR | 已实现,待交互验收 | 默认文字模式;区域截图一次框选后恢复文字模式,可复制/下载/OCR。NoneOCR / 本地 Tesseract.js,临时 OCR 文字层不写回 PDF;未内置厂商引擎或厂商配置表单。 | | 独立选区翻译 | 已实现,待实际调用验收 | 引擎解耦;NoneTranslation / DSH 模型;默认中文,结果留在 PDF 中,不加入会话历史;已有输入、输出及超时限制。 | | macOS 原生查询 | 受宿主接口阻塞 | 仅能力注册接口;macOS 按钮禁用,其他平台隐藏。尚无选区旁原生词典浮窗,不采用词典应用替代。 | | 文件与加密兼容 | 有明确限制 | 只支持宿主本地文件系统;数字签名和可直接打开的加密 PDF 只读;需密码文件不支持交互式解锁,不能编辑或保存加密文件。 | | 性能改进 | 已实现,未测量耗时 | 二分滚动定位、局部命中索引、选区边界遍历、批量删除、历史检查点、页面组件复用、相同内容摘要复用。普通编辑仍完整解析/序列化 PDF,详见第 9 节。 | | 阅读布局与鼠标缩放 | 已实现,待交互验收 | 顶部一行工具栏,删除底部文件路径/重载栏;左 PDF、右可折叠及调宽的阅读辅助栏,默认展开标注视图;Ctrl 配合滚轮在 PDF 内容区进行 10%~500% 缩放。 | | PDF 书签 | P1,未实现 | 右阅读辅助栏预留入口;列表、定位、管理与持久化尚未交付。 | | 会话发送与模型 PDF 工具 | P3,未实现 | 未注册模型 PDF 工具;选区/页面发送、会话解读与会话翻译仍属 P3。当前独立选区翻译不改变这一优先级。 | ## 1. 产品目标与约束 让用户在 DeepSeek Harness 的右侧 Sidebar 中阅读和标注 PDF,并在交叉引用跳转后回到原阅读位置。P0 完成这一闭环;P1 增加 PDF 书签;P3 才增加选区/整页发到会话及模型精细读取、解读、翻译和标注工具。 插件作为独立 bundle 开发、构建和安装,源码、依赖、测试和文档都位于插件项目目录。接入现有插件、文档预览和会话扩展接口,不需要修改 DeepSeek Harness 仓库的源码、manifest、默认配置或锁文件。 P0 成功标准:打开已有标注的 PDF → 阅读/选择及按需 OCR → 人工编辑标注 → 内部跳转并逐级返回 → 手动保存 → 用其他阅读器重开,看到原有和新增标注。 P1 在此基础上增加书签读取与管理;P3 再完成发送选区到会话 → 模型继续读取或修改同一工作副本 → 用户或模型显式保存的协作闭环。 ## 2. 核心概念 | 概念 | 含义 | | --- | --- | | 源文件 | 磁盘或文件提供方中已保存的 PDF。 | | 工作副本 | 当前会话正在操作的 PDF 状态,包括尚未保存的标注。P0 用户界面使用此状态;P3 模型操作共享同一状态。 | | 源文件版本 | 用于判断文件在上次读取后是否被其他程序修改的版本标识;调用方只能比较是否相等。 | | 工作修订号 | 工作副本每次成功修改后变化的标识;用于防止模型或界面基于旧内容修改标注。 | | 文档句柄 | 插件为某个会话中的某份文档分配的身份。模型操作必须明确携带它。 | | 页码 | 物理页序号,从 1 开始;PDF 自带的显示页标签另行展示,例如封面的 i、ii。 | | 选区快照 | 用户选择时的文字或图像、位置和版本。发送后保持不变,不随文件重新读取而被替换。 | | 原生标注 | PDF 中独立存储的高亮、下划线、便笺等对象,可以具有正文、颜色、作者和位置。 | | 页面内标记 | 已经绘制进页面的颜色或笔迹,例如扁平化标注。可被看到,但不能假定仍有独立可编辑的标注对象。 | | 页内容 | 某一物理页的可见页面及相关标注信息。分别提供可提取文字、页面图像和标注视角,不能把提取到的字符串等同于整页内容。 | | OCR 文本 | 从页面或区域图像识别得到的文字及几何位置,是带来源的派生结果;识别成功不等于文字准确或图表含义已理解。 | | OCR 引擎 | 可替换的识别实现,由统一 OCR 功能调用;自身不管理 PDF 文档、会话或标注。 | | OCR 引擎实例 | 某个引擎及其独立配置,例如同一厂商的不同端点/账号;具有稳定身份及配置修订。 | | 返回位置 | 一次成功跳转之前的阅读位置,包含物理页、页面内锚点和视图状态;不同 PDF tab 分别维护返回栈。 | ## 3. 主要使用场景 1. **读论文并问模型(P3)**:用户打开论文,选择一个段落,点击“解读”;当前会话收到选中文字和定位信息,模型解释该段,并能继续读取相邻段落或相关图表。 2. **翻译选区(P3)**:用户选择一段或跨页内容,指定目标语言,点击“翻译”;原文与翻译请求进入当前会话,结果显示在会话中。 3. **继续已有标注(P0)**:用户打开已在其他软件中高亮和批注的 PDF,查看标注内容、定位原文,修改批注或颜色,添加新的标注并保存。 4. **让模型辅助标注(P3)**:用户要求模型寻找方法部分并高亮关键句;模型查找、读取、定位并创建标注,Sidebar 展示修改和未保存状态。 5. **读扫描件或图表(P0;会话解读为 P3)**:P0 用户查看、框选、按需 OCR 并进行标注;普通 PDF 的图片、图表和公式保持可见。P3 才提供解读本页/区域、发送图像和基于模型能力的读取策略。 6. **同一文档、多轮交流(P3)**:用户持续阅读,模型通过文档句柄和位置引用读取局部内容,不必在每一轮重新上传整份 PDF。 7. **更换 OCR 引擎(P0)**:用户在 PDF 设置卡片选择本地或已安装的厂商引擎,查看器继续调用统一 OCR 功能;P3 模型工具随后复用同一功能。 8. **查阅交叉引用后返回(P0)**:用户从正文跳到参考页,再从参考页跳到附录;看完后连续点击返回,先回到参考页的原位置,再回到正文的原位置。 ## 4. 四个功能块与交付优先级 交付优先级:P0 为首版;P1 为后续书签能力;P3 为会话交互和模型工具。本 SPEC 保留各阶段的完整产品设计,但后续条款不能被当作 P0 的交付要求。 | 编号 | 功能块 | 优先级 | 范围 | | --- | --- | --- | --- | | 1 | PDF 编辑 | P0 | 已有标注识别、高亮/下划线/删除线/批注编辑、撤销重做、手动保存、另存为、冲突处理和草稿恢复。 | | 2 | 模型操作 PDF 的工具 | P3 | 模型读取/搜索/渲染/OCR/标注/保存工具,以及用户把文字、区域或整页发送到会话、解读和翻译。 | | 3 | PDF 书签 | P1 | 读取与定位已有书签,以及书签管理;持久化方式和管理细节在该阶段设计中确定。 | | 4 | 阅读跳转 | P0 | 基本阅读和定位、PDF 内部链接/命名目标跳转、页内位置恢复、嵌套跳转的返回栈。 | Sidebar 接入、工作副本、文字/区域选择、页面渲染、按需 OCR、OCR 引擎扩展和 PDF 设置卡片是功能块 1、4 的 P0 共同基础。OCR 通过用户操作提供选择、搜索和标注支持;它不依赖模型工具先行交付。 ### 4.1 P0:阅读、编辑和跳转 | 功能 | 交付行为 | | --- | --- | | Sidebar 打开 PDF | 工作区文件入口和已有文件链接可以进入插件查看器。 | | 分页阅读 | 连续滚动、上一页/下一页、输入物理页码、缩放、适应宽度、显示旋转。 | | 跳转与返回 | 支持内部页/命名目标;成功跳转前记录原位置;按后进先出顺序逐级返回。 | | 文本搜索 | 查找原有文字及已识别 OCR 文字,显示匹配位置和实际覆盖范围。 | | 文字与区域选择 | 跨行/跨页文字选择和单页区域选择,用于标注、OCR 与预览。 | | 页面内容与渲染 | 分别取得文字、整页/区域图像和标注;扫描页、混合页不被当作空白页。 | | 已有标注与编辑 | 识别、保留、添加和修改已确认范围的标注。 | | 撤销、保存和恢复 | 编辑历史、手动保存/另存为、外部版本冲突保护和未保存草稿恢复。 | | 按需 OCR 与引擎扩展 | 功能层与 NoneOCR、LocalOCR、厂商适配扩展解耦;所有 UI 入口使用统一功能。 | | PDF 设置卡片 | 配置阅读、标注、OCR 和返回栈,支持保存、校验及可用状态。 | P0 界面不提供会话解读、加入会话或模型自动操作入口,也不注册模型 PDF 工具。用户追加的独立选区翻译在当前阅读界面交付,遵循 FR-13,不向聊天消息或会话日志写入选区及译文。P0 的 OCR、阅读和编辑必须能独立工作。 ### 4.2 P1:PDF 书签 提供书签列表、定位及管理。点击书签复用 P0 导航操作和返回栈;P0 不依赖书签 UI,但应能解析内部链接引用的命名目标。已有书签、用户新建书签的关系和存储位置在后续设计中明确。 ### 4.3 P3:会话交互与模型工具 选中文字、区域或整页后,可以加入输入框、解读或翻译;模型通过文档句柄细粒度读取、搜索、渲染、OCR 和编辑标注,并显式保存。模型能力判断、附件快照、会话排队、工具日志和模型/人工共享工作副本均在此阶段验收。 ### 4.4 其他后续能力 批量 OCR、缩略图、复杂目录树和更多标注类型保留为后续备选,它们的具体交付优先级尚未确定。修改正文、页面重排、真正删除敏感内容及翻译文档导出仍在当前已确定范围之外。“PDF 编辑”在 P0 继续采用标注编辑范围。 P0 若存在无法满足的宿主接口限制,必须在技术设计阶段指出并调整交付范围,不能在实现中静默降级。 ## 5. 功能需求 FR-01~06、FR-08、FR-10、FR-11、FR-14 和 FR-09 中的页面/OCR 基础为 P0;其中描述模型操作的条款到 P3 才生效。FR-13 是用户追加的当前阅读扩展。FR-07、FR-09 的模型读取/发送策略及第 7、8 节的会话/工具要求为 P3。FR-12 的 PDF 书签为 P1。P3 条款保留设计,不要求首版界面暴露入口。 ### FR-01:安装与 Sidebar 接入 插件可以作为一个独立 bundle 安装到指定 profile,并通过标准插件管理方式启用和停用。Web 和 Desktop 的 Sidebar 接入采用同一套插件能力。 启用后,PDF 的默认文档渲染器优先选择插件,宿主原有 PDF 预览器仍作为可选实现存在。停用后,宿主正常处理 PDF,已保存的文件保持可读。 打开多个不同 PDF 时,每份文档具有独立身份。同一会话从不同入口打开同一文件时,共享工作副本,避免两个 tab 保存相互覆盖。 ### FR-02:阅读与定位 查看器显示文件名、物理页码/总页数、当前缩放、加载状态和保存状态。PDF 自带页标签存在时,同时显示标签,所有工具调用仍使用物理页码。 页面按需要加载和绘制。切换页面、缩放或旋转不会丢失标注及选区定位。旋转是显示偏好,不修改源文件的页面方向。 搜索返回页码、原文片段和位置。文字不存在、文字编码异常或阅读顺序不确定时,结果需说明限制,并允许查看对应页面图像。 查看器应正确处理非零页面裁剪原点、不同尺寸页面和页面旋转;标注和选区不能因缩放、显示旋转或高 DPI 屏幕而偏移。 PDF 内容区和右侧功能视图各自滚动;滚动条作为浮层显示,不占用布局宽度。滚动、悬停、拖动或键盘聚焦滚动条时保持可见,停止滚动且未悬停或聚焦时自动隐藏。支持滑块拖动、轨道点击和键盘滚动。 在左侧 PDF 内容区按住 Ctrl 滚动鼠标滚轮进行文档缩放,缩放围绕鼠标所在的页面位置,范围为 10%~500%,当前比例同步到顶部缩放控件;该手势更新 PDF 比例而非浏览器页面比例。普通滚轮仍用于滚动。右侧阅读辅助栏和输入框不拦截此手势;缩放属于阅读状态,不建立跳转返回记录,也不修改 PDF。 ### FR-03:文字及区域选择 用户可以选择单词、跨行段落和跨页文字。选中文字按照实际被选择的片段生成,不用一个大矩形把栏间、页眉或未选择内容一起提取。 默认始终为文字选择。选中文字后,在选区附近显示浮动工具条,提供复制、高亮、下划线、删除线及便笺动作;固定顶部不放置文字选区操作。工具条随滚动与缩放保持对应位置,不挤动正文。 点击页面、查看器空白或查看器外部时清除当前选区、标注选择和未提交便笺编辑;点击操作按钮、批注输入框或拖动选择文字不被当作空白点击。清理浏览器选区只影响该 PDF,不清除其他 PDF 或会话的选择。 对于扫描页、公式、表格、图表以及无法可靠提取文字的内容,用户通过“工具 → 区域截图”显式启用一次框选,在单页内拖出矩形后生成预览,并自动恢复文字选择;可随时取消。P0 预览提供复制图片、下载 PNG 和区域 OCR。P3 再增加解读、翻译和加入输入框;图像与 OCR 的选择遵循 FR-09。 P0 支持整页绘制与识别本页文字。P3 每页增加“解读本页”“翻译本页”“加入输入框”,范围是该物理页完整可见范围,不要求先滚动至页底或框出整页;按钮显示实际页码,不把多页默默当作一页。跨页文字选择保留原有行为;首版矩形区域限定在单页。 整页或区域图像由 PDF 工作副本按需绘制生成。它不依赖屏幕截图,不包含 Sidebar、工具栏、鼠标、选区边框或其他会话的内容,清晰度不受 Sidebar 宽度和当前显示缩放限制。用户预览图像后可调整范围或取消;创建选区和预览不会自动提交模型请求。 无可用文字层时,查看器保留页面阅读和区域选择能力,显示“未发现可用文字,可识别本页文字”。用户按需执行 OCR 后,可在识别成功的范围内选择文字;不以整个文档是否为扫描版作为唯一判断。 选区预览显示原文或区域图像、文件名、页码及是否包含多页,用户可以清除选区。工具栏点击不会意外丢失已经捕获的选区。 跨页文字选区以一个用户动作提交,但保留每页各自的文字片段和几何位置。旋转或倾斜文字需要保留文字标记的几何信息,不能仅存一个包围所有内容的大矩形。 ### FR-04:已有标注识别和兼容 首版必须识别并显示原生 Highlight、Underline、StrikeOut 和 Text 便笺,包括位置、颜色、批注正文、作者、创建时间和修改时间;源文件没有提供的字段显示为缺失,不推测。 标注列表支持按页定位和选择标注。选中一条标注可以跳到对应页面、显示其批注,并在可能时提取其覆盖的原文;无法恢复原文时仍显示批注及区域图像。 用户也可以直接点击页面上的原生标注选中,并通过浮动工具栏修改颜色、删除或编辑批注。点击命中按各行四边形计算,不覆盖正常拖动或双击选字。标注列表和批注编辑放入右侧阅读辅助栏;切换辅助栏功能时不改变左侧 PDF 内容区宽度。创建和修改时间解析 PDF 日期格式,按本地时区显示。 内部和外部 PDF 链接悬停时仅将鼠标指针改为手形,不绘制链接框、按钮或悬浮面板。链接点击采用被动坐标检测,链接文字仍可拖选;双击选词取消待执行的单击跳转。 支持的已有标注与新标注使用相同的编辑入口。批注含中文、换行和 Unicode 字符时,保存后应能正确重读。 对墨迹、印章、形状、回复链、附件、表单等首版不编辑的对象,优先呈现可用外观和信息,并保留原始对象;不能因为解析或编辑能力不足而删除它们。 页面内标记保留可见外观,不能承诺恢复成原生标注。[Adobe 的说明](https://blog.adobe.com/en/publish/2008/01/31/ensuring-the-pdf-comments-get-pr)指出,扁平化后的页面不再包含原先独立的评论对象。插件不把视觉上的颜色块直接判定为可编辑高亮,也不能把“没有可识别标注”解释为“文件从未被修改”。 具有锁定或只读属性的标注显示状态并禁止修改。原有数字签名、加密及文档权限的处理见 FR-08。 ### FR-05:标注编辑 文字选区支持新增高亮、下划线和删除线。标注可以选择颜色并添加批注。区域或页面位置支持新增文字便笺。 新增文字标记在操作提交时立即预览;Host 提交失败时撤回临时预览并显示错误。页面替换在新画布绘制完成后进行,避免编辑时页面闪空。临时预览不代表已经保存到原 PDF。 支持修改批注正文、修改颜色、删除标注。首版不要求拖动已有标注来重新定位;重新标记可通过删除和新增完成。 用户可以撤销或重做尚未保存的标注操作。跨页标注作为一个撤销单位处理;P3 模型提交的一批标注变更也作为一个单位处理。 P3 用户和模型操作同一份工作副本。模型修改成功后,页面外观、标注列表、工作修订号和未保存状态同时更新。失败的批次不留下部分修改。 P3 模型回复默认显示在当前会话中。只有用户明确要求或执行“写入批注”动作时,回复才成为 PDF 批注。 基于 OCR 文字创建的高亮、下划线和删除线使用识别文字映射回 PDF 页面的位置;识别文字和定位不可靠时提示用户核对,可改用区域便笺。保存这些标注不意味着同时向扫描页写入隐藏文字层。 ### FR-06:手动保存、另存为与冲突 所有成功的标注编辑先更新工作副本,文件状态变为“未保存”。新增标注和编辑批注不隐式写回源文件;P3 模型修改遵循同一规则。 “保存”将当前工作副本提交到已打开的文件;“另存为”提交到明确的目标路径,保留原文件,成功后让当前工作副本绑定到新文件。 保存前检查源文件版本。文件被外部程序修改、替换或删除时,保存失败并进入冲突状态。保留当前工作副本,提供“另存为”或“重新加载源文件”的动作;重新加载必须说明将丢弃当前草稿。首版不要求自动合并外部修改。 另存为不能静默覆盖已经存在的目标文件。UI 采用明确的替换动作;P3 模型调用必须显式声明覆盖意图,并符合宿主的文件操作权限。 同一工作副本的保存和修改按明确顺序处理。保存完成后,只把实际保存的修订标为已保存;保存期间产生的更新仍为未保存。 写入必须完整提交,失败不得留下半份 PDF。保存成功须返回新的文件版本和被提交的工作修订号,重新读取后确认可解析,再显示成功;无法确认提交结果时显示“保存结果待核实”,不能错误显示为已保存或盲目重复写入。 保存保留未修改的页面内容、支持的已有标注和可保留的其他对象,不把整份文件重新打印或栅格化成图片。保存前后文件字节可以不同,验收关注内容、外观和标注语义。 提供“丢弃全部修改”按钮,一次点击立即恢复到上次成功保存或首次打开的基线,清空撤销/重做及持久化草稿,同时清除未提交的便笺和批注编辑,不再要求确认。源文件被移走或删除时仍可丢弃,丢弃操作不向源文件写入。 用户切换当前会话时关闭旧会话的 PDF tab,直接删除相应工作副本和草稿;打开、修改或保存请求与丢弃按资源授权会话顺序处理,迟到的打开响应不得恢复被丢弃的修改,快速切回也必须先等旧清理完成。显示设置等全局面板不等于切换当前会话。后台及浮窗中已接管的 PDF tab 同样关闭;尚未挂载的恢复标签若没有旧 Sidebar 可执行关闭,则保留精确关闭任务,在原 Sidebar/阅读器下一次挂载时完成,避免误关后来新建的标签。 同一会话内手动关闭 PDF tab、断开客户端连接或重启仍可从插件存储恢复未保存草稿。恢复时重新验证源文件版本;版本不同显示冲突,不能直接覆盖。切换会话和显式丢弃均不再保留对应草稿。 撤销/重做是工作副本编辑历史。保存成功后清空这段历史并建立新的已保存基线,避免“撤销”被误认为已经回滚磁盘上的文件。 ### FR-07:选区与当前会话交互(P3) 用户主动发送文字、区域和整页,以及会话中的解读/翻译在 P3 交付。独立选区翻译另按 FR-13 提前提供,不属于向会话发送内容。 选区提供三个入口: | 动作 | 行为 | | --- | --- | | 加入输入框 | 将选区引用和内容加入当前草稿,保留已有输入,用户自行补充问题并发送。 | | 解读 | 将选区快照和解读请求提交到当前会话。 | | 翻译 | 将选区快照、明确的目标语言和翻译请求提交到当前会话。 | 这些动作同时适用于文字选区、区域和整页。对于区域或整页,“解读/翻译”按 FR-09 选择可用读取方式;“加入输入框”显示文字或图像附件预览及来源标签,供用户决定何时提交。若需要 OCR,应显示识别进度并保留用户原来的问题;识别或提交失败不丢弃选区。 P3 翻译默认目标语言建议为简体中文,入口应展示目标语言并允许修改;这个默认值是待评审的产品选择,不依赖界面语言暗中推断。 点击动作时捕获目标会话。发送期间切换到另一会话,不能把内容转发给新会话。多个 Sidebar、PDF tab 或并行会话也不能混用文档及选区。 当前会话正在运行时,解读/翻译采用宿主的排队机制;默认不打断模型。提交失败显示原因,并保留选区及用户输入。客户端重复操作或重试不应产生重复消息;具体去重方式由 API 设计规定。 发送内容包含足够的原文或区域图像。插件不能仅向模型发送文件路径并声称“已发送选区”,也不能只在浏览器内存中保存模型已经看到的内容。 已发送选区作为历史快照保留;文档之后修改或移动时,会话中的原文不变。后续工具读取当前文档时返回当前版本,并说明它和引用快照是否一致。 发送前展示实际内容范围。超过输出或附件限额时明确提示,允许缩小选区或分段发送;不能静默发送半段原文或宣称已经发送整份选区。 选区来源作为用户提供的文档内容处理。文档内出现的命令、系统提示或工具调用文本不成为插件指令;打开文档和创建选区也不会自动发起模型请求。 ### FR-08:不可编辑或读取失败的文档 损坏文件、解析失败、文件过大和提供方访问失败需显示明确原因,并提供重试入口。失败结果不会被当作空白文档或空文本。 首版遇到需要密码的 PDF,显示“需要密码”状态,不要求用户把密码发到模型会话。交互式解锁和加密文件保存属于后续设计范围。 允许直接打开、无需输入密码的加密 PDF 使用 PDF.js 只读兼容方式加载,保留页面、文字层、跳转和原有标注的查看能力。界面明确显示只读原因,禁止标注修改、保存和另存为;不将原始密文交给不支持解密的编辑引擎重写。 包含数字签名的文件在能够读取时可以预览;发送选区在 P3 提供;首版不提供会使原文件签名失效的写回。编辑能力显示为受限,不能在另存为时宣称签名仍有效。 文件提供方只支持读取,或者当前会话不允许目标路径写入时,阅读功能仍可用,保存入口明确说明受限。模型工具也返回同样的限制,插件不能把权限不足解释为需要修改宿主源码。 ### FR-09:页内容、扫描页与混合页读取(共同基础 P0;模型交互 P3) #### 9.1 同一页的三个视角(P0 基础) “一页的内容”包括完整可见页范围内的内容及关联的标注。以下视角共享页码、页面几何位置和工作副本版本: | 视角 | 包含内容 | 限制 | | --- | --- | --- | | 可提取文字 | PDF 现有文字及按需产生的 OCR 文字块;保留位置和来源。 | 不代表图片、布局、曲线和图表含义已被读取;阅读顺序可能不确定。 | | 页面图像 | 页面中的文字、扫描图像、图片、矢量绘图、表格、公式及可见标注的合成外观。 | 接收图像不保证模型准确理解;低分辨率下可能需要继续读取局部。 | | 标注信息 | 原生标注身份、位置、颜色、批注正文,以及当前工作副本中的修改。 | 批注正文不一定显示在页面图像中,需单独提供;页面内标记仍按页面内容处理。 | 页面图像是按 PDF 页范围绘制的合成结果。不能仅提取 PDF 内部的图片对象来代表整页或一幅完整图,因为图的文字、坐标轴或其他部分可能由不同对象共同组成。图片/图表区域索引是定位辅助,首版不承诺自动准确识别全部图表边界。 页面摘要分别说明文字提取状态、可见内容检测结果和 OCR 状态。无文字不等于空白页;有文字不等于文字覆盖整页;未检测出图片对象不等于没有图形。无法可靠判断时返回未知或疑似,不伪装成已验证结论。每页独立判断,同一份文档可以同时有正文页、扫描页和混合页。 #### 9.2 自然的读取与发送策略(P3) 本小节涉及会话提交及模型输入能力,仅在 P3 生效。P0 使用同一套文字、渲染和 OCR 基础供用户阅读及编辑,不调用模型、不发送附件。 插件提供“自动、文字、页面图像”读取方式;自动是整页/区域解读的建议默认值。文字选区优先使用实际选中文字,并允许附带对应图像。对整个页面发起“阅读/解读”时,模型工具与 UI 使用相同策略: | 页面情况 | 当前模型明确支持图像 | 当前模型不支持图像或能力未知 | | --- | --- | --- | | 普通文字页 | 整页/区域图像,并附带范围内可用文字,方便理解布局和核对原文;显式文字方式可仅取文字。 | 提取原有文字,报告实际文字范围;不能声称已观察页面外观。 | | 无可用文字的扫描页 | 提供整页/区域图像;不必先 OCR,用户或模型仍可另外请求 OCR。 | 使用已配置的 OCR 获取文字;无 OCR 提供方或识别失败时返回不可读取的原因和可用入口。 | | 已带 OCR 文字的扫描页 | 提供图像并附带已有文字;文字可能来自原文件中的识别结果,来源能确定时标出,不能确定时不猜测。 | 先读取已有文字;结果异常或用户要求重识别时执行 OCR,提示现有文字不保证准确。 | | 正文加图片/图表/公式的混合页 | 提供页面图像和可用文字,支持按位置继续读取图表局部。 | 返回原有文字;按需 OCR 补充视觉区域内的文字,明确图像和图表关系尚未理解,不能声称整页已完整解读。 | 自动方式在支持图像时,整页/区域读取始终提供该范围的图像,不根据“文字很多”就跳过图像。调用方可以显式选择文字方式节省上下文,但工具结果必须标明这是文字读取。按需读取可以只读一页或一个区域;打开文件不自动读取所有页。 图像能力查询以当前执行路线的精确 provider/model 为准,使用宿主的输入模态声明。显式包含 image 才向模型提供图像块;未包含 image 和能力未知分别说明。能力来自目录/适配器/配置,不是实际视觉理解能力的测试。发送或工具执行时重新检查,不能仅使用打开文档时缓存的能力;不自动替用户切换模型。 模型不支持图像时,用户仍能在查看器中查看、选取和生成图像。禁用的是直接交给该模型解读的动作;仍可识别文字或选择其他模型。对于没有可提取文字、也没有可用 OCR 的范围,保留选区并给出原因,不能把空内容当成成功发送。 #### 9.3 OCR 的功能边界(P0;模型入口 P3) P0 按需识别单页或单页区域,由用户“识别文字”触发;P3 再增加自动发送策略或模型 OCR 工具入口;不因打开文件自动 OCR 整份文档。各入口调用统一 OCR 功能,由设置选中的引擎实例执行。当前实现默认 NoneOCR,用户配置后可选择 LocalOCR 或已安装的厂商引擎。外部 OCR 需要明确配置和启用,是否调用及失败原因可见。 OCR 的输入是明确版本的页面/区域图像。默认识别页面基础内容,避免新建高亮、选区边框和便笺遮挡原文;已经扁平化进页面的标记无法以此方式去除。视觉解读默认包含工作副本的可见标注,结果须说明实际是否包含标注;批注正文另外提供。OCR 与视觉读取的不同标注策略须在预览和结果中可查。 OCR 返回原文、文字块/行/词的位置及来源;引擎提供置信信息时保留其原始语义,不提供时标为未知。低可信或无法识别的范围明确标记。OCR 文字和原有文字在重叠区域按来源关联,避免简单拼接造成重复;发现冲突时保留差异供核对,不默默改写原文。 识别结果可以形成查看器中的选择层和搜索索引,并被模型继续读取。它属于插件派生缓存,不改变 PDF 源文件、不产生未保存标注状态,也不因为“保存标注”而写入隐藏文字层。重载源文件后检查缓存版本;OCR 位置仍须映射到原始页面坐标,不能随显示缩放漂移。 OCR 支持进度、取消和明确的失败状态。只完成部分区域时报告覆盖范围;结果过长时提供游标,不静默丢字。原有文字和 OCR 结果均不擅自替用户修正原文;模型的解读或转写不称为经校验的 OCR 文字层。 #### 9.4 OCR 功能与引擎的解耦契约(P0) PDF 插件拥有 OCR 功能层:确定请求页/区域及版本、生成识别图像、解析所选引擎实例、调度任务、映射坐标、规范化结果、维护派生缓存,并向选择、搜索、标注和模型工具提供结果。P0 查看器和 P3 模型工具只调用这层,不引用某个厂商的 SDK 或识别格式。 引擎只接收约定的图像与识别选项,执行识别并返回约定的结果。它不自行打开任意 PDF、不修改文件、不控制会话、不创建标注,也不决定模型是否具有图像输入能力。引擎可以作为独立子插件或独立包注册;新增厂商实现不要求修改 PDF 功能层或 DSH 源码。 | 引擎 | 行为 | | --- | --- | | NoneOCR | 明确关闭新的 OCR 任务,返回“已关闭”,不返回成功的空文本,不调用本地或外部识别。原文件已有文字仍可读取,视觉模型仍可解读页面图像。 | | LocalOCR | 在宿主允许的运行环境中本地识别;实现自行报告所需依赖、支持语言和可用状态,不暗中改用外部服务。 | | 指定厂商 OCR | 封装该厂商的认证、请求、结果转换和厂商错误;向 PDF 功能层返回统一结果,不暴露厂商格式给查看器或模型工具。 | 注册描述包含引擎身份、显示名称、实现版本、配置/凭据需求和能力,例如语言、位置粒度、置信信息、输入限制及可用状态;不能把引擎列表写成必须逐厂商修改的固定分支。引擎类型与配置实例区分,允许同一实现对应多个配置实例。 统一识别请求包含图像、图像尺寸、语言/识别选项及取消信号;结果包含文字块、位置、可用置信信息、实际识别范围和完成状态。引擎结果使用约定的图像坐标,功能层统一映射到 PDF 页面位置。坐标和粒度不足时声明限制,不能编造词级位置。 关闭、未配置、缺少本地依赖、认证失败、超时、取消、部分完成和识别失败分别表达;识别成功但确无文字是另一个结果。厂商原始错误转换为稳定的功能错误,诊断可以保留必要细节。限额、取消和资源释放遵循统一约束。 任务开始时固定引擎实例及配置快照。运行中切换引擎只影响新任务,旧任务的结果保留原引擎来源,不改名为新引擎的结果;引擎卸载或停用导致无法继续时取消任务并报告。失败不自动切换引擎,尤其不把本地失败隐式转成厂商请求。 缓存和识别结果包含引擎身份/版本、配置与识别选项标识、文档内容版本及区域,不包含明文凭据。切换引擎不会把旧缓存当作新引擎结果;旧结果及已发送快照仍可查看。NoneOCR 下可以明确查看或选择已有识别结果,但不产生新识别任务。 #### 9.5 完整性、图像清晰度与后续读取(基础 P0;模型继续读取 P3) 每次读取结果分别报告请求范围、实际返回范围、文字来源、是否附图、标注处理方式、识别失败/遗漏区域、截断情况和继续读取入口。“已提取所有现有文字”“已提供整页图像”“已 OCR 全页”是不同事实,都不等于内容已被准确理解。 整页图像必须包含完整可见页范围,不能因为页面下半部不在屏幕上而缺失。全页预览不足以辨认小字时,P0 允许用户查看局部高清图像,P3 允许模型按页面坐标继续获取;超长或超大页面可以分块,但须返回各块的位置和明确的缺失/重叠范围,不能只给缩得看不清的图片并声称全文可读。 OCR 仅提供识别文字和定位。纯文字模型可以利用这些文字推理,但不能据此承诺准确理解图像内容、曲线走势、空间关系或复杂公式。需要视觉理解且当前路线无法提供时,明确返回仍缺少的材料。 ### FR-10:DSH 设置中的 PDF 配置卡片(P0) 插件启用后在 DSH 设置中贡献“PDF”入口,在该页显示“PDF 阅读器”配置卡片。接入现有设置分区和配置表单扩展点,配置归属插件在当前 profile 的实例;不要求修改宿主设置页面或建立第二套配置文件。插件停用后入口随注册撤下。 卡片分组呈现以下配置;具体默认值和字段名在 API/配置 SPEC 中确定: | 分组 | 配置与反馈 | | --- | --- | | 阅读 | 显示偏好、页面/区域图像输出限制等阅读配置。 | | 翻译(当前阅读扩展) | 引擎、原文/目标语言和超时;默认 DSH 模型、自动检测、中文、30 秒。NoneTranslation 可关闭此功能。 | | 会话(P3) | P3 再提供默认发送方式 auto/text/visual 及模型能力相关反馈;P0 卡片不展示未交付的会话配置。 | | 标注 | 默认颜色等编辑偏好;标注保存继续采用已确认的手动保存方式。 | | OCR | 所选引擎/实例、识别语言、任务超时与限额;显示已关闭、可用、未配置或依赖/连接失败。 | | 引擎专属配置 | 由所选实现声明的配置,例如本地运行参数、厂商端点/模型/凭据引用;不适用的字段不混在通用 OCR 配置中。 | | 导航 | 返回历史容量等偏好;界面显示有效范围,不要求用户配置才能使用返回功能。 | 引擎选择来自注册目录,包含 NoneOCR、LocalOCR 及已安装的厂商实现。不具备运行条件的引擎显示原因。已保存的实例引用缺失时明确显示不可用,不悄悄改选其他引擎。切换选项时保留其他引擎的配置;删除配置是明确的独立动作。 表单修改先保存在设置草稿,点击“保存配置”后校验并通过宿主设置机制持久化;这与保存 PDF 标注是两个独立动作。“恢复默认”清除对应覆盖,展示恢复的生效值。配置在当前 profile 重启后保留,多个插件实例不共享错误的配置身份。 无效配置不写入。并发修改以设置修订号检查,冲突时保留当前草稿并提示重新读取;设置不可写时显示原因并禁用提交。所有界面读取同一套生效配置,下一次操作读取已接受的新值;已经开始的 OCR 任务保留启动时的快照。 凭据通过宿主的凭据机制及秘密字段策略处理;读取设置时仅显示是否配置和引用,不回传密钥明文,也不把密钥写入 PDF 或会话。编辑普通字段不覆盖未返回的秘密值。 卡片提供显式“检查引擎”动作。检查当前配置和所需依赖;需要实际识别请求时使用说明清楚的固定样本,不自动上传当前 PDF。打开设置和编辑字段不会启动识别任务。检查成功只代表引擎可用,不声称识别所有文档都会成功。 ### FR-11:PDF 跳转与返回栈(P0) 查看器支持同一 PDF 内的页目标和命名目标,解析到具体页面位置及目标指定的视图方式。页内远距离跳转也属于跳转;外部网址或其他文档交给宿主现有入口处理,首版不建立跨文件的返回栈。 每次成功的显式离散跳转之前,记录跳转发起时的原阅读位置。P0 内部链接、搜索结果、输入页码和标注列表定位采用同一导航操作;P1 书签定位、P3 用户点击模型引用随后复用该操作。普通连续滚动、缩放、显示旋转及上一页/下一页的线性阅读不入栈。 返回位置包含文档内容版本、物理页码、页面内锚点、缩放/适应模式、显示旋转和必要的连续滚动视图信息。使用页面坐标及视图状态恢复,不仅保存页码或浏览器像素偏移。调整窗口尺寸后仍应回到原阅读内容附近;不能把第 5 页页底的原位置恢复成第 5 页页顶。 跳转形成后进先出的返回栈。例如 A → B → C:进入 B 前记录 A;在 B 阅读、滚动后进入 C 前记录 B 当时的位置;点击返回依次恢复 B 和 A。返回动作本身不再次入栈,普通滚动也不把阅读路径填满。首版要求返回,不要求前进历史。 工具栏提供“返回上一跳”按钮,提示可返回的页码;空栈时禁用。返回操作与标注撤销分别呈现,不混用撤销历史或浏览器后退。快捷键可以通过宿主快捷键体系提供,具体绑定后续确定。 无效链接、跳转失败和没有实际位置变化的动作不入栈。原位置先捕获,仅在目标成功生效后提交栈记录;异步跳转按导航操作顺序处理,不能把已取消的目标补记为成功。返回失败时保留该记录并说明原因,不静默丢掉未成功恢复的位置。 返回栈属于某个 PDF tab 的阅读视图。不同文档、不同会话和同一文件的多个 tab 各自维护栈;它们可以共享工作副本,但不共享浏览位置。正常标注编辑和保存不清空导航记录。源文档内容重新加载且发生变化时清空旧位置历史并提示,不能把旧页坐标当作已核实位置。 后台 OCR 不自动移动用户视图或增加返回记录。P3 模型读取、OCR 和创建标注同样不改变视图;用户点击工具结果/模型引用定位时才记录跳转。跳转和返回不修改 PDF、不改变未保存状态、不自动向模型发送内容。首版不要求关闭 tab 或重启后恢复返回栈。 ### FR-12:PDF 书签(P1) 提供已有 PDF 书签的列表和目标定位,区分显示名称与实际目标;不能访问或无法解析的目标显示原因。书签点击复用 P0 导航及返回栈,支持回到点击之前的阅读位置。 P1 书签管理建议包含新建、改名和删除。新建时捕获文档身份、物理页、页内位置和必要的视图方式;书签是可长期保存的位置,与临时的跳转返回记录分别管理。 已有 PDF 原生书签与插件创建的书签应明确来源。新建/修改是否写入 PDF 原生目录,或保存为插件数据,在 P1 的技术设计中确定;界面明确保存位置和生效范围,不宣称插件数据已嵌入 PDF。不将删除插件书签等同于删除源文件的书签。 书签持久化和版本变化后的目标有效性需要明确契约;重开后仍能按所选存储方式恢复。若写入 PDF,遵循手动保存、权限、签名和冲突规则;若保存为插件数据,不假装 PDF 因此已被修改。以上管理细节为设计建议,具体范围在 P1 开始前评审。 ### FR-13:独立选区翻译与原生词典查询(用户追加) 选中文字后,浮动工具条提供“翻译”。统一翻译功能与具体引擎分离,支持 NoneTranslation、DSH 模型和后续厂商或本地实现。设置卡片配置引擎、原文语言、目标语言与超时;默认采用 PDF 所属会话的 DSH 模型、自动检测原文、译成中文、30 秒超时。 只提交当前选中文字,不附带聊天上下文,不注册模型 PDF 工具,不向会话消息或日志追加原文、请求或译文。结果在右侧阅读辅助栏的翻译视图显示,包含原文、页码、引擎和完整/部分状态,支持取消、重试、切换目标语言后再次翻译和复制。 单次输入限制为 8192 个 UTF-16 字符、统一输出限制为 32768 个字符;DSH 模型实现输出上限为 4096 tokens。超限输入明确报错,不静默截断;输出截断保留部分译文并提示未完成。明确关闭译文、切换文档或配置变化取消旧请求,迟到结果不能替换新选区;切换到其他右栏视图或折叠阅读辅助栏保留翻译状态,正在执行的翻译继续运行。翻译不改变 PDF 或保存状态,缺少模型服务不妨碍阅读与编辑。 “查询”仅针对 macOS,必须调用选区旁的系统词典浮窗。其他平台不显示。按钮依据真实原生桥接能力启用,保持真实 DOM 选区供宿主查询;没有桥接时禁用并说明原因。当前 DSH 0.2.0-rc.1 未提供此主窗口插件接口,在不修改宿主源码的约束下实际浮窗功能仍受阻,只有能力注册层已实现。 ### FR-14:紧凑工具栏与右侧阅读辅助栏(已实现,待交互验收) 插件内部顶部仅有一行固定工具栏,合并阅读导航与文档操作:返回、上一页/下一页、页码、比例/适应宽度、旋转,以及工具、撤销/重做、保存、另存为和丢弃全部修改。左侧工具菜单和右侧保存状态常驻;中间导航与文档操作在窄宽度下横向滚动,不叠出第二条固定操作栏,工具菜单不会被横向滚动区裁切。 删除插件底部重复的文件路径和“重新加载”栏,文件路径继续使用宿主已提供的文档头部。重新加载保留在工具菜单中,并继续遵循冲突与丢弃提示规则。 主区域分为两栏:左边是独立滚动的 PDF 内容区;右边是阅读辅助内容区,最右侧保留竖向功能入口。默认展开标注视图,参考宽度为 320 像素,窄窗口按可用空间限制宽度,折叠后只保留 44 像素入口栏。辅助栏可拖动分隔线调宽,也支持聚焦分隔线后用左右方向键及 Home/End 调整;功能入口支持上下方向键及 Home/End 切换。展开、折叠或用户调整宽度后,“适应宽度”根据实际 PDF 内容区重新计算,并保持当前页内阅读位置,不记录为跳转。翻译、标注、便笺和搜索共用辅助内容区,一次展示一种视图,切换视图不改变 PDF 可用宽度。 | 右栏视图 | 用途与入口 | | --- | --- | | 标注 | 默认视图;列出受支持的文字标记及批注,定位原文、修改颜色/正文或删除;`Text` 便笺集中在便笺视图。 | | 便笺 | `Text` 原生标注的快捷视图;复用标注身份、编辑和手动保存规则,不创建独立笔记存储。 | | 翻译 | 选区工具条的“翻译”自动进入该视图;保留原文、结果与翻译操作,尚未选择文字时提示先选择。 | | 搜索 | 集中搜索输入、覆盖说明和定位结果;点击结果仍使用阅读跳转及返回栈。 | | 书签 | 预留 P1 入口,当前禁用并显示未实现原因;不以占位入口表示书签能力已交付。 | 文字和标注的就近工具条继续显示在 PDF 内。右栏承载较长的结果、列表和批注正文编辑;空白点击仅清理上下文选择与未提交编辑,不删除已经提交的标注、译文或搜索结果。 右栏各视图保留挂载,切换视图或折叠辅助栏不清空翻译结果、取消进行中的翻译或删除搜索结果。用户通过明确关闭译文/取消操作结束请求,文档及翻译配置变化继续执行 FR-13 的取消规则。 ## 6. 状态与会话归属 文档内容状态与模型是否正在运行分别管理。建议使用以下文档状态: | 状态 | 用户可见行为 | | --- | --- | | 加载中 | 显示进度或加载反馈,允许取消。 | | 已加载且已保存 | 可以阅读、选择和编辑;保存按钮无待提交修改。 | | 已加载且未保存 | 页面展示工作副本并显示未保存标记。 | | 保存中 | 显示提交反馈,防止重复提交;保留当前可见内容。 | | 版本冲突 | 保留草稿,禁止静默覆盖,提供恢复路径。 | | 受限 | 显示文档可执行的操作及具体限制。 | | 失败 | 显示原因,允许重试,不丢弃已有草稿。 | 同一会话的同一文件共享工作副本;不同会话分别持有草稿。不同会话保存同一源文件通过版本检查解决竞争。工具不能通过一个会话的句柄访问另一个会话的草稿。 Sidebar 的当前页面、缩放、选区和跳转返回栈是阅读状态;不会仅因为用户滚动或跳转页面而增加模型上下文。打开文件也不会自动把整份 PDF 注入会话。OCR 引擎选择属于插件实例配置,不属于某一 PDF 工作副本;识别任务和缓存则保留明确的文档、引擎及版本来源。 ## 7. 精确引用要求(P3;位置与版本基础由 P0 复用) 本节关于发送快照、会话历史和模型引用的要求在 P3 验收。P0 仍使用相同的页面坐标和版本原则定位标注、OCR 及跳转。 所有可用于后续模型读取的引用至少包含:文档身份、来源路径、源文件版本、工作修订号、物理页码、位置及已发送内容快照。 文字选区还需要每页的原文片段和文字块/字符范围信息,并标明原有文字或 OCR 来源;区域选区还需要区域图像及其对应的页面位置;整页图像引用包含完整可见页范围;标注引用还需要标注身份和批注文本。OCR 引用额外保留识别结果版本及可用的置信信息;重新 OCR 不替换已发送快照。 几何位置采用 PDF 页面的原始坐标体系,并携带可见页范围和旋转信息。客户端像素坐标只能作为临时交互数据,不作为持久引用。坐标单位、字符偏移单位及四边形顺序必须在 API SPEC 中明确定义。 模型引用能够定位到页面及区域。若源文件版本仍可用,点击引用可以跳回原位置;若文件变化,显示旧版本提示并允许查看引用快照,不能把新页面中的相同坐标当成已验证的原文。 选区快照及附图通过宿主现有的消息/附件机制进入会话日志,确保恢复会话后仍能重现模型收到的材料。插件可以维护自己的草稿及索引,但不在宿主会话中写入未声明的事件类型。 ## 8. 模型工具能力草案(P3) 这些工具在 P3 才向模型注册。P0 可以复用对应的内部文档操作,但不需要实现或暴露模型工具入口,也不以模型调用作为首版验收路径。 下面的工具名和字段用于功能设计,不是已实现或已经冻结的 API。后续 API SPEC 可以合并工具,但须保留这些能力。 | 能力草案 | 主要输入 | 主要输出或效果 | | --- | --- | --- | | `pdf_open` | 明确路径 | 会话内文档句柄、源版本、工作修订号、页数、可用能力和限制。 | | `pdf_read` | 文档句柄;页范围、区域、选区引用或文字块范围之一;auto/text/visual 方式;输出限额/游标 | 按 FR-09 返回文字、页面图像及相关标注;标明来源、覆盖范围、未读取的内容、版本和继续读取信息。 | | `pdf_search` | 文档句柄、查询及可选页范围、游标 | 原有文字/已识别 OCR 文字中的匹配、来源和位置;搜索实际覆盖页及未识别范围;总量或截断标识。 | | `pdf_render` | 文档句柄、物理页码、可选区域、清晰度/图像限额、标注策略 | 完整页或局部合成图像、实际尺寸、页面坐标、版本及继续放大读取信息;进入模型前检查图像能力。 | | `pdf_ocr` | 文档句柄、物理页码、可选区域、识别语言/选项、输出限额 | 经统一 OCR 功能调用当前配置引擎;返回文字块、位置、引擎来源、可用置信信息、识别范围及失败区域;NoneOCR 明确返回已关闭;不要求当前模型具备图像输入能力。 | | `pdf_annotations` | 文档句柄;list/add/update/delete;位置或标注身份 | 标注列表或变更结果,新的工作修订号及未保存状态。 | | `pdf_save` | 文档句柄、预期工作修订号、保存/另存为目标和覆盖意图 | 提交的修订号、新源版本、路径或明确的冲突/权限结果。 | | `pdf_status` | 文档句柄 | 当前路径、版本、未保存状态、能力限制和恢复状态。 | 工具共同要求: - 调用必须明确指定文档,不根据“用户现在聚焦的 tab”隐式选择文件。 - 修改须提供预期工作修订号;陈旧修订拒绝修改,并告知如何重新读取。保存同时验证源文件版本。 - `pdf_read` 可以从局部游标继续读取同一页,不因输出截断而跳过页面剩余内容。 - 搜索必须覆盖组合后的连续文本,而不只逐个 PDF 内部文字对象匹配,以便找到跨文字块的词句。 - 输出有可配置的页数、文字量、结果数或图像大小上限,并明确说明实际范围及是否完整。 - 无文字层、区域没有文字、无法可靠排序和读取失败是不同结果,不能合并成同一个空字符串。页摘要也不能仅根据文字长度断言扫描页、空白页或完整可读。 - 图像工具和整页/区域发送遵循当前精确模型路线的图像输入能力;区分支持、不支持和未知。执行时重新检查;无法输入图像时说明原因,不把传输成功等同于模型可以理解图像。 - 读取分清文字、视觉和标注的实际覆盖范围。图像不足以辨认或只进行了 OCR 时明确限制,提供局部继续读取或其他方式;纯文字输出不被标为整页视觉阅读成功。 - OCR 结果必须带来源和位置;OCR 任务与分页搜索报告未识别范围。识别完成不隐式修改 PDF,不把模型转写结果伪装成原有文字。工具不绕过设置自选另一厂商、不更改 OCR 配置、不隐式切换引擎。 - 工具读取不自动改变阅读视图。返回栈仅由成功的用户导航动作产生;查看器的后退不等同于模型上下文回退。 - UI 和模型工具调用同一组文档操作,权限、冲突判断和失败语义一致。 - 模型创建标注默认只改变工作副本;只有明确调用保存工具才写入文件。 - 工具结果和会话中的可见引用使用能被宿主正常记录与重放的消息及附件;读取内容不依赖隐蔽内存注入。 - 取消读取或绘制应释放资源。修改批次提交前取消不留下半批变更;持久保存提交之后的取消不得把已提交结果伪装成未发生。 ## 9. 质量要求 **文件兼容性**:保存后的 PDF 能在其他阅读器中继续选择文字、查看并编辑支持的原生标注。未参与本次编辑的页面内容和标注外观不能发生可见退化。首版不承诺保存后仍满足所有 PDF/A、PDF/UA 等专门格式认证。 **可恢复性**:草稿与 PDF 源文件分开保存。草稿、索引和渲染缓存不是会话历史的替代品。工作副本与源文件版本不一致时先处理冲突。 **会话隔离**:工具句柄、草稿、选区及发送目标具有明确归属。文件路径相对哪个工作区解析须明确,不能把地址里的原会话与发送目标会话混为一谈。跨会话文件引用的访问规则需在技术设计中进一步明确。 **性能**:可见页优先,长文档不一次性绘制全部页面;读取、搜索、绘制和保存可取消。当前仍为每页保留布局占位及文档几何,不是所有页都常驻画布或文字层。默认文件上限为 64 MiB,可在 1~256 MiB 内配置;响应时间指标须在测量代表样本后确定,不把未测量的数字作为性能承诺。 已完成的源码优化包括:当前页滚动定位由 O(P) 扫描变为每帧合并后的 O(log P) 二分;标注/链接命中使用近页有界索引;文字选区只遍历相关边界范围并在线合并几何;批量删除由 O(D×A) 改为 O(A+D);历史未命中时从有效检查点回放;复用页面组件、OCR 几何和相同摘要的内容。渲染历史缓存总量上限为 32 MiB,每文档最多三个状态,远页释放命中索引。具体最坏情形、空间边界和审查记录见 [PERFORMANCE.md](./PERFORMANCE.md)。 **尚存性能成本**:普通标注编辑仍由 pdf-lib 完整解析当前文件、修改和序列化,再由 PDF.js 加载新字节并绘制近页;保存仍有完整磁盘写入、版本检查和提交校验。当前实现没有将普通编辑变成只返回标注差量,后续优化需同时保证原生外观、标注身份、撤销、草稿提交、截图和 OCR 的一致性。 **使用体验**:中文和英文界面文案、宿主明暗主题、清晰的禁用原因、键盘可访问的主要操作。颜色选择不能成为辨识标注类型的唯一方式。 **隐私与执行**:读取和标注默认在提供方允许的环境中完成;打开、滚动和选区预览不上传内容。当前独立翻译只在用户点击翻译时向所选引擎提交选中文字;P3 用户明确发送或会话中获授权的工具读取只提交请求范围。外部 OCR 提供方须明确配置和启用,仅按需处理请求范围。PDF 内的脚本、启动动作和外部引用不能因打开或解析而执行。文件写入服从当前会话和提供方的权限。 ## 10. 分阶段验收用例 ### 10.1 P0:阅读、编辑、跳转及共同基础 | 编号 | 场景 | 验收结果 | | --- | --- | --- | | AC-01 | 独立安装、启用、停用 | 插件可通过 bundle 接入 Sidebar;宿主源码、默认配置和锁文件无需修改;停用后宿主 PDF 预览恢复可用。 | | AC-02 | 打开其他阅读器标注的 PDF | 高亮、下划线、删除线、便笺的外观及信息正确,点击列表可定位并返回。 | | AC-03 | 保存首版不编辑的对象 | 墨迹、印章等对象仍存在,并能在外部阅读器查看。 | | AC-04 | 新增和修改标注 | 界面即时展示,标为未保存;源文件在保存前保持原版本。 | | AC-05 | 跨行、跨页和多栏选区 | 选区文字与实际选择一致,保留逐页位置;标注不混入未选择的另一栏。 | | AC-06 | 缩放、旋转和裁剪原点 | 选区与标注跟随内容;保存重开后位置一致。 | | AC-09 | 无文字层的扫描件 | 可预览、框选、按需 OCR、选择识别文字并标注;OCR 不可用时显示原因,不把页面当作空白。 | | AC-13 | 手动保存与另存为 | 外部阅读器可重开并编辑标注;另存为保留源文件;目标覆盖需明确意图。 | | AC-14 | 外部修改及多会话保存竞争 | 旧版本不覆盖新文件;草稿仍在,可另存为或明确丢弃后重载。 | | AC-15 | 保存失败及提交期间取消 | 源文件不会成为半份 PDF;状态反映实际提交结果,不盲目重复写入。 | | AC-16 | 关闭 tab、断线或重启 | 未保存草稿可恢复;恢复前重新检查源版本。 | | AC-17 | 权限、加密、签名和损坏限制 | 显示具体原因;不可保存时不报告成功;不通过会话索取密码。 | | AC-18 | 插件卸载和资源清理 | 预览、设置及引擎注册和后台任务结束;已保存文件仍可使用。 | | AC-19 | 页面含图片、矢量图表和公式 | 查看器和整页/区域渲染保留合成外观;文字提取不被标为覆盖全部视觉内容。 | | AC-20 | 页面部分在屏幕之外 | 整页图像仍包含完整可见页范围,不受 Sidebar 宽度、缩放和滚动裁切。 | | AC-21 | 扫描页已有或部分已有 OCR 文字 | 利用已有文字但不保证准确;重识别可查看来源及差异;不以少量文字认定全页可读。 | | AC-22 | OCR 选择、搜索、标注和版本变化 | 文字与位置一致,搜索说明覆盖范围;标注可定位;OCR 本身不写回 PDF;旧缓存不冒充当前原文。 | | AC-23 | 小字和超大页面 | 用户可以放大和查看局部高清图像;分块、超限或失败的范围明确。 | | AC-25 | 批注与未保存高亮 | 界面/渲染体现工作副本标注,批注正文可查看;OCR 默认读取基础内容,实际策略可查。 | | AC-26 | OCR 引擎替换与扩展 | UI 始终调用统一功能;位置和失败语义一致;新增厂商无需改宿主或 PDF 功能流程。 | | AC-27 | 选择 NoneOCR | 不产生新识别请求,显示已关闭;已有文字及页面阅读仍可用;不以空文本报告识别成功。 | | AC-28 | PDF 设置卡片 | 设置中有 PDF 入口和配置卡片;校验/保存/恢复默认正常,重启保留;冲突保留草稿;密钥明文不进入读取响应。 | | AC-29 | OCR 运行中切换或停用引擎 | 新任务使用新配置,旧结果保留旧来源;取消明确;缓存不跨引擎误用,也不自动转用厂商服务。 | | AC-30 | 正文 → 参考页 → 附录 | 返回依次恢复参考页跳转前位置和正文原位置,包括页内锚点与视图状态;返回不再次入栈。 | | AC-31 | 跳转前后滚动、缩放及窗口变化 | 普通阅读不污染栈;再次跳转记录当时的位置;窗口变化后仍回到原内容附近。 | | AC-32 | 无效/取消跳转与返回失败 | 无效目标不入栈;取消不补记;返回失败保留记录;按钮反映实际栈。 | | AC-33 | 多 tab、会话及 OCR | 返回栈隔离;后台识别不移动页面;导航不改变标注草稿。 | | AC-34 | P0 的产品范围 | 完成阅读、编辑、OCR 和返回闭环无需模型;独立选区翻译仅按明确点击调用引擎,不增加会话上下文;没有会话解读/加入会话入口或插件注册的模型 PDF 工具。 | | AC-40 | 点击空白 | 便笺编辑、选区和标注工具条隐藏;已提交标注保留;重新选择和按钮操作正常。 | | AC-41 | 一键丢弃 | 恢复已保存基线,撤销/重做和草稿全部清空,源文件不变;未提交的便笺也关闭。 | | AC-42 | 切换会话及快速切回 | 旧 PDF 关闭且未保存修改丢弃;打开中响应与并行操作不能使旧草稿恢复;设置面板不触发丢弃。 | | AC-43 | 工具栏与布局 | 顶部合并为一行,底部路径/重载栏移除;左右内容区独立滚动,辅助栏可折叠、调宽,并可用键盘操作;切换视图不改变 PDF 内容区宽度,改变宽度时保持页内阅读位置。 | | AC-44 | Ctrl+滚轮缩放 | 只在 PDF 内容区缩放文档,鼠标锚点保持在原内容附近;普通滚轮仍滚动,辅助栏不触发 PDF 缩放;不修改文档或返回栈。 | | AC-45 | 阅读辅助栏 | 翻译、标注、便笺和搜索切换到同一内容区;切换视图和折叠不丢失结果或中断翻译;便笺与对应 Text 标注身份一致,编辑/保存结果一致;书签清楚标为 P1 尚未实现。 | ### 10.2 P1:PDF 书签 下列管理细节为 P1 的设计建议,存储契约在该阶段确定。 | 编号 | 场景 | 验收结果 | | --- | --- | --- | | AC-35 | 已有 PDF 书签 | 展示已有书签及其目标;缺失或无效目标说明原因。 | | AC-36 | 用户管理书签 | 创建、改名和删除书签有明确结果;不误删其他来源的书签。 | | AC-37 | 书签定位及返回 | 定位复用 P0 导航;能够回到点击书签前的阅读位置。 | | AC-38 | 书签持久化 | 按已确定的存储方式保存后重开仍可恢复,并说明书签是文件内容还是插件数据。 | ### 10.3 P3:会话交互与模型工具 | 编号 | 场景 | 验收结果 | | --- | --- | --- | | AC-07 | 选区加入输入框 | 保留原有输入,引用可查看,尚未提交模型请求。 | | AC-08 | 解读/翻译期间切换会话 | 提交到动作开始时的会话;忙碌会话按约定排队;重试不重复提交。 | | AC-10 | 模型精确阅读和搜索 | 按页、区域和文字块读取;跨块词句可找到;截断可无遗漏继续。 | | AC-11 | 模型编辑与人工编辑 | 同一工作副本结果一致;旧修订号被拒绝;界面同步显示模型修改。 | | AC-12 | 模型批次失败或取消 | 未提交批次不部分生效;已提交批次结果明确并可作为一个单位撤销。 | | AC-24 | 模型图像能力及切换 | 发送/执行时检查实际路线,区分支持、不支持和未知;OCR 文字工具不要求视觉能力。 | | AC-39 | 整页/区域发送及历史恢复 | 文字、图像及来源快照进入会话历史;文件变化或重识别不替换旧快照;完整性与图像清晰度限制明确。 | | AC-46 | 工具、导航及插件停用 | 工具读取不移动用户视图;点击引用定位可返回;停用后工具注册撤下,已记录内容仍可重放。 | P0 以 UI 和内部文档操作验收,P1 追加书签验收,P3 再要求 UI 与模型工具使用同一组操作并产生一致结果。标注互操作性需要外部阅读器样本及重开检查,不能仅靠自身写入后读取。P1/P3 用例不作为 P0 发布的前置条件。 ## 11. 已确定契约与后续事项 ### 11.1 当前实现采用的契约 - **接入**:独立 Host / Client bundle,`documentPreviews` 注册 PDF 扩展优先渲染器,`sidebar.right.tab.document` 注册阅读器,`settings.section` 注册 PDF 配置。插件目录与 DSH checkout 分离。 - **文件访问与保存**:只支持宿主本地文件系统,按资源地址携带的会话授权读写,并检查路径、访问策略和符号链接。保存使用同路径队列、源文件摘要校验、同目录临时文件及替换,另存覆盖需明确选择。任意外部进程仍可能在最终摘要检查与替换之间修改文件,普通文件系统不提供跨进程事务保证。 - **工作副本**:Host 维护同一资源会话/路径的共享副本,变更检查工作修订号,按会话串行处理;持久化草稿包含原始字节和分组操作。保存建立新基线;显式丢弃恢复基线而不重写源文件;切换会话删除对应副本与草稿。Client 保存明确的资源会话和标签生命周期。 - **PDF 引擎**:PDF.js 负责阅读、文字层、链接和合成画面,pdf-lib 负责已支持的原生标注。签名文件和无需密码可打开的加密文件只读;需密码文件暂不交互解锁。首版不编辑的对象按原对象保留,互操作仍需代表样本验收。 - **选择和图像**:跨页文字保留逐页几何;一次区域截图后恢复文字模式,按工作副本区域渲染 PNG,包含可见标注及显示旋转。当前截图上限为 2 倍和 1600 万像素,不使用桌面截图。 - **OCR**:公开 `@local/dsh-pdf/ocr` SDK 和 `pdfOcr` Registry,内置 NoneOCR / LocalOCR;LocalOCR 的 Tesseract.js worker、WASM、`eng`/`chi_sim` 随包提供,资源同源加载。结果按图像像素坐标转换为 PDF 坐标,保留引擎、覆盖范围和置信信息;只形成临时文字层。 - **翻译**:公开 `@local/dsh-pdf/translation` SDK 和独立 Registry / Service,内置 NoneTranslation / DSH 模型;经认证 Host 路由只提交选中文字,复用模型凭据,不加入会话历史。默认目标语言中文;模型不可用时阅读与标注仍可用。 - **设置与限额**:ConfigForms 手动保存及恢复默认。默认 NoneOCR、OCR 120 秒、DSH 翻译 30 秒、颜色 `#ffff00`、返回栈 100 项、PDF 64 MiB。选区翻译输入 8192 个 UTF-16 字符,统一输出 32768 字符,DSH 模型输出最多 4096 tokens。 - **导航**:每个 PDF 标签有独立返回栈;成功跳转记录 PDF 坐标与视图状态,普通滚动不入栈,失败或无位移跳转不入栈,返回不重复入栈。内容基线改变时重置相应导航/OCR 状态。 ### 11.2 后续仍需完成或确认 1. **验收与性能**:实际宿主 UI、外部阅读器标注互操作、不同 PDF 样本、取消/冲突/会话切换边界尚未完成完整验收;打开、编辑和保存的实际耗时及内存需测量。普通编辑差量化架构仍为后续优化。 2. **布局交互验收**:FR-14 已实现并通过类型检查、构建;仍需在实际宿主确认窄窗口、辅助栏调宽/折叠、鼠标锚点缩放、键盘操作与后台翻译的交互。不扩大书签功能范围。 3. **读取兼容**:PDF 自带显示页标签、需密码文件交互式解锁、加密保存和远程文件提供方均尚未实现。特殊 PDF、权限、签名与不支持标注继续按明确限制处理。 4. **OCR 扩展**:厂商引擎、专属设置表单与凭据绑定尚未内置;LocalOCR 同源 HTTP / HTTPS 资源方案在自定义 scheme 场景仍需确认。批量 OCR、复杂目录和更多标注类型没有确定交付阶段。 5. **原生词典**:macOS 选区旁词典浮窗需真实宿主原生桥接;当前公开插件接口不能提供,保持未交付状态。 6. **P1 书签**:确认已有/新建书签的来源、存储位置、管理范围、文档变化与手动保存语义,然后实现右栏功能。 7. **P3 会话与模型工具**:明确选区入输入框、消息提交、图像附件与精确引用的公开接口;模型句柄/游标、auto/text/visual 能力判断、输出预算、工具注册/日志、切换会话和重复提交协议仍待设计。 ## 12. 设计依据 功能要求由用户需求和本 SPEC 的设计建议组成。以下宿主文档用于确认接入约束,不表示已经完成运行验证: - [第一个插件](../deepseek-harness/docs/user/develop/basic/index.zh.md):本地插件、依赖注入和 effect 生命周期。 - [打包与安装插件](../deepseek-harness/docs/user/develop/basic/publish.zh.md):独立 bundle、profile、外部 linked package 和 patch 层。 - [Right Sidebar](../deepseek-harness/docs/subsystems/sidebar-right.md#document-renderers):文档渲染器注册、extension 优先级、文件地址及读取生命周期。 - [Web Client Slots](../deepseek-harness/docs/subsystems/slots.md#component-inputs):组件输入、会话作用域和框架绑定。 - [Human Commands](../deepseek-harness/docs/subsystems/commands.md):插件命令、调用归属、取消和日志。 - [工具编写参考](../deepseek-harness/docs/cookbook/adding-a-tool.md):规范结果、取消、权限、工具呈现和日志。 - [Workspace Files](../deepseek-harness/packages/api/workspace-files/README.md):文件读取、版本、字节传输及提供方限制。 - [Harness 架构](../deepseek-harness/docs/architecture.md#session-log):模型可见内容应能够从会话日志重建。 - [用户动作和工具共用操作](../deepseek-harness/packages/preset/agent-preset/skills/cordis-plugin-development/references/user-actions.md):UI 与模型调用共享 Host 操作。 - [模型图片输入设置](../deepseek-harness/docs/user/guide/providers.zh.md#图片输入)及 [LLM 服务](../deepseek-harness/packages/llm/llm/README.zh.md):输入模态来自精确路线元数据,缺失时是未知;设置声明不是视觉能力实测。 - [设置领域底座](../deepseek-harness/packages/client/ui-settings/README.zh.md#填充设置-slot)及 [设置外壳](../deepseek-harness/packages/client/ui-settings-general/README.zh.md):功能插件可通过 settings.section 贡献设置入口与页面。 - [即时配置表单](../deepseek-harness/docs/cookbook/adding-a-settings-card.zh.md)及 [插件配置表单](../deepseek-harness/docs/subsystems/settings.zh.md):volatile Config、设置修订检查、秘密字段脱敏及 profile patch 持久化。 - [pypdf:文字提取与 OCR](https://pypdf.readthedocs.io/en/stable/user/extract-text.html):文字提取无法识别图像中的文字;扫描 PDF 可以已有隐藏 OCR 文字;排版和文字顺序存在提取限制。 - [PDF.js:PDFPageProxy](https://mozilla.github.io/pdf.js/api/draft/module-pdfjsLib-PDFPageProxy.html):页面文字、渲染与标注是分别取得的能力;有些页具备结构树,不能假定每页都有可靠的语义结构。