@cxyhhhhh/dsh-qqbot 0.3.0-dev.202608160954 → 0.4.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/.orange-ci.yml +2 -68
- package/CHANGELOG.md +15 -0
- package/README.md +34 -14
- package/README_EN.md +34 -14
- package/cordis.patch.yml +1 -1
- package/cordis.yml +46 -3
- package/dist/commands/help.d.ts +6 -7
- package/dist/commands/help.d.ts.map +1 -1
- package/dist/commands/help.js +23 -7
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/index.d.ts +7 -5
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +12 -12
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/misc.d.ts +9 -7
- package/dist/commands/misc.d.ts.map +1 -1
- package/dist/commands/misc.js +20 -5
- package/dist/commands/misc.js.map +1 -1
- package/dist/commands/model.d.ts +3 -4
- package/dist/commands/model.d.ts.map +1 -1
- package/dist/commands/model.js +8 -7
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/preset.d.ts +8 -0
- package/dist/commands/preset.d.ts.map +1 -0
- package/dist/commands/preset.js +52 -0
- package/dist/commands/preset.js.map +1 -0
- package/dist/commands/session.d.ts +11 -7
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +29 -13
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/status.d.ts +3 -4
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +2 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/types.d.ts +9 -2
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/config.d.ts +38 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +35 -1
- package/dist/config.js.map +1 -1
- package/dist/features/answer-parser.d.ts +9 -0
- package/dist/features/answer-parser.d.ts.map +1 -0
- package/dist/features/answer-parser.js +23 -0
- package/dist/features/answer-parser.js.map +1 -0
- package/dist/features/approval-channel.d.ts +74 -0
- package/dist/features/approval-channel.d.ts.map +1 -0
- package/dist/features/approval-channel.js +142 -0
- package/dist/features/approval-channel.js.map +1 -0
- package/dist/features/approval-renderer.d.ts +18 -0
- package/dist/features/approval-renderer.d.ts.map +1 -0
- package/dist/features/approval-renderer.js +52 -0
- package/dist/features/approval-renderer.js.map +1 -0
- package/dist/features/button-utils.d.ts +33 -0
- package/dist/features/button-utils.d.ts.map +1 -0
- package/dist/features/button-utils.js +27 -0
- package/dist/features/button-utils.js.map +1 -0
- package/dist/features/history-store.d.ts.map +1 -1
- package/dist/features/history-store.js +0 -1
- package/dist/features/history-store.js.map +1 -1
- package/dist/features/question-channel.d.ts +96 -0
- package/dist/features/question-channel.d.ts.map +1 -0
- package/dist/features/question-channel.js +234 -0
- package/dist/features/question-channel.js.map +1 -0
- package/dist/features/question-renderer.d.ts +20 -0
- package/dist/features/question-renderer.d.ts.map +1 -0
- package/dist/features/question-renderer.js +70 -0
- package/dist/features/question-renderer.js.map +1 -0
- package/dist/gateway/bootstrap.d.ts +3 -3
- package/dist/gateway/bootstrap.d.ts.map +1 -1
- package/dist/gateway/bootstrap.js +74 -8
- package/dist/gateway/bootstrap.js.map +1 -1
- package/dist/gateway/index.d.ts +2 -2
- package/dist/gateway/index.js +2 -2
- package/dist/gateway/middleware-setup.d.ts +3 -3
- package/dist/gateway/middleware-setup.d.ts.map +1 -1
- package/dist/gateway/middleware-setup.js +9 -7
- package/dist/gateway/middleware-setup.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -4
- package/dist/media/media-cleaner.d.ts +19 -0
- package/dist/media/media-cleaner.d.ts.map +1 -0
- package/dist/media/media-cleaner.js +81 -0
- package/dist/media/media-cleaner.js.map +1 -0
- package/dist/media/send-file-tool.d.ts +35 -0
- package/dist/media/send-file-tool.d.ts.map +1 -0
- package/dist/media/send-file-tool.js +150 -0
- package/dist/media/send-file-tool.js.map +1 -0
- package/dist/media/vision-tool.d.ts +16 -0
- package/dist/media/vision-tool.d.ts.map +1 -0
- package/dist/media/vision-tool.js +241 -0
- package/dist/media/vision-tool.js.map +1 -0
- package/dist/middleware/attachment.d.ts +3 -3
- package/dist/middleware/attachment.d.ts.map +1 -1
- package/dist/middleware/attachment.js +17 -4
- package/dist/middleware/attachment.js.map +1 -1
- package/dist/middleware/question-answer.d.ts +10 -0
- package/dist/middleware/question-answer.d.ts.map +1 -0
- package/dist/middleware/question-answer.js +19 -0
- package/dist/middleware/question-answer.js.map +1 -0
- package/dist/model/index.d.ts +4 -4
- package/dist/model/index.js +3 -3
- package/dist/model/model-resolver.d.ts +27 -13
- package/dist/model/model-resolver.d.ts.map +1 -1
- package/dist/model/model-resolver.js +82 -27
- package/dist/model/model-resolver.js.map +1 -1
- package/dist/model/prefs-store.d.ts +6 -1
- package/dist/model/prefs-store.d.ts.map +1 -1
- package/dist/model/prefs-store.js +25 -1
- package/dist/model/prefs-store.js.map +1 -1
- package/dist/model/settings-reader.d.ts +1 -1
- package/dist/session/idle-evictor.d.ts +2 -2
- package/dist/session/idle-evictor.d.ts.map +1 -1
- package/dist/session/idle-evictor.js +1 -1
- package/dist/session/idle-evictor.js.map +1 -1
- package/dist/session/index.d.ts +3 -3
- package/dist/session/index.d.ts.map +1 -1
- package/dist/session/index.js +2 -2
- package/dist/session/session-manager.d.ts +67 -9
- package/dist/session/session-manager.d.ts.map +1 -1
- package/dist/session/session-manager.js +216 -20
- package/dist/session/session-manager.js.map +1 -1
- package/dist/session/types.d.ts +47 -1
- package/dist/session/types.d.ts.map +1 -1
- package/dist/shared/index.d.ts +3 -3
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +3 -3
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/send-helper.js +1 -1
- package/dist/shared/utils.d.ts +2 -0
- package/dist/shared/utils.d.ts.map +1 -1
- package/dist/shared/utils.js +2 -2
- package/dist/shared/utils.js.map +1 -1
- package/dist/transport/attachment.d.ts +18 -7
- package/dist/transport/attachment.d.ts.map +1 -1
- package/dist/transport/attachment.js +77 -30
- package/dist/transport/attachment.js.map +1 -1
- package/dist/transport/inbound.d.ts +5 -4
- package/dist/transport/inbound.d.ts.map +1 -1
- package/dist/transport/inbound.js +120 -80
- package/dist/transport/inbound.js.map +1 -1
- package/dist/transport/index.d.ts +4 -4
- package/dist/transport/index.js +4 -4
- package/dist/transport/msgid-cache.d.ts +23 -0
- package/dist/transport/msgid-cache.d.ts.map +1 -0
- package/dist/transport/msgid-cache.js +57 -0
- package/dist/transport/msgid-cache.js.map +1 -0
- package/dist/transport/outbound-buffer.d.ts +9 -6
- package/dist/transport/outbound-buffer.d.ts.map +1 -1
- package/dist/transport/outbound-buffer.js +5 -5
- package/dist/transport/outbound-buffer.js.map +1 -1
- package/dist/transport/outbound.d.ts +9 -9
- package/dist/transport/outbound.d.ts.map +1 -1
- package/dist/transport/outbound.js +7 -7
- package/dist/transport/outbound.js.map +1 -1
- package/dist/transport/reply-limiter.d.ts +31 -0
- package/dist/transport/reply-limiter.d.ts.map +1 -0
- package/dist/transport/reply-limiter.js +50 -0
- package/dist/transport/reply-limiter.js.map +1 -0
- package/dist/transport/reply-target.d.ts +29 -0
- package/dist/transport/reply-target.d.ts.map +1 -0
- package/dist/transport/reply-target.js +55 -0
- package/dist/transport/reply-target.js.map +1 -0
- package/dist/transport/streaming-writer.d.ts +3 -3
- package/dist/transport/streaming-writer.d.ts.map +1 -1
- package/dist/transport/streaming-writer.js +1 -1
- package/dist/transport/streaming-writer.js.map +1 -1
- package/dist/transport/tool-presenter.d.ts +0 -1
- package/dist/transport/tool-presenter.d.ts.map +1 -1
- package/dist/transport/tool-presenter.js +0 -1
- package/dist/transport/tool-presenter.js.map +1 -1
- package/dist/types.d.ts +9 -15
- package/dist/types.d.ts.map +1 -1
- package/docs/assets/qrcode.png +0 -0
- package/package.json +17 -1
- package/a.txt +0 -14
- package/tiezi.md +0 -34
package/dist/commands/model.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 模型命令:/
|
|
2
|
+
* 模型命令:/model — 查看或切换模型
|
|
3
3
|
*/
|
|
4
|
-
import type {
|
|
5
|
-
|
|
6
|
-
export declare function modelCommand({ manager, config }: CommandDeps): SlashCommand;
|
|
4
|
+
import type { CommandDeps, CategorizedCommand } from './types.ts';
|
|
5
|
+
export declare function modelCommand({ manager, config }: CommandDeps): CategorizedCommand;
|
|
7
6
|
//# sourceMappingURL=model.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/commands/model.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/commands/model.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGlE,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,WAAW,GAAG,kBAAkB,CAiEjF"}
|
package/dist/commands/model.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { getScopePeer, sendMarkdownChunked } from
|
|
1
|
+
import { getScopePeer, sendMarkdownChunked } from "../shared/index.js";
|
|
2
2
|
export function modelCommand({ manager, config }) {
|
|
3
3
|
return {
|
|
4
|
-
name: '
|
|
5
|
-
|
|
4
|
+
name: 'model',
|
|
5
|
+
category: 'agent',
|
|
6
|
+
description: '查看或切换模型(用法: /model [provider/model])',
|
|
6
7
|
handler: async (cmdCtx) => {
|
|
7
8
|
const { scope, peerId } = getScopePeer(cmdCtx);
|
|
8
9
|
const args = (cmdCtx.command?.raw ?? '').trim();
|
|
9
10
|
// 无参数:显示当前模型 + 可用模型列表(可点击)
|
|
10
11
|
if (!args) {
|
|
11
12
|
const current = manager.getEffectiveModel(scope, peerId);
|
|
12
|
-
const models = manager.listAvailableModels();
|
|
13
|
+
const models = await manager.listAvailableModels();
|
|
13
14
|
// 当前模型展示:优先用别名(name),找不到别名时回退到 provider/model id
|
|
14
15
|
let currentDisplay = '宿主默认配置';
|
|
15
16
|
if (current) {
|
|
@@ -26,10 +27,10 @@ export function modelCommand({ manager, config }) {
|
|
|
26
27
|
for (const m of models) {
|
|
27
28
|
const modelPath = `${m.provider}/${m.id}`;
|
|
28
29
|
const displayName = m.name ? `${m.name}` : modelPath;
|
|
29
|
-
lines.push(`<qqbot-cmd-input text="/
|
|
30
|
+
lines.push(`<qqbot-cmd-input text="/model ${modelPath}" show="/model ${displayName}"/>`);
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
|
-
lines.push('', '手动指定: `/
|
|
33
|
+
lines.push('', '手动指定: `/model provider/model`');
|
|
33
34
|
await sendMarkdownChunked(cmdCtx, lines.join('\n'), config.textChunkLimit);
|
|
34
35
|
return { kind: 'noop' };
|
|
35
36
|
}
|
|
@@ -48,7 +49,7 @@ export function modelCommand({ manager, config }) {
|
|
|
48
49
|
model = args;
|
|
49
50
|
}
|
|
50
51
|
if (!provider || !model) {
|
|
51
|
-
return '用法: /
|
|
52
|
+
return '用法: /model provider/model\n示例: /model deepseek-official/deepseek-v4-flash';
|
|
52
53
|
}
|
|
53
54
|
await manager.setModelOverride(scope, peerId, { provider, model });
|
|
54
55
|
return `✅ 模型已切换: ${provider}/${model}\n立即生效,对话上下文保留。`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/commands/model.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/commands/model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preset 命令:/preset — 查看或切换 agent preset
|
|
3
|
+
*
|
|
4
|
+
* 无参数列出可用 preset(可点击切换),有参数切换,reset/default 重置为默认。
|
|
5
|
+
*/
|
|
6
|
+
import type { CommandDeps, CategorizedCommand } from './types.ts';
|
|
7
|
+
export declare function presetCommand({ manager, config }: CommandDeps): CategorizedCommand;
|
|
8
|
+
//# sourceMappingURL=preset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../../src/commands/preset.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGlE,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,WAAW,GAAG,kBAAkB,CAwDlF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { getScopePeer, sendMarkdownChunked } from "../shared/index.js";
|
|
2
|
+
export function presetCommand({ manager, config }) {
|
|
3
|
+
return {
|
|
4
|
+
name: 'preset',
|
|
5
|
+
category: 'agent',
|
|
6
|
+
description: '查看或切换 agent preset(用法: /preset [id])',
|
|
7
|
+
handler: async (cmdCtx) => {
|
|
8
|
+
const { scope, peerId } = getScopePeer(cmdCtx);
|
|
9
|
+
const args = (cmdCtx.command?.raw ?? '').trim();
|
|
10
|
+
// 无参数:列出可用 preset + 当前
|
|
11
|
+
if (!args) {
|
|
12
|
+
const presets = await manager.listPresets();
|
|
13
|
+
if (presets.length === 0) {
|
|
14
|
+
return '当前部署无可用的 agent preset';
|
|
15
|
+
}
|
|
16
|
+
const record = manager.getSessionRecord(scope, peerId);
|
|
17
|
+
const currentId = record?.agentPreset ?? manager.getEffectivePreset(scope, peerId);
|
|
18
|
+
const lines = ['### 🧩 Agent Preset', ''];
|
|
19
|
+
lines.push(`**当前:** ${currentId ?? '默认'}`);
|
|
20
|
+
lines.push('', '**可用 preset(点击切换):**');
|
|
21
|
+
for (const p of presets) {
|
|
22
|
+
const display = p.name ? `${p.name} (${p.id})` : p.id;
|
|
23
|
+
lines.push(`<qqbot-cmd-input text="/preset ${p.id}" show="/preset ${display}"/>`);
|
|
24
|
+
}
|
|
25
|
+
lines.push('', '手动指定: `/preset <id>`,重置默认: `/preset reset`');
|
|
26
|
+
await sendMarkdownChunked(cmdCtx, lines.join('\n'), config.textChunkLimit);
|
|
27
|
+
return { kind: 'noop' };
|
|
28
|
+
}
|
|
29
|
+
// reset / default:清除 per-peer 覆盖,回到默认
|
|
30
|
+
if (args === 'reset' || args === 'default') {
|
|
31
|
+
const outcome = await manager.clearPresetOverride(scope, peerId);
|
|
32
|
+
return outcome.ok ? '✅ 已重置为默认 preset(新会话生效)' : '重置失败';
|
|
33
|
+
}
|
|
34
|
+
// 切换到指定 preset
|
|
35
|
+
const outcome = await manager.setPresetOverride(scope, peerId, args);
|
|
36
|
+
if (!outcome.ok) {
|
|
37
|
+
switch (outcome.reason) {
|
|
38
|
+
case 'unavailable':
|
|
39
|
+
return '当前部署不支持 agent preset(agentPresets 服务未注入)';
|
|
40
|
+
case 'unknown-preset':
|
|
41
|
+
return `未知 preset: ${args}`;
|
|
42
|
+
case 'broken':
|
|
43
|
+
return `preset ${args} 加载失败: ${outcome.message ?? '未知错误'}`;
|
|
44
|
+
default:
|
|
45
|
+
return `切换失败: ${outcome.message ?? '未知错误'}`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return `✅ preset 已切换: ${args}\n新会话生效(当前会话保持原 preset,发送 /new 后生效)。`;
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=preset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preset.js","sourceRoot":"","sources":["../../src/commands/preset.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 会话相关命令
|
|
3
|
+
*
|
|
4
|
+
* - /new(别名 /reset /clear):开始新会话(换新 sessionId)
|
|
5
|
+
* - /compact:原地压缩会话历史(保留 sessionId,摘要替换旧历史)
|
|
6
|
+
*
|
|
7
|
+
* 两者都对应底层 dsh agent 能力,分类为 agent(通用能力)。
|
|
3
8
|
*/
|
|
4
|
-
import type {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export declare function newCommand({ manager }: CommandDeps): SlashCommand;
|
|
9
|
+
import type { CommandDeps, CategorizedCommand } from './types.ts';
|
|
10
|
+
/** /new(别名 /reset /clear)— 开始新会话 */
|
|
11
|
+
export declare function newCommand({ manager }: CommandDeps): CategorizedCommand;
|
|
12
|
+
/** /compact — 原地压缩会话历史 */
|
|
13
|
+
export declare function compactCommand({ manager }: CommandDeps): CategorizedCommand;
|
|
10
14
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGlE,oCAAoC;AACpC,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE,WAAW,GAAG,kBAAkB,CAWvE;AAED,0BAA0B;AAC1B,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,EAAE,WAAW,GAAG,kBAAkB,CA0B3E"}
|
package/dist/commands/session.js
CHANGED
|
@@ -1,25 +1,41 @@
|
|
|
1
|
-
import { getScopePeer } from
|
|
2
|
-
/** /
|
|
3
|
-
export function
|
|
1
|
+
import { getScopePeer } from "../shared/index.js";
|
|
2
|
+
/** /new(别名 /reset /clear)— 开始新会话 */
|
|
3
|
+
export function newCommand({ manager }) {
|
|
4
4
|
return {
|
|
5
|
-
name: ['
|
|
6
|
-
|
|
5
|
+
name: ['new', 'reset', 'clear'],
|
|
6
|
+
category: 'agent',
|
|
7
|
+
description: '开始新会话(清空上下文)',
|
|
7
8
|
handler: (cmdCtx) => {
|
|
8
9
|
const { scope, peerId } = getScopePeer(cmdCtx);
|
|
9
10
|
void manager.remove(scope, peerId);
|
|
10
|
-
return '
|
|
11
|
+
return '已开启新会话 ✓';
|
|
11
12
|
},
|
|
12
13
|
};
|
|
13
14
|
}
|
|
14
|
-
/** /
|
|
15
|
-
export function
|
|
15
|
+
/** /compact — 原地压缩会话历史 */
|
|
16
|
+
export function compactCommand({ manager }) {
|
|
16
17
|
return {
|
|
17
|
-
name: '
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
name: 'compact',
|
|
19
|
+
category: 'agent',
|
|
20
|
+
description: '压缩会话历史(摘要替换旧记录,保留上下文)',
|
|
21
|
+
handler: async (cmdCtx) => {
|
|
20
22
|
const { scope, peerId } = getScopePeer(cmdCtx);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
const outcome = await manager.compact(scope, peerId);
|
|
24
|
+
if (outcome.ok) {
|
|
25
|
+
if (!outcome.shadowed)
|
|
26
|
+
return '没有可压缩的历史';
|
|
27
|
+
return `✅ 已压缩 ${outcome.shadowed} 条历史记录(约 ${outcome.tokens ?? 0} tokens)`;
|
|
28
|
+
}
|
|
29
|
+
switch (outcome.reason) {
|
|
30
|
+
case 'no-session':
|
|
31
|
+
return '当前无活跃会话';
|
|
32
|
+
case 'busy':
|
|
33
|
+
return '正在生成中,无法压缩';
|
|
34
|
+
case 'unavailable':
|
|
35
|
+
return '压缩能力不可用(当前会话的 agent preset 未加载 compaction 服务)';
|
|
36
|
+
default:
|
|
37
|
+
return `压缩失败: ${outcome.message ?? '未知错误'}`;
|
|
38
|
+
}
|
|
23
39
|
},
|
|
24
40
|
};
|
|
25
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,oCAAoC;AACpC,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,EAAe;IACjD,OAAO;QACL,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC;QAC/B,QAAQ,EAAE,OAAO;QACjB,WAAW,EAAE,cAAc;QAC3B,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;YAC/C,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACnC,OAAO,UAAU,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,0BAA0B;AAC1B,MAAM,UAAU,cAAc,CAAC,EAAE,OAAO,EAAe;IACrD,OAAO;QACL,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,OAAO;QACjB,WAAW,EAAE,uBAAuB;QACpC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACxB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAErD,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;gBACf,IAAI,CAAC,OAAO,CAAC,QAAQ;oBAAE,OAAO,UAAU,CAAC;gBACzC,OAAO,SAAS,OAAO,CAAC,QAAQ,YAAY,OAAO,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC;YAC5E,CAAC;YAED,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC;gBACvB,KAAK,YAAY;oBACf,OAAO,SAAS,CAAC;gBACnB,KAAK,MAAM;oBACT,OAAO,YAAY,CAAC;gBACtB,KAAK,aAAa;oBAChB,OAAO,+CAA+C,CAAC;gBACzD;oBACE,OAAO,SAAS,OAAO,CAAC,OAAO,IAAI,MAAM,EAAE,CAAC;YAChD,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 状态命令:/bot-status
|
|
2
|
+
* 状态命令:/bot-status(QQBot 特有)
|
|
3
3
|
*/
|
|
4
|
-
import type {
|
|
5
|
-
import type { CommandDeps } from './types.js';
|
|
4
|
+
import type { CommandDeps, CategorizedCommand } from './types.ts';
|
|
6
5
|
/** /bot-status — 查看当前会话状态 */
|
|
7
|
-
export declare function statusCommand({ manager }: CommandDeps):
|
|
6
|
+
export declare function statusCommand({ manager }: CommandDeps): CategorizedCommand;
|
|
8
7
|
//# sourceMappingURL=status.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGlE,6BAA6B;AAC7B,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,EAAE,WAAW,GAAG,kBAAkB,CAoB1E"}
|
package/dist/commands/status.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { getScopePeer, formatRelativeTime } from
|
|
1
|
+
import { getScopePeer, formatRelativeTime } from "../shared/index.js";
|
|
2
2
|
/** /bot-status — 查看当前会话状态 */
|
|
3
3
|
export function statusCommand({ manager }) {
|
|
4
4
|
return {
|
|
5
5
|
name: 'bot-status',
|
|
6
|
+
category: 'qqbot',
|
|
6
7
|
description: '查看当前会话状态',
|
|
7
8
|
handler: (cmdCtx) => {
|
|
8
9
|
const { scope, peerId } = getScopePeer(cmdCtx);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEtE,6BAA6B;AAC7B,MAAM,UAAU,aAAa,CAAC,EAAE,OAAO,EAAe;IACpD,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE,OAAO;QACjB,WAAW,EAAE,UAAU;QACvB,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAChD,IAAI,CAAC,MAAM,CAAC,MAAM;gBAAE,OAAO,SAAS,CAAC;YACrC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YAC/E,OAAO;gBACL,SAAS;gBACT,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE;gBAC9D,OAAO,SAAS,EAAE;gBAClB,WAAW,MAAM,CAAC,MAAM,IAAI,GAAG,EAAE;gBACjC,QAAQ,MAAM,CAAC,YAAY,IAAI,CAAC,EAAE;gBAClC,SAAS,kBAAkB,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE;aACnD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/commands/types.d.ts
CHANGED
|
@@ -3,10 +3,17 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 每个命令工厂函数接收 CommandDeps,由 commands/index.ts 统一注入。
|
|
5
5
|
*/
|
|
6
|
-
import type {
|
|
7
|
-
import type {
|
|
6
|
+
import type { SlashCommand } from '@tencent-connect/qqbot-nodejs';
|
|
7
|
+
import type { SessionManager } from '../session/index.ts';
|
|
8
|
+
import type { ImQQBotConfig } from '../config.ts';
|
|
8
9
|
export interface CommandDeps {
|
|
9
10
|
manager: SessionManager;
|
|
10
11
|
config: ImQQBotConfig;
|
|
11
12
|
}
|
|
13
|
+
/** 命令分类:agent = 底层 agent 通用能力,qqbot = 插件特有 */
|
|
14
|
+
export type CommandCategory = 'agent' | 'qqbot';
|
|
15
|
+
/** 带分类的斜杠命令(category 供 help 分组展示,SDK 忽略未知字段) */
|
|
16
|
+
export interface CategorizedCommand extends SlashCommand {
|
|
17
|
+
category: CommandCategory;
|
|
18
|
+
}
|
|
12
19
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC;CACvB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,8CAA8C;AAC9C,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,CAAC;AAEhD,gDAAgD;AAChD,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,QAAQ,EAAE,eAAe,CAAC;CAC3B"}
|
package/dist/config.d.ts
CHANGED
|
@@ -12,6 +12,36 @@ export interface AccessControlConfig {
|
|
|
12
12
|
/** 群聊白名单(group openid) */
|
|
13
13
|
groupAllow: string[];
|
|
14
14
|
}
|
|
15
|
+
export interface MediaConfig {
|
|
16
|
+
/** 是否启用富媒体理解(图片/视频下载 + 工具分析) */
|
|
17
|
+
enabled: boolean;
|
|
18
|
+
/** 富媒体下载大小上限(MB),默认 200 */
|
|
19
|
+
maxMB: number;
|
|
20
|
+
/** 富媒体存活时长(小时,TTL),默认 24,0 = 永不过期 */
|
|
21
|
+
ttlHours: number;
|
|
22
|
+
}
|
|
23
|
+
export interface VisionConfig {
|
|
24
|
+
/** 是否启用视觉理解(qqbot_describe_image 工具) */
|
|
25
|
+
enabled: boolean;
|
|
26
|
+
/** 视觉模型 provider(dsh 注册的 llm adapter,如 pi-ai) */
|
|
27
|
+
provider: string;
|
|
28
|
+
/** 视觉模型 id(如 qwen-vl-max) */
|
|
29
|
+
model: string;
|
|
30
|
+
/** 默认描述 prompt(调用未显式指定时使用) */
|
|
31
|
+
defaultPrompt: string;
|
|
32
|
+
/** 图片字节上限,默认 10MB */
|
|
33
|
+
maxBytes: number;
|
|
34
|
+
/** 输出 token 上限 */
|
|
35
|
+
maxTokens: number;
|
|
36
|
+
/** 视觉调用超时(ms) */
|
|
37
|
+
timeoutMs: number;
|
|
38
|
+
}
|
|
39
|
+
export interface SendFileConfig {
|
|
40
|
+
/** 是否启用路径白名单(默认 true,仅允许 media + cwd + extraRoots;关闭则任意路径) */
|
|
41
|
+
restrictPaths: boolean;
|
|
42
|
+
/** 额外允许访问的根目录(media 和 agent cwd 始终默认允许) */
|
|
43
|
+
extraRoots: string[];
|
|
44
|
+
}
|
|
15
45
|
export interface ImQQBotConfig {
|
|
16
46
|
/** QQ Bot AppID */
|
|
17
47
|
appId: string;
|
|
@@ -41,6 +71,8 @@ export interface ImQQBotConfig {
|
|
|
41
71
|
maxQueue: number;
|
|
42
72
|
/** 处理超时(ms),超时中断当前 LLM 调用 */
|
|
43
73
|
processingTimeoutMs: number;
|
|
74
|
+
/** 待答问题超时(ms),超时自动拒绝并提示(ask_user_question) */
|
|
75
|
+
askTimeoutMs: number;
|
|
44
76
|
/** 群历史缓冲条数 */
|
|
45
77
|
historyLimit: number;
|
|
46
78
|
/** 访问控制 */
|
|
@@ -49,6 +81,12 @@ export interface ImQQBotConfig {
|
|
|
49
81
|
showToolResults: boolean;
|
|
50
82
|
/** 调试模式 */
|
|
51
83
|
debug: boolean;
|
|
84
|
+
/** 富媒体理解(图片/视频) */
|
|
85
|
+
media: MediaConfig;
|
|
86
|
+
/** 视觉理解(qqbot_describe_image 工具,走 dsh llm + attachments) */
|
|
87
|
+
vision: VisionConfig;
|
|
88
|
+
/** 附件发送(qqbot_send_file 工具) */
|
|
89
|
+
sendFile: SendFileConfig;
|
|
52
90
|
}
|
|
53
91
|
export declare const ConfigSchema: Schema<ImQQBotConfig>;
|
|
54
92
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,MAAM,MAAM,0BAA0B,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAClC,eAAe;IACf,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC;IAC3C,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa;IACb,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC;IAC7C,0BAA0B;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,mBAAmB;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,cAAc,EAAE,OAAO,CAAC;IACxB,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yBAAyB;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+BAA+B;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,wBAAwB;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,2BAA2B;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW;IACX,MAAM,EAAE,mBAAmB,CAAC;IAC5B,6BAA6B;IAC7B,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW;IACX,KAAK,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,MAAM,MAAM,0BAA0B,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAClC,eAAe;IACf,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC;IAC3C,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa;IACb,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC;IAC7C,0BAA0B;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,aAAa,EAAE,OAAO,CAAC;IACvB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,mBAAmB;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,cAAc,EAAE,OAAO,CAAC;IACxB,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yBAAyB;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+BAA+B;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,wBAAwB;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,2BAA2B;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW;IACX,MAAM,EAAE,mBAAmB,CAAC;IAC5B,6BAA6B;IAC7B,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW;IACX,KAAK,EAAE,OAAO,CAAC;IACf,mBAAmB;IACnB,KAAK,EAAE,WAAW,CAAC;IACnB,4DAA4D;IAC5D,MAAM,EAAE,YAAY,CAAC;IACrB,+BAA+B;IAC/B,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,aAAa,CA+D7C,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -16,7 +16,8 @@ export const ConfigSchema = Schema.object({
|
|
|
16
16
|
streaming: Schema.boolean().default(true).description('是否启用流式输出(群聊始终不启用)'),
|
|
17
17
|
sessionIdleTimeout: Schema.number().default(30 * 60 * 1000).description('会话闲置超时(ms)'),
|
|
18
18
|
maxQueue: Schema.number().default(20).description('并发队列最大长度'),
|
|
19
|
-
processingTimeoutMs: Schema.number().default(
|
|
19
|
+
processingTimeoutMs: Schema.number().default(30 * 60 * 1000).description('处理超时(ms),超时中断当前 LLM 调用'),
|
|
20
|
+
askTimeoutMs: Schema.number().default(5 * 60 * 1000).description('待答问题超时(ms),超时自动拒绝并提示'),
|
|
20
21
|
historyLimit: Schema.number().default(10).description('群历史缓冲条数'),
|
|
21
22
|
access: Schema.object({
|
|
22
23
|
c2cMode: Schema.union(['open', 'allowlist', 'disabled']).default('open').description('C2C访问模式'),
|
|
@@ -31,5 +32,38 @@ export const ConfigSchema = Schema.object({
|
|
|
31
32
|
}).description('访问控制'),
|
|
32
33
|
showToolResults: Schema.boolean().default(false).description('是否展示工具调用成功结果(错误始终展示)'),
|
|
33
34
|
debug: Schema.boolean().default(false),
|
|
35
|
+
media: Schema.object({
|
|
36
|
+
enabled: Schema.boolean().default(true).description('是否启用富媒体理解(图片/视频下载 + 工具分析)'),
|
|
37
|
+
maxMB: Schema.number().default(200).description('富媒体下载大小上限(MB)'),
|
|
38
|
+
ttlHours: Schema.number().default(24).description('富媒体存活时长(小时),0=永不过期'),
|
|
39
|
+
}).default({
|
|
40
|
+
enabled: true,
|
|
41
|
+
maxMB: 200,
|
|
42
|
+
ttlHours: 24,
|
|
43
|
+
}).description('富媒体理解配置'),
|
|
44
|
+
vision: Schema.object({
|
|
45
|
+
enabled: Schema.boolean().default(false).description('是否启用视觉理解(qqbot_describe_image 工具)'),
|
|
46
|
+
provider: Schema.string().default('').description('视觉模型 provider(dsh 注册的 llm adapter,如 pi-ai)'),
|
|
47
|
+
model: Schema.string().default('').description('视觉模型 id(如 qwen-vl-max)'),
|
|
48
|
+
defaultPrompt: Schema.string().default('Describe this image in detail.').description('默认描述 prompt'),
|
|
49
|
+
maxBytes: Schema.number().default(10 * 1024 * 1024).description('图片字节上限'),
|
|
50
|
+
maxTokens: Schema.number().default(1024).description('输出 token 上限'),
|
|
51
|
+
timeoutMs: Schema.number().default(120000).description('视觉调用超时(ms)'),
|
|
52
|
+
}).default({
|
|
53
|
+
enabled: false,
|
|
54
|
+
provider: '',
|
|
55
|
+
model: '',
|
|
56
|
+
defaultPrompt: 'Describe this image in detail.',
|
|
57
|
+
maxBytes: 10 * 1024 * 1024,
|
|
58
|
+
maxTokens: 1024,
|
|
59
|
+
timeoutMs: 120000,
|
|
60
|
+
}).description('视觉理解配置'),
|
|
61
|
+
sendFile: Schema.object({
|
|
62
|
+
restrictPaths: Schema.boolean().default(true).description('是否启用路径白名单(默认 true,仅允许 media + cwd + extraRoots)'),
|
|
63
|
+
extraRoots: Schema.array(Schema.string()).default([]).description('额外允许访问的根目录'),
|
|
64
|
+
}).default({
|
|
65
|
+
restrictPaths: true,
|
|
66
|
+
extraRoots: [],
|
|
67
|
+
}).description('附件发送工具配置'),
|
|
34
68
|
});
|
|
35
69
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,MAAM,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QQ 文本回复 → 结构化答案(纯函数,便于单测)。
|
|
3
|
+
*
|
|
4
|
+
* 逐题解析:一次解析一个问题的答案。
|
|
5
|
+
*/
|
|
6
|
+
import type { UserQuestion, UserQuestionAnswer } from './question-channel.ts';
|
|
7
|
+
/** 把用户对单个问题的文本回复解析为答案 */
|
|
8
|
+
export declare function parseAnswer(question: UserQuestion, text: string): UserQuestionAnswer;
|
|
9
|
+
//# sourceMappingURL=answer-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"answer-parser.d.ts","sourceRoot":"","sources":["../../src/features/answer-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE9E,yBAAyB;AACzB,wBAAgB,WAAW,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAmBpF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** 把用户对单个问题的文本回复解析为答案 */
|
|
2
|
+
export function parseAnswer(question, text) {
|
|
3
|
+
const opts = question.options ?? [];
|
|
4
|
+
if (opts.length > 0) {
|
|
5
|
+
// 纯数字/分隔符 → 按编号选择
|
|
6
|
+
if (/^[\d\s,,、;;./]+$/.test(text)) {
|
|
7
|
+
const nums = [...text.matchAll(/\d+/g)]
|
|
8
|
+
.map((m) => parseInt(m[0], 10))
|
|
9
|
+
.filter((n) => n >= 1 && n <= opts.length);
|
|
10
|
+
if (nums.length > 0) {
|
|
11
|
+
const picked = question.multiSelect ? nums : nums.slice(0, 1);
|
|
12
|
+
const selected = [...new Set(picked.map((n) => opts[n - 1]?.label).filter((l) => typeof l === 'string'))];
|
|
13
|
+
return { id: question.id, selected };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// 文本与某个选项 label 完全一致(忽略大小写)
|
|
17
|
+
const exact = opts.find((o) => o.label.toLowerCase() === text.toLowerCase());
|
|
18
|
+
if (exact)
|
|
19
|
+
return { id: question.id, selected: [exact.label] };
|
|
20
|
+
}
|
|
21
|
+
return { id: question.id, selected: [], custom: text };
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=answer-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"answer-parser.js","sourceRoot":"","sources":["../../src/features/answer-parser.ts"],"names":[],"mappings":"AAOA,yBAAyB;AACzB,MAAM,UAAU,WAAW,CAAC,QAAsB,EAAE,IAAY;IAC9D,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,kBAAkB;QAClB,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;iBACpC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;iBAC9B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpB,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC9D,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACvH,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC;YACvC,CAAC;QACH,CAAC;QACD,4BAA4B;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC7E,IAAI,KAAK;YAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;IACjE,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ApprovalChannel — 把 dsh 的审批 seam(`approval/request` waterfall)桥接到 QQ。
|
|
3
|
+
*
|
|
4
|
+
* 接入方式:监听 `approval/request` waterfall,按 `request.agent.id` 路由到 QQ
|
|
5
|
+
* 会话;非 QQ 会话委托链上其他 answerer(`next()`),多通道(Web/TUI)共存。
|
|
6
|
+
*
|
|
7
|
+
* 每个会话同一时间最多一个 pending 审批(审批是阻塞式的);outcome 是 dsh
|
|
8
|
+
* 协议的闭合集合,无 allow-always,只提供「允许一次 / 拒绝」两个按钮。
|
|
9
|
+
*/
|
|
10
|
+
import type { InteractionEvent } from '@tencent-connect/qqbot-nodejs';
|
|
11
|
+
import type { ChatScope, Logger, ReplyTarget } from '../types.ts';
|
|
12
|
+
export type ApprovalOutcome = 'allowed-once' | 'rejected' | 'cancelled' | 'unavailable';
|
|
13
|
+
/** session log 中 tool/call 事件的最小结构(commandOf 回显命令用) */
|
|
14
|
+
interface ApprovalSessionEvent {
|
|
15
|
+
type: string;
|
|
16
|
+
data?: {
|
|
17
|
+
callId?: unknown;
|
|
18
|
+
arguments?: unknown;
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export interface ApprovalRequest {
|
|
23
|
+
agent: {
|
|
24
|
+
id: string;
|
|
25
|
+
session: {
|
|
26
|
+
events: ApprovalSessionEvent[];
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
toolName: string;
|
|
30
|
+
/** 关联的 tool/call 事件 id,用于从 session log 找回被 gate 的命令 */
|
|
31
|
+
callId?: string;
|
|
32
|
+
/** asker 的人类可读解释 */
|
|
33
|
+
reason?: string;
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
}
|
|
36
|
+
export interface ApprovalSessionRecordLike {
|
|
37
|
+
sessionKey: string;
|
|
38
|
+
scope: ChatScope;
|
|
39
|
+
replyTarget: ReplyTarget;
|
|
40
|
+
}
|
|
41
|
+
export interface ApprovalChannelManagerLike {
|
|
42
|
+
findBySessionId(sessionId: string): ApprovalSessionRecordLike | undefined;
|
|
43
|
+
getSessionRecord(scope: ChatScope, peerId: string): ApprovalSessionRecordLike | undefined;
|
|
44
|
+
}
|
|
45
|
+
export interface ApprovalChannelSenderLike {
|
|
46
|
+
sendMarkdown(target: ReplyTarget, content: string, opts?: {
|
|
47
|
+
keyboard?: unknown;
|
|
48
|
+
}): Promise<unknown>;
|
|
49
|
+
}
|
|
50
|
+
/** approval/request waterfall 的 answerer handler */
|
|
51
|
+
export interface ApprovalChannelContext {
|
|
52
|
+
get(name: string): unknown;
|
|
53
|
+
on(event: string, handler: (...args: unknown[]) => unknown): void;
|
|
54
|
+
}
|
|
55
|
+
export declare class ApprovalChannel {
|
|
56
|
+
private readonly pending;
|
|
57
|
+
private readonly manager;
|
|
58
|
+
private readonly sender;
|
|
59
|
+
private readonly logger;
|
|
60
|
+
constructor(manager: ApprovalChannelManagerLike, sender: ApprovalChannelSenderLike, logger: Logger);
|
|
61
|
+
/**
|
|
62
|
+
* 注册 approval/request waterfall answerer。approval 服务未挂载时优雅禁用。
|
|
63
|
+
*/
|
|
64
|
+
install(ctx: ApprovalChannelContext): void;
|
|
65
|
+
/** 会话回收时清理其 pending 审批,避免 Promise 悬挂 */
|
|
66
|
+
cancelPending(sessionKey: string): void;
|
|
67
|
+
/** 按钮点击决策:解码 button_data,settle pending 审批 */
|
|
68
|
+
handleInteraction(event: InteractionEvent): boolean;
|
|
69
|
+
/** 走 QQ 通道:发审批消息 + 挂起 Promise,等待用户决策 */
|
|
70
|
+
private park;
|
|
71
|
+
private removeAbort;
|
|
72
|
+
}
|
|
73
|
+
export {};
|
|
74
|
+
//# sourceMappingURL=approval-channel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-channel.d.ts","sourceRoot":"","sources":["../../src/features/approval-channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAMlE,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,CAAC;AAExF,uDAAuD;AACvD,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;CAC1E;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE;YAAE,MAAM,EAAE,oBAAoB,EAAE,CAAA;SAAE,CAAC;KAC7C,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAID,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,MAAM,WAAW,0BAA0B;IACzC,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,yBAAyB,GAAG,SAAS,CAAC;IAC1E,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,yBAAyB,GAAG,SAAS,CAAC;CAC3F;AAED,MAAM,WAAW,yBAAyB;IACxC,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACrG;AAED,oDAAoD;AACpD,MAAM,WAAW,sBAAsB;IACrC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CACnE;AAyCD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsC;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAG9B,OAAO,EAAE,0BAA0B,EACnC,MAAM,EAAE,yBAAyB,EACjC,MAAM,EAAE,MAAM;IAOhB;;OAEG;IACI,OAAO,CAAC,GAAG,EAAE,sBAAsB,GAAG,IAAI;IAuBjD,wCAAwC;IACjC,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAQ9C,8CAA8C;IACvC,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO;IAoB1D,wCAAwC;YAC1B,IAAI;IAkClB,OAAO,CAAC,WAAW;CAKpB"}
|