DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
S

dsh-speak-up

Speak Up

Speak Up on Her Own (dsh-speak-up): DSH plugin. When no one is talking to her, she starts a conversation herself — rolls a local die at the interval you set (without using the model), and if it hits, runs DSH's own turn (her personality, history, tools, and memory are all her own).

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:Yuuyuko-uu/dsh-speak-up#438bb636b4c631218e1d0b18b2bf957e3cb17b6d
READMECompatibilityVersions

Compatibility and provenance

Speak Up is published as dsh-speak-up and currently resolves to version 0.2.9. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
11/4/2026

Versions

0.2.9stable
11/1/2026
0.2.8stable
10/31/2026
0.2.7stable
10/28/2026
Show 5 more versionsCollapse versions
0.2.6stable
10/26/2026
0.2.4stable
10/26/2026
0.2.3stable
10/24/2026
0.2.2stable
10/23/2026
0.2.1stable
10/22/2026

Related plugins

Loading related plugins…

Latest
0.2.9
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
SEE LICENSE IN LICENSE
Source
github
GitHub
★ 200
Weekly downloads
10,914
Last push
11/1/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

README

dsh-speak-up(主动搭话)· 让它自己先开口

给 DSH 里某个会话装一颗「会自己起话头」的心:没人在跟它说话的时候,它也有可能先开口。

定时器到点
  └─ 掷一次本地骰子(Math.random,一个 token 都不花)
       ├─ 没掷中 → 什么都不做,只留一条记录
       └─ 掷中   → 往「目标会话」送一句话 → agent.followup(message)
                    → DSH 自己开一轮:它的人格、历史、工具、记忆全都照旧

一句话:只有掷中之后的那一步才花模型,掷骰子本身是纯本地随机。


适配哪个 DSH 版本(不用操心)

这个插件跟着 DSH 一起更新:作者这边跑的就是最新版的 DSH,最新版插件永远是给最新版 DSH 写的。

所以看到「不适配 / 不支持」之类的提示,基本都是装到了旧版本 —— 升级到最新版、重启一次 DSH 就好。 真遇到新版对不上(比如 DSH 刚升级、插件还没跟上),提个 issue,作者会跟着改。

当前实测对照:插件 0.2.4 ↔ DSH 0.2.1-rc.3(2026-10-26)

装

一、在 DSH 里装(推荐)

打开 设置 → 插件 → 安装,把这一行填进去:

dsh-speak-up

或者命令行(--profile 照你平时那个写;桌面端一般是 desktop、网页端是 web):

dsh plugin --profile desktop add dsh-speak-up

也可以在 npm 上直接看到这个包(含历史版本):https://www.npmjs.com/package/dsh-speak-up

上面那条要是碰到网络问题(npm 抽风、或者想固定某一次的代码快照),可以改用 tarball 直链,不用 git:

dsh plugin --profile desktop add https://codeload.github.com/Yuuyuko-uu/dsh-speak-up/tar.gz/refs/heads/main

装完重启一次 DSH,然后去 设置 → 主动搭话 看一眼在不在。

⭐ 最省事的一条:把仓库链接贴给你自己的 DSH,说「帮我装这个插件」。

二、手动装(没有 dsh 命令、或者装不动的时候)

  1. 把这个文件夹放到 profile 能找到的地方: %USERPROFILE%\.dsh\profiles\<profile>\node_modules\dsh-speak-up\
  2. 在 profile 的 package.json 里,把 dsh-speak-up 加进 dsh.profile.bundles 数组;
  3. cordis.patch.yml 里那一行会把它插进 loader(id: speak-up);
  4. 重启 DSH。

⚠️ 改 package.json 一定要存成 UTF-8 无 BOM。存成带 BOM 的话,DSH 下次启动会直接起不来, 报 Unexpected token '' … is not valid JSON(看着像插件坏了,其实只是开头多了三个看不见的字节)。 检查是哪个文件(不同装法位置不一样,别猜 —— 真正的 profile 目录里同时有 cordis.yml、cordis.patch.yml、package.json):

Get-ChildItem C:\,D:\,E:\ -Directory -Filter profiles -Recurse -Depth 4 -ErrorAction SilentlyContinue |
  ForEach-Object {
    Get-ChildItem $_.FullName -Directory -ErrorAction SilentlyContinue | ForEach-Object {
      $p = Join-Path $_.FullName 'package.json'
      if ((Test-Path (Join-Path $_.FullName 'cordis.patch.yml')) -and (Test-Path $p)) {
        $b = [System.IO.File]::ReadAllBytes($p)
        $bom = ($b.Length -ge 3 -and $b[0] -eq 0xEF -and $b[1] -eq 0xBB -and $b[2] -eq 0xBF)
        "{0}   BOM={1}" -f $p, $bom
      }
    }
  }

BOM=True 的那一行就是要修的(标准安装在 C:\Users\<你>\.dsh\profiles\<档名>\package.json)。 去掉 BOM(路径换成上面那一行):

$p = "把上面 BOM=True 那一行的路径粘到这里"
[System.IO.File]::WriteAllText($p, [System.IO.File]::ReadAllText($p), (New-Object System.Text.UTF8Encoding($false)))

让 AI 帮你改时,别让它用 Set-Content -Encoding UTF8 或 Out-File -Encoding utf8 —— Windows 自带的这两个默认带 BOM。

三、开发时(想改代码、改完就想看到)

上面那个 node_modules\dsh-speak-up 做成指向你这个文件夹的目录联接(junction / 符号链接), 或者 pnpm add link:<这个文件夹的绝对路径> —— 这样改的就是装的那一份。

⚠ 本仓库自己不装、不改任何 DSH 配置、不重启任何东西:上面三步都由装的人自己做。 ⚠ 改完插件代码,只重启 DSH 才一定生效(关掉插件再打开、重装都不一定重新读代码)。

更新到最新版

最省事:把这个仓库的地址丢给你自己的 DSH,说「帮我更新这个插件」。装完重启一次 DSH。

也可以点 设置 → 主动搭话 最上面的「检查更新」 —— 有新版会提示,还能一键复制更新命令。

命令行(--profile 照你平时那个写,桌面端一般 desktop、网页端 web):

dsh plugin --profile desktop remove dsh-speak-up
dsh plugin --profile desktop add dsh-speak-up

⚠️ 必须先卸再装:直接装可能拿到缓存里的旧副本,装完还是老的。 ⚠️ 装完重启一次 DSH才会用新代码。

我的设置会不会丢?

不会。 设置存在 DSH 家目录(%USERPROFILE%\.dsh\)里,不在插件代码里;卸载只删代码:

.dsh\speak-up-config.json

所以卸载 → 重装,设置、搭话记录 都还在。

三件小事提醒:

  • 别用「重装 DSH」来更新插件 —— 那是两件事,重装可能动到 profile。
  • 新版本新加的设置项会用默认值(以前没这一项),想要自己的值就再填一次。
  • 设置项改名或换单位时,旧值会按规则自动换算,不用你管。

怎么用

设置页(设置 → 主动搭话)里从上到下:

项默认说明
总开关开关掉就完全不动
试运行开开着时掷中了也只记账、不真发
掷骰子间隔(分钟)301~1440;改完保存,下一轮就按新间隔走,不用重启
搭话冷却(分钟)20它真的说了话之后,这么多分钟内不再开口;只是把念头投进去、它没开口不算;0 = 不冷却。手动按钮不受它限制
没中加成(百分点)10每没掷中一次,下一次命中线加这么多;0 = 关掉这个功能
加成上限(百分点)40加成最多加到这么多
安静时段起/止(小时)1 / 8含起不含止;跨午夜也行(23~7);起 === 止 = 不启用(设置页里单独一行红字写着)
近:刚聊过 → 命中线 ×0.1520 分钟距它上次说话不到 20 分钟 → 命中线乘 0.15(更难开口)
远:冷太久 → 命中线 ×1.5360 分钟超过 6 小时没说话 → 命中线乘 1.5(更容易开口);中间那段 ×1
峰时命中线(%)20峰时(贵)→ 少开口。峰谷时段是固定的,不用填
谷时命中线(%)60谷时(便宜)→ 多开口
目标会话空勾选清单(可勾多个);勾一下立刻自动保存,不用再按保存
触发文案见下用它自己的口吻写(这是它的动机,不是系统提示)
角色user见下面「做不到的地方」—— developer 目前送不了,本插件会拒发

峰谷时段写死在代码里,不给设置项(就一条规则):

峰时(贵):周一~周五  09:00–12:00 和 14:00–18:00
谷时(便宜,价钱是峰时的一半):其余全部
         —— 含 12:00–14:00 午休、18:00~次日 09:00、周六周日全天

(判断用这台机器的本地时区;它这台就是北京时间。周末直接算谷时。)

一句话记住这个数怎么来的(骰子 掷到命中线以下才开口):

命中线 = min(100, 峰时/谷时命中线 × 时机因子(刚聊过 0.15 / 冷太久 1.5 / 中间 1)
                       + min(加成上限, 连着没中几次 × 没中加成))
  • 「两格命中线填成一样」= 不分峰谷,全天一个命中线。
  • 掷中(含试运行掷中)就把「连着没中」清零,回到一开始;没掷中就一次次往上加,加到上限为止。
  • ⚠ 「连着没中」这个数只记在内存里:DSH 一重启就回到 0。
  • ⚠ 这两格(没中加成 / 加成上限)只影响自动的定时掷骰;手动按钮(演练 / 真发)不掷骰子,也不动这个计数器。

⚠ 安静时段会盖住谷时:安静时段内根本不掷,谷时命中线再高也用不上。 默认安静时段是 18 点、默认谷时里有 18:00次日 9:00 —— 想让谷时那半便宜时段真的用上, 得把安静时段改小(或让起 === 止关掉它)。

触发文案的默认值是中性的(「好久没人跟我说话了,我该主动去打个招呼」)。在设置页那一格里改成你自己的口吻就行, 不用动代码 —— 这一句是「它的动机」,不是系统提示,写得越像它自己越好。 默认值只在 lib/host.js 的 默认配置 里写了一份。

配置文件落在 %USERPROFILE%\.dsh\speak-up-config.json(不是 DSH 的 config,本插件自己一份)。 ⚠ 改名(dsh-her-words → dsh-speak-up)之前的 her-words-config.json 还会被兜底读一次,设置不丢。

怎么安全地试(建议按这个顺序)

  1. 装好、重启,打开 设置 → 主动搭话,确认「最近记录」里有那条启动日志: 已装好 v0.1.0:……现在命中线 20.0 = 峰时命中线 20% × 时机因子 1(刚起来…)|没中加成 +10/次,最多 +40|搭话冷却 20 分钟|……。 没有这条说明宿主半边没起来,先别往下走。
  2. 在「目标会话」的清单里 勾上要说话的那个会话(点一下就生效,不用再按保存)。
  3. 点 「演练一次(绝不真发)」:它不掷骰子、直接走一遍「本来要发什么」。不会真发。
  4. 让它自己按 30 分钟跑几轮,看记录里的命中线是不是你想要的节奏。每条都写成 掷出 X(命中线 Y —— 掷到 Y 以下就开口)|Y = 这一档命中线 × 时机因子(距上次说话 …), 没中还会告诉你「下次命中线变多少(没中加成 +10)」。觉得太频繁就调小命中线 / 拉长间隔。
  5. 时机满意了,关掉「试运行」。之后只有掷中才会真发。
  6. 想当场验证「真发到底能不能跑通」:点 「真发一次(跳过等待)」,然后去目标会话里看 有没有多出一轮,以及它是不是照自己的口吻开了话头。

随时可以再打开「试运行」让它安静下来。「总开关」关掉则连记录都不再走。

⚠ 改数字 / 触发文案 / 开关 / 角色之后要点「保存设置」——页面顶上会显示 「⚠ 上面有改动还没保存」提醒你。只有「目标会话」的勾选是一点就自动保存的。

💡 有改动的时候,底下会自动浮出一条「⚠ 有改动还没保存 + 保存设置」的条, 不用再滚到页面最下面去找那个按钮;保存完它自己就收起来了。

自测(不装插件也能跑)

两个冒烟测试不碰 DSH、不碰会话(DSH_HOME 指向系统临时目录,agent 是假的; 峰谷那几条全都喂假时间,所以半夜跑也不会红):

node tests\宿主半边.mjs     :: 默认值/归一化/落盘/安静时段/时机因子/峰谷分时(判峰时边界+两格命中线)/
                            :: 没中加成(纯函数 + 真路)/搭话冷却/改名兼容(旧键名 + 旧文件名)/
                            :: 标题两条来源/勾选清单/多目标只挑一个/消息形状/developer 拒发/换表/坏配置兜底
node tests\网页半边.mjs     :: 设置页渲染(假 React + 假 fetch):7 组设置 + 峰谷卡片(只有两个数字)+
                            :: 没中加成/冷却那几格 + 命中线口径、勾一下真的会 POST 保存、没标题也能勾

改完代码先跑这两个,再去 DSH 里试。当前状态:宿主 73 条、网页 59 条,全部通过 ✅。


会话名字是从哪儿读的(两条路,按顺序试)

顺序来源依赖说明
①ctx.sessionTitle.get(session)需要 sessionTitle 服务(已写进 inject)抄朗读桥 dsh-tts-bridge 的 titleOf()(lib/index.js 147~156 行)。纯内存、改了名字马上能看到
②%USERPROFILE%\.dsh\storages\session_projcache\sessions\<id>.json 里的 record.rows.title.val只要读盘拿不到就再看同一份文件里的 record.rows.titleInput.val.first.text(第一条输入)
③都没有—显示「(还没起名)」+ 短 id,照样可以勾

⚠ 第 ② 条两种文件名都试:<id>.json 和 session-<id>.json(目录里两种都存在)。 只试一种就会全部退化成「(还没起名)」。读盘结果缓存 30 秒。


做不到的地方(诚实清单)

1. 触发消息只能是 user 角色,developer 送不了

这是当前 DSH 版本的硬限制,不是本插件偷懒。三条证据(都是读 DSH 本体的源码读到的):

  1. @deepseek-ai/dsh-agent-loop/lib/index.js 的 step() 里,把收件箱认领到的消息 写死成 user/message 事件,完全不看 message.role:
    if (firstAttempt) for (const message of decision.messages)
      this.session.append("user/message", message, { surfaceOp: "append" })
    
  2. @deepseek-ai/dsh-session/lib/index.js 的 append() 会校验:
    if (event.type === "developer/message" !== (message["role"] === "developer")) throw
    
    于是「user/message 事件 + developer 角色」会直接抛错,那一轮 turn 变成 error。 (assertMessageEventShape 同样要求 user/message 的角色必须是 user;system 角色也不行。)
  3. 另一个方向也堵着:developer 消息在 @deepseek-ai/dsh-llm 里会被 withoutDeveloperMessages() / projectToolUpdates() 从发给模型的请求里摘掉 (它只服务于「工具清单变更」这一种用途)。所以就算塞进历史,模型也看不见那句话。

本插件的处理:送出去的是一条 source.kind = "speak-up" 的 user 消息 —— 角色上确实是 user(DSH 唯一放行的),但来源标记是它自己的,不是它打的字(网页端也不会 把它当成真人排队消息来处理,因为它只认 source.kind === "user")。 设置里的「角色」填成 developer 时,插件会主动拒发并记一条,而不是去写坏会话日志。 将来 DSH 放开了 developer,改这一处就能直接切过去。

2. 只认活着的 agent,不会自动唤醒冷会话

DSH 自带的 @deepseek-ai/dsh-schedule 用的是 ctx.sessionController.resolveAgent(id), 那个会把没活着的会话也 resume 起来。本插件故意不用它:目标会话没有活着的 agent 时, 就什么都不做、只记一条。理由是这个版本的要求就是「不活着就安全地什么都不做」, 而且偷偷唤醒一个冷会话(可能还要花一次冷启动)比不开口更冒犯。

3. 设置的读写走的是本插件自己的 JSON,不是 DSH 原生「插件配置」页

不是不能做,是在这个安装位置上有风险:插件被装进 profile 的 node_modules, 而那里没有 @deepseek-ai/schemastery(profiles/<p>/node_modules/@deepseek-ai/ 下只有 dsh-home-paths)。export const Config = z.object({...}) 需要静态 import 它, import 一失败整个插件就加载不了。所以本版跟 dsh-write / dsh-fish-memory 一样: 自己的 json + 自己的设置页。 (想改成原生页:profiles/<p>/node_modules/schemastery 这个同名上游包 3.18.0 是在的, 可以试着 import z from 'schemastery' 再导出 Config,但没验证过 Cordis 认不认这个包身份的 schema,改之前先备份。)

4. 别的地方也没验证过

  • settings.section 这个槽位名:跟 dsh-write / dsh-fish-memory 用的是同一个, 在这台机器上它们是跑通的;换 DSH 版本可能变。
  • 「距它上次说话」用 ctx.sessionController.inspect(sid) 翻一次已落盘的历史来找最后一条 user/message。会话特别长的话这一次读会有点重(一个会话只翻一次,之后靠 session/event 实时更新)。
  • ctx.sessionController.create() 建「小屋会话」这条路没实际跑过,失败会返回一句人话, 不会静默。
  • 掷骰子不做持久化:插件重启后「自己上次开口」的时间和「连着没中」都会归零。

它到底做了什么(给下一个看代码的人)

  • lib/host.js(宿主半边):配置读写 + 安静时段 + 时机因子 + 峰谷分时(时段写死) + 没中加成/冷却 + 掷骰
    • agent.followup(message) + 四条 /dsh-speak-up/* 路由 + 内存里最近 60 条记录。 另外导出了 判峰时() / 算基础命中线() / 算命中线() 三个纯函数,只是为了冒烟测试能喂假时间、 能把"连着没中几次"直接喂进去(官方 dsh-goal-round-driver 也这么导出 renderGoalRoundPrompt)。
  • lib/client.js(网页半边):settings.section 槽位里的「主动搭话」设置页; 会话清单来自宿主(标题两条来源),勾选/取消立刻自动保存,数字/文案类改完要点「保存设置」 (有没保存的改动时,底下会自己浮出一条保存条)。
  • 两边只有一份掷骰逻辑(在宿主那边),网页只负责读写和显示。
  • CHANGELOG.md(改动记录):每一次改动一行一条。版本号规矩:每改一次 +0.0.1,末位满 10 进位。

Related plugins

More verified plugins in agents-orchestration.

Headless@deepseek-ai/dsh-headlessThe dsh one-shot bundle: a direct core Agent/Session runner over dsh-base with no Host, HTTP, or browser layerExperimental Agent Team Profile@deepseek-ai/dsh-experimental-agent-team-profileAgent Teams collaboration, tools, and Web UI in one experimental bundleExperimental Ralph Bundle@deepseek-ai/dsh-experimental-ralph-bundleRun explicitly requested repeated work with fresh agents.Subagent Codex@deepseek-ai/dsh-subagent-codexOne-shot Codex subagent provider over the official app-server protocol