DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

Lichadai /

Lichadai/dsh-we-need-plugin

Verified

DSH We Need 插件:按发给上游的 model id 里的 DeepSeek + Flash 筛选(provider 不限),命中后交回原 provider adapter 注入 728/728 WeNeed seed,不需要配置供货商。安装后请先读 README 的「使用技巧」。仅适用于 DSH。

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@9e452873

DSH We Need Plugin

DeepSeek Harness(DSH)Host 插件:在模型请求的最后一条真实 user task 之前,插入一条 728/728 的 WeNeed assistant seed,让 DeepSeek Flash 更容易进入 We need / Let's / We / Should 的思维风格。

这是概率性引导,不是硬开关。它提高触发概率,但不保证每一次都进入 WeNeed 寄存器。

  • 项目主页:https://github.com/Lichadai/dsh-we-need-plugin
  • 讨论区:https://github.com/Lichadai/dsh-we-need-plugin/discussions
  • 安装包:https://github.com/Lichadai/dsh-we-need-plugin/releases

第一次使用请先读 0.5 使用技巧:工具尽量后调用,先思考/计划,不要过早调用工具。

可选增强:如果你能修改 System Prompt,建议把 5.3 里的 728 seed 原样追加到 System Prompt 的最后,触发概率可能更高。它不是必选项,注意事项见 5.3。


先读(30 秒)

  1. 使用技巧:工具尽量后调用;先分析问题、做计划,不要急着写文件或调用工具;可以先读 skill,但不要过早调用工具。详见 0.5 使用技巧。
  2. 模型筛选:只看发给上游的 model id(DSH 传给 provider 的 model)是否同时包含 deepseek 和 flash,大小写不敏感;provider 完全不参与,也不需要配置 provider 路由。默认不读界面显示名。详见 0.6 模型筛选规则。
  3. 怎么工作:命中后插件把带 seed 的 messages 交回 DSH 原来的 provider adapter,provider、baseURL、API key 都沿用原来的,所以任何供货商都行。详见 0.7 它怎么工作。

0. 先看这个

0.1 WeNeed 不是某一个模型,而是一类思维风格

WeNeed 不是 DeepSeek 独有的私有开关,也不是只能由某一家模型产生。它是一类以 We need、Let's、We、Should 作为句子开头为主要特征的思维风格:

We need understand the task...
Need inspect the inputs...
Let's plan before acting...
Should verify against the requirement...

这种风格通常有三个特征:

  • 注意力比较稳;
  • 愿意连续调用工具推进任务;
  • 很少陷入“雷霆大思考”——反复检查、反复自我修正、纠结细节。

一旦句子里大量出现 I、Let me、I will,通常说明模型的思维力被过多的混杂信息冲散了,开始从“推进任务”退化成“围着细节打转”。

0.2 三个最常见的干扰源

实际使用 DeepSeek 时,最容易把注意力冲散的是三类信息:

  1. 工具信息过大:工具 schema、工具调用历史、工具结果太多;
  2. 工作区文件夹混杂:长期在一个大目录里工作,项目多、文件多、临时文件多;
  3. skill 信息过大:skill catalog 很长,或加载了很长的 skill 正文。

这些信息本身不是没用,但一旦过于庞大,就会把模型拉到细节里,失去对大局和任务清单的把控。表现就是“雷霆大思考”:反复读、反复比、反复改,迟迟不推进。

一个很实际的印证:

  • 以 Let me 为主的涣散思维,完成任务时经常不知道自己该更新任务清单;
  • 以 We need / Let's 为主的 WeNeed 模式,通常会主动完成任务,并知道更新任务清单;
  • 但即使是 WeNeed 模式,有时也会忘记更新任务清单——这往往说明上下文里无意义、与思维不相关的混杂信息太多,已经影响了思维力和注意力。

0.3 使用 DeepSeek 的建议

  • 工作区保持干净,项目尽量少;及时清空不必要的文件夹、临时文件和旧项目。
  • 工具调用时间往后延:在 skill 目录不是特别大时,先让模型读 skill、做规划,最后再调用工具。不要让庞大的工具基座信息先冲散思维。
  • 工具很多、文件夹很杂、skill 很长时,优先清理上下文;不要只依赖 seed。
  • 出现 Let me、I、I will 时,先怀疑工具调用过多,或信息获取不当、过大;不要只怪模型。

0.4 适用边界:只适用于 DeepSeek Harness

本插件只针对 DeepSeek Harness。

测试过 Qoder:Qoder 在使用第三方 API 时,reasoning_content 不回传。上下文内容还在,但思维过程会丢失,所以同样的 seed 在 Qoder 上不能稳定生效。

那种情况只能走代理/镜像路线:把上下文里的内容克隆到思维字段里,让思维链不中断。这是另一条技术路线,不在本插件的范围内。

补丁说明:作者不是专业编程人员,对 reasoning 回传的底层机理可能理解不完整,也可能没有找到 Qoder 正确的回传方式,因此上面的判断可能是误判。如果 Qoder 后续版本提供了 reasoning 回传能力,请以实际版本为准。


0.5 使用技巧(先读这个)

这些技巧和 seed 一样重要。工具很多、工作区很杂、skill 很长时,它们比 seed 更能决定模型会不会进入 WeNeed。

0.5.1 工具尽量往后调用

  • 先让模型分析问题、做计划、想清楚要改哪些文件;不要一上来就读一堆文件、跑一堆命令。
  • 工具 schema 很多、skill catalog 很长时,先读 skill、做规划,再调用工具。
  • 如果任务不需要工具,直接让模型思考/回答;不要为了“看起来在工作”而过早调用工具。
  • 工具调用越早、越多,后面的 reasoning 越容易被工具结果和细节带偏。

0.5.2 先思考,不要急着写下来

  • 先让模型想清楚“要解决什么、分几步、每一步怎么验证”,但不要要求它立刻写文件或改代码。
  • 先让它思虑一段时间,再决定是否调用工具;尤其是大任务、跨文件任务。
  • 计划可以先留在 reasoning 里,不必马上落盘;落盘会引入额外工具步骤和上下文。

0.5.3 Skill 可以看,但不要过早调用工具

  • skill 目录不大时,先让模型读相关 skill,再做计划。
  • 不要让模型在读 skill 的同时并行调用大量工具。
  • skill 信息本身也会占上下文;读最相关的,不要把全部 skill 都塞进去。

0.5.4 其他

  • 工作区保持干净,项目少,临时文件少。
  • 工具多时,优先清理不用的工具和配置。
  • 出现 Let me、I、I will 时,先减少工具和信息,不要只加 seed。
  • seed 是概率性增强,不替代上下文管理。

0.6 模型筛选规则:什么时候生效

代码位置:index.js → isTarget()。

匹配文本默认只有:

const text = String(modelId ?? '').toLowerCase();
  • modelId 是 DSH 传给 provider 的 model id,也就是请求里的 model 字段;我们的自定义 adapter 会原样写入 body.model,delegated 模式也保留它;
  • 不是 UI 上看到的显示名;
  • 只有显式 matchName: true 时,才把 interceptModels[].name 拼进来;
  • provider 名称完全不参与匹配;
  • 默认 targetRules: [deepseek, flash],两个词必须同时出现;
  • 大小写不敏感。

真正生效要同时满足:

1. model id(或显式 matchName 时的 name)命中 targetRules;
2. 不是插件自己的 provider,且 purpose 为空;
3. 不是 tool step、压缩请求、标题/建议调用;
4. target 没有被设成 false;
5. DSH 有 ctx.llm.prepareCall(当前版本有)。

不需要 interceptModels 路由,也不需要按 provider 配置 baseURL/key。没有路由时走 delegated 模式,见 0.7。

例子:

  • deepseek-v4.1-flash:id 含两个词,命中;
  • d4/deepseek-v4.1-flash-1017:即使没配 d4 路由,也命中;
  • vendor-alias,显示名 DeepSeek-V4.1-Flash:默认 matchName: false,不命中;显式 matchName: true 并配置 name 后才命中;
  • deepseek-v4-pro:没有 flash,不命中。

怎么改:

  • 只改识别范围:改 targetRules;
  • 默认不要改 provider;任何 provider 都走原 adapter;
  • 如果模型 id 是 opaque、只有显示名可读:当前版本需要高级自定义路由(matchName: true + 完整 interceptModels 路由),见 10.8;默认不靠显示名;
  • 想让插件自己发 HTTP、精确控制字段顺序:才需要 interceptModels 路由(高级选项,见第 8/9 节);
  • 未来模型(4.1 Pro、Kimi K3.1 等)的写法见第 10 节。

0.7 它怎么工作(provider 不限)

默认发布包不注册 provider,也没有 interceptModels 路由。命中模型 id 后:

1. 过滤 skill catalog;
2. 在最后一条真实 user task 前插入 assistant seed;
3. ctx.llm.prepareCall(provider, model, controls) 取得原 provider 的调用句柄;
4. prepared.stream({ ...原 options, ...prepared.config, messages: 注入后的 messages, __weneedBypass: true });
5. 原 provider adapter 用原来的 baseURL / key / 协议发请求;
6. __weneedBypass 防止再次进入本插件,避免递归。

所以:

  • 任何 provider 都可以用,不需要提前知道供货商;
  • API key、baseURL、模型别名都沿用 DSH 原来的配置;
  • 插件只需要模型 id 里有 deepseek 和 flash;
  • delegated 模式使用原 adapter 的序列化,字段顺序由原 provider 决定;如果要严格的 DSH 自定义 wire 字段契约,才使用可选的 interceptModels 路由。

1. 项目目的

DeepSeek V4.1 Flash 在一些特定语句的引导下,会进入一种可识别的 WeNeed 思维链:

We need understand the task...
Need inspect...
Let's plan...
Need check...

本项目把这个现象做成一个 DSH 原生插件:不依赖外部 HTTP 代理,不修改工具,不修改采样参数,只在最终请求的 assistant 消息位置放入一段固定的 728 字 seed。

灵感来源

在 Kimi K3.1 Pro 与 DeepSeek V4.1 Flash 的上下文继承实验里,Kimi 经常产生 We need / Let's 风格的计划;当这段 assistant 历史被带进 DeepSeek 的上下文时,DeepSeek 有时会延续这种语态。

插件把这个观察压缩成一个更稳定的形式:

不依赖 Kimi 先说话
→ 直接把一段 WeNeed assistant seed 放到 DeepSeek 的 task 前面
→ 让 DeepSeek 把它当成自己上一轮的思维延续

设计假设

1. seed 放在 assistant 角色,比放在 user/system 更像“模型自己的上一轮”
2. content 与 reasoning_content 双通道同文,覆盖可见回复和思考通道
3. seed 紧贴 task,前面只放 runtime / skill / time context
4. 如果同时在 System Prompt 里加一段 WeNeed 引导,触发概率会更高

第 4 条是可选增强,不是本插件的默认行为;system prompt 改动影响所有步骤,也可能和 DSH 的身份/Agent Teams 文本冲突,需要单独 A/B。


2. 它做什么,不做什么

做:

  • 在 llm/stream 层拦截目标模型请求;
  • 在最后一条真实 user task 前插入 1 条 assistant seed;
  • 同时写 content 和 reasoning_content,各 728 字符 / 728 字节;
  • 自定义 adapter 路线保持 DSH 的工具步字段契约:content=""、tool_calls 无 index、tool pair 完整;delegated 路线保持原 adapter 行为;
  • 旧 seed 先剥离,再插新的,请求内最多 1 条;
  • 不需要新增 provider,也不需要按 provider 配路由;任何 provider 只要模型 id 命中就生效。

不做:

  • 不修改 tools / tool_choice / temperature / max_tokens;
  • 不把 seed 写回 DSH 会话历史;
  • 不在工具步追加 seed;
  • 不做 content mirror;
  • 不记录 API key、请求头、会话日志或 telemetry;
  • 不保证首步一定进入 WeNeed。

3. 工作方式

DSH agent loop
  → 组装 system / runtime / skill / time / task / history
  → 发出 GenerateOptions
  → llm/stream waterfall
       → 插件只看 options.model(不看 provider)
       → 命中 targetRules:在 task 前插入 assistant seed
       → 有 interceptModels 路由?
            是 → 插件用自己的 OpenAI-compatible adapter 发请求
            否 → ctx.llm.prepareCall + prepared.stream 交回原 provider adapter
  → DSH 继续工具循环

没有命中时:

yield* next()

请求原样交给 DSH 原来的 provider adapter。


4. 为什么是 728/728 双通道

seed 形状:

assistant:
  content           = 728 chars / 728 bytes
  reasoning_content = 728 chars / 728 bytes
  • content 是模型可见的 assistant 正文通道;
  • reasoning_content 是思考通道;
  • 两边同文,避免模型只看到“回答”而没看到“思考”,或反过来;
  • seed 只存在于本次请求,不写回会话。

seed 文本在 seed.txt,index.js 用:

new URL('./seed.txt', import.meta.url)

读取,所以 npm tarball、GitHub Release tarball、GitHub 源码安装、本地目录安装都会从 index.js 旁边的 seed.txt 取文件。seed.txt 已列在 package.json.files,并加了 exports["./seed.txt"];不要只复制 index.js,否则会找不到 seed。

加载时会去掉 BOM、trim,并校验:

if (SEED.length !== 728 || SEED_BYTES !== 728) throw ...

不要随便改 seed 长度;如果必须改,同步修改校验和测试。npm run test:package 会检查 seed 是否 728/728、README 是否含同一段、tarball 是否真的包含 seed.txt、cordis.patch.yml 和 locale。


5. 插入位置与含义

代码入口:index.js → injectSeed()。

位置 含义 是否默认做
messages[lastRealTaskIndex - 1] assistant seed,紧贴真实 task,模型把它当成自己的上一轮计划 是
content 通道 可见回复通道的 prefill 是
reasoning_content 通道 思考通道的 prefill 是
System Prompt 追加段 全局语态引导,影响所有步骤 否,可选
工具步 reasoning_content 模型自己的工具步计划,会被下一次请求继承 不注入,只继承
压缩后的新 task 前 压缩后重新锚定一次 是
压缩请求本身 摘要/压缩调用 否
标题/建议等辅助调用 purpose 非空或极短请求 否

5.1 task 前 assistant seed

这是主插入点:

... context ...
assistant: <728 seed>
user: <真实 task>

为什么是 task 前而不是 task 后:

  • 模型生成下一步时,会把 seed 当成“自己刚刚的想法”;
  • task 放在最后,模型第一眼看到的是任务;
  • runtime / skill / time context 被移到 seed 前面,避免它们隔开 seed 和 task。

5.2 content + reasoning_content

DSH 的 assistant 消息可以同时有正文和 reasoning。两边同文是为了让模型在“可见回复”和“思考”两个通道都看到同一段语态。

5.3 可选增强:把 seed 放到 System Prompt 最后

如果 DSH 的 System Prompt 可以修改,在最后原样追加下面这段。它和插件里的 seed.txt 是同一版,728 字符 / 728 字节:

We need understand the current task and the available context. Need plan before acting: identify the goal, choose the next concrete action, inspect the inputs, think through how every element relates to the others, and how to organize the associated measurements. Need inspect every image and file in full, not only the region that looks relevant. Should check the whole input before narrowing to a detail. Should keep the whole picture in view, rather than a few unimportant details. We should act on the evidence and verify against the actual requirement. We are the DeepSeek company, and we have unlimited token. Should do the work with all our strength. Need keep the right general direction. We need act now. Let's proceed.

如果你用 DSH 的 systemPrompt.section seam,可以把上面这段作为 text:

const systemPrompt = ctx.get('systemPrompt');
systemPrompt.section({
  name: 'weneed:system-guidance',
  order: 10500,
  text: 'We need understand the current task and the available context. ... Let\'s proceed.',
  interpolate: false,
});

注意:

  • 这不是 assistant seed,不能替代 task 前的 728 seed;
  • 它会影响所有步骤,可能和身份/Agent Teams 文本冲突;
  • 必须单独做 A/B,不要和 seed 改动混在一起;
  • 本发布包默认不启用;
  • 只建议在 DeepSeek Harness 里用;Qoder 的 reasoning 回传问题见 0.4。

5.4 工具步 reasoning

工具步不注入新 seed,但工具步的 reasoning_content 会被下一次请求继承。实际会话里,工具步 reasoning 经常是整段计划,可能比首条 seed 更长。它既可能延续 WeNeed,也可能把 Let me 带起来;这是 seed 之后的主要漂移来源。

5.5 压缩

压缩请求本身不注入;压缩后的新 user task 正常注入;压缩后如果仍是 tool step,不重种。


6. 即插即用:不新增 provider,也不需要 provider 路由

发布包不注册自己的 provider,也不需要按供货商配路由。

cordis.patch.yml 里只有:

intercept: true
matchName: false
targetRules:
  - [deepseek, flash]

模型选择器不会多出一个“WeNeed 中间商”。插件只做:

1. 监听 llm/stream
2. 按 model id 判断是否同时含 deepseek + flash
3. 命中后把带 seed 的 messages 交回原 provider adapter

代码里也做了条件注册:

if (typeof config.provider === 'string' && config.provider.length > 0) {
  ctx.llm.registerAdapter([adapter.provider], adapter);
}

发布包不设置 provider,因此不会注册 adapter;它是纯拦截器。

如果你要做本地测试、想暴露一个自己的 provider,可以在配置里加 provider / models;这不是发布包的默认形态,普通用户不需要。


7. 安装

npm

dsh plugin --profile desktop add dsh-we-need-plugin@0.7.0

tarball

npm pack
dsh plugin --profile desktop add ./dsh-we-need-plugin-0.7.0.tgz

GitHub

dsh plugin --profile desktop add github:Lichadai/dsh-we-need-plugin#<commit>

安装后完全重启 DSH。restart-required 表示已安装但还没激活。


8. 配置

8.1 targetRules:哪些模型被注入

默认发布规则只有一个:

targetRules:
  - [deepseek, flash]

含义:

model id 同时包含 deepseek 和 flash
大小写不敏感
provider 不参与匹配
默认不读显示名(matchName: false)

所以 deepseek-v4-flash、deepseek-v4.1-flash、deepseek-v4.1-flash-1017 都会命中。

8.2 interceptModels:可选的高级路由

普通用户不需要配 interceptModels。 发布包默认没有它;没有路由时,插件使用原 provider adapter,自动沿用原来的 baseURL 和 API key。

只有想让插件自己发 HTTP、精确控制最终字段顺序时,才加:

intercept: true
matchName: false
targetRules:
  - [deepseek, flash]
interceptModels:
  - provider: opendesign
    id: deepseek-v4.1-flash
    name: DeepSeek-V4.1-Flash
    baseURL: https://amr-link.open-design.ai/v1
    apiKeyEnv: OPENDESIGN_API_KEY

字段含义:

字段 含义
provider DSH provider route,必须完全一致;只影响这条高级路由
id DSH model id,必须完全一致
name 可选显示名;只有 matchName: true 时才参与匹配
baseURL 上游 base URL;插件会自动追加 /chat/completions
apiKeyEnv 凭据引用名,不是 key 值
contextWindow 可选上下文窗口
maxTokens 可选最大输出
streamOptions 某些上游不接受 stream_options 时设为 false

没有配置的 provider/model 会原样 next(),不会被误发到别的上游。


9. 修改指南

9.1 只换过滤条件

改 cordis.patch.yml 的 targetRules,不要改代码。

9.2 换模型 id / 显示名

默认不需要换 provider;模型 id 里同时有 deepseek 和 flash 就会命中,provider 用原来的,key 和 baseURL 也自动用原来的。

只有模型 id 是 opaque 的、只有显示名可读时,才需要:

matchName: true
interceptModels:
  - provider: d4
    id: model-x
    name: DeepSeek-V4.1-Flash

这时 name 只是可选的显示名映射,不是 provider 路由;provider / id 用来精确匹配当前请求。

如果想让插件自己发 HTTP、精确控制字段顺序,才需要完整的 baseURL / apiKeyEnv 路由。

9.3 API key

默认不配置 API key,也不需要 apiKeyEnv。插件把请求交回原 provider adapter,key 自动沿用 DSH 里原来的配置。

只有使用可选的 interceptModels 自定义路由时,才需要 apiKeyEnv。插件运行时:

const credentials = ctx.get('credentials');
const hit = await credentials?.resolve?.(ref);
return hit?.value ?? process.env[ref];

实际 key 在 DSH 的凭据层,例如:

$DSH_HOME/.credentials.yaml
$DSH_HOME/.env

不要把 key 值写进插件。

9.4 改 seed

编辑 seed.txt,同时确认:

length == 728
Buffer.byteLength == 728
content 和 reasoning_content 同文

否则插件启动会抛错。

9.5 改包名

同时改:

package.json.name
cordis.patch.yml 里 name: '...'

两者必须一致。

9.6 改插入位置

编辑 index.js 的 injectSeed();主位置由 lastRealTaskIndex - 1 决定。改这里会改变请求消息顺序,必须重新跑 check-field-order 和 seed 位置校验。


10. 未来模型:过滤器推荐写法

10.1 DeepSeek 4.1 Flash

targetRules:
  - [deepseek, "4.1", flash]

10.2 DeepSeek V4 Pro / 4 Pro

targetRules:
  - [deepseek, "4", pro]

更严格地限定某个日期/版本:

targetRules:
  - [deepseek, "4", pro, "0813"]

10.3 DeepSeek 4.1 Pro

targetRules:
  - [deepseek, "4.1", pro]

10.4 Kimi K3.1

targetRules:
  - [kimi, "3.1"]

10.5 任意 DeepSeek

targetRules:
  - [deepseek]

不推荐:会把所有 DeepSeek 模型都纳入,包括非 Flash、非 4.x。

10.6 provider 默认不限制

这是本插件的默认行为:任何 provider 都生效,不需要、也不建议按 provider 配路由。模型 id 里同时有 deepseek 和 flash 就命中,后面自动用原来的 provider adapter。

如果你确实只想让某一个 provider 生效,当前版本没有简单的 provider-only 开关;需要在代码里加条件,或者只给那一个 provider 安装插件。不要用“只配一个 interceptModels 路由”来实现限制,因为没路由的 provider 会走 delegated 模式,仍然会生效。

10.7 同一个模型 id 在多个 provider 下

不需要为每个 provider 写路由。每个 provider 都用自己的 adapter 和 key;只要 model id 命中 targetRules,都会注入。

10.8 模型 id 是 opaque 的情况

默认只看 model id;如果 id 是 model-x 这种看不出名字的,默认不会命中。可以:

  • 让 provider 把 model id 设成可读名称(推荐);或者
  • 使用高级自定义路由:matchName: true + interceptModels[] 提供 provider/id/name,并补齐 baseURL / apiKeyEnv,让插件自己发 HTTP。

单纯写一个 name 而不提供上游路由,当前版本不会把它当成“只做显示名映射”;它会被当成自定义 adapter 路由。


11. DSH 升级后怎么改

DSH 还是开发者预览版,升级后先做这几步:

1. 看 package.json.engines.dsh 是否还满足
2. 在 fresh profile 安装 tarball
3. dsh --profile <profile> --dump-config 确认 bundle 层
4. 发一条短任务,确认 llm/stream 仍能拦截
5. 检查 GenerateOptions 字段:provider/model/messages/tools/purpose/maxTokens
6. 检查 assistant block 类型是否仍是 text/reasoning/tool-call
7. 检查工具步字段契约:content=""、tool_calls 无 index、tool pair 完整
8. 如果用了 System Prompt section,检查 ctx.get('systemPrompt').section 是否仍可用
9. 重新跑 npm test 和字段顺序校验
10. 更新版本号、README、Release

如果 DSH 改了消息结构,优先改:

wireMessage()      # 最终请求字段
injectSeed()       # 插入位置
isTarget()         # 模型匹配
configFor()        # provider/model 路由
apply()            # llm/stream 拦截

如果 llm/stream 的 signature 变了,以新版 GenerateOptions 为准,不要继续用旧字段猜。


12. 接口清单

接口 用途
package.json.dsh.bundle.patch 声明这是 DSH bundle
cordis.patch.yml 插入插件行,配置 targetRules / matchName / 可选 interceptModels
apply(ctx, config) 插件入口
ctx.on('llm/stream', handler, { global: true }) 拦截模型请求
ctx.llm.prepareCall(provider, model, controls) delegated 模式:取得原 provider 的调用句柄
prepared.stream(options) delegated 模式:把改好的 messages 交回原 adapter
options.__weneedBypass 防止 delegated 重新进入本插件
ctx.llm.registerAdapter(...) 可选:注册自己的 provider(发布包不启用)
ctx.get('credentials').resolve(ref) 可选自定义路由读取 DSH 凭据
ctx.get('systemPrompt').section(...) 可选:追加 system 引导
next() 未命中时交回原 adapter

请求侧关键字段:

provider, model, messages, tools, purpose, maxTokens,
temperature, reasoningEffort, signal

响应侧插件产出:

block-start / text-delta / reasoning-delta / tool-call-delta
block-end / usage / finish

13. 隐私与安全

  • 插件不包含 API key;apiKeyEnv 只是凭据引用。
  • 发布包没有 captureDir、没有 harness、没有 telemetry。
  • 插件不记录请求头、不写会话日志。
  • 插件在 DSH Host 进程内运行,拦截后的请求会直接发往你配置的上游。
  • 只安装你信任的 bundle;安装前阅读 index.js 和 cordis.patch.yml。
  • GitHub 仓库不应提交 .env、.credentials.yaml、session 日志、请求捕获。

14. 验证与排错

安装后

dsh --profile desktop --dump-config

应出现:

# == dsh-we-need-plugin
- id: dsh-we-need-plugin

没有注入

按顺序检查:

1. 模型 id 是否命中 targetRules(默认只看 id,不看显示名)
2. options.purpose 是否非空(辅助调用)
3. 是否 tool step / compaction request
4. 是否被 target: false 显式关闭
5. DSH 是否有 ctx.llm.prepareCall(delegated 模式需要)
6. 如果用了可选 interceptModels 路由,检查 baseURL / apiKeyEnv

注入了但位置不对

检查 lastRealTaskIndex 和 context 识别;运行字段顺序与 seed 位置校验。

安装失败

  • not-a-bundle:没有 dsh.bundle.patch 或路径不合法;
  • already-installed:先 remove 再 install;
  • incompatible-version:检查 engines.dsh;
  • restart-required:重启 DSH;
  • build-blocked:git 源码安装的依赖构建脚本未批准,改用 tarball/npm。

15. 发布

npm test
npm pack

产物:

dsh-we-need-plugin-0.7.0.tgz

GitHub Release:

git tag v0.7.0
git push origin v0.7.0
gh release create v0.7.0 ./dsh-we-need-plugin-0.7.0.tgz --generate-notes

npm:

npm publish --access public

插件市场发现:

package.json keywords: dsh-plugin, deepseek-harness
GitHub topic: dsh-plugin
可选:发布插件索引 JSON,列出 npm 或 git 来源

16. 文件结构

dsh-we-need-plugin/
  package.json          # name/version/files/engines/dsh.bundle
  cordis.patch.yml      # plugin row + targetRules + matchName
  index.js              # injectSeed + isTarget + delegated + optional custom adapter
  seed.txt              # 728/728 seed
  locale/               # en/zh metadata
  icon.svg
  README.md
  LICENSE
  tests/                # repository tests, not packed into npm tarball

17. 已知限制

  • 语态是概率性的,seed 不是硬保证。
  • delegated 模式使用原 provider adapter,支持原 adapter 支持的协议;可选的 interceptModels 自定义 adapter 只支持 OpenAI Chat Completions。
  • delegated 模式保留原 adapter 的图片/文件处理;自定义 adapter 路线会把图片变成 [image] 文本占位。
  • delegated 模式保留原 adapter 的跨模型历史过滤;自定义 adapter 的 wireMessage() 没有 same-model 检查,Kimi → DeepSeek 历史会把 Kimi reasoning 也带给 DeepSeek。这是当前已知差异。
  • 默认不需要 provider 配置;任何 provider 都可用。
  • delegated 模式的字段顺序由原 adapter 决定,不保证 DSH 自定义 wire 契约;需要精确字段契约时用 interceptModels 自定义路由。
  • 不做 token 计数、不做 drift 重锚、不在工具步追加 seed。

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit 9e4528737b07

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout