koishi-plugin-chatluna-think-viewer 1.0.18 → 1.0.19

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 (2) hide show
  1. package/index.js +41 -39
  2. package/package.json +2 -1
package/index.js CHANGED
@@ -18,27 +18,27 @@ const defaultForbidden = [
18
18
 
19
19
  const Config = Schema.intersect([
20
20
  Schema.object({
21
- command: Schema.string().default('think').description('�鿴˼�����ݵ�ָ����'),
22
- keywords: Schema.array(Schema.string()).default(['�鿴˼��', '�ϴ�˼��']).description('����ǰ��ָ��Ĺؼ���'),
23
- allowPrivate: Schema.boolean().default(false).description('�Ƿ�������˽��ʹ��'),
24
- emptyMessage: Schema.string().default('��ʱû�п��õ�˼����¼��').description('û�м�¼ʱ����ʾ�ı�'),
25
- renderImage: Schema.boolean().default(false).description('�Ƿ�ͨ�� ChatLuna �� image renderer ��˼����ȾΪͼƬ��ʧ��ʱ�����ı�'),
26
- }).description('˼���鿴����'),
21
+ command: Schema.string().default('think').description('查看思考内容的指令名'),
22
+ keywords: Schema.array(Schema.string()).default(['查看思考', '上次思考']).description('可无前缀触发的关键词'),
23
+ allowPrivate: Schema.boolean().default(false).description('是否允许在私聊中使用'),
24
+ emptyMessage: Schema.string().default('暂时没有可用的思考记录。').description('没有记录时的提示文本'),
25
+ renderImage: Schema.boolean().default(false).description('是否通过 ChatLuna image renderer 将思考渲染为图片,失败时回退文本'),
26
+ }).description('思考查看配置'),
27
27
  Schema.object({
28
- guardEnabled: Schema.boolean().default(true).description('����쳣��ʽ���Զ�����/����'),
29
- guardMode: Schema.union(['recall', 'block']).default('recall').description('recall=�ȷ��󳷻أ�block=ֱ����ֹ����'),
30
- guardDelay: Schema.number().default(1).min(0).max(60).description('�����ӳ٣��룩'),
31
- guardAllowPrivate: Schema.boolean().default(true).description('�Ƿ���˽���������쳣���'),
32
- guardGroups: Schema.array(Schema.string()).default([]).description('ֻ����ЩȺ���ã���ձ�ʾȫ��'),
28
+ guardEnabled: Schema.boolean().default(true).description('异常输出自动拦截开关'),
29
+ guardMode: Schema.union(['recall', 'block']).default('recall').description('recall=先发送后撤回,block=直接阻止发送'),
30
+ guardDelay: Schema.number().default(1).min(0).max(60).description('撤回延迟(秒)'),
31
+ guardAllowPrivate: Schema.boolean().default(true).description('是否在私聊中也启用拦截'),
32
+ guardGroups: Schema.array(Schema.string()).default([]).description('只在这些群生效,留空表示全部'),
33
33
  guardForbiddenPatterns: Schema.array(Schema.string())
34
34
  .default(defaultForbidden)
35
- .description('��������������Ϊ�쳣������˼����й©������ JSON ��'),
35
+ .description('命中即视为异常的模式,用于避免思考泄露或 JSON 生出'),
36
36
  guardAllowedPatterns: Schema.array(Schema.string())
37
37
  .default(['[\\s\\S]+'])
38
- .description('��ѡ�İ�����������������һ������Ϊ����'),
39
- guardLog: Schema.boolean().default(true).description('�Ƿ�����־�м�¼�쳣���ݺ�ԭ��'),
40
- guardContentPreview: Schema.number().default(80).min(10).max(500).description('��־�ﱣ�������Ԥ���ַ���'),
41
- }).description('�쳣��ʽ�Զ�����'),
38
+ .description('可选白名单,至少匹配一个才算正常'),
39
+ guardLog: Schema.boolean().default(true).description('是否在日志记录异常原因和内容'),
40
+ guardContentPreview: Schema.number().default(80).min(10).max(500).description('日志内容预览长度'),
41
+ }).description('异常输出自动处理'),
42
42
  ]);
43
43
 
44
44
  function extractText(content) {
@@ -60,7 +60,7 @@ function extractText(content) {
60
60
  }
61
61
 
62
62
  function extractThink(text) {
63
- // ijЩģ��/�м������ͬһ����Ϣ���γ��� <think>��ȡ���һ�γ��ֵ�Ƭ��
63
+ // 某些模型/中间件会在同一条消息里多次出现 <think>,取最后一次
64
64
  let last = '';
65
65
  const regex = /<think>([\s\S]*?)<\/think>/gi;
66
66
  let m;
@@ -72,7 +72,7 @@ function extractThink(text) {
72
72
 
73
73
  function formatThink(text) {
74
74
  if (!text) return text;
75
- // ���Ը�ʽ�� JSON��ʧ�����ȥ��β/�ϲ�����
75
+ // 尝试格式化 JSON,失败则做基础去空行/缩进美化
76
76
  try {
77
77
  const parsed = JSON.parse(text);
78
78
  return JSON.stringify(parsed, null, 2);
@@ -145,22 +145,24 @@ function getLatestRawThink(temp) {
145
145
  }
146
146
 
147
147
  function compileRegex(list) {
148
- return (list || []).map((p) => {
149
- try {
150
- return new RegExp(p, 'i');
151
- } catch (err) {
152
- return null;
153
- }
154
- }).filter(Boolean);
148
+ return (list || [])
149
+ .map((p) => {
150
+ try {
151
+ return new RegExp(p, 'i');
152
+ } catch (err) {
153
+ return null;
154
+ }
155
+ })
156
+ .filter(Boolean);
155
157
  }
156
158
 
157
159
  function detectAbnormal(text, forbidden, allowed) {
158
160
  if (!text) return null;
159
161
  for (const re of forbidden) {
160
- if (re.test(text)) return `���н�ֹ����: /${re.source}/`;
162
+ if (re.test(text)) return `命中禁止模式: /${re.source}/`;
161
163
  }
162
164
  if (allowed.length && !allowed.some((re) => re.test(text))) {
163
- return 'δ�����κΰ���������';
165
+ return '未匹配任何允许模式';
164
166
  }
165
167
  return null;
166
168
  }
@@ -227,10 +229,10 @@ function applyGuard(ctx, config) {
227
229
  }
228
230
 
229
231
  function apply(ctx, config) {
230
- // ˼���鿴����
232
+ // 思考查看指令
231
233
  const cmd = ctx
232
- .command(`${config.command} [index:string]`, '��ȡ���һ�ΰ��� <think> �����ݣ���ָ���� N ��')
233
- .usage('���� think 2 �ɲ鿴������ 2 �� AI �ظ���˼������');
234
+ .command(`${config.command} [index:string]`, '读取上一条含 <think> 的内容,可指定倒数第 N ')
235
+ .usage('不带参数默认最新;示例:think 2 查询倒数第 2 AI 回复的思考');
234
236
 
235
237
  for (const keyword of config.keywords || []) {
236
238
  cmd.shortcut(keyword, { prefix: false });
@@ -238,23 +240,23 @@ function apply(ctx, config) {
238
240
 
239
241
  cmd.action(async ({ session, args }, rawIndex) => {
240
242
  if (!config.allowPrivate && !session.guildId) {
241
- return '��֧����˽�����ѯ��';
243
+ return '不支持在私聊中查询。';
242
244
  }
243
245
 
244
246
  const service = ctx.chatluna_character;
245
- if (!service) return 'chatluna-character δ���ء�';
247
+ if (!service) return 'chatluna-character 未加载。';
246
248
 
247
249
  const temp = await service.getTemp(session);
248
250
  const targetIndex = parseIndex(rawIndex ?? args?.[0]);
249
251
 
250
- // 1) �ȶ����һ��ԭʼ��Ӧ��ͨ��ֻ�Ե� 1 ����Ч��
252
+ // 1) 优先读取最新一次原始响应(通常仍含 <think>),仅对第 1 条有效
251
253
  const thinkFromRaw = targetIndex === 1 ? getLatestRawThink(temp) : '';
252
254
 
253
- // 2) ����ʷ completionMessages �в��Ұ��� <think> �� AI ��Ϣ
255
+ // 2) 历史 completionMessages 中真正带 <think> AI 消息
254
256
  const messages = temp?.completionMessages || [];
255
257
  const thinkFromHistory = thinkFromRaw ? '' : getNthThink(messages, targetIndex);
256
258
 
257
- // 3) ���ף�ȡ�� N �� AI ��Ϣ�ٴ�����ȡ <think>
259
+ // 3) 回退:第 N AI 消息再尝试抽取 <think>
258
260
  const fallbackMsg = thinkFromRaw || thinkFromHistory ? null : getNthAiMessage(messages, targetIndex);
259
261
  const think = thinkFromRaw || thinkFromHistory || extractThink(extractText(fallbackMsg?.content));
260
262
  const formatted = formatThink(think);
@@ -262,7 +264,7 @@ function apply(ctx, config) {
262
264
 
263
265
  if (config.renderImage && ctx.chatluna?.renderer) {
264
266
  try {
265
- const title = `### ���˼�����ݣ������� ${targetIndex} ����`;
267
+ const title = `### 上一条思考(倒数第 ${targetIndex} 条)`;
266
268
  const markdown = `<div align="center">\n${title}\n</div>\n\n<div align="left">\n${formatted}\n</div>`;
267
269
  const rendered = await ctx.chatluna.renderer.render(
268
270
  {
@@ -276,10 +278,10 @@ function apply(ctx, config) {
276
278
  }
277
279
  }
278
280
 
279
- return `���˼�����ݣ������� ${targetIndex} ����\n${formatted}`;
281
+ return `上一条思考(倒数第 ${targetIndex} 条)\n${formatted}`;
280
282
  });
281
283
 
282
- // �쳣��ʽ�Զ�����
284
+ // 异常输出自动处理
283
285
  applyGuard(ctx, config);
284
286
  }
285
287
 
@@ -288,4 +290,4 @@ module.exports = {
288
290
  apply,
289
291
  Config,
290
292
  inject,
291
- };
293
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-chatluna-think-viewer",
3
- "version": "1.0.18",
3
+ "version": "1.0.19",
4
4
  "main": "index.js",
5
5
  "description": "View chatluna <think> blocks and auto recall abnormal formatted replies.",
6
6
  "license": "MIT",
@@ -41,3 +41,4 @@
41
41
  "README.md"
42
42
  ]
43
43
  }
44
+