# DeepSeek Harness PDF 插件 - 功能 SPEC 文档修订号:0.11;适用包版本:0.1.5;状态:V2 分层、共享草稿读写工具及持久化检索已接入;常规阅读交互的既有用户验收保留,未完成的 Desktop/真实模型专项验收仍按下文限制处理;更新:2026-11-03。 本文件定义产品行为、功能范围和验收标准。当前实现采用的 API、服务拆分、PDF 引擎和构建方式见第 11 节;其余未交付条款保留为设计目标。 ## 0. 当前实现状态 以下状态依据当前插件源码、此前的宿主激活记录、2026-10-14 的合成组件基准及用户对此前“待交互验收”项目的通过确认;具体自动化结果以执行时的构建、测试输出为准。这里的用户交互验收不等于外部阅读器互操作、真实模型调用、复杂文档/竞态边界或端到端性能验收;已有千页合成语料的 Host/Reader 组件测量,但尚无千页级真实样本、完整 DSH Desktop 测量或浏览器与原生 helper 的合计峰值内存数据,不提供实际加速比例。后文保留产品需求和阶段设计,未交付项以本表为准。 | 能力 | 当前状态 | 范围与限制 | | --- | --- | --- | | 独立安装与宿主接入 | 已实现,Host 已激活 | 独立 `@dylanl1/dsh-plugin-pdf` bundle;npm 主包按系统和 CPU 选择精确版本的预构建原生依赖,注册 PDF 默认渲染器和设置页。无需修改 DSH 源码或在安装时构建原生文件。 | | 阅读、选择、搜索与跳转 | 已实现,用户交互验收通过 | 连续滚动、可见窗口高清绘制及原有文字层、物理页码、缩放/适应宽度、原有文字搜索、被动链接命中和独立返回栈。PDF 自带显示页标签(如 i、ii;不同于物理页码和内置目录)尚未实现。 | | 原生标注编辑 | 普通回复读写与页面内评论交互已接入;待完整浏览器与外部阅读器互操作验收 | Highlight、Underline、StrikeOut、Text 的读取与人工编辑,选区即时预览、页面直接选择、颜色/正文/删除、PDF 日期本地化。支持将普通 `/IRT` 回复按标注组成多评论线程、逐条编辑与新增回复;`/Popup` 不作为评论,`/RT /Group` 不作为普通回复。扁平化标记仍只是页面内容。 | | 工作副本、保存与丢弃 | 已实现,用户交互验收通过 | 手动保存/另存为、版本冲突、撤销/重做、草稿恢复;一键丢弃恢复基线并清空草稿/历史;空白点击关闭上下文操作及未提交便笺。复杂冲突竞态仍待专项验证。 | | 切换会话清理 | 已更新,自动化回归通过,待 Desktop 验收 | 关闭旧会话 PDF 视图并释放独立引用,不丢弃共享草稿;按视图令牌清理可覆盖响应丢失的打开。旧 Sidebar 未挂载的恢复标签保留精确关闭任务,下次挂载时关闭。 | | 区域截图与 OCR | 已接入,待真实模型/桌面交互验收 | 区域截图可复制/下载;阅读器可按需识别整页或截图区域,入口由 Host 按所属会话模型和所选 OCR 后端决定。内置 SessionLLM 后端要求图像输入,结果仅为可复制的转写,不生成精确 PDF 文字层;尚无本地/远端 Host 后端。 | | 独立选区翻译 | 已实现,待真实模型调用验收 | 默认使用当前会话模型;单词要求音标、逐义词性、含义和例句,短语要求各义项的类别、含义与例句,句子直接翻译。译文留在 PDF 中,不加入会话历史;已有输入、输出及超时限制。 | | 文件与加密兼容 | 有明确限制 | 只支持宿主本地文件系统;数字签名 PDF 只读;加密 PDF 暂不支持,需密码文件不支持交互式解锁。 | | 性能改进 | 已实现;合成组件已测,端到端待测 | 二分滚动定位、局部命中索引、选区边界遍历、批量删除、相同基线字节复用;普通编辑只投影标注操作,保存时物化 PDF。测量口径和结果见 [PERFORMANCE.md](./PERFORMANCE.md)。 | | 长文档内部架构 | 已接入,待性能验收 | 仅使用原生 PDFium 阅读;数字页布局与有界页面挂载使可见页优先绘制,选择相关页可保留文字层。没有后台全页文字/低清预览预热;搜索按需读取并使用有界缓存。沿用现有 PDF 预览入口。 | | 阅读布局与鼠标缩放 | 已实现,悬浮样式待交互验收 | PDF 内容区顶部悬浮文档工具栏,页码与翻页控件位于阅读辅助栏底部;左 PDF、右可折叠及调宽的阅读辅助栏;Ctrl 配合滚轮在 PDF 内容区进行 10%~500% 缩放。 | | 页面缩略图和 PDF 书签 | 已实现,用户交互验收通过 | 右栏按需绘制页面缩略图;读取和编辑 PDF 内置目录;修改进入共享草稿,保存后写回 PDF。复杂目录和失效目标仍待专项验证。 | | 会话发送与模型 PDF 工具 | P3 证据闭环及草稿写入已接入;真实模型调用待验收 | 解释模式可将多段文字及单页区域的必填问题组成一轮提词;Host 重提取文字、绘制区域、签发并在发送前重验会话限定引用。工具可后台打开、读取、检索、编辑标注/表单/内置书签,共用 Reader 可撤销草稿;只有覆盖保存需要批准。搜索/相关检索/定位/上下文提供文字引用,模型标注、精确页内导航及三个历史文字卡复用源文件/全文/范围/native 字形验证,成功跳转进入多级回退;不自动打开侧栏。普通模型页图仍不含未保存草稿覆盖层。证据存储有界,图像只存受保护附件句柄;图像工具卡、答案正文逐句引用和完整解释提词统一证据仍未实现。 | ## 1. 产品目标与约束 让用户在 DeepSeek Harness 的右侧 Sidebar 中阅读和标注 PDF,并在交叉引用跳转后回到原阅读位置。阶段划分为:P0 完成这一闭环;P1 增加 PDF 书签(现已接入);P3 才增加选区/整页发到会话及模型精细读取、解读、翻译和标注工具。 插件作为独立 bundle 开发、构建和安装,源码、依赖、测试和文档都位于插件项目目录。接入现有插件、文档预览和会话扩展接口,不需要修改 DeepSeek Harness 仓库的源码、manifest、默认配置或锁文件。npm 主包 `@dylanl1/dsh-plugin-pdf` 提供 Host、Client 和公开 SDK,五个平台原生子包通过 optional dependencies 自动选择;Linux 构建要求 glibc。源码开发仍自行构建 `dist/native/`,普通安装无需编译器。旧 `@local/dsh-pdf` 包切换前须先保存草稿、备份插件存储并停用旧 bundle,设置及持久状态的迁移另行核对,不同时启用两者。 P0 成功标准:打开已有标注的 PDF → 阅读/选择及按需 OCR → 人工编辑标注 → 内部跳转并逐级返回 → 手动保存 → 用其他阅读器重开,看到原有和新增标注。 P1 已在此基础上接入书签读取与管理;P3 的“发送选区到会话 → 模型只读补充上下文”已部分接入,“模型审阅后修改同一工作副本 → 显式保存”的协作闭环仍是后续目标。 ## 2. 核心概念 | 概念 | 含义 | | --- | --- | | 源文件 | 磁盘或文件提供方中已保存的 PDF。 | | 工作副本 | 当前会话正在操作的 PDF 状态,包括尚未保存的标注。P0 用户界面使用此状态;P3 模型操作共享同一状态。 | | 源文件版本 | 用于判断文件在上次读取后是否被其他程序修改的版本标识;调用方只能比较是否相等。 | | 工作修订号 | 工作副本每次成功修改后变化的标识;用于防止模型或界面基于旧内容修改标注。 | | 文档句柄 | 插件为某个会话中的某份文档分配的身份。模型操作必须明确携带它。 | | 页码 | 物理页序号从 1 开始,当前已支持显示与跳转;PDF 自带的逻辑显示页标签(`/PageLabels`,例如封面的 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 | 读取、定位与编辑 PDF 目录,保存后写入 PDF。 | | 4 | 阅读跳转 | P0 | 基本阅读和定位、PDF 内部链接/命名目标跳转、页内位置恢复、嵌套跳转的返回栈。 | Sidebar 接入、工作副本、文字/区域选择、页面渲染、按需 OCR、OCR 引擎扩展和 PDF 设置卡片是功能块 1、4 的 P0 共同基础。OCR 通过用户操作提供选择、搜索和标注支持;它不依赖模型工具先行交付。 ### 4.1 P0:阅读、编辑和跳转 | 功能 | 交付行为 | | --- | --- | | Sidebar 打开 PDF | 工作区文件入口和已有文件链接可以进入插件查看器。 | | 分页阅读 | 连续滚动、上一页/下一页、输入物理页码、缩放、适应宽度;页面自身的方向按 PDF 定义显示。 | | 跳转与返回 | 支持内部页/命名目标;成功跳转前记录原位置;按后进先出顺序逐级返回。 | | 文本搜索 | 查找原有文字及已识别 OCR 文字,显示匹配位置和实际覆盖范围。 | | 文字与区域选择 | 跨行/跨页文字选择和单页区域选择,用于标注、OCR 与预览。 | | 页面内容与渲染 | 分别取得文字、整页/区域图像和标注;扫描页、混合页不被当作空白页。 | | 已有标注与编辑 | 识别、保留、添加和修改已确认范围的标注。 | | 撤销、保存和恢复 | 编辑历史、手动保存/另存为、外部版本冲突保护和未保存草稿恢复。 | | 按需 OCR 与引擎扩展 | 功能层与 NoneOCR、LocalOCR、厂商适配扩展解耦;所有 UI 入口使用统一功能。 | | PDF 设置卡片 | 配置阅读、标注、OCR 和返回栈,支持保存、校验及可用状态。 | 原定 P0 界面不提供会话解读、加入会话或模型自动操作入口;模型工具也不作为 P0 阅读闭环的验收前提。当前已先行交付解释模式、多项只读模型工具,以及须用户批准的批注与保存工具,具体边界以第 0 节为准。独立选区翻译在当前阅读界面交付,遵循 FR-13,不向聊天消息或会话日志写入选区及译文。阅读器 OCR 已可按需使用 Host 后端;基础阅读与编辑不依赖模型工具。 ### 4.2 P1:PDF 书签 提供书签列表、定位及管理。点击书签复用 P0 导航操作和返回栈;内置书签支持新增、改名、目标页修改、排序、层级调整及删除子树,进入共享草稿,保存后写入 PDF;页码失效时停止跳转。 ### 4.3 P3:会话交互与模型工具 当前解释模式支持收集多段文字及单页框选区域,逐项输入问题后向所属会话排队发送一轮提词;模型还可按会话授权的文档句柄后台打开、读页、搜索、列书签、渲染页图和 OCR。这些能力尚待真实模型与 Desktop 交互验收。区域发送走独立图像理解服务,而不是复用 OCR 来假装理解图像。选区加入聊天输入框、整页解释、会话内翻译,以及模型编辑标注、显式保存、控制阅读区导航,仍是后续目标。 ### 4.4 其他后续能力 批量 OCR 和更多标注类型保留为后续备选,它们的具体交付优先级尚未确定。页面缩略图和 PDF 内置目录树已实现。修改正文、页面重排、真正删除敏感内容及翻译文档导出仍在当前已确定范围之外。“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 自带页标签存在时,同时显示标签,所有工具调用仍使用物理页码。 Reader 为每页保留数字几何,视口及其前后约一个视口范围内挂载完整页面;跨页拖选经过的页和捕获后的选区页另保留文字层与定位信息,但离屏高清画布释放。大范围选区的文字 DOM 用量随选中页数增长。原生 PDFium 按需绘制,没有后台全页文字或低清预览预热;跳到未缓存页时仍可能等待绘制。缩放预览作用于整个页面布局容器,使页面及页间距一起变化;提交比例后重算数字几何并保持可见页锚点。页面按 PDF 自带方向显示,不提供手动显示旋转。搜索首次按页读取文字和坐标,后续查询使用有界文字缓存与页面摘要跳过确定无匹配的页。 搜索返回页码、原文片段和位置。文字不存在、文字编码异常或阅读顺序不确定时,结果需说明限制,并允许查看对应页面图像。 查看器应正确处理非零页面裁剪原点、不同尺寸页面和 PDF 自带页面旋转;标注和选区不能因缩放、自带旋转或高 DPI 屏幕而偏移。 PDF 内容区和右侧功能视图各自滚动;滚动条作为浮层显示,不占用布局宽度。滚动、悬停、拖动或键盘聚焦滚动条时保持可见,停止滚动且未悬停或聚焦时自动隐藏。支持滑块拖动、轨道点击和键盘滚动。 在左侧 PDF 内容区按住 Ctrl 滚动鼠标滚轮进行文档缩放,缩放围绕鼠标所在的页面位置,范围为 10%~500%,当前比例同步到顶部缩放控件;该手势更新 PDF 比例而非浏览器页面比例。普通滚轮仍用于滚动。右侧阅读辅助栏和输入框不拦截此手势;缩放属于阅读状态,不建立跳转返回记录,也不修改 PDF。 ### FR-03:文字及区域选择 用户可以选择单词、跨行段落和跨页文字。选中文字按照实际被选择的片段生成,不用一个大矩形把栏间、页眉或未选择内容一起提取。 默认始终为文字选择。选中文字后,在选区附近显示浮动工具条,提供复制、高亮、下划线、删除线及便笺动作;点击高亮即以当前颜色创建标注(初次为黄色),随后可在选中标注的颜色条中改色。三种文字标记(高亮、下划线、删除线)共用同一条颜色选择:五个可编辑快捷色、调色板和“加入快捷色”,所选颜色同时作为后续新建标记的当前颜色,因此三者的改色方式一致。便笺沿用单色块取色。选中标注的类型由其动作图标标识,不依赖颜色区分。固定顶部不放置文字选区操作。工具条随滚动与缩放保持对应位置,不挤动正文。 点击页面、查看器空白或查看器外部时清除当前选区和已提交标注的选择;未应用的批注正文或便笺草稿需明确应用或取消,不能因空白点击静默丢失。点击操作按钮、批注输入框或拖动选择文字不被当作空白点击。清理浏览器选区只影响该 PDF,不清除其他 PDF 或会话的选择。 对于扫描页、公式、表格、图表以及无法可靠提取文字的内容,用户通过“工具 → 区域截图”显式启用一次框选,在单页内拖出矩形后生成预览,并自动恢复文字选择;可随时取消。P0 预览提供复制图片、下载 PNG 和区域 OCR。解释模式中可另行框选单页区域并输入问题;整页解读、区域翻译和加入聊天输入框仍待实现。图像与 OCR 的选择遵循 FR-09。 P0 支持整页绘制与识别本页文字。P3 每页增加“解读本页”“翻译本页”“加入输入框”,范围是该物理页完整可见范围,不要求先滚动至页底或框出整页;按钮显示实际页码,不把多页默默当作一页。跨页文字选择保留原有行为;首版矩形区域限定在单页。 整页或区域图像由 PDF 工作副本按需绘制生成。它不依赖屏幕截图,不包含 Sidebar、工具栏、鼠标、选区边框或其他会话的内容,清晰度不受 Sidebar 宽度和当前显示缩放限制。用户预览图像后可调整范围或取消;创建选区和预览不会自动提交模型请求。 无可用文字层时,查看器保留页面阅读和区域选择能力,显示“未发现可用文字,可识别本页文字”。用户按需执行 OCR 后,可在识别成功的范围内选择文字;不以整个文档是否为扫描版作为唯一判断。 选区预览显示原文或区域图像、文件名、页码及是否包含多页,用户可以清除选区。工具栏点击不会意外丢失已经捕获的选区。 跨页文字选区以一个用户动作提交,但保留每页各自的文字片段和几何位置。旋转或倾斜文字需要保留文字标记的几何信息,不能仅存一个包围所有内容的大矩形。 ### FR-04:已有标注识别和兼容 必须识别并显示原生 Highlight、Underline、StrikeOut 和 Text 便笺,包括位置、颜色、批注正文、作者、创建时间和修改时间;源文件没有提供的字段显示为缺失,不推测。一个标注可关联多条评论:标注自身的正文是首条内容,普通 PDF `/IRT`、`/RT /R` 回复是独立的后续条目;`/Popup` 只是展示容器,不算一条回复,`/RT /Group` 不是普通回复。 标注列表支持按页定位和选择标注。选中一条标注可以跳到对应页面;如果没有评论,显示就近操作条并由“添加批注”显式进入输入框;如果已有评论,直接显示就近的只读评论卡片,并在可能时提取其覆盖的原文;无法恢复原文时仍显示批注及区域图像。 用户也可以直接点击页面上的原生标注选中,按有无评论使用上述同一交互。工具条的评论按钮只是查看/添加批注的快捷入口;卡片默认只读,显式点击“添加批注”或某条评论的“编辑”才出现输入框。保存后返回评论列表;取消选中隐藏卡片,不再弹出另一层工具条。工具条仍提供颜色和删除标注操作。已有评论的标注上方保留可点击的评论标识。滚动、缩放时卡片和连线跟随标注,离开可见区域时收起。点击命中按各行四边形计算,不覆盖正常拖动或双击选字。右侧阅读辅助栏保留标注列表用于浏览和跳转,但不承载批注编辑;切换辅助栏功能时不改变左侧 PDF 内容区宽度。创建和修改时间解析 PDF 日期格式,按本地时区显示。 内部和外部 PDF 链接悬停时仅将鼠标指针改为手形,不绘制链接框、按钮或悬浮面板。链接点击采用被动坐标检测,链接文字仍可拖选;双击选词取消待执行的单击跳转。 支持的已有标注与新标注使用相同的编辑入口。普通回复按线程顺序展示,逐条显示原文件提供的作者与时间,允许对可编辑条目单独修改或删除,并可追加新回复;有子回复的条目不能直接删除,以免留下孤立回复。批注含中文、换行和 Unicode 字符时,保存后应能正确重读,并在其他 PDF 阅读器中保留普通回复关系。作者只是 PDF 元数据,不代表经过身份验证。 对墨迹、印章、形状、附件、表单,以及不符合普通回复关系的分组或损坏回复链,优先呈现可用外观和信息,并保留原始对象;不能因为解析或编辑能力不足而删除它们。 页面内标记保留可见外观,不能承诺恢复成原生标注。[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、切换会话、断开客户端连接或重启仍可从插件存储恢复未保存草稿。恢复时重新验证源文件版本;版本不同显示冲突,不能直接覆盖。只有显式丢弃操作才清理对应草稿。Host 内同一资源会话与规范路径始终共用同一文档身份、修订和撤销历史;后台资源回收保留逻辑 ID,下次使用时按需恢复,不创建第二份模型草稿。 撤销/重做是工作副本编辑历史。保存成功后清空这段历史并建立新的已保存基线,避免“撤销”被误认为已经回滚磁盘上的文件。 ### FR-07:选区与当前会话交互(P3) 用户主动发送文字、区域和整页,以及会话中的解读/翻译在 P3 交付。独立选区翻译另按 FR-13 提前提供,不属于向会话发送内容。 **当前首版**:用户在工具菜单进入解释模式,状态条显示发送与退出操作。选中文字,或选择“框选区域”后在单页拖出矩形;两种选段都须在选区旁输入问题并保存,才计入临时选段。已保存选段可通过页上的编号标记重新编辑或删除;文字与区域可按选择顺序混合发送。同一 PDF 最多收集 20 个选段,其中区域图像最多 5 张,文字总计不超过 24000 字符;这些选段不会写入 PDF 批注或未保存状态。区域图像经 `pdf.region` 由 Host 基于已授权工作副本绘制、核对附件字节并产生会话限定的区域证据 `refId`;文字选段经 `pdf.selection` 由 Host 按 PDFium 字形位置重新提取、核对整页文字并签发引用。Client 仍负责临时选段、提词组合与发送前来源复核;发送区域图像时经 `pdf.image` 的 `prepare-reference` 再验证会话、文档、源文件、附件与摘要,直送图片只使用 Host 返回的字节。提交时只向该 PDF 所属且仍为当前激活的会话排队一轮普通用户提词;解释主模型固定跟随该会话模型,模型回复出现在聊天中。区域图像在当前模型声明支持图像时直送;文本会话则调用所选图像理解引擎生成描述,只将带来源及局限说明的派生文字发送给当前会话,不自动降级为 OCR。没有可用路线或转换失败时保留选段与问题并显示错误,不把空内容当成成功。此版尚未实现整页附件发送、聊天输入框草稿预览或另行指定解释主模型。下表是后续完整目标,并非全部已交付;真实模型与桌面交互尚待验收。 解释模式在 PDF 设置中分别配置 `explanationGeneralInstruction`、`explanationTextInstruction`、`explanationImageInstruction`;每项是可选的普通文字,留空时沿用内置行为,不要求用户编写占位符。每项最多 2000 字符,可通过 profile patch 配置。插件负责按顺序插入已校验文字、问题和图片,不能把图片序列化为普通文字;来源警示、证据引用和 Host 校验始终保留。旧版 `explanationPromptTemplate` 仍供已有 profile 使用:只有三个新字段均为空时才生效;设置页可明确切换到分项提示词。旧模板仍要求恰好一次 `{{items}}`,并限制长度 8192 字符。 选区提供三个入口: | 动作 | 行为 | | --- | --- | | 加入输入框 | 将选区引用和内容加入当前草稿,保留已有输入,用户自行补充问题并发送。 | | 解读 | 将选区快照和解读请求提交到当前会话。 | | 翻译 | 将选区快照、明确的目标语言和翻译请求提交到当前会话。 | 这些动作同时适用于文字选区、区域和整页。对于区域或整页,“解读/翻译”按 FR-09 选择可用读取方式;“加入输入框”显示文字或图像附件预览及来源标签,供用户决定何时提交。若需要 OCR,应显示识别进度并保留用户原来的问题;识别或提交失败不丢弃选区。 P3 翻译默认目标语言建议为简体中文,入口应展示目标语言并允许修改;这个默认值是待评审的产品选择,不依赖界面语言暗中推断。 点击动作时捕获目标会话。发送期间切换到另一会话,不能把内容转发给新会话。多个 Sidebar、PDF tab 或并行会话也不能混用文档及选区。 当前会话正在运行时,解读/翻译采用宿主的排队机制;默认不打断模型。提交失败显示原因,并保留选区及用户输入。客户端重复操作或重试不应产生重复消息;具体去重方式由 API 设计规定。 发送内容包含足够的原文或区域图像。插件不能仅向模型发送文件路径并声称“已发送选区”,也不能只在浏览器内存中保存模型已经看到的内容。 已发送选区作为历史快照保留;文档之后修改或移动时,会话中的原文不变。后续工具读取当前文档时返回当前版本,并说明它和引用快照是否一致。 发送前展示实际内容范围。超过输出或附件限额时明确提示,允许缩小选区或分段发送;不能静默发送半段原文或宣称已经发送整份选区。 选区来源作为用户提供的文档内容处理。文档内出现的命令、系统提示或工具调用文本不成为插件指令;打开文档和创建选区也不会自动发起模型请求。 ### FR-08:不可编辑或读取失败的文档 损坏文件、解析失败、文件过大和提供方访问失败需显示明确原因,并提供重试入口。失败结果不会被当作空白文档或空文本。 首版遇到需要密码的 PDF,显示“需要密码”状态,不要求用户把密码发到模型会话。交互式解锁和加密文件保存属于后续设计范围。 当前不支持加密 PDF,包括无需输入密码即可打开的文件;界面显示原因,不会在其他引擎中降级打开,也不会将密文交给编辑引擎重写。 包含数字签名的文件在能够读取时可以预览;发送选区在 P3 提供;首版不提供会使原文件签名失效的写回。编辑能力显示为受限,不能在另存为时宣称签名仍有效。 文件提供方只支持读取,或者当前会话不允许目标路径写入时,阅读功能仍可用,保存入口明确说明受限。模型工具也返回同样的限制,插件不能把权限不足解释为需要修改宿主源码。 ### FR-09:页内容、扫描页与混合页读取(共同基础 P0;模型交互 P3) #### 9.1 同一页的三个视角(P0 基础) “一页的内容”包括完整可见页范围内的内容及关联的标注。以下视角共享页码、页面几何位置和工作副本版本: | 视角 | 包含内容 | 限制 | | --- | --- | --- | | 可提取文字 | PDF 现有文字及按需产生的 OCR 文字块;保留位置和来源。 | 不代表图片、布局、曲线和图表含义已被读取;阅读顺序可能不确定。 | | 页面图像 | 页面中的文字、扫描图像、图片、矢量绘图、表格、公式及可见标注的合成外观。 | 接收图像不保证模型准确理解;低分辨率下可能需要继续读取局部。 | | 标注信息 | 原生标注身份、位置、颜色、批注正文,以及当前工作副本中的修改。 | 批注正文不一定显示在页面图像中,需单独提供;页面内标记仍按页面内容处理。 | 页面图像是按 PDF 页范围绘制的合成结果。不能仅提取 PDF 内部的图片对象来代表整页或一幅完整图,因为图的文字、坐标轴或其他部分可能由不同对象共同组成。图片/图表区域索引是定位辅助,首版不承诺自动准确识别全部图表边界。 页面摘要分别说明文字提取状态、可见内容检测结果和 OCR 状态。无文字不等于空白页;有文字不等于文字覆盖整页;未检测出图片对象不等于没有图形。无法可靠判断时返回未知或疑似,不伪装成已验证结论。每页独立判断,同一份文档可以同时有正文页、扫描页和混合页。 #### 9.2 自然的读取与发送策略(P3) 本小节涉及会话提交及模型输入能力,原定仅在 P3 生效。基础阅读与编辑不自动调用模型;用户主动触发 OCR、翻译或解释时,当前实现可使用会话模型及图片附件。 插件提供“自动、文字、页面图像”读取方式;自动是整页/区域解读的建议默认值。文字选区优先使用实际选中文字,并允许附带对应图像。对整个页面发起“阅读/解读”时,模型工具与 UI 使用相同策略: | 页面情况 | 当前模型明确支持图像 | 当前模型不支持图像或能力未知 | | --- | --- | --- | | 普通文字页 | 整页/区域图像,并附带范围内可用文字,方便理解布局和核对原文;显式文字方式可仅取文字。 | 提取原有文字,报告实际文字范围;不能声称已观察页面外观。 | | 无可用文字的扫描页 | 提供整页/区域图像;不必先 OCR,用户或模型仍可另外请求 OCR。 | 使用已配置的 OCR 获取文字;无 OCR 提供方或识别失败时返回不可读取的原因和可用入口。 | | 已带 OCR 文字的扫描页 | 提供图像并附带已有文字;文字可能来自原文件中的识别结果,来源能确定时标出,不能确定时不猜测。 | 先读取已有文字;结果异常或用户要求重识别时执行 OCR,提示现有文字不保证准确。 | | 正文加图片/图表/公式的混合页 | 提供页面图像和可用文字,支持按位置继续读取图表局部。 | 返回原有文字;按需 OCR 补充视觉区域内的文字,明确图像和图表关系尚未理解,不能声称整页已完整解读。 | 自动方式在支持图像时,整页/区域读取始终提供该范围的图像,不根据“文字很多”就跳过图像。调用方可以显式选择文字方式节省上下文,但工具结果必须标明这是文字读取。按需读取可以只读一页或一个区域;打开文件不自动读取所有页。 图像能力查询以当前执行路线的精确 provider/model 为准,使用宿主的输入模态声明。显式包含 image 才向模型提供图像块;未包含 image 和能力未知分别说明。能力来自目录/适配器/配置,不是实际视觉理解能力的测试。发送或工具执行时重新检查,不能仅使用打开文档时缓存的能力;不自动替用户切换模型。 模型不支持图像时,用户仍能查看、选取和生成图像。解释模式由 Host 在发送时检查当前会话:明确支持图像时直接附上经验证的图片,不额外调用视觉模型;否则调用配置的图像理解引擎,将注明来源与局限的描述文字交给当前会话。缺少可用视觉引擎时保留选段和问题,明确说明原因,不自动改用 OCR。用户或模型仍可单独请求 OCR;它只提取可见文字,不能替代图表、空间关系或版面的视觉理解。 图片处理只保留两个独立可扩展契约:`ocr.recognize(image)` 返回文字、可选位置与置信信息;`imageUnderstanding.understand(image, prompt)` 实际调用后端并返回生成的文字及来源。直接传图是会话编排,不属于图像引擎;OCR 不再重复注册成图像后端。内置图像引擎只有 `dsh-vision`,默认跟随当前会话;选择“指定模型”后才加载并显示 DSH 按提供商分组的视觉模型列表及该模型公布的推理强度,不要求手填 Provider、Model 或 reasoningEffort。选择只修改 PDF 的引擎配置,不切换聊天模型;底层仍保存 provider/model 和可选 reasoningEffort,切回跟随时同时清除这些覆盖。指定模式尚未选定模型时不能保存;已保存但暂时不可用的模型保留显示,不能自动改成跟随或另一模型。Host 在真正调用前重新检查所选模型及图像输入能力。最终解释仍由当前会话回答。 PDF 设置统一选择 `ocrEngine`、`imageEngine` 和 embedding 引擎,默认及第三方实现都通过同一服务注册。文字识别索引 `indexScanPages` 与视觉描述索引 `indexImageDescriptions` 是每份 PDF 独立保存的两个开关,放在搜索侧栏并复用全局引擎;设置页不重复展示这两个开关,也没有文档级引擎覆盖。两项可同时开启,视觉描述索引为整页生成文字再索引,仍非图表区域识别或图像向量化。开启语义检索后,后台预建可能在首次搜索前调用这些引擎并产生费用。 解释模式的框选 PNG 由 PDF Host 的 `pdf.region` 根据坐标渲染与签发引用,发送前再验证源文件、版本与附件;拒绝附件像素被改写或工作副本已变化的结果。第三方插件注入现有 Host 服务,通过 `ctx.effect()` 注册并在卸载时撤销,不创建另一份注册表;可运行示例与契约测试位于 `examples/` 和 `tests/examples/`。 #### 9.3 OCR 的功能边界(P0;模型入口 P3) 直接 OCR 按需识别单页或单页区域,由用户主动触发;开启语义检索及文字识别索引后,后台预建可对原生文字缺失/损坏的页调用同一个 OCR 引擎。当前阅读器经认证的 `pdf.ocr` 接口让 Host 判定所属会话的 OCR 后端是否可用、渲染整页或指定区域,并在执行前再次检查。独立 Host `image-ocr` 插件提供通用 `ocr_recognize` 工具,消费 `pdf_page_render` 返回的图像句柄;区域 OCR 仅由 UI 发起。引擎可以是当前视觉会话模型、本地或远端实现,其实际可用性由所选后端决定。SessionLLM 结果目前只有转写文字和图像覆盖范围,不提供可用于精确标注的词/行坐标。 OCR 的输入是明确版本的页面/区域图像。默认识别页面基础内容,避免新建高亮、选区边框和便笺遮挡原文;已经扁平化进页面的标记无法以此方式去除。视觉解读默认包含工作副本的可见标注,结果须说明实际是否包含标注;批注正文另外提供。OCR 与视觉读取的不同标注策略须在预览和结果中可查。 OCR 返回原文、文字块/行/词的位置及来源;引擎提供置信信息时保留其原始语义,不提供时标为未知。低可信或无法识别的范围明确标记。OCR 文字和原有文字在重叠区域按来源关联,避免简单拼接造成重复;发现冲突时保留差异供核对,不默默改写原文。 未来有可信坐标的识别结果可形成查看器中的选择层;当前 SessionLLM 转写只在侧栏展示为可复制文本,整页结果可用于页级搜索,不生成词级选择层或精确命中位置。它属于插件派生缓存,不改变 PDF 源文件、不产生未保存标注状态,也不因为“保存标注”而写入隐藏文字层。重载源文件后检查缓存版本;将来提供 OCR 位置时须映射到原始页面坐标,不能随显示缩放漂移。 OCR 支持进度、取消和明确的失败状态。只完成部分区域时报告覆盖范围;结果过长时提供游标,不静默丢字。原有文字和 OCR 结果均不擅自替用户修正原文;模型的解读或转写不称为经校验的 OCR 文字层。 #### 9.4 OCR 功能与引擎的解耦契约(P0) 职责拆分:PDF 插件确定文档/页面、会话授权和内容版本,并在 Host 渲染待识别图像;独立 OCR 插件提供 `ocr` 服务、后端注册与选择、任务调度、规范化结果及模型识别工具。阅读器经认证的 `pdf.ocr` 请求 Host 服务,Client 不自行判断模型能力或上传页面图像。把未来带坐标的识别结果映射到 PDF、形成词级选择层仍是后续工作;不能把首版 SessionLLM 转写当作已有精确文字层。 引擎只接收约定的图像与识别选项,执行识别并返回约定的结果。它不自行打开任意 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 秒;设置中不提供关闭翻译的选项。 | | 会话(P3) | P3 再提供默认发送方式 auto/text/visual 及模型能力相关反馈;P0 卡片不展示未交付的会话配置。 | | 标注 | 创建或编辑单条标注时可选颜色;不提供全局默认颜色配置,标注保存仍采用手动保存方式。 | | OCR | 所选引擎/实例、识别语言、任务超时与限额;显示已关闭、可用、未配置或依赖/连接失败。 | | 引擎专属配置 | 由所选实现声明的配置,例如本地运行参数、厂商端点/模型/凭据引用;不适用的字段不混在通用 OCR 配置中。 | | 导航 | 返回历史容量等偏好;界面显示有效范围,不要求用户配置才能使用返回功能。 | 引擎选择来自注册目录,包含 NoneOCR、LocalOCR 及已安装的厂商实现。不具备运行条件的引擎显示原因。已保存的实例引用缺失时明确显示不可用,不悄悄改选其他引擎。切换选项时保留其他引擎的配置;删除配置是明确的独立动作。 PDF 文件大小上限不在设置卡片中编辑;Host 的 `maxFileBytes` 默认 64 MiB,可通过 bundle/profile 的 `cordis.patch.yml` 覆盖 `pdf-reader` 条目配置(schema 范围 1~256 MiB)。后应用的 patch 替换该条目的整个 `config`,已有其他配置值需一并重述。原生阅读器另有 128 MiB 工作集上限。 表单修改先保存在设置草稿,点击“保存配置”后校验并通过宿主设置机制持久化;这与保存 PDF 标注是两个独立动作。“恢复默认”清除对应覆盖,展示恢复的生效值。配置在当前 profile 重启后保留,多个插件实例不共享错误的配置身份。 无效配置不写入。并发修改以设置修订号检查,冲突时保留当前草稿并提示重新读取;设置不可写时显示原因并禁用提交。所有界面读取同一套生效配置,下一次操作读取已接受的新值;已经开始的 OCR 任务保留启动时的快照。 凭据通过宿主的凭据机制及秘密字段策略处理;读取设置时仅显示是否配置和引用,不回传密钥明文,也不把密钥写入 PDF 或会话。编辑普通字段不覆盖未返回的秘密值。 卡片提供显式“检查引擎”动作。检查当前配置和所需依赖;需要实际识别请求时使用说明清楚的固定样本,不自动上传当前 PDF。打开设置和编辑字段不会启动识别任务。检查成功只代表引擎可用,不声称识别所有文档都会成功。 ### FR-11:PDF 跳转与返回栈(P0) 查看器支持同一 PDF 内的页目标和命名目标,解析到具体页面位置及目标指定的视图方式。页内远距离跳转也属于跳转;外部网址或其他文档交给宿主现有入口处理,首版不建立跨文件的返回栈。 每次成功的显式离散跳转之前,记录跳转发起时的原阅读位置。内部链接、搜索结果、输入页码、标注列表和书签定位采用同一导航操作;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 导航及返回栈,支持回到点击之前的阅读位置。 内置书签支持新建、改名、删除子树、修改目标页、排序与父子层级调整。UI 与模型共用同一目录领域及工作副本事务,支持撤销、重做、草稿恢复,保存后写入 PDF。保留原目的地、外链及样式;修改目标页时才替换为页适合目的地。 ### FR-13:独立选区翻译 选中文字后,浮动工具条提供“翻译”。统一翻译功能与具体引擎分离,默认使用 DSH 模型,支持切换到后续厂商或本地实现;不提供关闭翻译的设置。设置卡片只配置引擎与超时;原文始终自动检测,初次默认采用 PDF 所属会话的 DSH 模型、译成中文、30 秒超时。目标语言在翻译视图中从中、英、日、韩、法、德语选项中选择,改变后保存至当前 Profile 的插件设置,后续翻译默认沿用。 当前模型自行判断选区语义及输出类型,不按词数强制分类:句子、可读的句子片段和长段落直接翻译;独立短语逐义列出短语类别、适用含义及例句;单词给出可靠可判断的音标,并逐义列出词性、含义和例句。可利用有界邻近文字纠正提取错误或补全残缺内容;通过 `interpretation` 单独返回据以翻译的文字、修复类型、确定程度及说明,UI 保留原选区并明确标出推测。正常片段不为凑成完整句子而添写内容;不凭空补造人名、数字或事实。不设置 `recognized` 或选区完整性门禁;仍无法理解时由模型在结果中说明不确定性,代码不再二次判断是否可译、修复是否改变原文,或按词汇类型限制音标。协议结构、权限、大小和请求生命周期仍需校验。无法可靠判断读音时由模型省略音标。首版沿用当前会话模型,不另设翻译/OCR 模型选择;后续可独立配置这两项,解释模式仍固定跟随会话模型。 这条独立翻译流程提交当前选中文字及两侧各最多 80 个字符的邻近文字,不附带聊天上下文,也不调用 P3 的模型 PDF 工具;它不向会话消息或日志追加原文、请求或译文。结果在右侧阅读辅助栏的翻译视图显示,包含原文、可选修复结果、页码、引擎和完整/部分状态,支持取消、重试、切换目标语言后再次翻译和复制。复制修复后的译文时附带原文和修复/推测说明,避免将补全当作 PDF 原文。 原文区固定展示发起翻译时捕获的选中文字,加载、失败、取消、重试和更换目标语言时也保持显示,不依赖模型是否返回修复说明。词条结果仅显示类型、音标、释义及例句,不再重复原文标题;纠正或补全使用独立说明区,明确区分原始选文与模型解释后的文字。 单次输入限制为 8192 个 UTF-16 字符、统一输出限制为 32768 个字符;DSH 模型实现输出上限为 4096 tokens。超限输入明确报错,不静默截断;输出截断保留部分译文并提示未完成。明确关闭译文、切换文档或配置变化取消旧请求,迟到结果不能替换新选区;切换到其他右栏视图或折叠阅读辅助栏保留翻译状态,正在执行的翻译继续运行。翻译不改变 PDF 或保存状态,缺少模型服务不妨碍阅读与编辑。图像理解引擎供图片理解工具、解释的派生文字处理与视觉描述索引共用,不改变翻译或 OCR 的引擎配置。 ### FR-14:左右细轨与右侧阅读辅助栏 左工具栏、PDF 内容区、右阅读辅助栏为三个实际占位的布局列。左右入口栏均采用 56px 一体玻璃细轨,按钮宽 36px;分组用细线区分,不叠加多块玻璃。展开、折叠和调宽仅重新分配内容区与右栏宽度,自动适应模式保持页内阅读位置。保留右栏开合以及内部内容的淡入、位移动画;拖动调宽时直接跟随指针,减少动态效果设置下取消位移动画。 左细轨提供返回及历史、缩放、解释、便签、区域截图、OCR、文档操作及后台任务入口。撤销/重做纵向排列;高度不足时收进文档菜单。中部只滚动工具列表,解释计数、发送和退出固定可见,错误入口复用计数行。页码、总页数和上一页/下一页始终位于右细轨底部,展开或折叠内容卡片不移动、不重复挂载。保存、OCR、索引等任务共用任务入口和面板;索引运行中可取消,完成通知可由“完成”关闭,失败可重建。当前 PDF 的建立/重建入口位于搜索面板,细轨不单独显示索引按钮。其他成功反馈短暂保留,失败及冲突保留待处理。各类菜单挂在当前 Reader 的浮层内,不被细轨滚动或玻璃层裁切。减少透明度、高对比度或不支持背景模糊时使用可读的实体背景。 删除插件底部重复的文件路径和“重新加载”栏,文件路径继续使用宿主已提供的文档头部。重新加载保留在工具菜单中,并继续遵循冲突与丢弃提示规则。 右栏默认展开标注视图,总宽参考 296px,内容卡片保留原有可读宽度;窄窗口按可用空间限制或自动折叠,折叠后保留 56px 细轨。辅助栏可拖动分隔线调宽,也支持聚焦分隔线后用左右方向键及 Home/End 调整;功能入口支持上下方向键及 Home/End 切换。展开、折叠或用户调整宽度后,“适应宽度”根据实际 PDF 内容区重新计算,并保持当前页内阅读位置,不记录为跳转。页面、书签、翻译、标注和搜索共用辅助内容区,一次展示一种视图,切换视图不改变 PDF 可用宽度。 | 右栏视图 | 用途与入口 | | --- | --- | | 页面 | 只为可见列表项按需绘制缩略图;显示物理页码,点击缩略图定位。 | | 标注 | 默认视图;统一列出高亮、下划线、删除线和 `Text` 点位便笺。文字标记上的批注与页面任意位置的便笺都是标注,仅附着位置不同;它们复用标注身份、定位、正文编辑、删除和手动保存规则,不创建独立笔记存储。 | | 翻译 | 选区工具条的“翻译”自动进入该视图;保留原文、结果与翻译操作,尚未选择文字时提示先选择。 | | 搜索 | 集中搜索输入、覆盖说明和定位结果;点击结果仍使用阅读跳转及返回栈。 | | 书签 | 展示与编辑 PDF 内置目录;修改进入共享草稿,保存重开后恢复;失效目标明确提示。 | 文字和标注的就近工具条继续显示在 PDF 内;标注没有评论时由工具条显式添加,已有评论时点击标注或评论标识直接打开只读线程卡片。工具条评论入口也可打开同一张卡片。取消标注选择时卡片一并隐藏,不在卡片和工具条之间反复切换。右栏承载较长的结果和列表,批注正文在页面附近逐条查看、编辑;空白点击不会丢弃未应用的评论,不删除已经提交的标注、译文或搜索结果。 右栏各视图保留挂载,切换视图或折叠辅助栏不清空翻译结果、取消进行中的翻译或删除搜索结果。用户通过明确关闭译文/取消操作结束请求,文档及翻译配置变化继续执行 FR-13 的取消规则。 ## 6. 状态与会话归属 文档内容状态与模型是否正在运行分别管理。建议使用以下文档状态: | 状态 | 用户可见行为 | | --- | --- | | 加载中 | 显示进度或加载反馈,允许取消。 | | 已加载且已保存 | 可以阅读、选择和编辑;保存按钮无待提交修改。 | | 已加载且未保存 | 页面展示工作副本并显示未保存标记。 | | 保存中 | 显示提交反馈,防止重复提交;保留当前可见内容。 | | 版本冲突 | 保留草稿,禁止静默覆盖,提供恢复路径。 | | 受限 | 显示文档可执行的操作及具体限制。 | | 失败 | 显示原因,允许重试,不丢弃已有草稿。 | 同一会话的同一文件共享工作副本;不同会话分别持有草稿。不同会话保存同一源文件通过版本检查解决竞争。工具不能通过一个会话的句柄访问另一个会话的草稿。 Sidebar 的当前页面、缩放、选区和跳转返回栈是阅读状态;不会仅因为用户滚动或跳转页面而增加模型上下文。打开文件也不会自动把整份 PDF 注入会话。OCR 引擎选择属于插件实例配置,不属于某一 PDF 工作副本;识别任务和缓存则保留明确的文档、引擎及版本来源。 ## 7. 精确引用要求(P3;位置与版本基础由 P0 复用) 本节关于发送快照、会话历史和模型引用的要求在 P3 验收。P0 仍使用相同的页面坐标和版本原则定位标注、OCR 及跳转。 所有可用于后续模型读取的引用至少包含:文档身份、来源路径、源文件版本、工作修订号、物理页码、位置及已发送内容快照。 文字选区还需要每页的原文片段和文字块/字符范围信息,并标明原有文字或 OCR 来源;区域选区还需要区域图像及其对应的页面位置;整页图像引用包含完整可见页范围;标注引用还需要标注身份和批注文本。OCR 引用额外保留识别结果版本及可用的置信信息;重新 OCR 不替换已发送快照。 几何位置采用 PDF 页面的原始坐标体系,并携带可见页范围和旋转信息。客户端像素坐标只能作为临时交互数据,不作为持久引用。坐标单位、字符偏移单位及四边形顺序必须在 API SPEC 中明确定义。 模型引用能够定位到页面及区域。若源文件版本仍可用,点击引用可以跳回原位置;若文件变化,显示旧版本提示并允许查看引用快照,不能把新页面中的相同坐标当成已验证的原文。 选区快照及附图通过宿主现有的消息/附件机制进入会话日志,确保恢复会话后仍能重现模型收到的材料。插件可以维护自己的草稿及索引,但不在宿主会话中写入未声明的事件类型。 ## 8. 模型工具契约 工具按确定性职责划分,当前源码的完整输入、输出和限额见 [AI_READER_TOOLS.md](./docs/AI_READER_TOOLS.md)。模型组合搜索、读取、标注和导航,不注册总结、问答等工作流工具。 | 能力 | 工具 | | --- | --- | | 文档生命周期与状态 | `pdf_current`、`pdf_open`、`pdf_close`、`pdf_info`、`pdf_status`、`pdf_save` | | 页面读取与导航 | `pdf_page_read`、`pdf_page_render`、`pdf_page_jump` | | 检索与证据 | `pdf_keyword_search`、`pdf_semantic_search`、`pdf_evidence_read` | | 表单 | `pdf_form_inspect`、`pdf_form_fill` | | 标注 | `pdf_annotation_list`、`pdf_annotation_create`、`pdf_annotation_update`、`pdf_annotation_delete` | | 内置书签 | `pdf_bookmark_list`、`pdf_bookmark_edit` | | 通用图像处理 | `ocr_recognize`、`image_understand` | 页图工具只生成图像及可信句柄;OCR 与图像理解工具只消费句柄,并调用同一服务中的已配置引擎。文本模型可取得句柄供其他引擎处理,但不能接收图片后就被视为看懂图片。区域 OCR 仅由 UI 提供,不注册模型工具或区域参数;两种入口共用底层识别、取消、限额和错误处理。 读页及搜索签发来源明确的引用;`pdf_evidence_read` 负责重读、缩小和连续跨页范围解析。标注与精确跳转消费同一种最终引用,执行时重新验证源文件、文档修订、整页文字和原生字形。关键词搜索负责精确/显式归一化匹配,语义搜索要求实际可用的 embedding 引擎,不静默返回关键词结果。搜索续调只用同一工具的 `searchId`,输出限额、覆盖范围和未完成状态必须明确。 模型只操作本会话获准的文档,不根据 UI 聚焦状态隐式写入。UI 与模型复用唯一工作副本、草稿、修订、撤销历史和文件保存入口。`pdf_info` 读取文件元信息而不取得长期模型引用;重复 `pdf_open` 不重复累加同一模型持有者,`pdf_close` 不关闭 UI 或删除草稿。源变化和陈旧修订拒绝写入。 单页表单填写、连续范围标注和书签树批量编辑仍是事务:全部成功或零修改。表单检查图与编号映射属于同一快照,填写后读回验证;不让模型分别读取后自行拼接。标注修改保留对象身份与评论关联。修改直接进入未保存草稿,只有 `pdf_save` 通过 DSH 受信交互请求批准;批准绑定将保存的修订、差异及源摘要,不接受模型自报的授权。模型另存为仍未提供。 所有工具支持会话隔离、取消与卸载排空;文档和派生文字是资料,不是指令。读取、搜索和编辑不自动移动用户视图。只有明确请求的 `pdf_page_jump` 或用户点击证据卡会定位到已验证内容,成功后进入统一的多级回退历史,不新增模型 back 工具。真实模型、Desktop 和外部阅读器验收与自动测试分别报告。 ## 9. 质量要求 **文件兼容性**:保存后的 PDF 能在其他阅读器中继续选择文字、查看并编辑支持的原生标注。未参与本次编辑的页面内容和标注外观不能发生可见退化。首版不承诺保存后仍满足所有 PDF/A、PDF/UA 等专门格式认证。 **可恢复性**:草稿与 PDF 源文件分开保存。草稿、索引和渲染缓存不是会话历史的替代品。工作副本与源文件版本不一致时先处理冲突。 **会话隔离**:工具句柄、草稿、选区及发送目标具有明确归属。文件路径相对哪个工作区解析须明确,不能把地址里的原会话与发送目标会话混为一谈。跨会话文件引用的访问规则需在技术设计中进一步明确。 **性能**:可见页优先,长文档不一次性绘制全部高清页面;读取、搜索、绘制和保存可取消。每页保留数字布局几何,完整页面仅在视口附近挂载;跨页选区页可离屏保留文字层,其内存随选中页数增长。文字搜索按需读取,文字缓存和页面摘要有界;没有后台全页预热或低清预览。页码缩放重算布局仍随总页数增长,远页首次绘制可能等待。默认文件上限为 64 MiB,可通过 patch 在 1~256 MiB 内配置;原生阅读器另有 128 MiB 工作集上限。响应时间指标须在测量代表样本后确定,不把未测量的数字作为性能承诺。 已完成的源码优化包括:当前页滚动定位由 O(P) 扫描变为每帧合并后的 O(log P) 二分;标注/链接命中使用近页有界索引;文字选区只遍历相关边界范围并在线合并几何;批量删除由 O(D×A) 改为 O(A+D);普通编辑只更新标注投影和操作日志,撤销重放有效操作,保存时才物化 PDF;近页复用页面组件和 OCR 几何,原生文档以基线摘要标识。远页卸载完整组件并清理页面资源;保留所有页的数字几何。页面缩略图列表也按可见项虚拟化。具体最坏情形、空间边界和审查记录见 [PERFORMANCE.md](./PERFORMANCE.md)。 **尚存性能成本**:首次打开仍需读取整份 PDF,Host 扫描页和标注;原生 helper 也保留输入及页面缓存。每页数字几何、布局计算和缩放提交仍随页数增长;搜索在缓存缺失或命中时仍需读取相应页的文字及坐标,缩略图绘制也消耗可见列表项的页面资源。首次编辑须持久化一次完整基线;标注投影、操作日志和响应元数据仍随标注、历史和页数增长。删除或改色原有标注的近页预览需局部修补旧外观;修补区域与未知或自定义 appearance 重叠时可能覆盖交叠部分。保存仍需完整解析/序列化、磁盘写入、版本检查和提交校验。千页合成语料的 Host/Reader 组件耗时已测;完整 Desktop、真实复杂 PDF 的滚动体验与合计峰值内存未测。标注投影与响应元数据差量化属于后续优化。 **使用体验**:中文和英文界面文案、宿主明暗主题、清晰的禁用原因、键盘可访问的主要操作。颜色选择不能成为辨识标注类型的唯一方式。 **隐私与执行**:读取和标注默认在提供方允许的环境中完成;打开、滚动和选区预览不上传内容。当前独立翻译只在用户点击翻译时向所选引擎提交选中文字;P3 用户明确发送或会话中获授权的工具读取只提交请求范围。外部 OCR 提供方须明确配置和启用,仅按需处理请求范围。PDF 内的脚本、启动动作和外部引用不能因打开或解析而执行。文件写入服从当前会话和提供方的权限。 ### 9.1 自定义 UI 组件现状 本节记录阅读器内自定义交互组件的现状与收敛待办。它描述**当前实现**和**已识别的重复**,不是待实现的契约;分类与 API 方案尚未确定,见末尾的开放问题。 #### 自定义控件清单 | 控件 | 组件与文件 | 触发形态 | 弹出层 role | 定位方式 | 键盘支持 | | --- | --- | --- | --- | --- | --- | | 工具 | [Reader.tsx](./src/client/Reader.tsx) 内联 `
` + 自定义菜单 | 单一点击区(图标 + 文字 + ▾) | `group` | CSS 固定,菜单绝对定位 | 无方向键 | | 缩放 | [ZoomMenu.tsx](./src/client/ZoomMenu.tsx) | 单一点击区(图标 + ▾) | `group` | CSS 固定 + `translateX(-50%)`,`useLayoutEffect` 只算 `max-height` | 无方向键 | | 回退 | [BackHistoryControl.tsx](./src/client/BackHistoryControl.tsx) → [SplitActionControl.tsx](./src/client/SplitActionControl.tsx) | **分离**(主按钮 + 箭头按钮) | `dialog` | `ResizeObserver` + `data-position` 上方翻转 + `max-width` 夹取 | Escape + 焦点归还;菜单项无方向键 | | 选区高亮 | [SelectionHighlightControl.tsx](./src/client/SelectionHighlightControl.tsx) → 同上 | **分离**(主按钮 + 箭头按钮) | `dialog` | 同上 | 同上 | | 快捷颜色 | [AnnotationColorBar.tsx](./src/client/AnnotationColorBar.tsx) | 色块按钮 + 每个色块自己的编辑气泡 | `dialog` | 内联 `left/right`,第 3 个色位起右对齐 | Escape + 焦点归还;无方向键 | | 翻译语言 | [TranslationLanguageMenu.tsx](./src/modules/viewer/components/TranslationLanguageMenu.tsx) | 单一点击区(语言名 + 箭头,标签跟随当前值) | `group` | `onToggle` 内联测量 + 上下翻转阈值 | Escape + 焦点归还;无方向键 | | 标注筛选 | [AnnotationList.tsx](./src/modules/viewer/components/AnnotationList.tsx) 内联 ``。 - **role 与真实语义不符**:自定义菜单用 `group`/`dialog`,而其内容语义是选项列表(listbox/option 或 menu/menuitemradio)。 - **选中态只有 `aria-pressed`,没有视觉勾选**:缩放菜单和翻译语言菜单都属于此类;当前唯一有勾选标记的是原生 `` 无法满足统一需求**:触发器不能放任意节点、`