dsh-quote-message
Verified@sumomok/dsh-quote-message · v0.3.1 · MIT · Web UI
Quote earlier content of the current session into the composer: select any passage in the chat and a native reference chip carries the text into the prompt, rendered back as a quote card above your message
Install
dsh plugin add @sumomok/dsh-quote-message Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Published to npm without a public repository. Inspect the package contents before installing.
Tags
Readme
@sumomok/dsh-quote-message
English | 中文
在输入框里精确引用当前会话已有的内容:在任意消息里选中一段话,一枚原生引用 chip 就把那段文字带进这次提问。发出去之后,引文不会以一串 > 留在气泡里,而是变成气泡上方一张独立的引用卡片。
模型于是确切知道"这个"指的是什么,而你没有重新打一遍。
为什么需要它
对话一长,代词就变贵。"把你列的第二个问题修掉"要求模型重读上文并猜你指哪一条,猜错的频率高到最省事的补救是手工把原文粘回去。
手工粘贴丢掉了出处:模型看到的是一段没有来历的文字,不知道那是它自己此前的回答,还是你自己此前的提问。这个插件把引用说清楚——角色、位置、原文——并且在你发送之前就以一枚 chip 的形式摆在那里。
怎么用
选中即引用。 在任意消息里选中文字——用户提问、助手回复、工具结果的文本都算——选区上方浮出一枚 引用 小按钮。点击后,chip 追加到草稿末尾,后面跟着输入框自己补的那个分隔空格。之所以落在末尾而不是光标处:输入机器对外发布的草稿状态只有正文和一个修订号,不含光标位置。Escape、点击别处、滚动都会让它消失,它自始至终不会把焦点从输入框抢走。
chip 和内置的 @file / @session chip 一样渲染——同样的高度、同样的配色,@ 的位置换成会话图标(引用指向的正是本会话里的一条消息)——在你继续编辑草稿时保持完整,只在发送时才展开。
@ 不归我们管。 那个触发符属于文件和会话,本插件不往那个菜单里加任何分组。它注册的那一个 trigger source 只携带 codec:引用位点是靠 source 名字在这个注册表里查到展开器的——注册是为了让 chip 能被发送,不是为了上菜单。
模型收到什么
发送时,每枚 chip 在它所在的位置展开成一段 markdown 引用块:
> 引用:
> 被引用的第一行
>
> 被引用的第二行
表头只说明一件事:下面是一段引文。位置、角色、宿主内部的 message id 都不进表头——那些是你挑选原文时用得上的上下文,不是模型阅读时用得上的。chip 自己的载荷里仍然带着它们(它的标签写作 引用 #12 助手,message id 留给将来的解析),而人和模型读到的任何投影都不会印出那个 id。
表头跟随界面语言,且在发送那一刻读取而不是插入那一刻:中文界面下是 引用:,英文界面下是 Quote:。下面那行截断提示两种语言下都保持英文:它是对节选长度的度量,不是写给读者的话。
除此之外不注入任何东西。引用块就是你这次提问的一部分,宿主按普通的 user/message 记账。
在转录里长什么样
发出去的引用不会以一串 > 留在气泡内部。插件把它提到消息上方,排成一段纯排版的引文:左侧 2px 的竖线加次级字色的正文,没有卡片底也没有抬头标签,右对齐,宽度贴着文字并沿用气泡自己的上限。超过三行折叠,并给出 展开 / 收起;这个按钮只在文字真的溢出时出现,展开状态属于当前视图,不做持久化。模型读的那行 > 引用: 是标记引文的记号,本身不属于引文,因此它不进入显示,也永远不会从日志里被拿掉。
这是遮挡,不是打补丁。keyed 的 conversation.chat.node 槽位渲染每个格子里优先级最低的那个在册条目,所以本插件用 priority: -1 注册 user 和 steering 两个格子,从槽位账本里取出宿主自己的渲染器,把其余一切原样交回去——宿主条目仍以默认优先级在册,既没有被替换也没有被 import。不含引用块的消息原封不动地抵达它:渲染测试断言产出的标记与单独渲染宿主组件逐字节相同;浏览器里对同一条普通消息在装与不装插件两种状态下截图,287264 个像素中有 20 个不同,全部落在滚动条那一列,且差值不超过 2/255。
退场条件。 宿主哪天自己渲染引用内容,插件的这一半就删掉,只留序列化。遮挡之所以存在,是因为客户端没有发送阶段的缝,也没有按消息挂装饰的槽位:引文只能藏在提问正文里传过去,于是把它再取出来只能是渲染期的决定。
边界
- 每条引用 4000 字符。 更长的消息按码点截断到 4000,块尾补一行
…(truncated, 9123 chars total),让模型知道自己读到的是节选。 - 小按钮是追加到末尾,不是插到光标处。 宿主发布的输入状态里没有光标可用。
- 只限当前会话。 跨会话引用是宿主自带的
@session引用的职责。 - 只带文字。 被引用消息里的图片和附件不会被带上,助手的思维链也不引用——引用带走的是"说了什么"。
- 要改就删掉重引。 chip 插入后不支持原地编辑。
- 只从选区开始。 没有选择器:引用的起点永远是你在会话里选中的那段文字。
- 复制按钮复制的是余下正文,不含引文。 宿主的复制读的是气泡自己的内容,而引文已经不在里面;只有引文、没有正文的消息复制出来是空的。卡片里的文字可以直接选中,会话日志里也仍是完整提问。
- 只有落在消息两端的引用块才变成卡片。 夹在中间的
>是你自己写的散文,留在原处。
安装
pnpm run build
cd packages/quote-message && pnpm pack --pack-destination ../../dist
dsh plugin --profile <name> add ../../dist/sumomok-dsh-quote-message-0.3.1.tgz
发布之后,dsh plugin --profile <name> add @sumomok/dsh-quote-message 从 npm 装同一份东西。
清单里声明了 dsh.bundle.patch,所以安装会把本包追加进 profile 的 dsh.profile.bundles,由它的 patch 层挂载插件;profile 自己的 cordis.patch.yml 不需要任何改动。请装 tarball 而不是 link: 路径——被 link 的副本会解析到自己的 @deepseek-ai/* 并加载第二个 cordis,插件拿到的服务注册表就不是应用真正在跑的那个了。
profile 里需要有组装 Web 界面的 bundle(@deepseek-ai/dsh-web-app);纯 headless 的 profile 里没有东西可看。
权限与安全
本插件纯客户端。宿主半边是个空实现,存在的唯一理由是让 loader 看到一个真正的 cordis 插件。
- 不联网。 它不建立任何自己的连接;被引用的文字除了随你发出的提问之外,不离开页面。
- 不碰文件系统。 无论工作区内外,它不读也不写任何文件。
- 不写自定义会话事件。 它不往会话日志里写任何东西。它交给模型的一切都走普通提问通道,由宿主记为
user/message——所以卸载它绝不会留下一个宿主拒绝加载的会话。 - 不加宿主路由、不加宿主服务、不加 RPC。 Web 服务器和远程 API 上都没有它的新增面。
- 不做持久化。 引用只活在输入框草稿里,没有缓存、没有 local storage、没有跨刷新的状态。
它确实接触的东西:当前会话的对话快照(只读)、输入触发器注册表(一个 @ source)、输入区 dock 的一个槽位、被它遮挡用来画卡片的两个 keyed 聊天节点格子,以及 document 上的选区事件。
兼容性
针对 @deepseek-ai/* 0.1.1-rc.2 构建,对应这一代宿主(桌面应用或源码检出)。peer 范围写成 >=0.1.0-rc.1 <0.2.0 是为了让预发布版本的宿主能匹配上:按 semver 的预发布规则,^0.1.0-rc.7 匹配不上 0.1.1-rc.2。
它用的都是公开的缝:inputTriggers.registerSource(ReferenceInsert 结果 + ReferenceCodec)、conversation.input.dock 槽位、作用域事件 slash/input-insert-reference,以及 keyed 的 conversation.chat.node 槽位——以 priority: -1 进 user 和 steering 两个格子(文档化的遮挡语义:优先级最低者渲染)。它不对宿主渲染的气泡做 DOM 手术,不拦截输入框按键,也不装 MutationObserver——它从宿主 DOM 里读的唯一一样东西,是 Web 客户端为自己的滚动锚定打在每个聊天行上的 data-chat-flow-key 属性。
许可
MIT。