Passer au contenu principal
H

dsh-plugin-response-window

heiheiha798/dsh-plugin-response-window

Plugin d’interface web qui replie la réflexion et les appels d’outils de chaque réponse étagée dans des fenêtres coulissantes délimitées par segment et défilables, avec une hauteur configurable, en gardant chaque réponse intermédiaire visible.

Installer

dsh plugin --profile web add github:heiheiha798/dsh-plugin-response-window

README

dsh-plugin-response-window

DeepSeek Harness (DSH) Web 插件:把一轮里的 think(推理)和工具调用放进有限高度的可滚动窗口(默认 10 行),以阶段性文字回复为界分段,每个分段一个 slide;文字回复保持原生完整显示、不做限高。中间过程始终可见(只是不撑爆页面)——Grok Build 风格。

与「全部折叠成 summary」类插件(如 dsh-tool-summary)不同:本插件不隐藏任何内容。think 与工具调用一条条列在 slide 里,每段都能展开翻到底;文字回复完全原生展示。 只包 bash + think:阶段性/最终文字 response 不加限高、不加「展开全部/收起」按钮。

效果

一个 prompt 之后有 100 次 tool call + 长回复时:

  • think(推理)和工具调用 → 合并为 slide(think 与 tool call 都是 implementation,不做区分):
    • 以「阶段性文字回复」为界分段:模型中途直接返回给用户的每条文字 response 是天然分隔点;两个分隔点之间的一段 think+bash 是一个 slide。不会两个 input prompt 之间挤成一整个 slide
    • 头部:10 个工具调用 · 5 Think(无 emoji、无冗余序号)+ 进行中 / 失败徽标,可点击收起/展开
    • 主体:max-height: N 行(默认 10)的内部滚动区
      • think 与工具调用严格按真实输出顺序交错排列(不做「think 全在上 / bash 全在下」的强行分区)
      • 每段 think 一行(Think + 单行摘要 + 展开箭头),默认折叠,点击展开完整推理(内部限高滚动);展开文字与工具输出同字号(同一 mono 字体)
      • 每条工具调用一行(状态点 + 工具名 + 单行摘要),点击展开参数/输出(输出再限高一档,内部滚动)
    • 执行中自动跟随底部
  • 原生 Think 行从消息流中隐藏(该段已并入 slide,避免重复显示),与 slide 内展示共用同一份内容
  • 阶段性文字回复与最终回复 → 完全原生展示,保持全文可见,不套 slide 窗口、不加任何按钮
  • 用户消息始终是「整轮的分隔点」,保持原位

效果预览见 GitHub 仓库页面或自行安装体验(仓库不再内置运行截图,避免暴露会话内容)。

安装

dsh plugin --profile web add github:heiheiha798/dsh-plugin-response-window

或本地 link 方式(开发调试):

git clone https://github.com/heiheiha798/dsh-plugin-response-window.git
cd dsh-plugin-response-window
dsh plugin --profile web add "link:$(pwd)"

装完重启 dsh web(或等 profile HMR)生效。

卸载:dsh plugin --profile web remove dsh-plugin-response-window

配置

cordis.patch.yml 里插入了默认配置,可改:

键默认说明
lines10窗口高度(行)。0 = 不限高(等价于关闭窗口)
collapsedfalse每轮 slide 是否默认收起成一行 bar。默认 false:始终展开、内容可见
showReadOnlytrue是否在 slide 里列出 read/grep/web_search 等只读调用(默认全列出,不藏)
minCollapseRows3仅 collapsed: true 时生效:少于该数量的轮次不收起

设置页(Settings → General)

插件在 Web UI 的 Settings → General 里注册了一项 「响应窗口大小(行数)」:

  • − / 数值输入 / +:调整 lines(0–200,0 = 不限高,默认 10)
  • 即时生效:改动后已渲染的 slide 高度立刻变化(经宿主 settings namespace dsh-plugin-response-window 持久化)

实现说明(为什么安全)

  • 0.2.0 起:工具调用 slide 通过 conversation.chat.node 的 keyed 替换(key: 'tool-call')实现 —— 这是 dsh 0.1.5-rc keyed Chat Node 契约的文档化语义(同 key 注册即替换该 kind 的渲染器),不再使用旧的 priority shadow。
  • 分组完全走会话模型:渲染器拿到类型化 node(node.location.turn.turn)与 useChat 选择器(ChatSnapshot.locations.getTurn(turn) + nodes),与右侧用户消息索引(turn rail)消费同一份 turn/location 数据 —— rail 导航落点与本插件的分段分组天然一致,不依赖任何 DOM 测量。
  • DOM 标记(隐藏的原生 Think 行、null 渲染的 sibling 工具行、think-only 幽灵行)全部由模型推导的覆盖集合驱动:slide 渲染器把每轮的覆盖键集合发布到注册表,一个隐形 dock 通过 MutationObserver 把集合应用到行上的 data 属性。布局竞态不再能标错行 —— 消除了 DOM 启发式版本的整类 bug(底部空隙、最终回复刷新前不可见)。
  • 绝不移走 React 拥有的 [data-chat-anchor-key] 行节点。实测:把行移进自定义容器后,一旦 DSH 后续移除该行(会话切换/编辑/压缩),React 会调用 parent.removeChild(row) 抛 NotFoundError,整个会话树被卸载——因此本插件只用「keyed 替换 + 类/CSS」两种方式,对 React 行结构零改动。
  • 原生 Think 行隐藏与 slide 内的 think 同步:只对「该段内有 slide」的原生 data-variant="think" 行加 display:none(DOM 类/CSS,无重挂、无删除),其余(无工具调用的纯 Think 段)保持原生显示。
  • 插件只读 ChatSnapshot(useChat),不写快照、不调宿主 API。createSnapshotStore 依赖已移除(dsh-client-runtime 包已于 2026-08-22 从 dsh 移除),改用内置的最小可观察值存储。

开发 / 测试

纯 JS,无构建步骤:

npm run check   # node --check lib/index.js && node --check lib/client.js

E2E(需要已启动的 dsh web 与 python playwright):

dsh --profile web --no-open --port 3639 &
python3 test/e2e.py --url http://127.0.0.1:3639 --session "架构重构不顺原因分析"
  • 宿主半:lib/index.js(注册 settings namespace,依赖 @deepseek-ai/schemastery)
  • 浏览器半:lib/client.js(window.__ModuleLoader__.load,依赖 web 运行时注入的 react、slots 与 settings scope)

License

MIT

Plugins associés