← Back to home@msun1999

dsh-next-suggestion

Inline next-reply suggestion for the DeepSeek Harness composer: predicts your most likely next message and fills it on Tab.

Stars
0
Language
JavaScript
Created
Oct 22, 2026
Updated
Oct 22, 2026

Introduction

dsh-next-suggestion

DeepSeek Harness 插件 · Inline “next reply” suggestion for the chat composer.

在对话输入框里用灰字预言你接下来最可能说的那句话,按 Tab 一键填入草稿——像 GitHub Copilot,但补全的是你自己的下一句话。


它长什么样

输入框里的下一步建议

助手这一轮回复刚结束,输入框里就会浮现一行灰色文字(上图为界面示意,样式取自真实界面):那是模型根据最近几轮对话猜的你下一句。按 Tab 接受,它变成可编辑的正常草稿(Ctrl+Z 可撤销);不理它、开始打字,它自动消失;直接点这行灰字也能接受。

特性

  • 理解上下文:读当前会话最近 5 条消息,模仿你的语言和口吻(中文/英文都会跟着对话走)
  • 零打扰:只在草稿为空时显示;有内容就自动隐藏;不弹窗、不抢焦点
  • 一键接受:Tab 插入,走编辑器原生的插入接口,可撤销;也可以直接点那行灰字
  • 快:Host 侧订阅 turn/end 事件,回复一结束立刻开始预测(不等轮询、不等静默计时),通常 2–3 秒出现
  • 省钱:按“会话 + 日志序号”缓存,每个轮次最多生成一次,重复轮询不产生额外请求;单次输出上限 700 tokens
  • 纯 JS,无需构建:Host 半是 ESM 模块,Client 半是浏览器直接加载的单文件

安装

方式一:本地目录

# 把仓库克隆到任意位置
git clone https://github.com/msun1999/dsh-next-suggestion.git

然后在 DeepSeek Harness 里让它作为 bundle 安装(plugin_manager 的 install_bundle,target 指向该目录的绝对路径)。 安装后插件会以 include:next-suggestion 出现在 profile 里,重启 GUI 依然生效。

方式二:直接从 GitHub 装

# 在 profile 目录里
pnpm add github:msun1999/dsh-next-suggestion

见方式三的 cordis.patch.yml 片段。

方式三:手动接入 profile

  1. 把包加入 profile 的依赖(pnpm add <路径或包名>)
  2. 在 profile 的 cordis.patch.yml 里加:
- insert:
    - id: next-suggestion
      name: 'dsh-next-suggestion'
  1. 刷新 Web UI 页面

需要 Web 形态的 GUI(dsh.client.platform = "web")与内置的 @deepseek-ai/dsh-client-ui-conversation(对话界面)插件。

使用

操作结果
什么都不做灰字在输入框里徘徊,随时可接受
Tab接受建议,写入草稿(可 Ctrl+Z 撤销)
点击灰字同上
直接开始打字灰字消失,正常输入
发出去 / 换会话该位置的建议被消费,不再重复出现

工作原理

一轮回复结束
   │  Host 订阅 session/event.turn/end
   ▼
生成预测(llm.stream,最近 5 条消息 + 指令,reasoningEffort=low)
   │  结果按 (sessionId, seq) 缓存
   ▼
Client 每 800ms 轮询 GET /dsh-next-suggestion/get?sessionId=…
   │
   ▼
在 conversation.input.overlay 插槽里绘制 ghost text(盖住 placeholder)
   │  Tab
   ▼
inputActions.captureInsertion() + insertText(text, span) → POST /consume

文件结构

文件作用
index.jsHost 半:注册 HTTP 路由、读取会话日志、调用 llm 服务生成预测、缓存与预热
client.jsClient 半:注册到 conversation.input.overlay 插槽,测量输入框位置、绘制 ghost text、处理 Tab
cordis.patch.yml把插件插入 profile 的 Loader 配置
locale/*.json插件在「插件」面板里的标题与描述(中/英)

Host 路由

路由说明
GET /dsh-next-suggestion/get?sessionId=返回 { text }。&refresh=1 丢弃缓存重新生成;&debug=1 只读返回诊断字段(不触发生成)
POST /dsh-next-suggestion/consume{ sessionId },标记该位置的建议已被接受/丢弃,不再重复出现

数据来源与模型选择都跟随当前会话:

ctx.get('sessions').get(id).deriveMessages()                       // 会话上下文
ctx.get('agentDefaultModel').currentSelection()                    // 用户当前选的模型
ctx.get('llm').stream({ provider, model, system, messages, … })    // 生成预测

可调参数

index.js:

常量默认值含义
KEEP_MESSAGES5喂给模型的最近消息条数
MAX_MESSAGE_CHARS300单条消息截断(助手侧)
MAX_USER_CHARS400单条消息截断(用户侧)
MAX_TRANSCRIPT_CHARS3200整段对话总长度上限
MAX_SUGGESTION_CHARS120建议句最大长度
CACHE_LIMIT200缓存会话数上限
TIMEOUT_MS25000单次生成超时
STABLE_MS1200没有状态事件时的静默判定阈值
maxTokens / reasoningEffort700 / 'low'生成预算与思考强度

maxTokens 别压太低:思考内容会先吃掉预算,压到 300 左右会出现“思考写完但正文为空”的空建议。

client.js:

常量默认值含义
POLL_MS800轮询建议的间隔
PROBE_MS300测量输入框位置与空状态的间隔

已知限制

  • 只在草稿为空时提示;已有内容不显示
  • 同一轮里反复改草稿不会重算,要等下一轮回复结束才更新
  • 依赖输入框实现为 contenteditable="true",且 placeholder 写在属性上;若对话界面大改,需要重新校准 pickEditor() 与背景取色
  • 预测走当前会话所用的模型;若该模型思考很长,出现时间会相应变慢
  • 建议可能不准——它只是一句话级的猜测,接受前请自己过一眼

开发与调试

改完 index.js / client.js 后,把 profile 里的 include:next-suggestion 关掉再打开即可重载(ESM 缓存会被重置、Client bundle 版本号会更新);不行就再刷新一次浏览器页面。

诊断接口:

curl "http://127.0.0.1:<gui-port>/dsh-next-suggestion/get?sessionId=session-xxxx&debug=1"

返回 sessionFound / seq / tailRole / ready / busy / inflight / cachedSeq / lastMs / lastRaw / lastError / target / text,可用来确认是否命中会话、是否在生成、上一次生成花了多久、原始输出有没有被清理。

License

MIT