koishi-plugin-chatluna-think-viewer 1.0.20 → 2.0.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.
Files changed (3) hide show
  1. package/README.md +47 -47
  2. package/index.js +22 -2
  3. package/package.json +4 -5
package/README.md CHANGED
@@ -1,48 +1,48 @@
1
- # koishi-plugin-chatluna-think-viewer
2
-
3
- ????/????? `chatluna-character` ??????? `<think>` ?????????????????/??????
4
-
5
- ## ??
6
- - ?? `chatluna-character` ??????????????????????
7
- - ??????????????????
8
- - **????????/??**????? `<think>`?`<status>`?`<output>`?`<analysis>`?`<system>` ??? JSON ????????(think/json/yaml)????????????(recall)?????(block)?
9
-
10
- ## ??
11
- ```bash
12
- # Koishi ??????? chatluna-think-viewer ??
13
- npm install koishi-plugin-chatluna-think-viewer
14
- ```
15
-
16
- ## ???? (koishi.yml)
17
- ```yaml
18
- plugins:
19
- chatluna-character: {}
20
- chatluna-think-viewer:
21
- command: think
22
- keywords:
23
- - ????
24
- - ????
25
- allowPrivate: false
26
- emptyMessage: ????????????
27
- # ??????
28
- guardEnabled: true
29
- guardMode: recall # recall | block
30
- guardDelay: 1 # ????????block ????
31
- # ??????????????? think/status/output/analysis/system ????? JSON/????
32
- guardForbiddenPatterns:
33
- - '<think>[\s\S]*?<\/think>'
34
- - '<status>[\s\S]*?<\/status>'
35
- - '<output>[\s\S]*?<\/output>'
36
- - '```\s*think[\s\S]*?```'
37
- ```
38
-
39
- ## ??
40
- - ????? `think` ????????????? `<think>` ???`think 2` ????? 2 ??
41
- - ???????????? bot ???????????????????????????????
42
-
43
- ## ??
44
- - koishi >= 4.18.0
45
- - koishi-plugin-chatluna-character >= 0.0.180
46
-
47
- ## ??
1
+ # koishi-plugin-chatluna-think-viewer
2
+
3
+ 通过命令/关键词查看 `chatluna-character` 最近一次回复的 `<think>` 思考内容,并提供“异常格式自动撤回/拦截”守卫。
4
+
5
+ ## 功能
6
+ - 依赖 `chatluna-character` 存储的思考上下文,支持命令与前缀关键词调用。
7
+ - 支持群聊使用(可配置是否允许私聊)。
8
+ - **异常格式自动撤回/拦截**:默认检测 `<think>`、`<status>`、`<output>`、`<analysis>`、`<system>` 等块或调试 JSONthink/json/yaml 代码块;命中后可选择先发后撤回(recall)或直接阻止(block)
9
+ - **严格输出模式(小白化)**:可选仅允许 `<output><message>…</message></output>` 结构;@ 仅允许数字 user_id,1~5 条 message,不符合即拦截/撤回。
10
+
11
+ ## 安装
12
+ ```bash
13
+ # Koishi 控制台市场搜索 chatluna-think-viewer 安装
14
+ npm install koishi-plugin-chatluna-think-viewer
15
+ ```
16
+
17
+ ## 配置示例 (koishi.yml)
18
+ ```yaml
19
+ plugins:
20
+ chatluna-character: {}
21
+ chatluna-think-viewer:
22
+ command: think
23
+ keywords:
24
+ - 查看思考
25
+ allowPrivate: false
26
+ emptyMessage: 暂时没有可用的思考记录。
27
+ # 异常撤回/拦截
28
+ guardEnabled: true
29
+ guardMode: recall # recall | block
30
+ guardDelay: 1 # 撤回延迟(秒),block 模式忽略
31
+ guardStrictOutputOnly: true # 只允许 <output><message>…</message></output>
32
+ guardStrictPattern: '^\s*<output>\s*(<message>(?:<at>\d+<\/at>\s*)?(?:<sticker>[^<]*<\/sticker>|[^<]*)<\/message>\s*){1,5}<\/output>\s*$'
33
+ guardForbiddenPatterns:
34
+ - '<think>[\\s\\S]*?<\\/think>'
35
+ - '<status>[\\s\\S]*?<\\/status>'
36
+ - '```\\s*think[\\s\\S]*?```'
37
+ ```
38
+
39
+ ## 使用
40
+ - 群聊里发送 `think` 或配置的关键词查看最近一次 `<think>` 内容;`think 2` 查看倒数第 2 条。
41
+ - 异常/严格模式:当 bot 发送的消息命中禁用规则或不符合严格输出结构时,记录日志并撤回(或直接阻止发送)。
42
+
43
+ ## 依赖
44
+ - koishi >= 4.18.0
45
+ - koishi-plugin-chatluna-character >= 0.0.180
46
+
47
+ ## 协议
48
48
  MIT
package/index.js CHANGED
@@ -10,12 +10,24 @@ const inject = {
10
10
 
11
11
  const defaultForbidden = [
12
12
  '<think>[\\s\\S]*?<\\/think>',
13
+ '<status>[\\s\\S]*?<\\/status>',
14
+ '<output>[\\s\\S]*?<\\/output>',
15
+ '<analysis>[\\s\\S]*?<\\/analysis>',
16
+ '<system>[\\s\\S]*?<\\/system>',
13
17
  '```\\s*think[\\s\\S]*?```',
18
+ '```\\s*(json|yaml|yml)[\\s\\S]*?```',
14
19
  '"role"\\s*:\\s*"assistant"',
15
20
  '"analysis"\\s*:',
16
21
  '"thought"\\s*:',
22
+ '(?:human_relations|人际关系)\\s*[:=]',
23
+ '(?:memory|记忆|记忆点|总结)\\s*[:=]',
17
24
  ];
18
25
 
26
+ // 严格 <output><message>... 结构:允许文本 / <at>user_id</at> 文本 / <sticker>url</sticker>
27
+ // 1~5 条 message,@ 仅允许数字 user_id
28
+ const strictOutputPattern =
29
+ '^\\s*<output>\\s*(<message>(?:<at>\\d+<\\/at>\\s*)?(?:<sticker>[^<]*<\\/sticker>|[^<]*)<\\/message>\\s*){1,5}<\\/output>\\s*$';
30
+
19
31
  const Config = Schema.intersect([
20
32
  Schema.object({
21
33
  command: Schema.string().default('think').description('\u67e5\u770b\u601d\u8003\u5185\u5bb9\u7684\u6307\u4ee4\u540d'),
@@ -36,6 +48,12 @@ const Config = Schema.intersect([
36
48
  guardAllowedPatterns: Schema.array(Schema.string())
37
49
  .default(['[\\s\\S]+'])
38
50
  .description('\u53ef\u9009\u767d\u540d\u5355\uff0c\u81f3\u5c11\u5339\u914d\u4e00\u4e2a\u624d\u7b97\u6b63\u5e38'),
51
+ guardStrictOutputOnly: Schema.boolean()
52
+ .default(false)
53
+ .description('\u53ea\u5141\u8bb8\u7b26\u5408 <output><message>\u2026</message></output> \u7ed3\u6784\u7684\u6d88\u606f\uff0c\u4e0d\u7b26\u5408\u5373\u62e6\u622a/\u64a4\u56de'),
54
+ guardStrictPattern: Schema.string()
55
+ .default(strictOutputPattern)
56
+ .description('\u81ea\u5b9a\u4e49\u4e25\u683c\u8f93\u51fa\u6b63\u5219\uff1b\u4e3a\u7a7a\u65f6\u4f7f\u7528\u5185\u7f6e\u7684 <output><message>\u2026</message> \u89c4\u5219'),
39
57
  guardLog: Schema.boolean().default(true).description('\u662f\u5426\u5728\u65e5\u5fd7\u8bb0\u5f55\u5f02\u5e38\u539f\u56e0\u548c\u5185\u5bb9'),
40
58
  guardContentPreview: Schema.number().default(80).min(10).max(500).description('\u65e5\u5fd7\u5185\u5bb9\u9884\u89c8\u957f\u5ea6'),
41
59
  }).description('\u5f02\u5e38\u8f93\u51fa\u81ea\u52a8\u5904\u7406'),
@@ -187,7 +205,9 @@ function applyGuard(ctx, config) {
187
205
  if (!config.guardEnabled) return;
188
206
  const logger = ctx.logger(`${name}:guard`);
189
207
  const forbidden = compileRegex(config.guardForbiddenPatterns);
190
- const allowed = compileRegex(config.guardAllowedPatterns);
208
+ const allowed = config.guardStrictOutputOnly
209
+ ? compileRegex([config.guardStrictPattern || strictOutputPattern])
210
+ : compileRegex(config.guardAllowedPatterns);
191
211
  const original = Bot.prototype.sendMessage;
192
212
 
193
213
  Bot.prototype.sendMessage = async function patched(channelId, content, referrer, options = {}) {
@@ -290,4 +310,4 @@ module.exports = {
290
310
  apply,
291
311
  Config,
292
312
  inject,
293
- };
313
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-chatluna-think-viewer",
3
- "version": "1.0.20",
3
+ "version": "2.0.0",
4
4
  "main": "index.js",
5
5
  "description": "View chatluna <think> blocks and auto recall abnormal formatted replies.",
6
6
  "license": "MIT",
@@ -27,8 +27,8 @@
27
27
  },
28
28
  "koishi": {
29
29
  "description": {
30
- "zh": "?? chatluna-character ? <think> ??????????????????/???",
31
- "en": "View <think> blocks from chatluna-character and auto recall malformed replies."
30
+ "zh": "通过命令/关键词查看 chatluna-character 最近一次回复的 <think> 思考内容,并在消息格式异常时自动拦截/撤回。",
31
+ "en": "View <think> blocks from chatluna-character and auto recall/guard malformed replies."
32
32
  },
33
33
  "service": {
34
34
  "required": [
@@ -40,5 +40,4 @@
40
40
  "index.js",
41
41
  "README.md"
42
42
  ]
43
- }
44
-
43
+ }