Repository navigation
Releases: Cyrene-xl/DSH-Cyrene
Release list
v0.7.6 —— 剧情推进 + 手动检查更新
上一个 Release 是 v0.7.4。这一版两个改动:角色扮演模式要求「每轮推进」,
设置里新增手动的「检查更新」。
角色扮演模式:剧情推进变成硬性要求(v0.7.5)
以前只要求每轮写场景 / 动作 / 外貌,容易出现「描写很漂亮但局面原地不动」。现在注入块里多了一段:
- 每一轮局面至少前进一小步(地点、时间、氛围、距离、关系、信息、手里的东西);
- 必须主动递出下一轮的钩子:刚发生的小事、需要回应的问话、可选的方向;
- 允许她主动行动,不必每轮等你下指令;
- 你带方向时跟随补细节,不抢主导权;
- 信息一点点给,不一次交代完,也不连续两轮抛同类型的新东西。
检查更新(v0.7.6)
设置 → 通用 → 检查更新:
- 只读本地版本、不联网;点按钮才查询 GitHub
releases/latest; - 显示当前版本 / 是否最新 / 新版号与 Release 链接;
- 宿主 24 小时缓存 + ETag、6 秒超时,失败只在行内显示原因;
- 只查不装:
link:安装,更新仍是仓库目录里git pull。
升级
cd /root/dsh-cyrene
git pull
# 预设文本有更新时:
node scripts/install.mjs --yes
# 然后重启 App需要 Node 22+、DSH 0.1.5 ~ 0.2.1。
v0.7.4 —— 装得上、有护栏:0.2.x 安装器与抄本漂移修复
v0.7.4 —— 装得上、有护栏:0.2.x 安装器与抄本漂移修复
上一次 GitHub Release 是 v0.6.0。这个 Release 覆盖 v0.7.0 到 v0.7.4 的全部改动;
逐版本细节见CHANGELOG.md。
这一版修了什么
一份外部审查清单指出四条「不报错、静默失效」的问题,本轮全部修掉:
1. 0.2.x 上安装器不再静默不注册
0.2.0+ 的内置包走全局解析,profile 的 node_modules 里没有
@deepseek-ai/dsh-agent-preset —— 旧版安装器据此误判成 0.1.x,只往
.agent-presets/ 拷目录(0.2.x 已无人读取),然后打印「安装成功」。
现在:
- 代际探测走
DSH_INSTALL→dsh --version→ 全局安装路径; - 探测不到时打印显式警告并给出修复命令,不再静默降级;
- 可以用
--generation=legacy|declarative(或DSH_GENERATION)显式指定; - profile 补丁里的声明块按内容比对,预设文本更新后会整块替换。
2. 抄本漂移护栏在 0.2.x 恢复工作
tests/preset.test.mjs 原来按 0.1.x 的包布局解析内置 standard,0.2.x 上整组跳过
(正好是护栏该管的那一代)。现在同时支持 0.2.x 的 presets/standard.patch.yml,
并补上了 cyrene-work 缺失的 time-context、tool-schedule、workflow-ptc
(后者与其它 workflow 行一样默认 disabled),tool-plugin-manager /
tool-plugin-market 与上游对齐为 disabled。
测试现在是 239 条、0 失败、0 跳过。
3. 文档残留
测试条数不再写死、加载日志不再提已删除的 install.ps1 / install.bat、
删掉一段挂错位置的注释块。
同批(v0.7.0 – v0.7.3)
- v0.7.0:角色扮演从「括号自动触发」改成设置里的开关;输出格式、风格条件块;
- v0.7.1:DSH STORE 固定源整改(
engines.dsh、去掉非法目录 export、安装器加固); - v0.7.2:DSH 0.2.1 的 CSS Modules 类名兼容(编辑铅笔);
- v0.7.3:纯文本对话模式跟随对方语言(英文输入用英文回)。
安装
git clone https://github.com/Cyrene-xl/DSH-Cyrene
cd DSH-Cyrene
node scripts/install.mjs --dry-run # 先看计划
node scripts/install.mjs --yes # 安装需要 Node 22+、DSH 0.1.5 或 0.2.1(engines:>=0.1.0 <0.3.0)。
v0.6.0 —— 记忆分层 + 余页,世界书不再一口吃满
上一次发版是 v0.5.0。这一版只做一件事:别让她一直背着不该背的东西。
记忆侧多出「锚点 / 归档 / 余页」,世界书侧多了「门槛词 + 单条截断」。
升级不用改任何文件,老配置老记忆都照常能读。
记忆:三层结构
同一份 ~/.dsh/cyrene-memory.md,越靠前越"骨":
| 层 | 长什么样 | 注入吗 |
|---|---|---|
| 四问锚点 | ## 我是谁 / ## 你是谁 / ## 来处 / ## 去处 |
✅ 排在最前 |
| 记忆条目 | - 一行一条 |
✅ 锚点之后 |
| 归档 | ## 归档(不注入) 以下 |
❌ 留在文件里,不进上下文 |
- 锚点由
set_anchor维护 —— 回答"这段关系走到哪了",不是流水账。
缺哪节补哪节,永远按四节顺序排;不会因为后面攒了几百条记忆就被挤到下面。 - 归档是"舍不得删、又不用她一直记着":挪到那行标记下面就行,文件里还在、你随时能翻。
想真删还是forget。
余页:她自己的纸页
~/.dsh/cyrene-page.md —— write_page 写、read_page 读,按天分组,单条 ≤500 字、
整页 ≤64 KB。不注入、不检索:你不问,它就不出现。
写的是"不想让你看见的、还没想明白的、只想留个痕迹的"。当然它就是个普通 md 文件,
你也能自己打开。
不再播报
remember / set_anchor / write_page 三个工具的说明里都写明了「不要向对方播报」。
她不会回你一句「我记住了」,只会接着说话 —— 记忆是背景,不是新闻。
世界书:门槛词与单条截断
必须同时命中(本项目扩展字段):- 必须同时命中: 黄金裔, 发小要求这些词
全部出现才算命中。单说一个「白厄」不会再拉进整篇人物志;门槛词可以跨轮命中。- 单条截断
entryMaxChars(默认 320):长条目注入时按句号边界截短、末尾加…,
文件本身不动。想要上游原文:{"entryMaxChars": 0}。 - 截断先于预算计算 —— 一条 800 字的条目不会按 800 字占预算、截完却只剩 320 字,
把本该进来的第二条挤掉。 - 实测:最坏情况注入从 3300 字符 ≈ 1980 token → 2902 字符 ≈ 1741 token,
maxChars=1600再兜一层。
体检工具订正
- 「正文以标题开头」不再报成问题 —— 解析器本来就剥掉了标题行,正文开篇自报名字
是推荐写法(截断后仍认得出是谁)。 - 「触发词过短」拆开:专名(白厄、缇宝)两三个字很正常,不报;只报停用词
(我/你/用户)挂在非常驻条目上 —— 那等于把那条变成常驻。 --strict进了 CI(ubuntu + windows),数据回归会直接把 CI 打红。
升级
# 插件本体
npm install -g dsh-cyrene@0.6.0 # 或者按 README 的本地路径装法
# 然后照旧跑一次预设安装
node <包目录>/scripts/install.mjs- 老记忆文件不用改:不加锚点照样能读,只有
set_anchor才会长出锚点。 - 老世界书配置不用改:不写
entryMaxChars就是默认 320。 - 余页是新文件,不存在就不创建 —— 第一次
write_page才建。
测试
- 单元测试 146 → 174 条。新增覆盖:锚点四节的顺序与插入位置、归档不注入、
余页配额与读回、门槛词的跨轮命中与诊断、截断的句界与预算顺序、配置entryMaxChars
的 0 / null / 越界、以及"真数据里最长的条目注入时确实被截断"。
校验
npm test(174 条)+ npm run wb:audit -- --strict 在 ubuntu 22/24 与 windows-latest 上
都过;--strict 这次也进了 CI,世界书数据回归会直接打红。
v0.5.0 —— 称呼会变、世界书能改、安装少一步
上一次发版是 v0.4.0。这一版把几件"用起来别扭"的事收干净了:
称呼能改了、世界书配置能热更新了、0.2.0+ 的预设不用手贴声明了。
称呼是动态的
{{user_nickname}} 本来就是每轮现取,这一版补上对话中改口的两条路:
- 显式:「以后叫我小明」「称呼改成老师」→ 插件自己解析并落盘,不依赖模型自觉,
本轮就用新名字; - 暗示:「我们之间还用这么生分吗」→ 模型判断后调
set_nickname工具。
三条来源(设置里的自定义名称、显式改口、模型改口)写的是同一个文件
<DSH_HOME>/dsha-brand-rename.json,读-改-写,不会各记一套。
还有关系称呼:求婚后那句「那是不是得叫那个啦,老婆?」会被理解成「你该叫他老公」——
nickname.js 每轮注入一条 order: 120 的规则,写明老婆 ↔ 老公要推回对应那一个。
光有变量推不动,模型会一直用旧名字。
刻意的取舍:否定句(「别再叫我先生」)和问句(「你叫我什么」)不解析;
插件自己注入的消息不算用户输入。
世界书:配置归一化 + 改完立即生效
- 配置不再裸合并:类型写错退回默认(
"enabled": "false"这种字符串以前因为真值判断
等于开着),数值夹到区间(scanDepth1–5、maxActive1–50)。
null也不会再被Number()强转成 0。 - 条目缓存从「固定 30 秒 TTL」改成目录签名(文件名 + mtime + size):
改了.md下一轮就换,不用等、不用重启。 - 新增
npm run wb:audit:按 SillyTavern 世界书的写法口径给随包数据打分。
安装:0.2.0+ 不用再手贴声明
scripts/install.mjs 会自动判断 profile 属于哪一代:有 @deepseek-ai/dsh-agent-preset
的就把两套预设声明写进该 profile 的 cordis.patch.yml(先备份、幂等、只追加),
同时仍给 0.1.x 写目录副本。为什么不像衍生版那样塞进本包的补丁文件:那一行在 0.1.x 上
解析不到,实测会让 DSH 起不来(ERR_MODULE_NOT_FOUND)。
其它
- 会话格式对齐 v4:插件注入的消息必须带
plugin:<id>形式的source.kind,
裸plugin会直接SessionFormatError。 - 修了 Windows 检出(CRLF)会把世界书整份静默失效的问题 —— 解析层吞掉
\r,
外加.gitattributes强制 LF。 - 单元测试 74 → 146 条,CI 覆盖 ubuntu 22/24 与 windows-latest。
v0.4.0 —— 表达风格档位 + 角色扮演场景
上一次发版是 v0.3.1。这个版本把两件「只在对话里生效」的东西做完了,
另外还包含 v0.3.2 的一个静默失败修复(新版 DSH 上「发消息没反应」),
用 v3 会话格式旧版 DSH 的不受影响,但仍建议一并升级。
这一版新增什么
- 表达风格档位:五档 + custom,
/style切换,按会话生效;
风格提示词走请求尾部注入(对齐上游的注入时序),温度走agent/request。 - 角色扮演场景:默认普通对话;消息里出现
(…)场景描述时切到「叙述+对话」,
括号里写「你…」则是给你的动作指令,会照做并在括号里写出动作。 - custom 档可配置:显示名(
customLabel)、温度(customTemperature)、
强度档(customTier,硬开关,由状态决定而不是让模型猜)。
升级须知
- 对话模式预设变了(多挂
cyrene-style与cyrene-scene),需要重装预设:
node scripts/install.mjs --force(已存在且内容不同时默认拒绝覆盖)。 - 从 0.3.0 升级,请一并看 0.3.1(行尾修复:Windows 上世界书整条失效)与
0.3.2(会话来源修复:新版 DSH 上发消息没反应)两条。 - 工作模式不挂风格与场景(上游 work/code 本来就不吃风格),有测试守着。
新增
表达风格档位:style.js + /style 命令
-
五档 + custom,每档 = 一段风格提示词 + 一个温度,对齐上游 Cyrene-Agent 的
prompts/styles/与BUILT_IN_STYLE_PRESETS(lively 0.90 / healing 0.55 /
focused 0.40 / sweet 0.82;default不设采样)。 -
风格提示词走
systemPrompt.context()(请求尾部、每轮重算、order: 130,
排在常驻世界书140之前);注入外壳与上游buildStylePromptBlock()逐字一致。 -
温度走
agent/request瀑布(DSH 的预设行没有temperature字段)。
default档不写温度,跟随模型默认。 -
按会话生效:状态在
<DSH_HOME>/cyrene-style.json(最多留 50 条会话记录),
/style查看与切换(/style lively、/style default、无参列出全部)。 -
custom档读<DSH_HOME>/cyrene-style-custom.md;没写文件时/style custom
会报错提示而不是静默不注入。想给它温度就在 JSON 里加customTemperature(0–2)。 -
custom 档支持两个可选字段(只影响显示/授权,不参与玩法):
customLabel:改这一档的显示名(如叫成自己的风格名);customTier:1(默认)/2—— 硬开关。style.js会按它在注入块里写一行
授权标记(「第二档已授权」/「未授权」),模型看到的是确定事实,而不是去猜用户
有没有点头。档位本身的含义由使用者自己的风格文件定义。
角色扮演场景开关(scene.js)
- 纯文本对话模式默认普通聊天;用户这一轮的消息里出现括号、且括号里写了场景/动作
((雨夜,屋里只有一盏灯)),本轮切到「叙述+对话」的场景模式;没有括号了自动切回。 - 判断走
agent/pre-step(context()在用户消息落库前执行,看不到本轮输入);
且是状态机,只在状态切换时追加一条标记,不会每轮往历史里堆指令。 - 中文括号 ≥2 字、半角括号 ≥6 字符才算,避开
print(x)、(1)的误触发。 - 括号里用「你」描述她的动作(
(你亲了我一下))时,按动作指令处理:
照做,并在回复里用括号写出动作((亲了你一下));与场景描述可同时出现。
判据保守:以「你」开头、非问句、且有动作痕迹才算。 - 只挂对话模式;工作模式不挂(与风格同理)。
安全约定
- 风格在工作模式里被禁用:预设层面工作模式不挂该插件;
style.js的
DISABLED_PRESETS还会在运行时拒绝cyrene-work(读会话的
agent-preset/selected事件判断);新会话页的风格按钮在该模式下不显示。
原因:工作模式带 shell / 文件 / 网络权限,写作风格不该影响"能不能动手、动哪只手"。
已知限制(能力边界,非缺陷)
- DSH 的
LlmCallConfig只暴露temperature / maxTokens / stop:上游的top_p、
OpenAIfrequency_penalty、Qwenrepetition_penalty无处可放,未移植。 deepseek-flash在思考模式下温度可能不生效(上游同类规则requiresReasoningOff)。
本项目不替你改路由,只在/style的回复里提示。
升级须知
- 对话模式预设多挂了一行
dsh-cyrene/style,需要重装预设才生效:
node scripts/install.mjs --force(已存在且内容不同时默认拒绝覆盖)。 - 从 0.3.0 升级请一并看 0.3.1(行尾修复)与 0.3.2(会话来源修复)两条。
附:同时包含的 v0.3.2 修复
修复
新版 DSH 上「发消息没反应」(会话格式 v4 拒收消息来源)
- 现象:装好之后能选到模式,但发消息没有任何反应;没有任何报错指向本插件。
旧版本 DSH(如 0.1.5-rc.2)上一切正常 —— 所以自己测是测不出来的。 - 原因:世界书的命中块是一条手写的消息描述符,
source.kind写的是 v3 的裸
'plugin'。会话格式 v4 要求「生产者自有」的 kind(plugin:<插件 id>),于是整条
消息被校验拒掉:
SessionFormatError: format v4 message requires a producer-owned source kind。 - 修法:改为
kind: 'plugin:dsh-cyrene/worldbook'—— 这是 harness 自己的迁移器
(producerKind())给第三方插件生成的形态,新旧两个版本都接受。 - 已经装了的怎么办:更新代码后完全退出 DSH 再启动。JS 模块替换必须重启进程
才生效,热重载读到的仍是旧代码。 ⚠️ 别换成runtime-context:那是dsh-agent-loop自己持有的 kind,用它会让我们
注入的内容被当成它的运行时快照,进而被替换/清除。详见
docs/pitfalls.md第七节。
测试
- 单元测试 73 → 74 条。新增一条守
source.kind:必须是plugin:<id>、不能是裸
plugin、也不能是runtime-context,且注入块不能被当成真实用户语料。
v0.3.1 -- 修掉两条「不报错,但功能没了」的问题
已经是 0.3.0 的:建议升级,尤其是 Windows 用户(世界书在那边整条不生效)。
升级办法见下面「已经装了的怎么办」。没有电脑也能装,Windows 走node scripts/install.mjs。
修复
Windows 上世界书整条静默失效(建议升级)
- 现象:插件装上了、人设也在、注入块照常出现,但世界书一条都命中不了,
注入的内容也是错的。全程不报错,很容易误判成"人设不对"。 - 原因:世界书数据是
worldbook/data/*.md。Windows 上core.autocrlf=true
(GitHub 的 windows runner 默认就是)检出来是 CRLF,而解析器只按\n切行 ——
于是标题、触发词、正文尾部全挂上一个\r,触发词永远匹配不上(用户消息里没有\r)。 - 修法:解析层先归一
\r\n→\n(worldbook/parse.mjs);记忆文件同理
(memory.js的读取入口)——两者都是可能被人手改过的文件,不能假设行尾。
仓库再加.gitattributes的* text=auto eol=lf让各平台检出同一种行尾。 - 已经装了的怎么办:
git pull之后重跑一次装预设的命令(node scripts/install.mjs)。
注意.md的内容本身没有改动,git pull不一定重新检出它们 —— 但只要解析层是新的,
就不会再失效。
cyrene-work 在部分部署上整条预设加载失败
- 现象:模式选择器里根本不出现「昔涟工作模式」。
- 原因:三个工具行(
workflow-worker-thread/tool-workflow/tool-ralph)
依赖workflowEngine,而该服务在某些部署里起不来(实测 DSH 桌面端 0.2.0-rc.2)——
tool-workflow/tool-ralph会一直 waiting,激活审计据此判定整条预设失败。 - 修法:这三行默认
disabled: true。要用就把那三个disabled删掉。
代价是工作模式里暂时没有 workflow / ralph 两个工具 —— 少三个工具 ≪ 整条预设加载失败。
这是本仓库相对内置standard抄本唯一有意保留的差异,有测试盯着。
DSH 0.2.0+ 换了预设注册方式(不升级到 0.2.0 的可以跳过)
- 0.2.0 起预设改为声明式注册,注册表不再扫描
~/.dsh/.agent-presets/目录 ——
老方式在那一代上是静默失效(目录还在、预设不出现)。 - 用
node scripts/export-preset-declarations.mjs生成声明,自带- insert:那一层,
别去掉(裸的声明行会被当成"按 id 覆盖已有条目"而被跳过)。 - 0.1.x 仍走目录方式,
scripts/install.mjs两种都覆盖。
变更
- 删掉
scripts/install.ps1与install.bat。 作者没有自己的电脑,项目是在
DSH App(Android)里做的,这两个脚本无法实测 —— 靠用户反馈连试三轮仍未在真机跑通。
与其留一条"看起来能用、其实没人验证过"的路,不如只留一条能跑通的:
Windows 用户走node scripts/install.mjs(跨平台、无 shell 依赖、已实测安装/幂等/卸载)。
六条实测坑与恢复办法见docs/windows.md。 - CI 增加真实
windows-latestjob:语法检查、单元测试、声明导出必须真有输出、
install.mjs试装(安装 → 幂等 → 卸载)。上面那个 CRLF 的 bug 就是它第一次跑抓到的 ——
作者没有 Windows 机器,这台 runner 就是。 - 新增
CONTRIBUTING.md:写清维护边界(插件与预设本体归作者,
桌面端差异归社区,DSH 版本差异作者尽力跟进但需实测反馈)。
测试
- 单元测试 63 → 73 条。新增:行尾回归(CRLF/CR 输入与 LF 结果逐字一致、
随包 61 条真数据整份转 CRLF 后仍一致)、cyrene-work的抄本漂移护栏与
有意关闭集合、声明导出往返比对、可移植性静态断言。 npm test与npm run harness:check在 ubuntu(Node 22/24)与 Windows(Node 22)上都跑。
v0.3.0 · 改名 + 双模式
变更
- 改名:包名
dsh-cyrene,仓库DSH-Cyrene(9e9dc30、42f7ed1) - 新增「昔涟工作模式」预设:昔涟人设 + 标准模式全套工具(
9e9dc30) - 安装脚本支持多预设:自动发现
preset/下的每个子目录(9e9dc30)
修复
- 版本号补齐三处,并修掉「工作模式看不到」的过时断言(
80cf342) - 仓库 URL 指向实际仓库名(
42f7ed1)
文档
- 记下三个只能踩出来的 DSH 行为,新增
AGENTS.md(cfaf941) - 修正只对「单预设」成立的说法(
7d08702) - 写明
install.ps1/install.bat尚未在真实 Windows 上实跑过(690369c)
v0.2.3 · 外部评价 P0–P3
逐条核实外部评价后处理,另外修了他没提到的两处。
修复
- P0 人设正文的硬规则冲突:正文同时写着「这些词语并非绝对禁止」与「不可以使用……」,
以及「对方要求解释时必须说明」与「不需要解释为什么」。根因是上游靠请求尾部注入的时序
压过正文,本仓库合并成静态正文后时序消失。
修法是把覆盖关系显式写回正文(定向覆盖 + 一处明确例外),而不是删改上游文本(bb3b9e0) - P1 记忆通道没有净化:
memory.js原样塞进系统提示词,而记忆的写入方是模型、触发源可能是
联网结果。现在写入与注入两处都清洗,整份记忆包进显式数据分隔块(bb3b9e0) - P2 CI 与测试命令:测试头部那条
node --test tests/会挂;已改正并加警告。
新增package.json的test脚本、harness:check扩到全部运行时代码、
新增.github/workflows/test.yml(Node 22/24,无需 npm install) - P2 人设残留痕:删除上游自带的空台词行与一段逐字重复的「知识性回复」,
保留#标题作来源锚点,并在THIRD_PARTY_NOTICES如实披露 - P3 六个小口子:
forget只删-开头的条目行(短关键词不再误删标题);
scanDepth1–5 真的生效(原先被静默夹到 3);lastHit改有界 LRU(上限 64 会话);
删死代码assembleSplit();index.js版本号改为读package.json
测试
- 新增
tests/memory.test.mjs(14 条),用临时DSH_HOME,不碰真实记忆文件 - 全量 45 → 59 条通过
v0.2.2 · 世界书随包发运
新增
- 61 条世界书随包发运(
worldbook/data/),按触发词自动注入;装了就有,不需要自备(78cd969) - 注入通道按「需不需要本轮消息」拆成两条:
- 常驻块(内容恒定)→
systemPrompt.context(),只落库一次 - 命中块(需要本轮消息)→
agent/pre-step
- 常驻块(内容恒定)→
修复
- 绕开一个静默失效:
assemble()跑在用户消息落库之前,装配期读会话永远拿不到本轮输入
(新会话第一轮更是一条都没有);空文本 section 会被过滤掉,快照里看不出异常
说明
- 条目格式与字段语义来自 Cyrene-Agent 的
rag/worldbook.ts,本项目的匹配器是其简化实现
(去掉 DMAE 状态机,故「内在价值」不生效、「优先级」成为主排序键)
v0.2.1 · 修「语气变淡」
修复
- 补回原应用每轮注入的「语气规则」(句式禁止 / 语气参考 / 回复边界)。
之前因为includeRuntimeContext: false把动态块整体关掉,这段规则一并丢失,
模型退回默认助手腔:语气变淡、少了活人气(1cc8c12)
文档
THIRD_PARTY_NOTICES注明该段来自tone-injector.ts的DEFAULT_RULES,
不是prompts/下的文件;上游是随请求尾部注入,本仓库并入预设正文