Back to catalog

shaoeric /

dsh-suggest

Verified

dsh-suggestion

2 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
READMESource: main@ccbc98ae

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

English | 中文


✨ 功能特性 / 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.patchdsh.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 的 dependenciesdsh.profile.bundles(因为包声明了 dsh.bundle)。装完重启生效:

  1. 在运行 dsh web 的终端 Ctrl+C 停掉服务器;
  2. 重新运行 dsh web;
  3. 刷新浏览器页面。

重启后: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)。

  1. 在 DSH Web GUI 中用「创造模式」preset 打开一个会话;
  2. 让 Agent 安装本插件(把仓库交给 Agent),或手动操作:
    • cordis_define 创建插件:code.host 粘贴 host.js 内容,code.client 粘贴 client.js 内容;
    • cordis_run 激活返回的 pluginId / packageId;
  3. 首次运行需在 GUI 中批准插件(单勾授权当前版本,双勾授权后续更新);
  4. 之后每一轮回答结束,答案下方即出现 3 个推荐问题。

⚠️ 生命周期说明:动态插件是进程内临时定义,DSH 进程重启后即丢失,需重新 define + run。如需跨重启持久存在,用上面的方式一(正式插件)。

🧰 依赖的能力 / Dependencies

  • Host 服务:llmsessions(可选 sessionQueryagentDefaultModel 作为回退);正式版另需 typert(注册 Remote manifest)
  • Client 内置:动态版 Reacthoststyles;正式版 remote(api-gateway client)、slots(client-runtime)与 react 模块
  • 客户端插槽:conversation.chat.turnTail(由 dsh-client-ui-conversation 声明)
  • 标准 Props:sessionIdinputActionsuseSession(客户端会话标准套件)

🛠️ 常见问题 / Troubleshooting

现象 处理
显示 ⚠️ 推荐生成失败 + 原因 按提示点击重试;错误文字含 kind 与错误码,可用于进一步定位
推荐项不出现 确认插件已批准并处于 running;刷新页面后查看历史轮次
希望恢复水平布局 client.js 中推荐区容器类名从 dshrec-x42-list 改回 dshrec-x42-section,并删除 list 相关 CSS

🏷️ GitHub Topics / 仓库标签

建议在仓库 Settings → Topics 中设置:

dsh  dsh-plugin  deepseek  deepseek-harness

同时推荐补上:deepseek-apicordis(可选)。

🔍 技术参考 / 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.tssrc/client/chat/TurnTailNodeView.tsx
链式选举分发:按 priority 升序遍历条目,运行 entry.select(ownerProps),首个非 null 返回值胜出并以 matched 属性挂载;全部返回 null 则走 owner fallback @deepseek-ai/dsh-client-web-react src/scoped-slots.tsx(SlotOutlet / renderOutletContentspec.kind === 'chain' 分支)
条目注册与优先级排序:SlotCore.registerrec.entriespriority 升序排序;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

/ 5

No ratings yet

Community comments

No comments yet. Be the first to write one.