dsh-ai-with-u 0.2.0 → 0.5.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/README.md +339 -23
- package/distill/flow-create.md +449 -0
- package/lib/client.js +1010 -149
- package/lib/distill.js +74 -21
- package/lib/import-card.js +33 -4
- package/lib/index.js +28 -11
- package/lib/preset.js +434 -0
- package/lib/prompt.js +719 -63
- package/lib/store.js +623 -23
- package/lib/tavern.js +237 -44
- package/lib/tools.js +128 -38
- package/lib/web.js +419 -33
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
**给 DeepSeek Harness 的角色扮演插件。** 蒸馏任意ip角色卡并让你的大肥鱼成为TA,选一张角色卡点「启用」,人设立刻生效;点「退出」,干净拔出,正常工作不受影响。
|
|
4
4
|
|
|
5
|
-

|
|
6
|
+

|
|
6
7
|

|
|
7
8
|

|
|
8
9
|

|
|
9
|
-

|
|
10
11
|
|
|
11
12
|
<p align="center">
|
|
12
13
|
<img src="docs/assets/panel.png" width="880" alt="角色管理器面板:左侧角色簿,右侧角色卡详情与编辑入口">
|
|
@@ -44,11 +45,16 @@
|
|
|
44
45
|
|
|
45
46
|
| | 原 skill | 本插件 |
|
|
46
47
|
|---|---|---|
|
|
47
|
-
| 提示词 | `SKILL.md` 13 KB,每轮全量注入 | 启用态约 2.
|
|
48
|
+
| 提示词 | `SKILL.md` 13 KB,每轮全量注入 | 启用态约 2.8–3.3 KB(lite 档),不启用时为 0 |
|
|
48
49
|
| 文件读写 | 模型自己动手 | 插件代码保证,原子写 + 跨进程锁 |
|
|
49
50
|
| 角色管理 | 在对话里说指令 | 可视化面板 |
|
|
50
51
|
| 生效时机 | 一直生效 | 可插拔,退出即卸载 |
|
|
51
52
|
|
|
53
|
+
有两处是**故意不做**,别当成缺功能:
|
|
54
|
+
|
|
55
|
+
- **8 个场景的扮演测试**(原 skill 里那套「测一遍人设像不像」的用例)没搬。人像不像只能靠聊,靠脚本测不出来——能测的(提示词长度、字段完整性、世界书命中、导入解析)都已经进了自检,共八套。
|
|
56
|
+
- **`manifest` / `full_card` 不单独落文件**,收进 `card.json` 的 `extensions.aiwu` 里。CCv3 本身只有一份真相,再存一份清单等于制造两个会互相漂移的事实来源;要读清单就 `GET /character`。
|
|
57
|
+
|
|
52
58
|
---
|
|
53
59
|
|
|
54
60
|
## 它是怎么工作的
|
|
@@ -58,10 +64,12 @@ flowchart LR
|
|
|
58
64
|
U[你的消息] --> S[DSH 会话]
|
|
59
65
|
S --> A{每轮组装系统提示词}
|
|
60
66
|
A --> L0[L0 底线]
|
|
67
|
+
A --> L05[L0.5 纪律包]
|
|
61
68
|
A --> L1[L1 角色卡]
|
|
62
69
|
A --> W[世界书命中]
|
|
63
70
|
A --> D[日记与会话摘要]
|
|
64
71
|
L0 --> M[模型]
|
|
72
|
+
L05 --> M
|
|
65
73
|
L1 --> M
|
|
66
74
|
W --> M
|
|
67
75
|
D --> M
|
|
@@ -75,11 +83,14 @@ flowchart LR
|
|
|
75
83
|
| 层级 | 什么时候在 | 内容 | 体积 |
|
|
76
84
|
|---|---|---|---|
|
|
77
85
|
| **L0 底线** | 启用期间 | 优先级声明 + 扮演底线 | 约 365 字符 |
|
|
86
|
+
| **L0.5 纪律包** | 启用期间,按档位 | 禁止词库、消息形态、动作格式、输入识别、内容边界 | lite 555 / full 736 字符 |
|
|
78
87
|
| **L1 角色** | 启用期间 | CCv3 角色卡(声线优先)+ 时间差 + 最近日记 | 约 1.9–2.4K,随卡增长 |
|
|
79
88
|
| **世界书** | 命中才注入 | 关键词 / 常驻条目,预算 12 条 · 6000 字符 | 典型约 0.2K |
|
|
80
89
|
| **L2 长流程** | 工具按需 | 蒸馏、建卡向导 | 不进系统提示词 |
|
|
81
90
|
|
|
82
|
-
|
|
91
|
+
退出时五段全部返回空串,宿主会过滤掉——这是「干净拔出」的实现方式,不是靠删文件。
|
|
92
|
+
|
|
93
|
+
纪律包有三档:`off`(关掉)/ `lite`(默认)/ `full`(多一段「遮住名字也要猜得出是谁」的语态锚点 + 每 10 轮日记自检)。切档走 `POST /_dsh/ai-with-u/discipline`,偏好存在 `_active.json` 里,退出角色也保留。
|
|
83
94
|
|
|
84
95
|
### 插拔
|
|
85
96
|
|
|
@@ -95,11 +106,35 @@ flowchart LR
|
|
|
95
106
|
|
|
96
107
|
四个分区:
|
|
97
108
|
|
|
98
|
-
- **角色簿** —
|
|
99
|
-
- **日记** —
|
|
109
|
+
- **角色簿** — 卡片墙、导入角色卡、注入预览、详情页、完整编辑
|
|
110
|
+
- **日记** — 时间线、关键词搜索、按月折叠、导出 markdown、逐条改写、危险区
|
|
100
111
|
- **统计** — 角色数、记忆条数、对话轮次
|
|
101
112
|
- **指南** — 首次打开时的使用说明
|
|
102
113
|
|
|
114
|
+
**注入预览**在角色簿详情的「预览」入口:列出此刻真正会进系统提示词的五段(L0 底线 / L0.5 纪律包 / L1 角色 / 世界书 / 时间差),每段给段名与字符数,下面是逐段正文,最后给总字符数。它显示的是宿主那一刻的真实渲染结果(`GET /preview`,纯只读:不刷新缓存、不写盘),不是面板自己另算的一份——两套算法的预览迟早会和实际注入对不上。
|
|
115
|
+
|
|
116
|
+
日记页支持**记忆回顾**:关键词搜索(标题、正文、日期都能命中)、按月份折叠,以及把当前角色的日记导出成 markdown 文件(浏览器里直接下载,不经过宿主)。
|
|
117
|
+
|
|
118
|
+
角色簿左栏顶部并排两枚同级按钮:**蒸馏角色卡**(从作品里蒸一张)和 **自创角色卡**(从零写一张)。旁边是对话模式的胶囊「纯文本 / 文本 + 动作」,当前值高亮,点一下立刻生效——不需要先启用角色,因为模式是偏好不是角色属性。
|
|
119
|
+
|
|
120
|
+
自创角色卡填三格(名字 / 身份 / 一句话背景)就能落档。想省事就勾「让 AI 补全人设」:插件先把这张骨架卡存好,再把补全指令发到当前会话,AI 会先问你 3–5 个关键问题(声线、关系、雷区、称呼),然后按酒馆卡格式补齐人设、开场白和世界书。合理推断标 `[AI推断]`,推不出来的标 `[待补]`,不编造。
|
|
121
|
+
|
|
122
|
+
角色簿左栏还有「导入角色卡」,吃酒馆卡的三种形态:带立绘的 `.png`、`.charx` 压缩包、裸 `.json`。选完文件先出预览(识别到的名字、格式、全部 warnings),同名卡会提醒冲突并要二次确认;确认后才写盘,取消不落任何文件。文件上限 11 MB——base64 会膨胀 4/3,11 MB 传到宿主正好还在 16 MB 收包线内;带立绘的 PNG 卡常见 3–10 MB。
|
|
123
|
+
|
|
124
|
+
「世界书太大」不再拦导入,只给警告:世界书是**按需注入**的(12 条 / 6000 字预算),超大书不会把提示词撑爆,只是超出预算的条目进不去当轮上下文。真正没有预算、直进提示词的那五个原生字段(描述 / 性格 / 场景 / 系统提示 / 历史后指令)仍然有硬上限。
|
|
125
|
+
|
|
126
|
+
角色卡编辑器是 10 组 34 字段,第 11 个分区是**世界书**:条目名、关键词 / 副关键词(逗号分隔)、内容长文本(可全屏写)、常驻、优先级、插入顺序、逐条启用与上移下移。高级项里有位置(角色设定前 / 后)、大小写敏感、`selective`、正则。
|
|
127
|
+
|
|
128
|
+
顶部体检按**三档**给结论,「必须处理」的只有两种真正会失效的情况:
|
|
129
|
+
|
|
130
|
+
| 档 | 报什么 |
|
|
131
|
+
|---|---|
|
|
132
|
+
| **必须处理(error)** | 非常驻且没有关键词(永远命不中)、内容为空(注入了等于没注入) |
|
|
133
|
+
| **建议看(warn)** | 条数超过建议线(30 条)——不会报错,超出预算的条目这一轮不进提示词,去「被裁条目」看清单 |
|
|
134
|
+
| **知道就好(info)** | 偏长条目**聚合一条**(默认不逐条;单条超 3000 字才会单独点名,因为命中一次就挤掉别人)、共享关键词**聚合一条** |
|
|
135
|
+
|
|
136
|
+
**字数不是问题**:世界书按需注入,总量再大也只是命中变少,所以「总字数超出」这条提醒已整条删掉(v0.3 之前会报,纯噪音)。体检只提示,不拦保存。
|
|
137
|
+
|
|
103
138
|
编辑器里「声线基因」是灵魂字段:说话节奏、自称、口头禅、禁忌词、小动作。这些决定「听起来像不像他」,所以给了金色描边和独立徽记。
|
|
104
139
|
|
|
105
140
|
---
|
|
@@ -114,6 +149,20 @@ flowchart LR
|
|
|
114
149
|
|
|
115
150
|
### 步骤
|
|
116
151
|
|
|
152
|
+
包已发布到 npm,可以跳过克隆直接装(装完仍要按第 3 步配 bundles):
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
npm install dsh-ai-with-u
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
GitHub Packages 上也有同一版本(scoped 名,需要带 `read:packages` 的 token):
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npm install @treasure-hub-agent/dsh-ai-with-u --registry=https://npm.pkg.github.com
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
或者从源码构建:
|
|
165
|
+
|
|
117
166
|
```bash
|
|
118
167
|
git clone https://github.com/Treasure-hub-agent/dsh-ai-with-u.git
|
|
119
168
|
cd dsh-ai-with-u
|
|
@@ -158,12 +207,163 @@ New-Item -ItemType Junction `
|
|
|
158
207
|
3. 开个新会话,像给老朋友发消息一样聊
|
|
159
208
|
4. 不想玩了点「退出」
|
|
160
209
|
|
|
210
|
+
想换说话方式(要不要带 `(动作)`)不用回面板:角色簿左栏工具栏有「纯文本 / 文本 + 动作」两枚胶囊,点一下 `POST /mode` 立刻切;也可以在对话里让模型切(`awu_mode`)。
|
|
211
|
+
|
|
161
212
|
开箱自带三张范例卡(丰川祥子 / 阿米娅 / 昔涟,都由插件自己的蒸馏流程产出)。首次启用时幂等种入:`characters/` 已存在就跳过,不会复活你删掉的卡。
|
|
162
213
|
|
|
214
|
+
### 角色启用:两种作用域
|
|
215
|
+
|
|
216
|
+
「启用」有两种,互不覆盖:
|
|
217
|
+
|
|
218
|
+
| 作用域 | 管谁 | 动作 |
|
|
219
|
+
|---|---|---|
|
|
220
|
+
| **全局启用** | 所有**没绑定**的会话(以及子代理) | `POST /activate` |
|
|
221
|
+
| **当前会话启用** | 只绑这一个会话 | `POST /bind {name, sessionId}` |
|
|
222
|
+
|
|
223
|
+
**决议优先级(写死、可被断言)**:
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
会话绑定 > 全局启用 > 未启用
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
举例:全局启用阿米娅、当前会话绑定丰川祥子 → 这个会话是祥子,其它会话是阿米娅。
|
|
230
|
+
全局切换不会动任何已有绑定;取消绑定后该会话自动回落到全局。
|
|
231
|
+
|
|
232
|
+
**两条硬边界**(不是限制,是防串台):
|
|
233
|
+
|
|
234
|
+
1. **绑定的卡被删掉 → 该会话视为「未启用」,绝不回落到全局**。
|
|
235
|
+
否则你会以为在跟祥子聊、其实在跟阿米娅聊——这种「静默串台」比报错难查得多。重新绑定会自动解除这个状态。
|
|
236
|
+
2. **子代理固定用全局角色,不继承父会话的绑定**。
|
|
237
|
+
子代理有自己的 agent/session 查不到绑定,于是自然走全局。这是设计选择:让子代理继承会让人设意外泄漏到工具链深处。
|
|
238
|
+
|
|
239
|
+
**面板怎么显示两态**:详情页把「启用」拆成两枚动作——「当前会话启用」和「全局启用」,状态条分行显示
|
|
240
|
+
「当前会话:X(已绑定)」与「全局:Y」。点两者都会就地提示影响范围(「只影响当前会话」/「所有未绑定会话」)。
|
|
241
|
+
拿不到会话标识时(面板不知道自己在哪个会话)「当前会话启用」会置灰并说明原因,**不会瞎猜一个 id 写进去**。
|
|
242
|
+
|
|
243
|
+
> 提示词级的隔离是真的:宿主每段提示词都能拿到当前 Agent,所以同一个插件可以按会话渲染不同角色。
|
|
244
|
+
> 技术细节(`PromptSection` 没有 `scope`、但 `text(context)` 里有 `agent`)写在 `docs/DEVELOPMENT.md` §十四。
|
|
245
|
+
|
|
163
246
|
### 兼容旧卡与酒馆卡
|
|
164
247
|
|
|
165
248
|
- **旧 34 字段卡**:直接放进 `characters/<名>/card.json`,读时自动归一成 CCv3,首次保存时才落成新格式并留下 `card.v1.bak.json`
|
|
166
249
|
- **酒馆卡导入**:支持 `.png`(`tEXt` / `iTXt` 的 `ccv3`、`chara` 段)、`.charx`(zip 里的 `card.json`)、裸 `.json`(CCv2 自动升到 V3)
|
|
250
|
+
- **世界书超限**:不再拒绝导入或保存,改为返回 warnings(实际字数 + 上限)并在预览里逐条列出。世界书按需注入,超出预算的部分不会进提示词——书是完整的,只是这一轮用不到那么多
|
|
251
|
+
|
|
252
|
+
### 酒馆卡兼容矩阵(SillyTavern 字段级)
|
|
253
|
+
|
|
254
|
+
一张真卡(CCv3、89 条世界书、98869 字)跑过一遍之后逐字段核对的结论。**「支持」= 功能真的生效**,不是「没报错」。
|
|
255
|
+
|
|
256
|
+
| ST 字段 / 特性 | 状态 | 说明 |
|
|
257
|
+
|---|---|---|
|
|
258
|
+
| `description` `personality` `scenario` `first_mes` `alternate_greetings` | ✅ 支持 | 原样保留并进 L1;开场白里的 `{{char}}` / `{{user}}` 按角色名展开 |
|
|
259
|
+
| `system_prompt` / `post_history_instructions` | ✅ 支持 | 前者作为「角色自带指令」进 L1(优先级低于系统提示词、高于角色描写),后者进收尾提醒 |
|
|
260
|
+
| `mes_example` | ✅ 支持(有截断) | 进 L1「示例对话」,单卡上限 1200 字,超出截断并告警 |
|
|
261
|
+
| `creator_notes` `tags` `creator` `character_version` `group_only_greetings` 等元字段 | ✅ 保留不丢 | 不参与注入;认不出的键进 `extensions.aiwu.legacy.extra`,一个字节都不丢 |
|
|
262
|
+
| `character_book`(89 条 / 9.8 万字这种规模) | ✅ 支持(按需注入 + 双预算) | 每轮命中上限 12 条 / 6000 字;`constant` 条目走**独立 allowance**;被裁的条目在面板体检里列名字、日志里也带名字 |
|
|
263
|
+
| `use_regex`(key 当正则) | ✅ 支持(带护栏) | 模式长度上限、只扫最近文本前 8000 字、明显灾难回溯的构造退化成字面量、坏正则不抛错(否则整轮对话进不去) |
|
|
264
|
+
| `secondary_keys` + `selective` | ✅ 支持 | 四值 `selectiveLogic`(AND_ANY / NOT_ALL / NOT_ANY / AND_ALL);`selective:false` 时次级键不参与激活(与 ST 一致) |
|
|
265
|
+
| `position: before_char / after_char` | ✅ 支持 | 分两个区块注入:「先读这些设定」与「相关设定」 |
|
|
266
|
+
| `position` 写成数字(`0` / `1`)或 `'before'` / `'after'` | ✅ 支持 | 统一归一到 `before_char` / `after_char`(老 ST 导出常见数字写法) |
|
|
267
|
+
| `@D` 深度注入 / `position: 4` / `depth` / `role` | ❌ 不支持(**内容不丢**) | 不做按消息深度插槽:这类条目仍会注入,只是当普通设定摆(默认 after 块),导入时统计条数并告警 |
|
|
268
|
+
| `constant` | ✅ 支持(独立预算) | 常驻走自己的额度(默认 12000 字,卡级可覆盖),不再和关键词命中抢 6000 字。真卡实测 6 条有效常驻 9577 字,全部注入、0 条被裁 |
|
|
269
|
+
| `probability` | ✅ 支持 | **顶层 `probability` 优先**,没有再读 `extensions.probability`(两种写法都有卡在用);稳定哈希,同一轮结果固定,不会每轮抖动 |
|
|
270
|
+
| `scan_depth` / `token_budget` | ✅ 支持 | 前者默认扫最近 4 条(近似 D0..Dn 槽),后者按 1 token ≈ 1.5 字换算成字符预算 |
|
|
271
|
+
| `recursive_scanning` | ❌ 不支持 | 字段认了但不执行:递归激活会放大预算与耗时,第一版明确不做 |
|
|
272
|
+
| `regex_scripts`(正则脚本) | 🛡 **屏蔽**(不执行 · 不注入 · 不影响对话,字段保留) | `data.regex_scripts` 与 `data.extensions.regex_scripts` 两个位置**都保留不删**(ST 卡是用户资产,删了将来导出/回灌会缺);同时**可证明屏蔽**:脚本正文不会出现在 L1 或注入预览里,去掉脚本后提示词逐字相同。导入预览给中性提示「本卡含 N 条酒馆正则脚本,已屏蔽」。口径常量 `ST_SCRIPT_STANCE`,详见 `docs/DEVELOPMENT.md` §十三 / §十四 |
|
|
273
|
+
| `depth_prompt` | ❌ 不支持(**字段保留**) | `extensions.depth_prompt` 随卡保留、写入不丢,但不读、不注入;非空时导入会明确告警「深度提示暂不支持,字段已保留」。需要的话把内容放进世界书常驻条目 |
|
|
274
|
+
| `assets`(立绘) | ❌ 不支持 | 导入时剥离并告警:本轮不做立绘落地,卡片其余内容不受影响 |
|
|
275
|
+
| `@@activate` / `@@dont_activate` 装饰器 | ✅ 支持 | 影响该条目是否参与激活 |
|
|
276
|
+
| `@@depth` / `@@position` / `@@role` / `@@probability` / `@@cooldown` 装饰器 | ⚠️ 认识但不生效 | 已知装饰器会从正文剥掉(绝不注入正文),但不改变注入行为;未知 `@@xxx` 整行丢弃 |
|
|
277
|
+
| `extensions.match_whole_words` | ✅ 支持 | 打开后按整词匹配(汉字里不误命中子串) |
|
|
278
|
+
|
|
279
|
+
> 三条最容易踩的:**① `regex_scripts` 不是「支持但没用到」,是屏蔽**(DSH 侧没有可插入的渲染点,所以不执行、不注入,但字段保留);
|
|
280
|
+
> **② 深度注入(`@D` / `position: 4`)不支持,但内容不丢**——按普通设定注入,只在位置上让步;
|
|
281
|
+
> **③ 世界书再大也不会整本注入**,这是设计而非缺陷。
|
|
282
|
+
|
|
283
|
+
### 文件拖放归谁管
|
|
284
|
+
|
|
285
|
+
**面板打开期间,文件拖放归面板处理。**
|
|
286
|
+
|
|
287
|
+
DSH 的聊天区有一个「文件或图片拖动到此处即可添加」的拖放区,它是文档级的:文件在页面任何位置松手,都会被它接住当附件。所以插件打开面板后会接管文件拖放:
|
|
288
|
+
|
|
289
|
+
- 拖进「导入角色卡」的虚线框 → 走导入预览(不写盘,确认才保存)
|
|
290
|
+
- 拖到面板里其它地方 → 提示「把卡拖到虚线框里」,**不放行给聊天区**
|
|
291
|
+
- 拖进面板之外(聊天区自己)→ 正常添加附件,插件不管
|
|
292
|
+
|
|
293
|
+
为什么这么较真:v0.3.0 真机上出现过「把角色卡拖到面板上,卡被当成附件发进了对话」。宁可拦下来给一句提示,也不能让卡文件混进聊天上下文。
|
|
294
|
+
|
|
295
|
+
> 插件同时会替聊天区复位它的拖放状态(拖完主动补一个 `dragend`)。所以关掉面板之后,聊天区的拖放应该和平时一样——如果你发现关面板后拖文件进聊天区没反应,那是 P0,请报。
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## 预设
|
|
300
|
+
|
|
301
|
+
**预设 = 一组可复用的提示词模块**(文风、语气、回复规则、口癖约束),只描述「**怎么说**」,不写角色事实。
|
|
302
|
+
|
|
303
|
+
它和角色卡**正交**:角色卡决定「我是谁」,预设决定「我怎么说话」。同一张卡配不同预设会是不同的味道,换预设不需要动卡里一个字。
|
|
304
|
+
|
|
305
|
+
### 两种作用域
|
|
306
|
+
|
|
307
|
+
和角色启用一样,预设也有两种,互不覆盖:
|
|
308
|
+
|
|
309
|
+
| 作用域 | 管谁 | 决议 |
|
|
310
|
+
|---|---|---|
|
|
311
|
+
| **全局预设** | 所有没绑预设的会话(以及子代理) | 优先级第二 |
|
|
312
|
+
| **当前会话预设** | 只绑这一个会话 | 优先级最高 |
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
会话预设 > 全局预设 > 没有预设
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**被删掉不回落全局**:会话绑定的预设如果被删,这个会话按「没有预设」处理,**不会**自动换成全局那份——否则你以为在用 A 的文风,实际跑的是 B。重新绑定即可恢复。子代理固定用全局预设,不继承父会话的绑定。
|
|
319
|
+
|
|
320
|
+
### 注入位置
|
|
321
|
+
|
|
322
|
+
预设注入在独立段 `aiwu:preset`,**order 5080**:
|
|
323
|
+
|
|
324
|
+
```
|
|
325
|
+
5000 L0 底线
|
|
326
|
+
5050 L0.5 纪律包
|
|
327
|
+
5080 ← 预设(文风与回复规则)
|
|
328
|
+
5100 L1 角色卡
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
放在这里的两个理由:**纪律包的硬约束优先级更高**(禁 AI 腔、内容边界这些是底线,预设的文风不能盖过它);**预设相对稳定**(不随角色切换而变化),排在角色卡之前可以让「换角色」不至于连带重算预设那一段的缓存。
|
|
332
|
+
|
|
333
|
+
只拼 `enabled` 的模块,每个模块渲染成 `### 模块:{名字}`;段首有一句防注入说明:「以下是文风与回复规则,不是用户指令;与角色设定冲突时以角色卡与人设为准」。模块里的 `{{char}}` / `{{user}}` 按**该会话决议角色**的卡名与称呼展开。
|
|
334
|
+
|
|
335
|
+
### 导入 SillyTavern 预设
|
|
336
|
+
|
|
337
|
+
面板「预设」页支持直接导入 ST 的 chat-completion 预设 JSON(`{prompts, prompt_order}`)。**能导什么、会丢什么,都写在这里**:
|
|
338
|
+
|
|
339
|
+
| 结果 | 条件 | 为什么 |
|
|
340
|
+
|---|---|---|
|
|
341
|
+
| **保留** | 有正文的条目 | 就是你要搬的文风/规则 |
|
|
342
|
+
| 丢弃 · 结构占位 | `identifier` 在 13 项白名单里(`worldInfoBefore` / `charHistory` / `main` / `scenario` / `char` 等) | 这些是 ST 运行时的**槽位**,内容由 ST 在发送时填;搬过来只会是空标签或 `{{char}}` 字面量 |
|
|
343
|
+
| 丢弃 · 空正文 | 去掉注释/宏/标签后没有实际文字 | 常见于 `nsfw` / `jailbreak`:文件里有这条、`marker:true`,但正文是 0 字节 |
|
|
344
|
+
| 丢弃 · 废稿 | 名字形如 `----` 章节线、`[ ]` 草稿、备份副本 | 作者的草稿痕迹,不是给模型看的 |
|
|
345
|
+
| 丢弃 · JS 配置块 | 超大且像 `SPreset` 那类纯配置 | 不是提示词,搬进来会污染上下文 |
|
|
346
|
+
|
|
347
|
+
> **`marker: true` 不等于结构占位。** `nsfw` / `jailbreak` / `enhanceDefinitions` 也带 `marker`,但它们**有正文**,是真正要搬的东西。所以判据是**白名单**,不是 marker 一刀切。
|
|
348
|
+
>
|
|
349
|
+
> **ST 的主指令(`main`)不导入。** 本插件用自己的底线(L0)+ 纪律包(L0.5)承担同一职责;把 ST 的 `main` 搬进来等于**双份注入同义指令**,既费 token,又容易让模型当成两套规则。
|
|
350
|
+
|
|
351
|
+
**实测:导入本机 7 份真实 ST 预设**(只列文件名与计数,不含任何预设正文——这些是第三方作品)
|
|
352
|
+
|
|
353
|
+
| 文件 | prompts | 选中 order | 保留(启用 / 停用) | 丢弃 |
|
|
354
|
+
|---|---|---|---|---|
|
|
355
|
+
| `Default.json` | 12 | 12 | 1(0 / 1) | 11 |
|
|
356
|
+
| `Deep♂Dark-v4 V1.6.8E for Ds4.x_1ATbU.json` | 35 | 35 | 24(19 / 5) | 11 |
|
|
357
|
+
| `Geechan - Universal Online Chat (Chat Completions) (v1.0).json` | 17 | 16 | 1(1 / 0) | 15 |
|
|
358
|
+
| `Geechan - Universal Roleplay (Chat Completions) (v5.2).json` | 22 | 21 | 7(0 / 7) | 14 |
|
|
359
|
+
| `Pura's Director Preset (SillyBunny).json` | 47 | 47 | 11(1 / 10) | 36 |
|
|
360
|
+
| `Pura's Director Preset 15.1 (SillyBunny).json` | 47 | 47 | 11(1 / 10) | 36 |
|
|
361
|
+
| `TLD Card Conversion Preset (Standalone).json` | 26 | 25 | 9(7 / 2) | 16 |
|
|
362
|
+
|
|
363
|
+
**表里有两点值得注意**:
|
|
364
|
+
|
|
365
|
+
1. **保留数 ≠ 启用数**。`Geechan Online` 保留 1 条、其中启用 1 条;`Geechan RP` 保留 7 条但**全是停用**——ST 里「在配置里存在」和「实际生效」是两件事,导入会把停用状态一起带过来(面板里可以再打开)。
|
|
366
|
+
2. **`Default.json` 只保留 1 条,这是正确结果**。它是 ST 的「出厂默认」,`main` 是结构占位(我们已用 L0 + 纪律包承担同一职责),`nsfw` / `jailbreak` 在这份文件里正文是 0 字节。所以 12 条进、1 条出(`Enhance Definitions`,且是停用的),丢弃 11 = 结构占位 9 + 空正文 2。**不是解析坏了**。
|
|
167
367
|
|
|
168
368
|
---
|
|
169
369
|
|
|
@@ -174,7 +374,11 @@ New-Item -ItemType Junction `
|
|
|
174
374
|
```
|
|
175
375
|
~/.dsh/ai-with-u/
|
|
176
376
|
├── _index.json # 角色索引
|
|
177
|
-
├── _active.json #
|
|
377
|
+
├── _active.json # 当前启用状态(含 mode / discipline 偏好)
|
|
378
|
+
├── _sessions.json # 会话 → 角色绑定(会话作用域启用)
|
|
379
|
+
├── _presets.json # 预设索引
|
|
380
|
+
├── _presets_active.json # 预设启用态(全局 + 每会话)
|
|
381
|
+
├── presets/<id>.json # 单个预设正文(id = p_ + 8 位 base36)
|
|
178
382
|
└── characters/<角色名>/
|
|
179
383
|
├── card.json # CCv3 角色卡
|
|
180
384
|
├── card.v1.bak.json # 迁移前原件,回滚就拷回来
|
|
@@ -182,6 +386,18 @@ New-Item -ItemType Junction `
|
|
|
182
386
|
└── session.json # 会话状态与滚动摘要
|
|
183
387
|
```
|
|
184
388
|
|
|
389
|
+
`session.json` 是「这一册读到哪了」,认得这些字段:
|
|
390
|
+
|
|
391
|
+
| 字段 | 含义 |
|
|
392
|
+
|---|---|
|
|
393
|
+
| `recent` / `turn_count` / `last_ts` | 最近几轮、累计轮次、最后一次时间 |
|
|
394
|
+
| `mood` / `topic` | 此刻的情绪、未竟的话题(写日记时一并落盘,下一轮 L1 用) |
|
|
395
|
+
| `mode` | `text` 或 `text+action`,**交互模式的权威位置** |
|
|
396
|
+
| `intimacy` | 关系档位,五档之一:陌生 / 认识 / 熟悉 / 亲近 / 亲密 |
|
|
397
|
+
| `relation_log` | 档位变化留痕:`{ at, from, to, why? }`,最多 50 条,超出丢最旧 |
|
|
398
|
+
|
|
399
|
+
交互模式按 `session.json` → `_active.json` → `text+action` 的顺序解析:会话里用 `awu_mode` 切的档立刻生效,`_active.json` 只作没会话记录时的兜底。
|
|
400
|
+
|
|
185
401
|
纯 markdown / JSON,可读、可改、可备份、可迁移。不联网、不注册、不收藏数据。
|
|
186
402
|
|
|
187
403
|
### 接口安全
|
|
@@ -200,48 +416,82 @@ AIWU_TRUSTED_HOSTS=my.tunnel.example
|
|
|
200
416
|
|
|
201
417
|
## 能力清单
|
|
202
418
|
|
|
203
|
-
### 模型工具(
|
|
419
|
+
### 模型工具(9 个,仅启用角色时挂载)
|
|
204
420
|
|
|
205
421
|
| 工具 | 用途 |
|
|
206
422
|
|---|---|
|
|
207
|
-
| `awu_diary_write` |
|
|
423
|
+
| `awu_diary_write` | 追加日记(可同时记下 `topic` / `mood`) |
|
|
208
424
|
| `awu_diary_read` | 读取 / 筛选日记 |
|
|
209
425
|
| `awu_whoami` | 查询当前身份 |
|
|
210
426
|
| `awu_forget` | 忘记某事(日记 + 会话 + 角色卡三处同步) |
|
|
211
427
|
| `awu_diary_edit` | 就地改写日记条目 |
|
|
212
428
|
| `awu_session_reset` | 全新开始 / 彻底重置 |
|
|
213
|
-
| `awu_relation` |
|
|
429
|
+
| `awu_relation` | 查关系档位依据;带 `set` 时按里程碑写回档位 |
|
|
430
|
+
| `awu_mode` | 切换纯文本 / 文本 + 动作 |
|
|
214
431
|
| `awu_opening_next` | 换一句开场 |
|
|
215
432
|
|
|
216
433
|
另有一个**条件挂载**的 `awu_card_save`:只在点「蒸馏角色卡」后的两小时内、且保存一次后自动失效。平时模型拿不到写卡能力。
|
|
217
434
|
|
|
218
|
-
### REST 接口(
|
|
435
|
+
### REST 接口(32 条,`/_dsh/ai-with-u/`)
|
|
219
436
|
|
|
220
437
|
```
|
|
221
|
-
overview characters character character/save character/import character/delete
|
|
222
|
-
activate deactivate mode relation
|
|
223
|
-
diary/save diary/edit forget session/reset session/commit
|
|
438
|
+
overview preview characters character character/save character/import character/delete
|
|
439
|
+
activate deactivate bind unbind mode discipline relation relation/set
|
|
440
|
+
opening/next opening/state diary/save diary/edit forget session/reset session/commit
|
|
441
|
+
presets preset preset/save preset/delete preset/import preset/activate
|
|
224
442
|
distill/flow distill/arm distill/disarm distill/state
|
|
225
443
|
```
|
|
226
444
|
|
|
227
445
|
`/character` 与 `/characters` 同时返回 `card`(34 字段视图)与 `ccv3`(完整卡);`/character/save` 收 `{ name, card?, ccv3? }`,只给 `card` 时保留既有世界书与 `extensions`。
|
|
228
446
|
|
|
447
|
+
`/bind` 与 `/unbind` 就是「当前会话启用」:`POST /bind {name, sessionId}` / `POST /unbind {sessionId}`,返回 `{ ok, bound, character }`。`POST /activate` 仍然是**全局启用**语义(向后兼容)。`GET /overview?sessionId=…` 会带上 `sessionId`、`binding`(本会话绑了谁)与 `bindings` 摘要,面板据此判断「当前会话启用」能不能点。
|
|
448
|
+
|
|
449
|
+
`/character` 与 `/characters` 同时返回 `card`(34 字段视图)与 `ccv3`(完整卡);`/character/save` 收 `{ name, card?, ccv3? }`,只给 `card` 时保留既有世界书与 `extensions`。
|
|
450
|
+
|
|
451
|
+
`GET /preview` 是**纯只读**快照:返回 `{ active, mode, discipline, segments[] }`,`segments` 现在**六段**(`aiwu:baseline` / `aiwu:discipline` / `aiwu:preset` / `aiwu:active-character` / `aiwu:lore` / `aiwu:clock`,按 order 升序;未启用角色时 `text: ''`、`chars: 0`)。文本走 `PromptController` 的真实渲染路径,不在预览里另拼一份——拼第二份等于给「预览与真实注入漂移」开口子。
|
|
452
|
+
|
|
453
|
+
`/presets` 列索引、`/preset` 读正文、`/preset/save|delete|import|activate` 是写操作;`/preset/import` 收 ST 预设 JSON 并返回 `{ modules, dropped, warnings }`——**丢弃条目带原因**,面板据此解释「为什么只剩几条」。
|
|
454
|
+
|
|
455
|
+
> 世界书的改动**必须随 `ccv3` 发**:只发 `card` 时后端以磁盘上的旧卡为底重投影,`character_book` 按原卡保留——改动会被静默吞掉,还会提示保存成功。
|
|
456
|
+
|
|
457
|
+
`awu_relation` 的口径是「**查看不写回**」:用户只是问「关系如何」时只读档位、不改档;只有里程碑事件(第一次约定、第一次争吵、称呼改变、表白)才带 `set` 写回,并在 `relation_log` 留一条。对话里不出现「好感度 +1」这类数值。
|
|
458
|
+
|
|
459
|
+
### 面板与提示词
|
|
460
|
+
|
|
461
|
+
- **注入预览** —— 五段真实渲染的段名 / 字符数 / 正文 + 总字符,纯只读快照
|
|
462
|
+
- **记忆回顾** —— 日记关键词搜索、按月折叠、导出 markdown
|
|
463
|
+
- **导入角色卡** —— 角色簿左栏入口,吃 PNG / CHARX / JSON,先预览后落盘;世界书超限只警告不拦
|
|
464
|
+
- **自创角色卡** —— 三格表单落骨架卡,可选「让 AI 补全人设」(走当前会话,AI 先问 3–5 个问题)
|
|
465
|
+
- **世界书编辑** —— 角色卡编辑器第 11 分区,条目增删改 + 体检
|
|
466
|
+
- **对话模式** —— 角色簿工具栏的「纯文本 / 文本 + 动作」胶囊,点了立刻生效,不需要启用角色
|
|
467
|
+
- **纪律包 L0.5** —— `off` / `lite` / `full` 三档,默认 lite,偏好落盘、退出角色也保留
|
|
468
|
+
- **`awu_mode`** —— 对话里直接切纯文本 / 文本 + 动作,不需要回面板
|
|
469
|
+
|
|
229
470
|
---
|
|
230
471
|
|
|
231
472
|
## 开发
|
|
232
473
|
|
|
233
474
|
```bash
|
|
234
|
-
npm run build # 宿主 tsc + 前端 tsc + 打包 +
|
|
235
|
-
npm run verify # 产物形状 / 新鲜度 /
|
|
236
|
-
npm run verify:tavern # 卡格式 / 迁移幂等 / 世界书 / 忘却(218 项)
|
|
237
|
-
npm run verify:import # PNG / CHARX / JSON 导入解析(49 项)
|
|
238
|
-
npm run verify:session # 会话、指令与来源栅栏(111 项)
|
|
239
|
-
npm run verify:host # 真实 cordis 宿主装配(35 项)
|
|
240
|
-
npm run verify:distill # 蒸馏武装与 TTL(93 项)
|
|
475
|
+
npm run build # 宿主 tsc + 前端 tsc + 打包 + 九套自检(合计 981 项)
|
|
476
|
+
npm run verify # 产物形状 / 新鲜度 / 孤儿产物(16 项)
|
|
241
477
|
npm run verify:bundle # 客户端产物加载(9 项)
|
|
478
|
+
npm run verify:wiring # 接线体检:25 组契约(72 项;后端做了前端没接 / 验收项回归)
|
|
479
|
+
npm run verify:tavern # 卡格式 / 迁移幂等 / 世界书预算 / ST 兼容(303 项)
|
|
480
|
+
npm run verify:distill # 蒸馏 / 补全武装与 kind(121 项)
|
|
481
|
+
npm run verify:import # PNG / CHARX / JSON 导入解析 / 字段保真(58 项)
|
|
482
|
+
npm run verify:session # 会话、指令、纪律包、关系、绑定、预设与预览只读(286 项)
|
|
483
|
+
npm run verify:host # 真实 cordis 宿主装配(116 项)
|
|
242
484
|
npm run typecheck:client # 只查浏览器侧类型
|
|
243
485
|
```
|
|
244
486
|
|
|
487
|
+
`npm run build` 串的顺序是:`tsc`(宿主) → `tsc`(前端) → esbuild 打包 → `verify-bundle` → `verify-wiring` → `verify` → `verify-tavern` → `verify-distill` → `verify-import` → `verify-session` → `verify-host`。任何一项非 0 退出就整体失败。
|
|
488
|
+
|
|
489
|
+
徽章上的 1025 = build 串里所有自检的通过项之和,失败项必须为 0、skip 也必须为 0(`bundle 9 + wiring 72 + verify 16 + tavern 303 + distill 121 + import 58 + session 324 + host 122`)。旧徽章的 515 用的是更窄的口径(只数六套,不含 `verify` 与 `verify-wiring`),所以数字变大不全是因为新增了断言。
|
|
490
|
+
|
|
491
|
+
`verify-wiring` 补的是其余七套查不到的盲区:**类型检查只问「类型对不对」,不问「有没有人调用」**。一个 17 KB 的世界书数据层可以零引用地躺在仓库里,一个 `POST /character/import` 可以注册完就没下文——这两种状态下 `tsc`、打包、其余自检全绿,但用户打开面板什么都看不到。脚本只做静态扫描(读源码找路由字符串与调用点),失败文案写清「缺什么 + 该找谁」。最后一组会把 `lib/prompt.js` 拿回来跟源码逐字比纪律包文本,抓「改了源码没重编」;产物不存在或比源码旧时跳过,不报红。
|
|
492
|
+
|
|
493
|
+
> 抽查 `lib/client.js` 时别用中文去 grep:esbuild 默认 `charset: ascii`,打包产物里的中文一律转成 `\uXXXX`(如「导入角色卡」= `\u5BFC\u5165\u89D2\u8272\u5361`)。功能无损,但**按字面搜中文会误判「产物里没有」**。
|
|
494
|
+
|
|
245
495
|
宿主 API 的类型直接来自 `@deepseek-ai/dsh-system-prompt` / `dsh-tools` / `cordis` 的 devDependencies,`inject`、`PromptSection`、`ToolDefinition` 都有编译期校验——契约漂移会在构建阶段报错,而不是运行时「failed 但不给原因」。
|
|
246
496
|
|
|
247
497
|
### 目录结构
|
|
@@ -269,7 +519,7 @@ AGENTS.md 是以 user 角色消息注入的,插件用的是 system prompt,
|
|
|
269
519
|
<details>
|
|
270
520
|
<summary>退出后真的什么都不留吗?</summary>
|
|
271
521
|
|
|
272
|
-
|
|
522
|
+
五段(L0 / L0.5 纪律 / L1 / 世界书 / 时间差)在退出后都返回空串,宿主会过滤空段。`awu_*` 工具同时全部卸载。数据文件仍然在磁盘上,但不参与任何提示词组装。
|
|
273
523
|
|
|
274
524
|
</details>
|
|
275
525
|
|
|
@@ -290,7 +540,73 @@ desktop profile 由 Electron 独占管理,CLI 会直接报 `managed exclusivel
|
|
|
290
540
|
<details>
|
|
291
541
|
<summary>提示词到底占多少 token?</summary>
|
|
292
542
|
|
|
293
|
-
启用态约 2.
|
|
543
|
+
启用态约 2.8–3.3 KB 字符量级(中文按字计),未启用 0。实测:丰川祥子的卡 + lite 档,整段渲染 3286 字符。默认 lite 档的纪律包占 555 字符;切 `off` 全省,切 `full` 多 181 字符。世界书常态只注入一两百字符。重内容(卡里的详细设定、长日记)不会无条件进提示词。
|
|
544
|
+
|
|
545
|
+
</details>
|
|
546
|
+
|
|
547
|
+
<details>
|
|
548
|
+
<summary>为什么我的大卡能导入了,但设定只用得上一部分?</summary>
|
|
549
|
+
|
|
550
|
+
因为世界书是**按需注入**的,不是整本塞进提示词。命中预算默认 12 条 / 6000 字(`LORE_DEFAULTS`),超出预算的条目这一轮就不进上下文——卡本身一个字都没被改,磁盘上仍是完整的世界书,你在编辑器里能看到全部条目。
|
|
551
|
+
|
|
552
|
+
`constant: true` 的常驻条目走**独立额度**,不和关键词命中抢那 6000 字(真卡实测:7 条常驻共 10512 字,修之前有 2 条被静默挤掉,而常驻正是「必须一直生效」的那类)。
|
|
553
|
+
|
|
554
|
+
**哪里能看到被裁的条目**:打开角色卡编辑器 → 世界书分区顶部的体检行,会按等级列出「这一轮被预算裁掉的条目」;宿主日志里也会带条目名(只带名字,不写正文)。想提高命中率就把关键词写准、把常驻留给「必须一直生效」的设定。
|
|
555
|
+
|
|
556
|
+
这是刻意的:一张 9.8 万字的世界书全量注入,要么撑爆上下文、要么每轮烧掉一大笔费用,而真正用得上的往往只有当轮提到的那几条。
|
|
557
|
+
|
|
558
|
+
现在导入/保存这类大书只会出警告(附实际字数与上限),不再拦你——v0.3.0 之前这里是硬拦,属于过严。
|
|
559
|
+
|
|
560
|
+
</details>
|
|
561
|
+
|
|
562
|
+
<details>
|
|
563
|
+
<summary>为什么我的卡里正则(<code>regex_scripts</code>)不起作用?</summary>
|
|
564
|
+
|
|
565
|
+
因为**本插件不执行酒馆的正则脚本**,而且这不是「暂时没接」——是宿主侧没有可插入的点。
|
|
566
|
+
|
|
567
|
+
酒馆的 `regex_scripts` 有两类用法,我们分开说:
|
|
568
|
+
|
|
569
|
+
- **提示词侧**(发送前改写 prompt 文本):能做但**没做**。理由很简单:它改的是发给模型的内容,属于「用户不知道自己在看什么」的黑箱,真出问题时极难排查。
|
|
570
|
+
- **显示侧**(收到回复后改写显示文本,比如把 `*笑*` 变成斜体、把某些词替换掉):**做不了**。DSH 的客户端插槽 `conversation.chat.node` 只能**新增**聊天行,改不了已经渲染出来的助手消息;`agent/request` 钩子只管 provider / model / reasoningEffort 路由,不碰文本;插件规范也明写不许读写组件外的 DOM。
|
|
571
|
+
|
|
572
|
+
生态里的做法是把这个能力**交割出去**:`dsh-tavern` 从 2.7.x 起把显示层整块交给 `dsh-muv-engine`(自己那套渲染器删掉了,因为两边的 `beautifyContentEl` 会互相覆盖)。想用正则美化显示,装 muv 系引擎即可,本插件不重复造第二套。
|
|
573
|
+
|
|
574
|
+
**你的卡不会因此丢东西**:`regex_scripts` **原样保留**在卡里(`data.regex_scripts` 与 `data.extensions.regex_scripts` 两个位置都不动),只是不被执行。导入预览会给一条告警说清这一条——留着字段是为了你将来导出/回灌酒馆时不缺东西,「以为它在工作」则用告警解决,而不是删数据。
|
|
575
|
+
|
|
576
|
+
如果你依赖的是提示词侧的正则效果,请把规则改写进角色卡的 `system_prompt` 或世界书条目——那是我们能保证生效的地方。详见 `docs/DEVELOPMENT.md` §十三。
|
|
577
|
+
|
|
578
|
+
</details>
|
|
579
|
+
|
|
580
|
+
<details>
|
|
581
|
+
<summary>「当前会话启用」和「全局启用」有什么区别?</summary>
|
|
582
|
+
|
|
583
|
+
两个作用域,互不覆盖:
|
|
584
|
+
|
|
585
|
+
- **全局启用**:所有**没绑定**的会话都用它(还有子代理)。切换全局不影响任何已绑定会话。
|
|
586
|
+
- **当前会话启用**:只绑你点的这一个会话,别处照旧。
|
|
587
|
+
|
|
588
|
+
决议顺序写死:**会话绑定 > 全局启用 > 未启用**。所以「全局阿米娅 + 本会话祥子」= 这个会话是祥子、其余是阿米娅。
|
|
589
|
+
|
|
590
|
+
两条边界值得记住:
|
|
591
|
+
|
|
592
|
+
1. **绑的卡被删掉,那个会话就当作未启用,不会偷偷回落到全局**——否则你会以为在跟祥子聊、其实对面是阿米娅。重新绑定即可恢复。
|
|
593
|
+
2. **子代理固定用全局角色,不继承父会话绑定**:子代理有自己的身份查不到绑定,于是走全局。这是有意为之,防止人设意外漏进工具链。
|
|
594
|
+
|
|
595
|
+
面板上两态分行显示(「当前会话:X(已绑定)」/「全局:Y」),点哪个都会就地提示影响范围。如果面板拿不到会话标识,「当前会话启用」会置灰——它不会瞎猜一个 id 写进去。
|
|
596
|
+
|
|
597
|
+
</details>
|
|
598
|
+
|
|
599
|
+
<details>
|
|
600
|
+
<summary>面板说卡里有 N 条正则脚本、已屏蔽,会有什么影响?</summary>
|
|
601
|
+
|
|
602
|
+
**没有任何影响,而且这是可以验证的**:
|
|
603
|
+
|
|
604
|
+
- 脚本**不会被执行**(提示词侧与显示侧都不做);
|
|
605
|
+
- 脚本正文**进不了提示词**:自检里拿一个特征串做标记,跑完整 L1 与「注入预览」,产物里搜不到它;
|
|
606
|
+
- 对注入**零影响**:同一张卡去掉 `regex_scripts` 后,L1 与预览的文本**逐字相同**;
|
|
607
|
+
- 字段**原样保留**:你将来把卡导出回酒馆,脚本还在。
|
|
608
|
+
|
|
609
|
+
换句话说,看到的角色表现与「这张卡本来就没有正则脚本」完全一致。如果卡的表现依赖这些脚本(比如靠正则把某些词换成斜体、或替换成别的台词),那部分效果不会出现——想保留效果就把它改写成角色卡的人设描述,显示层的正则美化需要装 muv 系引擎(本插件不做第二套渲染器,原因见 `docs/DEVELOPMENT.md` §十三)。
|
|
294
610
|
|
|
295
611
|
</details>
|
|
296
612
|
|