koishi-plugin-chatluna-think-viewer 1.0.8 → 1.0.10
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/index.js +32 -21
- package/package.json +5 -5
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { Schema } = require('koishi');
|
|
1
|
+
const { Schema } = require('koishi');
|
|
2
2
|
|
|
3
3
|
const name = 'chatluna-think-viewer';
|
|
4
4
|
|
|
@@ -53,12 +53,26 @@ function formatThink(text) {
|
|
|
53
53
|
const filtered = lines.filter((l, idx, arr) => !(l === '' && arr[idx - 1] === ''));
|
|
54
54
|
const nonEmpty = filtered.filter((l) => l.trim().length > 0);
|
|
55
55
|
const minIndent = nonEmpty.length
|
|
56
|
-
? Math.min(
|
|
56
|
+
? Math.min(
|
|
57
|
+
...nonEmpty.map((l) => {
|
|
58
|
+
const m = l.match(/^(\s*)/);
|
|
59
|
+
return m ? m[1].length : 0;
|
|
60
|
+
}),
|
|
61
|
+
)
|
|
57
62
|
: 0;
|
|
58
63
|
return filtered.map((l) => l.slice(minIndent)).join('\n');
|
|
59
64
|
}
|
|
60
65
|
}
|
|
61
66
|
|
|
67
|
+
function parseIndex(rawIndex) {
|
|
68
|
+
if (!rawIndex) return 1;
|
|
69
|
+
if (typeof rawIndex === 'number' && Number.isFinite(rawIndex) && rawIndex > 0) return Math.floor(rawIndex);
|
|
70
|
+
const match = String(rawIndex).match(/\d+/);
|
|
71
|
+
if (!match) return 1;
|
|
72
|
+
const num = parseInt(match[0], 10);
|
|
73
|
+
return Number.isFinite(num) && num > 0 ? num : 1;
|
|
74
|
+
}
|
|
75
|
+
|
|
62
76
|
function getNthAiMessage(messages, n = 1) {
|
|
63
77
|
if (!Array.isArray(messages) || n < 1) return null;
|
|
64
78
|
let count = 0;
|
|
@@ -66,7 +80,7 @@ function getNthAiMessage(messages, n = 1) {
|
|
|
66
80
|
const msg = messages[i];
|
|
67
81
|
const type = typeof msg?._getType === 'function' ? msg._getType() : msg?.type || msg?.role;
|
|
68
82
|
if (type === 'ai' || type === 'assistant') {
|
|
69
|
-
count
|
|
83
|
+
count += 1;
|
|
70
84
|
if (count === n) return msg;
|
|
71
85
|
}
|
|
72
86
|
}
|
|
@@ -75,14 +89,14 @@ function getNthAiMessage(messages, n = 1) {
|
|
|
75
89
|
|
|
76
90
|
function apply(ctx, config) {
|
|
77
91
|
const cmd = ctx
|
|
78
|
-
.command(`${config.command} [index:
|
|
79
|
-
.usage('不带参数默认读取最近一条;例如 think 2 读取倒数第二条 AI
|
|
92
|
+
.command(`${config.command} [index:string]`, '获取上一条回复中的 <think> 内容(可指定倒数第 N 条)')
|
|
93
|
+
.usage('不带参数默认读取最近一条;例如 think 2 读取倒数第二条 AI 回复的思考');
|
|
80
94
|
|
|
81
95
|
for (const keyword of config.keywords || []) {
|
|
82
96
|
cmd.shortcut(keyword, { prefix: false });
|
|
83
97
|
}
|
|
84
98
|
|
|
85
|
-
cmd.action(async ({ session }, rawIndex) => {
|
|
99
|
+
cmd.action(async ({ session, args }, rawIndex) => {
|
|
86
100
|
if (!config.allowPrivate && !session.guildId) {
|
|
87
101
|
return '仅支持在群聊中查询。';
|
|
88
102
|
}
|
|
@@ -94,26 +108,23 @@ function apply(ctx, config) {
|
|
|
94
108
|
const messages = temp?.completionMessages || [];
|
|
95
109
|
if (!messages.length) return config.emptyMessage;
|
|
96
110
|
|
|
97
|
-
|
|
98
|
-
if (!Number.isFinite(targetIndex) || targetIndex < 1) targetIndex = 1;
|
|
111
|
+
const targetIndex = parseIndex(rawIndex ?? args?.[0]);
|
|
99
112
|
|
|
100
|
-
const
|
|
101
|
-
if (!
|
|
113
|
+
const targetMessage = getNthAiMessage(messages, targetIndex);
|
|
114
|
+
if (!targetMessage) return config.emptyMessage;
|
|
102
115
|
|
|
103
|
-
const
|
|
104
|
-
if (!
|
|
105
|
-
|
|
106
|
-
const think = formatThink(extractThink(text));
|
|
107
|
-
if (!think) return config.emptyMessage || '上一次回复中没有 <think> 字段。';
|
|
116
|
+
const think = formatThink(extractThink(extractText(targetMessage.content)));
|
|
117
|
+
if (!think) return config.emptyMessage;
|
|
108
118
|
|
|
109
119
|
if (config.renderImage && ctx.chatluna?.renderer) {
|
|
110
120
|
try {
|
|
111
121
|
const title = `### 上一条思考(倒数第 ${targetIndex} 条)`;
|
|
112
|
-
const rendered = await ctx.chatluna.renderer.render(
|
|
113
|
-
|
|
114
|
-
{ type: 'text', text: `${title}\n\n\`\`\`\n${think}\n\`\`\`` },
|
|
115
|
-
|
|
116
|
-
|
|
122
|
+
const rendered = await ctx.chatluna.renderer.render(
|
|
123
|
+
{
|
|
124
|
+
content: [{ type: 'text', text: `${title}\n\n\`\`\`\n${think}\n\`\`\`` }],
|
|
125
|
+
},
|
|
126
|
+
{ type: 'image', session },
|
|
127
|
+
);
|
|
117
128
|
if (rendered?.length) return rendered.map((r) => r.element);
|
|
118
129
|
} catch (err) {
|
|
119
130
|
ctx.logger?.warn?.('[think-viewer] image render failed, fallback text', err);
|
|
@@ -129,4 +140,4 @@ module.exports = {
|
|
|
129
140
|
apply,
|
|
130
141
|
Config,
|
|
131
142
|
inject,
|
|
132
|
-
};
|
|
143
|
+
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
2
|
"name": "koishi-plugin-chatluna-think-viewer",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"main": "index.js",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "通过命令/关键词查看 chatluna-character 最近一次回复中的 <think> 思考内容。",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"koishi",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"koishi": {
|
|
26
26
|
"description": {
|
|
27
|
-
"zh": "
|
|
27
|
+
"zh": "通过命令/关键词查看 chatluna-character 最近一次回复的 <think> 思考内容。",
|
|
28
28
|
"en": "Expose a command/shortcut to read the last <think> block from chatluna-character."
|
|
29
29
|
},
|
|
30
30
|
"service": {
|
|
@@ -37,4 +37,4 @@
|
|
|
37
37
|
"index.js",
|
|
38
38
|
"README.md"
|
|
39
39
|
]
|
|
40
|
-
}
|
|
40
|
+
}
|