shaoeric/dsh-suggest
dsh 建议
项目介绍Project Overview
dsh-suggest 是 DeepSeek Harness 插件,在每轮 Agent 回答下方生成 3 个可点击、可编辑的后续问题。它基于最近 3 条用户消息及助手回复,优先用同 provider 的 flash 模型并关闭思考来快速生成,点击可直接发送,悬停可编辑后再发,带缓存、骨架占位与失败重试。适合想延续对话、减少手动提问时使用。注意推荐仅显示在最新一轮,动态形态重启后失效。
dsh-suggest is a DeepSeek Harness plugin that renders three clickable, editable follow-up questions under each agent answer. It uses the latest three user messages and intervening replies, preferring the provider’s flash model with thinking disabled for fast generation; clicks submit directly, while hover editing fills the draft first. Use it to continue conversations with less typing. Suggestions appear only on the latest turn, and the dynamic form is lost on restart.
请帮我了解并安装插件:【dsh-suggest】【https://github.com/shaoeric/dsh-suggest】
把上面这条消息直接发给当前会话里的 DSH,让它帮你了解并安装。安装命令不一定准确,发给 DSH 更稳。Send this message to DSH in your current session. CLI install commands may not be accurate across systems — DSH will figure it out for you.
或使用命令行安装(适合开发者)Or use CLI install (for developers)
命令行安装CLI Install
dsh plugin --profile web add github:shaoeric/dsh-suggest
把 shaoeric/dsh-suggest 加入你的 DSH 配置(web profile)即可启用。
READMEREADME
dsh-suggest
DeepSeek Harness 插件(动态 + 正式双形态):Agent 每轮回答完成后,在答案下方生成 3 个可点击、可编辑的推荐后续问题。
A DeepSeek Harness (DSH) plugin (dynamic and formal forms) that renders three clickable, editable follow-up question suggestions under every agent answer.
🏠 仓库:https://github.com/shaoeric/dsh-suggest
✨ 功能特性 / Features
- 自动生成:Agent 回答完成后,基于最近 3 条用户消息(含其间助手回复)自动生成 3 个推荐问题,以用户意图为锚点、紧扣最新进展;
- 一键直达:点击推荐项 → 内容直接提交给 Agent,自动开启新一轮回答;
- 先编辑再发送:悬停推荐项会浮现 ✏️ 编辑按钮,点击后内容填入输入框,编辑满意后自行发送;
- flash 模型 + 关闭思考:优先使用同 provider 的 flash 模型,请求携带
reasoningEffort: 'off'(DeepSeek 适配器映射为thinking: disabled),生成又快又省;找不到 flash 或适配器不支持时自动回退;失败则回退会话原模型; - 稳定兜底:按会话+轮次缓存、生成中显示骨架占位、失败显示具体原因并可一键重试;
- 只显示最新一轮:推荐项只在最新一轮回答下方显示,发起新一轮对话后自动隐藏,避免误触;同时补渲染 📎 产物行不丢失;
- 主题自适应:全部配色使用
--dsw-alias-*主题变量,自动适配明暗模式。
🧱 工作原理 / How It Works
| 半区 | 平台 | 职责 |
|---|---|---|
host.js |
Host(Node) | 通过 harness.handle('recommendations') 暴露包内 RPC(正式版经 Typert Remote 暴露 suggest/recommendations);读取会话日志(≤ 收尾 seq),以最近 3 条用户消息为锚点截取上下文;优先使用同 provider 的 flash 模型(找不到则回退会话模型)调用 llm.stream 生成 3 个推荐(关闭思考模式),带缓存与并发去重 |
client.js |
Client(浏览器) | 注册 conversation.chat.turnTail 链式插槽(priority: -1);渲染垂直左对齐的推荐列表;点击 → inputActions.setDraft + submit() 直发;点 ✏️ → 仅 setDraft 填入输入框 |
回答完成 → turn-tail 节点渲染
→ 链选举命中本插件 → 组件挂载
→ host.call('recommendations', {sessionId, turn, seq})
→ Host 截取最近 3 条用户消息上下文 → flash 模型(thinking off)生成 JSON 数组
→ 返回 3 条推荐 → 渲染为可点击列表
📁 文件结构 / Files
dsh-suggest/
├── host.js # 动态插件 Host 半:推荐生成(RPC、会话读取、LLM 调用、缓存)
├── client.js # 动态插件 Client 半:turnTail UI、点击直发、hover 编辑、产物行
├── lib/
│ ├── index.js # 正式插件 Host 半(与 host.js 同逻辑;Typert Remote + strict manifest)
│ └── client.js # 正式插件 Client 半(与 client.js 同逻辑;ModuleLoader bundle)
├── package.json # 正式插件包清单(dsh.bundle.patch + dsh.client)
├── cordis.patch.yml # 正式插件插入 host composition 的 patch 层
├── dsh.plugin.json # 正式插件清单
├── LICENSE # MIT License
└── README.md
🚀 安装与使用 / Install & Run
本插件提供两种安装方式:正式插件(从仓库安装,持久化,推荐)与动态插件(临时,进程重启即失效)。两套代码功能一致:lib/ 是正式插件形态,host.js / client.js 是其动态源。
方式一:正式插件(从仓库安装,持久化,推荐)
仓库根目录本身就是一个标准 Harness web 插件包(声明了 dsh.bundle.patch 与 dsh.client)。把仓库克隆到本地后,用 dsh plugin 直接装进 web profile,跨重启常驻。
从仓库安装:
git clone https://github.com/shaoeric/dsh-suggest
cd dsh-suggest
dsh plugin --profile web add file:$(pwd) # Linux/macOS
# Windows(PowerShell)换成仓库绝对路径,例如:
dsh plugin --profile web add file:C:/path/to/dsh-suggest
file:后面接的是仓库根目录的绝对路径——这个仓库根目录本身就是插件包(pnpm 只打包files字段列出的文件)。
dsh plugin add 会代理到 profile 目录里的 pnpm,并自动把包登记进 profile 的 dependencies 与 dsh.profile.bundles(因为包声明了 dsh.bundle)。装完重启生效:
- 在运行
dsh web的终端 Ctrl+C 停掉服务器; - 重新运行
dsh web; - 刷新浏览器页面。
重启后:Host 半随进程启动挂载(Typert Remote 端点 suggest/recommendations),浏览器半由 Web 服务器在 /plugins/dsh-suggest/client.js 提供给每个页面。
更新(改了 lib/ 或清单后):
⚠️
file:依赖缓存安装时的快照,直接重跑add不会刷新内容;先 remove 再 add。
dsh plugin --profile web remove dsh-suggest
dsh plugin --profile web add file:/绝对路径/dsh-suggest
# 然后重启 dsh web
卸载:
dsh plugin --profile web remove dsh-suggest
# 然后重启 dsh web
正式版与动态版的实现差异:
动态版(host.js / client.js) |
正式版(lib/) |
|
|---|---|---|
| 包内 RPC | harness.handle / host.call(动态 runner 注入) |
Typert Remote:suggest/recommendations 端点 + strict manifest,经 api-gateway 走 /api |
| 服务访问 | ctx.get('llm') 等(动态 sandbox 门面) |
相同(正式 Cordis ctx.get 语义一致) |
| 客户端环境 | runner 闭包注入的 React / host / styles 全局 |
require('react') + ctx.remote.$mount + <style> DOM 注入 |
方式二:动态插件(临时)
需要 DSH 的 Cordis 插件能力(「创造模式」agent preset)。
- 在 DSH Web GUI 中用「创造模式」preset 打开一个会话;
- 让 Agent 安装本插件(把仓库交给 Agent),或手动操作:
- 用
cordis_define创建插件:code.host粘贴host.js内容,code.client粘贴client.js内容; - 用
cordis_run激活返回的pluginId/packageId;
- 用
- 首次运行需在 GUI 中批准插件(单勾授权当前版本,双勾授权后续更新);
- 之后每一轮回答结束,答案下方即出现 3 个推荐问题。
⚠️ 生命周期说明:动态插件是进程内临时定义,DSH 进程重启后即丢失,需重新 define + run。如需跨重启持久存在,用上面的方式一(正式插件)。
🧰 依赖的能力 / Dependencies
- Host 服务:
llm、sessions(可选sessionQuery、agentDefaultModel作为回退);正式版另需typert(注册 Remote manifest) - Client 内置:动态版
React、host、styles;正式版remote(api-gateway client)、slots(client-runtime)与react模块 - 客户端插槽:
conversation.chat.turnTail(由dsh-client-ui-conversation声明) - 标准 Props:
sessionId、inputActions、useSession(客户端会话标准套件)
🛠️ 常见问题 / Troubleshooting
| 现象 | 处理 |
|---|---|
显示 ⚠️ 推荐生成失败 + 原因 |
按提示点击重试;错误文字含 kind 与错误码,可用于进一步定位 |
| 推荐项不出现 | 确认插件已批准并处于 running;刷新页面后查看历史轮次 |
| 希望恢复水平布局 | 把 client.js 中推荐区容器类名从 dshrec-x42-list 改回 dshrec-x42-section,并删除 list 相关 CSS |
🏷️ GitHub Topics / 仓库标签
建议在仓库 Settings → Topics 中设置:
dsh dsh-plugin deepseek deepseek-harness
同时推荐补上:deepseek-api、cordis(可选)。
🔍 技术参考 / Where the slot dispatch lives
conversation.chat.turnTail 是 DeepSeek Harness 内置的链式(chain)插槽,其声明与分发逻辑位于 DSH 源码(deepseek-ai/DeepSeek-Harness)的三个包中:
| 逻辑 | 包 | 源文件 |
|---|---|---|
插槽声明与渲染入口:turn-tail 节点注册(key: 'turn-tail',children 声明 conversation.chat.turnTail chain)并调用 renderSlotChain(..., { turn, seq, openFile }) |
@deepseek-ai/dsh-client-ui-conversation |
src/client/chat/register-node-renderers.ts、src/client/chat/TurnTailNodeView.tsx |
链式选举分发:按 priority 升序遍历条目,运行 entry.select(ownerProps),首个非 null 返回值胜出并以 matched 属性挂载;全部返回 null 则走 owner fallback |
@deepseek-ai/dsh-client-web-react |
src/scoped-slots.tsx(SlotOutlet / renderOutletContent 的 spec.kind === 'chain' 分支) |
条目注册与优先级排序:SlotCore.register 对 rec.entries 按 priority 升序排序;chain 注册必须提供 select |
@deepseek-ai/dsh-client-ui-slots |
src/index.ts(SlotCore.register,约 121–123 行的 next.sort) |
本插件即依赖这套机制:select 无条件认领(priority: -1,先于内置的产物行条目 x6),组件内自行补渲染产物行,因此推荐项出现在每个完成的回答下方。
📄 License
MIT © 2025 shaoeric
nexu-io/open-design
freestylefly/awesome-gpt-image-2
anywhere-labs/dsh-desktop
walkinglabs/learn-harness-engineering
awesome-dsh-plugin/awesome-dsh-plugin
MemTensor/MemOS