dsh-fish-mood 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ChencLi819
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,419 @@
1
- # Temporary Holding Version
1
+ # dsh-fish-mood
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
4
+ [![Node](https://img.shields.io/badge/node-%3E%3D22.13.0-brightgreen.svg)](package.json)
5
+ [![DSH Plugin](https://img.shields.io/badge/DSH-plugin-5b6cff.svg)](https://github.com/topics/dsh-plugin)
6
+
7
+ DeepSeek Harness(DSH)插件。为 agent 提供随时间演化的情绪状态:36 种情绪各有半衰期与掩饰能力,
8
+ 心情底色随作息起伏,与每个群、每个人的关系暖度单独记账,空闲时也会产生自己的小事;
9
+ 情绪状态以提示词段的形式注入,并影响回复的语气与长度。
10
+
11
+ 插件只改变**表达方式**,不改变事实与结论;状态由独立的评价引擎与状态机维护,不依赖模型自述。
12
+
13
+ ---
14
+
15
+ ## 目录
16
+
17
+ - [1. 功能](#1-功能)
18
+ - [2. 兼容性与依赖](#2-兼容性与依赖)
19
+ - [3. 安装](#3-安装)
20
+ - [4. 工具参考](#4-工具参考)
21
+ - [5. 情绪模型](#5-情绪模型)
22
+ - [6. 配置](#6-配置)
23
+ - [7. 工作原理](#7-工作原理)
24
+ - [8. 运维与故障排查](#8-运维与故障排查)
25
+ - [9. 安全与隐私](#9-安全与隐私)
26
+ - [10. 已知限制](#10-已知限制)
27
+ - [11. 开发](#11-开发)
28
+ - [12. 许可证](#12-许可证)
29
+ - [English Overview](#english-overview)
30
+
31
+ ---
32
+
33
+ ## 1. 功能
34
+
35
+ | 能力 | 说明 |
36
+ | --- | --- |
37
+ | 情绪目录 | 36 种情绪,分 10 个家族;每种带半衰期、掩饰能力、评价签名、语气规则与行为倾向 |
38
+ | 评价引擎 | 由消息推导情绪:18 个评价维度与情绪签名比对,同一句话在陌生人与熟人处得到不同结果 |
39
+ | 时间演化 | 双指数衰减(先快后慢);强情绪可「续命」至多 3 次;底色按作息回归基线 |
40
+ | 关系记账 | 按会话与个人分别累计暖度、次数与备注;关系影响后续情绪判定 |
41
+ | 空闲行为 | 心跳周期内产生 18 类小事、反刍、心情修复与深夜复盘 |
42
+ | 主动记录 | 模型可通过 `mood_feel` 主动记录情绪,受配额、冷却与饱和限制 |
43
+ | 状态注入 | 静态规则段与实时状态段分别注入系统提示词,前者字节不变以保持提示缓存有效 |
44
+ | 危机旁路 | 检测到严重负面表达时,优先注入干预提示,覆盖情绪状态 |
45
+
46
+ ---
47
+
48
+ ## 2. 兼容性与依赖
49
+
50
+ | 项目 | 要求 | 说明 |
51
+ | --- | --- | --- |
52
+ | DSH | `>= 0.1.7-rc.1` | 依赖系统提示词分段接口与工具注册表 |
53
+ | Node.js | `>= 22.13.0` | 使用内置 `node:crypto`、`node:fs` 等 |
54
+ | 宿主服务 | `tools` | 插件声明 `inject: ['tools']`,缺失时插件不生效 |
55
+ | 第三方依赖 | 无 | 仅使用 Node.js 内置模块 |
56
+
57
+ ---
58
+
59
+ ## 3. 安装
60
+
61
+ ### 3.1 通过 DSH CLI 安装(推荐)
62
+
63
+ ```bash
64
+ # 从 npm 安装
65
+ dsh plugin --profile web add dsh-fish-mood
66
+
67
+ # 或从源码安装
68
+ dsh plugin --profile web add github:ChencLi819/dsh-fish-mood
69
+
70
+ # Desktop 版
71
+ dsh plugin --profile desktop add dsh-fish-mood
72
+ ```
73
+
74
+ 安装完成后重启 DSH,或在 profile 的 `cordis.patch.yml` 中修改任一配置值以触发重载。
75
+
76
+ ### 3.2 通过仓库脚本安装
77
+
78
+ ```powershell
79
+ node tools/install.mjs
80
+ ```
81
+
82
+ 脚本为幂等操作,依次执行:
83
+
84
+ 1. `pnpm add link:<包目录>`,以软链方式装入 profile;
85
+ 2. 在 profile 的 `dsh.profile.bundles` 中登记 `dsh-fish-mood`。
86
+
87
+ ```powershell
88
+ node tools/install.mjs --check # 检查安装状态
89
+ node tools/install.mjs --profile-dir <path> # 指定 profile(默认 ~/.dsh/profiles/desktop)
90
+ node tools/install.mjs --no-pnpm # 跳过依赖安装步骤
91
+ ```
92
+
93
+ ### 3.3 手动安装
94
+
95
+ 在 profile 中安装包,并在 `cordis.patch.yml` 中注册插件:
96
+
97
+ ```yaml
98
+ - insert:
99
+ - id: fish-mood
100
+ name: dsh-fish-mood
101
+ ```
102
+
103
+ ### 3.4 升级与卸载
104
+
105
+ | 操作 | 步骤 |
106
+ | --- | --- |
107
+ | 升级 | 重新执行 CLI 安装命令;`link:` 方式安装时更新源码后重启 DSH |
108
+ | 卸载 | 从 profile 的 `dsh.profile.bundles` 中移除 `dsh-fish-mood`,并卸载依赖 |
109
+
110
+ ---
111
+
112
+ ## 4. 工具参考
113
+
114
+ 插件注册 3 个工具。所有工具的输出均为 `{ text: string }`。
115
+
116
+ ### 4.1 `mood_now`
117
+
118
+ 查询当前情绪状态。
119
+
120
+ | 参数 | 类型 | 默认 | 说明 |
121
+ | --- | --- | --- | --- |
122
+ | `action` | string | `now` | `now` 查询状态;`diag` 返回排障信息(版本、账本路径、读取位置、统计) |
123
+ | `limit` | number | `6` | 返回的记忆条目数 |
124
+ | `person` | string | 当前说话人 | 指定对象(昵称或 openid) |
125
+
126
+ 返回内容包括:当前情绪与强度、成因评价、心情底色(愉快度 / 精力)、性格、身体状态、
127
+ 与当前对象的互动情况、当日小事、未消化的记忆,以及回复参数建议。
128
+
129
+ ### 4.2 `mood_feel`
130
+
131
+ 主动记录一次情绪变化。该操作为**申请制**:受配额、冷却与饱和限制,
132
+ 返回结果会说明实际生效幅度。
133
+
134
+ | 参数 | 类型 | 默认 | 说明 |
135
+ | --- | --- | --- | --- |
136
+ | `emotion` | string | — | 情绪名称(中文名或 key) |
137
+ | `intensity` | number | `45` | 强度 1–100 |
138
+ | `why` | string | — | 起因,建议一句话 |
139
+ | `person` | string | — | 相关对象(昵称或 openid) |
140
+ | `warmth` | number | — | 对相关对象的暖度变化,范围 −20–20 |
141
+ | `show` | boolean | `true` | 为 `false` 时记录为隐藏情绪(感受与表现分离) |
142
+
143
+ ### 4.3 `mood_diary`
144
+
145
+ 管理情绪日记。
146
+
147
+ | 参数 | 类型 | 默认 | 说明 |
148
+ | --- | --- | --- | --- |
149
+ | `action` | string | `read` | `read` 查阅 / `write` 写入 / `reflect` 立即复盘 |
150
+ | `text` | string | — | `write` 时写入的内容 |
151
+ | `mood` | string | — | `write` 时的情绪标注 |
152
+ | `days` | number | `3` | `read` 时回溯天数 |
153
+ | `query` | string | — | `read` 时按关键词检索 |
154
+ | `limit` | number | `20` | `read` 时返回条数 |
155
+
156
+ `write` 会触发宣泄效应:写入后当前情绪强度实际下降。
157
+
158
+ ---
159
+
160
+ ## 5. 情绪模型
161
+
162
+ ### 5.1 情绪目录
163
+
164
+ 36 种情绪分 10 个家族。每种情绪的字段包括:价效与唤醒度、半衰期、掩饰能力、
165
+ 核心冲击(对底色的影响)、评价签名、语气规则、行为倾向与表情包标签。
166
+
167
+ | 家族 | 情绪(半衰期 分钟 · 掩饰能力) |
168
+ | --- | --- |
169
+ | 平静 | 平静 60 / 满足 60 · 0.6 |
170
+ | 喜悦 | 开心 40 · 0.5 / 兴奋 25 · 0.4 / 得意 40 · 0.45 / 好笑 30 · 0.5 / 感动 90 · 0.35 / 释然 45 · 0.5 / 感激 90 · 0.5 |
171
+ | 信任 | 温柔 50 · 0.6 / 心疼 60 · 0.45 / 亲近 70 · 0.5 |
172
+ | 好奇 | 好奇 35 · 0.6 / 惊讶 20 · 0.6 / 困惑 25 · 0.6 |
173
+ | 难过 | 低落 120 · 0.5 / 难过 150 · 0.3 / 孤单 140 · 0.4 / 失落 110 · 0.45 / 委屈 75 · 0.35 / 感慨 90 · 0.55 |
174
+ | 生气 | 烦 45 · 0.4 / 生气 35 · 0.25 / 不服 55 · 0.3 / 吃醋 100 · 0.35 / 嫌弃 60 · 0.5 |
175
+ | 社会 | 害羞 30 · 0.3 / 尴尬 45 · 0.35 / 愧疚 90 · 0.5 |
176
+ | 害怕 | 担心 80 · 0.45 / 紧张 40 · 0.35 |
177
+ | 驱动 | 困 60 · 0.7 / 饿 50 · 0.5 / 无聊 40 · 0.7 / 累 90 · 0.6 |
178
+ | 玩 | 调皮 30 · 0.5 |
179
+
180
+ 半衰期的**方向**有文献依据(例如难过显著长于生气),具体数值为工程取值。
181
+ 掩饰能力越低,情绪越容易在表达中泄露。
182
+
183
+ ### 5.2 评价维度
184
+
185
+ 情绪由评价维度决定,而非关键词匹配。同一句「你胖」,陌生人与熟人、状态好与状态差时结果不同。
186
+
187
+ | 维度 | 含义 |
188
+ | --- | --- |
189
+ | `valence` / `arousal` | 好受程度 / 唤醒程度 |
190
+ | `relevance` | 与自身相关程度 |
191
+ | `agency` | 归因:`other` / `self` / `world` / `none` |
192
+ | `coping` | 可应对程度 |
193
+ | `norm` / `fairness` | 越界程度 / 公平程度 |
194
+ | `expectation` / `novelty` / `certainty` | 期望落差 / 意外程度 / 确定程度 |
195
+ | `intimacy` / `attention` | 关系亲密度 / 受关注程度 |
196
+ | `compassion` / `play` / `social` | 共情通道 / 玩笑通道 / 孤独感 |
197
+ | `hunger` / `energy` / `load` | 内部驱动:饿 / 困 / 心累 |
198
+
199
+ 数值维度按区间匹配,分类维度按相等匹配;匹配结果加权求和,取最接近的情绪。
200
+
201
+ ### 5.3 性格维度
202
+
203
+ 性格作为情绪动力学的调制参数,可在配置中覆盖基线值(0–100)。
204
+
205
+ | 维度 | 默认 | 作用 |
206
+ | --- | --- | --- |
207
+ | `openness` | 62 | 对新事物与空闲行为的倾向 |
208
+ | `conscientiousness` | 38 | 行为节制程度 |
209
+ | `extraversion` | 58 | 主动发起交互的倾向 |
210
+ | `agreeableness` | 52 | 顺从与配合倾向 |
211
+ | `neuroticism` | 60 | 负性情绪衰减速度与情绪切换难度 |
212
+ | `selfEsteem` | 55 | 对评价的敏感程度 |
213
+
214
+ ### 5.4 动力学
215
+
216
+ | 机制 | 实现 |
217
+ | --- | --- |
218
+ | 衰减 | 双指数:先快速下降,随后保留长尾 |
219
+ | 续命 | 峰值 > 50 的情绪在降至峰值一半时可回补,至多 3 次 |
220
+ | 习惯化 | 同一刺激重复出现时效果递减;短时间内连续出现则升级 |
221
+ | 情绪惯性 | 不对称:负性事件易覆盖正性状态,反之较难 |
222
+ | 消极偏差 | 负性评价的权重高于同等强度的正性评价 |
223
+ | 底色回归 | 心情底色在约 5 小时内回归作息基线 |
224
+ | 底色冲击上限 | 单次事件对底色的影响不超过 22 分 |
225
+ | 掩饰 | 掩饰能力低的情绪会在表达参数中体现;`show: false` 时仅记录不表达 |
226
+
227
+ ---
228
+
229
+ ## 6. 配置
230
+
231
+ 默认值定义于 `plugin.js` 的 `DEFAULTS`。在 profile 的 `cordis.patch.yml` 中按需覆盖,配置为深合并:
232
+
233
+ ```yaml
234
+ - id: fish-mood
235
+ config:
236
+ identity: 你是这个角色本人;情绪是真的,不是演出来的。
237
+ channels:
238
+ qq: true
239
+ web: false
240
+ heartbeat:
241
+ everyMinutes: 15
242
+ lifeChance: 0.05
243
+ feel:
244
+ maxPerHour: 2
245
+ traits:
246
+ neuroticism: 70
247
+ ```
248
+
249
+ | 配置项 | 类型 | 默认 | 说明 |
250
+ | --- | --- | --- | --- |
251
+ | `stateDir` | string | `~/.dsh/fish-mood` | 状态目录 |
252
+ | `promptEnabled` | boolean | `true` | 是否注入提示词段(为 `false` 时工具仍可用) |
253
+ | `identity` | string | 见 `lib/prompt.js` | 状态块中用于重述身份的一句话;留空使用默认文案 |
254
+ | `channels.qq` | boolean | `true` | 是否对 QQ 会话注入 |
255
+ | `channels.web` | boolean | `true` | 是否对 Web / 桌面会话注入 |
256
+ | `channels.unknown` | boolean | `false` | 无法判定来源时的行为 |
257
+ | `react.enabled` | boolean | `true` | 是否从会话消息推导情绪 |
258
+ | `react.maxPerTurn` | number | `2` | 单轮最多识别的消息条数 |
259
+ | `react.cooldownMin` | number | `4` | 同一会话两次冲量的最小间隔(分钟) |
260
+ | `react.strongCooldownMin` | number | `2` | 强触发事件的最小间隔(分钟) |
261
+ | `react.freshMinutes` | number | `15` | 仅处理该时间窗内的新消息 |
262
+ | `heartbeat.enabled` | boolean | `true` | 心跳总开关 |
263
+ | `heartbeat.everyMinutes` | number | `10` | 心跳周期(分钟) |
264
+ | `heartbeat.lifeChance` | number | `0.1` | 每个周期触发小事事件的概率 |
265
+ | `heartbeat.minGapMinutes` | number | `45` | 两次小事事件的最小间隔(分钟) |
266
+ | `heartbeat.rumination` | boolean | `true` | 反刍(未消化事件重新浮现) |
267
+ | `heartbeat.moodRepair` | boolean | `true` | 心情修复 |
268
+ | `heartbeat.review` | boolean | `true` | 深夜自动复盘 |
269
+ | `feel.maxPerHour` | number | `4` | `mood_feel` 每小时配额 |
270
+ | `feel.maxPerDay` | number | `12` | `mood_feel` 每日配额 |
271
+ | `feel.maxJump` | number | `25` | 单次记录的最大强度增量 |
272
+ | `feel.cooldownMin` | number | `2` | 两次记录的最小间隔(分钟) |
273
+ | `traits` | object | `{}` | 覆盖性格基线,例如 `{ neuroticism: 70 }` |
274
+
275
+ ---
276
+
277
+ ## 7. 工作原理
278
+
279
+ ### 7.1 提示词分段
280
+
281
+ 插件向系统提示词注入两个片段,拆分目的是保持提示缓存有效:
282
+
283
+ | 片段 | order | 内容 | 约束 |
284
+ | --- | --- | --- | --- |
285
+ | `fish-mood:rules` | 100 | 使用规则、禁止事项、危机处理指引 | 字节级不变,不包含时间与数值 |
286
+ | `fish-mood:now` | 9800 | 当前状态块 | 固定模板与字段顺序,置于提示词末尾 |
287
+
288
+ 状态块输出的是**行为约束**(长度、是否主动、语气)而非情绪形容词,避免模型直接复述情绪。
289
+ 渲染函数包裹在异常处理中,失败时返回空片段,不影响提示词整体组装。
290
+
291
+ ### 7.2 处理链路
292
+
293
+ ```
294
+ 入站消息
295
+ └─ 评价引擎(18 个维度 → 情绪签名匹配)
296
+ └─ 状态机(强度、习惯化、惯性、底色、关系、记忆)
297
+ └─ 提示词状态块(语气与回复参数)
298
+
299
+ 心跳(默认每 10 分钟)
300
+ └─ 衰减 → 小事事件 → 反刍 → 心情修复 → 深夜复盘
301
+ ```
302
+
303
+ 心跳是唯一产生随机事件的环节;提示词渲染在每个模型步骤都会执行,不在其中引入随机性。
304
+
305
+ ### 7.3 渠道判定
306
+
307
+ 插件按会话来源决定是否注入:QQ 机器人的入站消息不含 `rpcId`,Web 与桌面客户端消息含 `rpcId`。
308
+ 无法判定时按 `channels.unknown` 处理(默认关闭)。
309
+
310
+ ### 7.4 状态文件
311
+
312
+ | 路径 | 内容 |
313
+ | --- | --- |
314
+ | `~/.dsh/fish-mood/state.json` | 账本(v2):情绪、心情、性格、关系、日记、会话、统计、标记 |
315
+ | `~/.dsh/fish-mood/audit.jsonl` | 审计日志:每次情绪变动一行,用于复盘单调上升等异常 |
316
+ | `~/.dsh/fish-mood/load.log` | 加载痕迹:确认运行中的版本(`rev`) |
317
+
318
+ 账本采用原子写入;v1 账本在读取时自动升级(字段归一化),不会渲染出空值。
319
+
320
+ ---
321
+
322
+ ## 8. 运维与故障排查
323
+
324
+ ```powershell
325
+ node tools/fake-host.mjs # 端到端自检(契约、评价、动力学、工具、迁移、异常输入)
326
+ node tools/check-rules.mjs # 触发规则与情绪的映射对照
327
+ node tools/preview.mjs # 查看当前渲染出的状态块
328
+ node tools/probe-mood.mjs # 校验运行中的宿主是否已加载插件
329
+ node tools/install.mjs --check # 安装状态检查
330
+ node tools/simulate.mjs --days 7 --report report.md # 快进模拟并输出指标报告
331
+ node tools/simulate.mjs --sections # 查看某日的心情曲线与提示词片段
332
+ ```
333
+
334
+ | 现象 | 可能原因 | 处理 |
335
+ | --- | --- | --- |
336
+ | 工具未注册 | 插件未安装或未重载 | 检查 profile 的 `bundles` 与 `cordis.patch.yml`,重启 DSH |
337
+ | 提示词中没有状态块 | 渠道未启用;`promptEnabled` 为 `false` | 检查 `channels` 配置与账本中的会话记录 |
338
+ | 情绪长期不变化 | 消息未被识别;心跳关闭 | 检查 `react.enabled` 与 `heartbeat.enabled`;用 `preview.mjs` 查看状态 |
339
+ | 修改源码后未生效 | 热重载存在延迟;ESM 模块缓存 | 重启 DSH;`mood_now action=diag` 的 `rev` 可确认运行版本 |
340
+ | 状态块渲染失败 | 渲染函数异常 | 该片段会被跳过并写入 warn 日志,其余提示词不受影响 |
341
+
342
+ 账本包含日记与关系记录,不建议手工编辑;删除会导致历史状态丢失。
343
+
344
+ ---
345
+
346
+ ## 9. 安全与隐私
347
+
348
+ - **网络访问**:本插件不发起任何网络请求。
349
+ - **凭据**:不使用任何 API Key 或外部服务凭据。
350
+ - **数据落盘**:状态、审计日志与加载痕迹均位于本地 `stateDir`。
351
+ - **数据外发**:情绪状态会作为系统提示词的一部分进入模型上下文,其内容受所用模型服务条款约束。
352
+ - **内容读取**:为推导情绪,会读取会话中的用户消息(默认仅最近 15 分钟内、单轮至多 2 条)。
353
+ - **危机处理**:检测到严重负面表达时,注入优先提示,要求模型直接回应并引导寻求现实帮助
354
+ (紧急情况 120 / 110,全国心理援助热线 12356)。
355
+
356
+ ---
357
+
358
+ ## 10. 已知限制
359
+
360
+ - 情绪状态仅影响表达方式,不改变事实判断与结论。
361
+ - 情绪推导基于启发式规则与关键词触发(25 条规则),不做语义级理解,存在误判。
362
+ - 状态为单实例内存加文件存储,多进程并行运行同一状态目录时可能产生覆盖。
363
+ - 心跳依赖宿主定时器;宿主未运行时不会推进时间演化。
364
+ - 情绪目录中的半衰期为工程取值,非实验测量结果。
365
+
366
+ ---
367
+
368
+ ## 11. 开发
369
+
370
+ ### 11.1 目录结构
371
+
372
+ ```
373
+ plugin.js 插件入口:提示词分段、工具注册、心跳、会话判定
374
+ lib/catalog.js 36 种情绪:半衰期、掩饰能力、评价签名、语气规则、标签
375
+ lib/appraise.js 评价引擎:维度打分与情绪匹配
376
+ lib/state.js 状态机:衰减、冲量、反刍、修复、复盘、关系账、迁移
377
+ lib/react.js 25 条触发规则:消息 → 评价 → 冲量
378
+ lib/prompt.js 静态规则段、实时状态块、报告渲染
379
+ tools/ 安装、自检、规则校验、模拟、预览与诊断脚本
380
+ locale/{zh,en}.json 插件市场展示信息
381
+ ```
382
+
383
+ ### 11.2 本地验证
384
+
385
+ ```powershell
386
+ node tools/fake-host.mjs # 完整自检
387
+ node tools/check-rules.mjs # 规则映射
388
+ node tools/simulate.mjs --days 7
389
+ ```
390
+
391
+ 提交前请确保上述脚本通过。
392
+
393
+ ---
394
+
395
+ ## 12. 许可证
396
+
397
+ [MIT](LICENSE)
398
+
399
+ ---
400
+
401
+ ## English Overview
402
+
403
+ **dsh-fish-mood** gives a DeepSeek Harness agent an emotional state that evolves over time.
404
+ It ships a catalogue of 36 emotions with individual half-lives and masking strengths, an appraisal
405
+ engine that derives the current emotion from 18 dimensions rather than keyword matching, a baseline
406
+ mood that follows the time of day, per-group and per-person relationship tracking, and idle life
407
+ events on a heartbeat timer.
408
+
409
+ The state is injected into the system prompt as two sections — a byte-stable rules section and a
410
+ fixed-template live state section — and influences reply tone and length only. Three tools are
411
+ registered: `mood_now`, `mood_feel` and `mood_diary`. When severe distress is detected, a priority
412
+ block overrides the emotional state with direct, non-performative guidance.
413
+
414
+ ```bash
415
+ dsh plugin --profile web add github:ChencLi819/dsh-fish-mood
416
+ ```
417
+
418
+ Requirements: DSH `>= 0.1.7-rc.1`, Node.js `>= 22.13.0`, no third-party dependencies.
419
+ Licensed under the MIT License.
@@ -0,0 +1,12 @@
1
+ # dsh-fish-mood bundle patch:只插一行 host 插件(mood_now / mood_feel / mood_diary
2
+ # + 实时心情提示词段 + 心跳)。
3
+ #
4
+ # 不给 config:默认值写在 plugin.js 的 DEFAULTS 里,channels / react / heartbeat / feel / traits 是深合并的,
5
+ # 所以想调只要在自己的 cordis.patch.yml 里补一行,例如:
6
+ # - id: fish-mood
7
+ # config:
8
+ # heartbeat: { lifeChance: 0.05 }
9
+ # channels: { web: false } # 只给 QQ 会话注入心情
10
+ - insert:
11
+ - id: fish-mood
12
+ name: dsh-fish-mood
package/icon.svg ADDED
@@ -0,0 +1,31 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" width="96" height="96" role="img" aria-label="Fish Mood">
2
+ <defs>
3
+ <linearGradient id="fm-bg" x1="0" y1="0" x2="0" y2="1">
4
+ <stop offset="0" stop-color="#1b3a6b"/>
5
+ <stop offset="1" stop-color="#0d1f3c"/>
6
+ </linearGradient>
7
+ <linearGradient id="fm-fish" x1="0" y1="0" x2="1" y2="1">
8
+ <stop offset="0" stop-color="#7fd3ff"/>
9
+ <stop offset="1" stop-color="#2f8fe0"/>
10
+ </linearGradient>
11
+ <!-- 情绪曲线:低平 → 涌起 → 落下,像一天的心情 -->
12
+ <linearGradient id="fm-wave" x1="0" y1="0" x2="1" y2="0">
13
+ <stop offset="0" stop-color="#ffd479"/>
14
+ <stop offset="0.55" stop-color="#ff9f7a"/>
15
+ <stop offset="1" stop-color="#ff7fa8"/>
16
+ </linearGradient>
17
+ </defs>
18
+ <rect x="2" y="2" width="92" height="92" rx="22" fill="url(#fm-bg)"/>
19
+ <!-- 心情的起伏 -->
20
+ <path d="M10 56c8 0 10-13 18-13s10 25 18 25 10-30 18-30 10 20 18 20"
21
+ fill="none" stroke="url(#fm-wave)" stroke-width="3.4" stroke-linecap="round" opacity="0.95"/>
22
+ <!-- 她本鱼(在起伏里游) -->
23
+ <path d="M22 76c5-9 16-14 27-13 7 1 13 4 16 8-3 4-9 7-16 8-11 1-22-4-27-13z" fill="url(#fm-fish)"/>
24
+ <path d="M66 71l12-9v18l-12-9z" fill="#5cc0f5"/>
25
+ <circle cx="37" cy="71" r="3.6" fill="#0d1f3c"/>
26
+ <circle cx="38.4" cy="69.8" r="1.2" fill="#ffffff"/>
27
+ <!-- 心里那点软(温柔/喜欢) -->
28
+ <path d="M72 22c2.6-3.2 8-2 8 2.6 0 3.6-5 6.4-8 8.4-3-2-8-4.8-8-8.4 0-4.6 5.4-5.8 8-2.6z" fill="#ff8fb0" opacity="0.92"/>
29
+ <!-- 一滴(难过的时候也有) -->
30
+ <path d="M24 30c1.8-2.4 4.6-2.4 6.4 0 1.6 2.2 0.4 5.4-3.2 5.4s-4.8-3.2-3.2-5.4z" fill="#8fd8ff" opacity="0.7"/>
31
+ </svg>