# dsh-context-annotations [![DSH Plugin](https://img.shields.io/badge/DSH-plugin-4D6BFE)](https://github.com/topics/dsh-plugin) ![DSH](https://img.shields.io/badge/DSH-%E2%89%A5%200.1.7--rc.2-4D6BFE) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) [English](README.md) · **中文** DSH(DeepSeek Harness)Web GUI 插件:在会话里选中任意文本、为它写下注释,让整批注释随你的下一条消息一起发出——只跟随那一轮。 本仓库带有 [`dsh-plugin`](https://github.com/topics/dsh-plugin) 标签(topic)——DeepSeek Harness 文档要求插件仓库带上它以便被发现;上面的链接就是该要求的行内可点击形式。 ## 功能 1. **选中即注释。** 在会话正文里(回复、工具卡片、你自己的消息)选中一段文本,选区旁会浮出「注释」按钮。点击后输入注释,按 **回车** 保存;Shift+回车换行,Escape 取消。 2. **支持多条。** 每条注释都会在它对应的原文处、该行左端显示一个编号标记;**鼠标悬停可看到该条注释的具体内容**。输入框上方出现「N 条注释」状态条,点开可以看到待发批次:每条都带所选文本和注释内容,可编辑、可删除。点编号标记会打开该条注释的编辑框(含删除按钮)。 3. **一起发送。** 发送消息时,你的话后面会多出一条**只有「💬 N 条注释」的短消息**——注释正文不出现在会话里。**鼠标悬停这条消息**可以立刻看到这一批注释分别引用了哪段原文、写了什么。注释本身作为 system prompt 的一节进入本轮请求,模型照样拿到完整的「所选文本 + 注释」。发送后这批注释不再随下一次发送,编号标记保留在会话里(淡显)。 4. **单独发送。** 输入框为空时,状态条上的发送按钮同样可以只用注释发起一轮。 ## 实现方式 浏览器半侧负责编辑界面,Host 半侧负责投递。 - 浏览器把完整批次 POST 到 `/api/dsh-context-annotations`(通过 `ctx.connection.fetch` 注册、位于 carrier 的信任栅栏之后),从不写进输入框草稿。 - Host 按 Session 保存该批次,并监听 `agent/pre-step` 瀑布事件。`pre-step` 交出的正是本步刚 claim 到的消息(不含回放历史),因此一批注释只可能跟随一轮。当该步包含 `source.kind === "user"` 的消息时,Host 在该消息后面追加**一条只含 `💬 N 条注释` 的用户消息**,原来那条用户消息一个字都不改。 - 注释正文不走消息,而是用 `ctx.systemPrompt.section()` 作为 system prompt 的一节提供给模型:日志把渲染后的提示词记为隐藏的 `system/message` 节点,会话界面不显示,模型请求里却有完整内容。 - 这条标记消息发生在该步记录消息之前,所以它是普通 `user/message` 记录的一部分;提示词本身同样可从日志重建。按设计,fork、resume、replay 应当能还原模型看到的那次对话,也没有发明新的插件事件类型。 - 空输入框无法自行提交,因此状态条的发送按钮会写入一个零宽草稿;那一轮就是「一条空的用户消息 + 一条 `💬 N 条注释` 标记」。 - 批次只活到它搭乘的那一轮结束:`pre-step` 标记为已消费(浏览器据此立即收起状态条),该轮 `turn/end` 时从提示词里退役,下一轮不会继承。没有被任何一轮消费的批次会继续待发——在模型还在回答时写下的注释,会等你下一条消息,而不是随那一轮消失。 - 发送后浏览器只做一次轻量核对:Host 显式回传 `consumed`,据此把本地注释标记为已发送(状态条收起、编号标记淡显保留);同一次请求也会在页面刷新后接收仍然待发的批次。 ## 会话里看到的 vs 模型收到的 会话记录里只多出一条短消息: ``` 💬 2 条注释 ``` 模型收到的则是 system prompt 里的一节: ``` 1. 所选文本: <所选原文> 注释:<你的注释> 2. 所选文本: <所选原文> 注释:<你的注释> ``` ## 文件 | 路径 | 作用 | |---|---| | `lib/index.js` | Host 半侧:批次存储、`/api/dsh-context-annotations`、`agent/pre-step` 并入 | | `lib/client.js` | 浏览器半侧:选区按钮、注释输入框、编号气泡、输入框上方状态条与面板 | | `cordis.patch.yml` | 把插件行插入 profile | | `locale/{zh,en}.json` | 插件管理页的标题与描述 | | `test/smoke.mjs` | 无外部依赖的测试:并入语义与浏览器 bundle 注册 | | `test/client.mjs` | 浏览器 store 的回归测试:按会话推送、显式消费、编辑器身份、composer 排除 | ## 配置 本 bundle 目前不读取任何配置。并入内容不带任何标记行,读起来就是用户自己写的编号注释,而不是插件块。 ## 安装 从本仓库安装: ``` plugin_manager install_bundle target="github:YubaiLoving/dsh-context-annotations" ``` 或从本地检出的本目录安装: ``` plugin_manager install_bundle (target: 本目录) ``` ## 已知限制 - 编号气泡以「会话正文扁平化文本里的字符偏移」为主键,并用记录的原文校验;该偏移失效时(上方内容变动),改用忽略空白的文本搜索兜底,靠这段文字的出现序号消歧——没有 DOM 路径兜底。同一段文字重复出现时靠序号区分,落在同一位置的多个气泡会自动错开。 - 注释批次保存在 Host 内存中(按 Session)。Host 重启会丢失待发批次(浏览器只会接收 Host 仍然持有的内容)。 - 浮层、状态条与面板读取会话外壳已公开的 `data-*` 标记(`[data-conversation-content]`、`[data-composer-seat]`、`[data-composer-card]`)以及浏览器自身的选区,不修改任何其他插件的 DOM。 ## 许可 MIT