koishi-plugin-chatluna-scene-rules 0.5.1
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 +21 -0
- package/README.md +66 -0
- package/index.js +65 -0
- package/package.json +48 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 妖祀
|
|
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
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# koishi-plugin-chatluna-scene-rules
|
|
2
|
+
|
|
3
|
+
> **ChatLuna livingmemory 记忆池别名器。** 让**同一个角色的多个预设**(私聊版 / 群聊版 / 语音版 / 旧版…)
|
|
4
|
+
> **共享同一个 livingmemory 记忆池**。运行时接管 `chatluna_living_memory` 服务的 `createScope` / `resolvePresetId`,
|
|
5
|
+
> 在 presetId 上套一层别名映射——**不改 chatluna-livingmemory 任何文件,插件停用即自动还原**。
|
|
6
|
+
|
|
7
|
+
> ℹ️ 包名 / 配置块键沿用旧名 `chatluna-scene-rules`(早期是「场合判定」插件),与现在的「记忆池别名」功能名字
|
|
8
|
+
> 不完全对应、但仅是个名字;`{scene_rules()}` 之类的旧用法已无关。
|
|
9
|
+
|
|
10
|
+
完整的安装 / 配置 / 验证 / 排障(以「髭切」为例)见仓库的
|
|
11
|
+
[**安装与使用指南**](https://github.com/ningningningning0420-ui/koishi-chatluna-plugins/blob/main/docs/记忆池别名器-安装与使用指南.md),这里只放速查。
|
|
12
|
+
|
|
13
|
+
## 为什么需要它
|
|
14
|
+
|
|
15
|
+
livingmemory 默认按 **presetId** 给每个预设单独开一个记忆池(角色预设的 presetId 形如 `名字(Character)`)。
|
|
16
|
+
你若把一个角色拆成「私聊版」「群聊版」两份独立预设 → 两个不同 presetId → 两个互不相通的记忆池
|
|
17
|
+
→ 私聊里聊过的事,群聊里它不记得。
|
|
18
|
+
|
|
19
|
+
本插件把这些 presetId 都映射到**同一个共享池 key**,于是它们读写同一个池,记忆打通。
|
|
20
|
+
|
|
21
|
+
## 依赖
|
|
22
|
+
|
|
23
|
+
- `koishi` ^4.17
|
|
24
|
+
- `chatluna`
|
|
25
|
+
- `chatluna-character`(角色预设;非本插件 service 硬依赖,但角色场景需要)
|
|
26
|
+
- **`chatluna-livingmemory`**(提供 `chatluna_living_memory` 服务,本插件的真正硬依赖)——
|
|
27
|
+
必须先装好并能正常记忆;它自身依赖的 embeddings/向量库是它的事,本插件不碰。
|
|
28
|
+
|
|
29
|
+
## 三步启用
|
|
30
|
+
|
|
31
|
+
1. 安装:在 Koishi 控制台的**插件市场**搜 `chatluna-scene-rules` 直接安装;或命令行
|
|
32
|
+
```bash
|
|
33
|
+
npm i koishi-plugin-chatluna-scene-rules
|
|
34
|
+
```
|
|
35
|
+
(从源码用:把本目录放到 koishi app 的 `external/` 下,再 `npm i ./external/koishi-plugin-chatluna-scene-rules`。)
|
|
36
|
+
2. `koishi.yml` 启用,填别名映射(**键 = presetId,全角括号;值 = 共享池 key**):
|
|
37
|
+
```yaml
|
|
38
|
+
chatluna-scene-rules:main:
|
|
39
|
+
debug: true # 首次开!日志里抄准确的 presetId
|
|
40
|
+
aliases:
|
|
41
|
+
髭切-本丸语音版(Character): 髭切-通用版(Character)
|
|
42
|
+
髭切-私聊版(Character): 髭切-通用版(Character)
|
|
43
|
+
髭切(Character): 髭切-通用版(Character)
|
|
44
|
+
```
|
|
45
|
+
3. 触发一次对话,看日志确认映射命中,稳了把 `debug` 关掉。**改 aliases 后重启 koishi** 最稳。
|
|
46
|
+
|
|
47
|
+
## 配置项
|
|
48
|
+
|
|
49
|
+
| 配置 | 默认 | 说明 |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| `aliases` | `{}` | 别名字典。**键** = 预设 presetId(角色预设通常是 `预设名(Character)`,**全角括号**);**值** = 共享池 key。命中的预设读写同一个 livingmemory 池。 |
|
|
52
|
+
| `debug` | `false` | 打印每次 presetId 解析 + 映射结果(`原样使用` 或 `→ 共享key`),首次配置务必开,用来抄准确键名。 |
|
|
53
|
+
|
|
54
|
+
## 关键坑
|
|
55
|
+
|
|
56
|
+
- **键名是全角括号 `(Character)`,不是半角 `(Character)`**;差一个字符就不命中。务必先开 `debug` 抄日志里的原样字符串。
|
|
57
|
+
- **共享池 key 不要求真有一个同名预设存在**——它只是个字符串池名(常用一个退役/专设的「通用版」名字,池里就是合并后的记忆)。
|
|
58
|
+
- 打通**之前**各预设旧池里的历史记忆不会自动迁移/合并;本插件只让此后的读写落到同一个池。
|
|
59
|
+
|
|
60
|
+
## 回滚
|
|
61
|
+
|
|
62
|
+
`koishi.yml` 把 `chatluna-scene-rules:` 改成 `~chatluna-scene-rules:`(禁用)→ 自动还原服务方法,各预设回到各自独立池。
|
|
63
|
+
|
|
64
|
+
## 许可
|
|
65
|
+
|
|
66
|
+
MIT
|
package/index.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const { Schema } = require('koishi')
|
|
2
|
+
|
|
3
|
+
exports.name = 'chatluna-scene-rules'
|
|
4
|
+
|
|
5
|
+
exports.inject = ['chatluna_living_memory']
|
|
6
|
+
|
|
7
|
+
exports.Config = Schema.object({
|
|
8
|
+
aliases: Schema.dict(Schema.string())
|
|
9
|
+
.default({})
|
|
10
|
+
.description(
|
|
11
|
+
'记忆池别名映射:键 = 预设的 presetId(通常为「预设名(Character)」),值 = 共享池 key。命中映射的预设读写同一个 livingmemory 记忆池,实现多预设(如私聊版/群聊版)共享记忆'
|
|
12
|
+
),
|
|
13
|
+
debug: Schema.boolean()
|
|
14
|
+
.default(false)
|
|
15
|
+
.description('打印每次 presetId 解析与映射结果(首次配置时用它核对键名拼写)')
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
// 记忆池别名器:运行时接管 livingmemory 服务的 createScope(主 hook,
|
|
19
|
+
// 召回/入库/快照/注入都经它构造记忆作用域)与 resolvePresetId(兜底旧路径),
|
|
20
|
+
// 在 presetId 上套一层别名映射。不修改 livingmemory 任何文件,
|
|
21
|
+
// 插件停用时自动还原原方法。
|
|
22
|
+
exports.apply = (ctx, config) => {
|
|
23
|
+
const logger = ctx.logger('chatluna-scene-rules')
|
|
24
|
+
const svc = ctx.chatluna_living_memory
|
|
25
|
+
const mapId = (id) => {
|
|
26
|
+
if (id == null) return id
|
|
27
|
+
const mapped = config.aliases[id]
|
|
28
|
+
if (config.debug) {
|
|
29
|
+
logger.info(
|
|
30
|
+
`presetId ${id}${mapped ? ` → ${mapped}` : '(未映射,原样使用)'}`
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
return mapped ?? id
|
|
34
|
+
}
|
|
35
|
+
// 接管前先确认方法存在:不同 chatluna-livingmemory 版本若改了方法名/签名,
|
|
36
|
+
// 这里 warn-and-skip 而不是直接 throw 崩掉插件加载。停用时只还原接管过的方法。
|
|
37
|
+
const restorers = []
|
|
38
|
+
|
|
39
|
+
// 总闸:所有记忆 scope(召回/入库/快照/注入)都经 createScope 构造,
|
|
40
|
+
// 在这里对 presetId 套别名。character 路径不走 resolvePresetId,
|
|
41
|
+
// 而是直接拼 `${presetName}(Character)` 后调 createScope。
|
|
42
|
+
if (typeof svc.createScope === 'function') {
|
|
43
|
+
const origScope = svc.createScope.bind(svc)
|
|
44
|
+
svc.createScope = (conversationId, presetId, userId, channelId, options = {}) => {
|
|
45
|
+
return origScope(conversationId, mapId(presetId), userId, channelId, options)
|
|
46
|
+
}
|
|
47
|
+
restorers.push(() => { svc.createScope = origScope })
|
|
48
|
+
} else {
|
|
49
|
+
logger.warn('chatluna_living_memory.createScope 不存在(livingmemory 版本不兼容?),记忆池别名未生效')
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 兜底:部分旧路径仍经 resolvePresetId(其结果随后也会进 createScope;
|
|
53
|
+
// 已映射的值不在别名键里,不会发生二次映射)。
|
|
54
|
+
if (typeof svc.resolvePresetId === 'function') {
|
|
55
|
+
const origResolve = svc.resolvePresetId.bind(svc)
|
|
56
|
+
svc.resolvePresetId = (message, fallbackPresetId) => {
|
|
57
|
+
return mapId(origResolve(message, fallbackPresetId))
|
|
58
|
+
}
|
|
59
|
+
restorers.push(() => { svc.resolvePresetId = origResolve })
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
ctx.effect(() => () => {
|
|
63
|
+
for (const restore of restorers) restore()
|
|
64
|
+
})
|
|
65
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "koishi-plugin-chatluna-scene-rules",
|
|
3
|
+
"version": "0.5.1",
|
|
4
|
+
"description": "ChatLuna livingmemory 记忆池别名器:把同一角色多个预设(私聊版/群聊版/语音版)的 presetId 映射到同一个共享记忆池,实现多预设共享 livingmemory 记忆;运行时接管服务方法,不改 chatluna-livingmemory 任何文件",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "妖祀",
|
|
8
|
+
"homepage": "https://github.com/ningningningning0420-ui/koishi-chatluna-plugins/tree/main/packages/koishi-plugin-chatluna-scene-rules#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/ningningningning0420-ui/koishi-chatluna-plugins.git",
|
|
12
|
+
"directory": "packages/koishi-plugin-chatluna-scene-rules"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/ningningningning0420-ui/koishi-chatluna-plugins/issues"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"index.js",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"keywords": [
|
|
23
|
+
"koishi",
|
|
24
|
+
"plugin",
|
|
25
|
+
"chatluna",
|
|
26
|
+
"chatluna-livingmemory",
|
|
27
|
+
"livingmemory",
|
|
28
|
+
"memory",
|
|
29
|
+
"alias",
|
|
30
|
+
"chatbot"
|
|
31
|
+
],
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"koishi": "^4.17.0",
|
|
34
|
+
"koishi-plugin-chatluna": "*",
|
|
35
|
+
"koishi-plugin-chatluna-livingmemory": "*"
|
|
36
|
+
},
|
|
37
|
+
"koishi": {
|
|
38
|
+
"description": {
|
|
39
|
+
"zh": "livingmemory 记忆池别名器:把同一角色的多个预设(如私聊版/群聊版/语音版)的 presetId 映射到同一个共享记忆池 key,让它们共享 livingmemory 记忆。运行时接管服务方法,不改 chatluna-livingmemory 任何文件,停用即还原。",
|
|
40
|
+
"en": "LivingMemory pool aliaser for ChatLuna: map several presets of one character (e.g. private/group/voice variants) onto a single shared memory-pool key so they share livingmemory. Wraps the service methods at runtime; touches no chatluna-livingmemory file and restores on unload."
|
|
41
|
+
},
|
|
42
|
+
"service": {
|
|
43
|
+
"required": [
|
|
44
|
+
"chatluna_living_memory"
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|