@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.
Files changed (176) hide show
  1. package/.orange-ci.yml +2 -68
  2. package/CHANGELOG.md +15 -0
  3. package/README.md +34 -14
  4. package/README_EN.md +34 -14
  5. package/cordis.patch.yml +1 -1
  6. package/cordis.yml +46 -3
  7. package/dist/commands/help.d.ts +6 -7
  8. package/dist/commands/help.d.ts.map +1 -1
  9. package/dist/commands/help.js +23 -7
  10. package/dist/commands/help.js.map +1 -1
  11. package/dist/commands/index.d.ts +7 -5
  12. package/dist/commands/index.d.ts.map +1 -1
  13. package/dist/commands/index.js +12 -12
  14. package/dist/commands/index.js.map +1 -1
  15. package/dist/commands/misc.d.ts +9 -7
  16. package/dist/commands/misc.d.ts.map +1 -1
  17. package/dist/commands/misc.js +20 -5
  18. package/dist/commands/misc.js.map +1 -1
  19. package/dist/commands/model.d.ts +3 -4
  20. package/dist/commands/model.d.ts.map +1 -1
  21. package/dist/commands/model.js +8 -7
  22. package/dist/commands/model.js.map +1 -1
  23. package/dist/commands/preset.d.ts +8 -0
  24. package/dist/commands/preset.d.ts.map +1 -0
  25. package/dist/commands/preset.js +52 -0
  26. package/dist/commands/preset.js.map +1 -0
  27. package/dist/commands/session.d.ts +11 -7
  28. package/dist/commands/session.d.ts.map +1 -1
  29. package/dist/commands/session.js +29 -13
  30. package/dist/commands/session.js.map +1 -1
  31. package/dist/commands/status.d.ts +3 -4
  32. package/dist/commands/status.d.ts.map +1 -1
  33. package/dist/commands/status.js +2 -1
  34. package/dist/commands/status.js.map +1 -1
  35. package/dist/commands/types.d.ts +9 -2
  36. package/dist/commands/types.d.ts.map +1 -1
  37. package/dist/config.d.ts +38 -0
  38. package/dist/config.d.ts.map +1 -1
  39. package/dist/config.js +35 -1
  40. package/dist/config.js.map +1 -1
  41. package/dist/features/answer-parser.d.ts +9 -0
  42. package/dist/features/answer-parser.d.ts.map +1 -0
  43. package/dist/features/answer-parser.js +23 -0
  44. package/dist/features/answer-parser.js.map +1 -0
  45. package/dist/features/approval-channel.d.ts +74 -0
  46. package/dist/features/approval-channel.d.ts.map +1 -0
  47. package/dist/features/approval-channel.js +142 -0
  48. package/dist/features/approval-channel.js.map +1 -0
  49. package/dist/features/approval-renderer.d.ts +18 -0
  50. package/dist/features/approval-renderer.d.ts.map +1 -0
  51. package/dist/features/approval-renderer.js +52 -0
  52. package/dist/features/approval-renderer.js.map +1 -0
  53. package/dist/features/button-utils.d.ts +33 -0
  54. package/dist/features/button-utils.d.ts.map +1 -0
  55. package/dist/features/button-utils.js +27 -0
  56. package/dist/features/button-utils.js.map +1 -0
  57. package/dist/features/history-store.d.ts.map +1 -1
  58. package/dist/features/history-store.js +0 -1
  59. package/dist/features/history-store.js.map +1 -1
  60. package/dist/features/question-channel.d.ts +96 -0
  61. package/dist/features/question-channel.d.ts.map +1 -0
  62. package/dist/features/question-channel.js +234 -0
  63. package/dist/features/question-channel.js.map +1 -0
  64. package/dist/features/question-renderer.d.ts +20 -0
  65. package/dist/features/question-renderer.d.ts.map +1 -0
  66. package/dist/features/question-renderer.js +70 -0
  67. package/dist/features/question-renderer.js.map +1 -0
  68. package/dist/gateway/bootstrap.d.ts +3 -3
  69. package/dist/gateway/bootstrap.d.ts.map +1 -1
  70. package/dist/gateway/bootstrap.js +74 -8
  71. package/dist/gateway/bootstrap.js.map +1 -1
  72. package/dist/gateway/index.d.ts +2 -2
  73. package/dist/gateway/index.js +2 -2
  74. package/dist/gateway/middleware-setup.d.ts +3 -3
  75. package/dist/gateway/middleware-setup.d.ts.map +1 -1
  76. package/dist/gateway/middleware-setup.js +9 -7
  77. package/dist/gateway/middleware-setup.js.map +1 -1
  78. package/dist/index.d.ts +2 -2
  79. package/dist/index.js +4 -4
  80. package/dist/media/media-cleaner.d.ts +19 -0
  81. package/dist/media/media-cleaner.d.ts.map +1 -0
  82. package/dist/media/media-cleaner.js +81 -0
  83. package/dist/media/media-cleaner.js.map +1 -0
  84. package/dist/media/send-file-tool.d.ts +35 -0
  85. package/dist/media/send-file-tool.d.ts.map +1 -0
  86. package/dist/media/send-file-tool.js +150 -0
  87. package/dist/media/send-file-tool.js.map +1 -0
  88. package/dist/media/vision-tool.d.ts +16 -0
  89. package/dist/media/vision-tool.d.ts.map +1 -0
  90. package/dist/media/vision-tool.js +241 -0
  91. package/dist/media/vision-tool.js.map +1 -0
  92. package/dist/middleware/attachment.d.ts +3 -3
  93. package/dist/middleware/attachment.d.ts.map +1 -1
  94. package/dist/middleware/attachment.js +17 -4
  95. package/dist/middleware/attachment.js.map +1 -1
  96. package/dist/middleware/question-answer.d.ts +10 -0
  97. package/dist/middleware/question-answer.d.ts.map +1 -0
  98. package/dist/middleware/question-answer.js +19 -0
  99. package/dist/middleware/question-answer.js.map +1 -0
  100. package/dist/model/index.d.ts +4 -4
  101. package/dist/model/index.js +3 -3
  102. package/dist/model/model-resolver.d.ts +27 -13
  103. package/dist/model/model-resolver.d.ts.map +1 -1
  104. package/dist/model/model-resolver.js +82 -27
  105. package/dist/model/model-resolver.js.map +1 -1
  106. package/dist/model/prefs-store.d.ts +6 -1
  107. package/dist/model/prefs-store.d.ts.map +1 -1
  108. package/dist/model/prefs-store.js +25 -1
  109. package/dist/model/prefs-store.js.map +1 -1
  110. package/dist/model/settings-reader.d.ts +1 -1
  111. package/dist/session/idle-evictor.d.ts +2 -2
  112. package/dist/session/idle-evictor.d.ts.map +1 -1
  113. package/dist/session/idle-evictor.js +1 -1
  114. package/dist/session/idle-evictor.js.map +1 -1
  115. package/dist/session/index.d.ts +3 -3
  116. package/dist/session/index.d.ts.map +1 -1
  117. package/dist/session/index.js +2 -2
  118. package/dist/session/session-manager.d.ts +67 -9
  119. package/dist/session/session-manager.d.ts.map +1 -1
  120. package/dist/session/session-manager.js +216 -20
  121. package/dist/session/session-manager.js.map +1 -1
  122. package/dist/session/types.d.ts +47 -1
  123. package/dist/session/types.d.ts.map +1 -1
  124. package/dist/shared/index.d.ts +3 -3
  125. package/dist/shared/index.d.ts.map +1 -1
  126. package/dist/shared/index.js +3 -3
  127. package/dist/shared/index.js.map +1 -1
  128. package/dist/shared/send-helper.js +1 -1
  129. package/dist/shared/utils.d.ts +2 -0
  130. package/dist/shared/utils.d.ts.map +1 -1
  131. package/dist/shared/utils.js +2 -2
  132. package/dist/shared/utils.js.map +1 -1
  133. package/dist/transport/attachment.d.ts +18 -7
  134. package/dist/transport/attachment.d.ts.map +1 -1
  135. package/dist/transport/attachment.js +77 -30
  136. package/dist/transport/attachment.js.map +1 -1
  137. package/dist/transport/inbound.d.ts +5 -4
  138. package/dist/transport/inbound.d.ts.map +1 -1
  139. package/dist/transport/inbound.js +120 -80
  140. package/dist/transport/inbound.js.map +1 -1
  141. package/dist/transport/index.d.ts +4 -4
  142. package/dist/transport/index.js +4 -4
  143. package/dist/transport/msgid-cache.d.ts +23 -0
  144. package/dist/transport/msgid-cache.d.ts.map +1 -0
  145. package/dist/transport/msgid-cache.js +57 -0
  146. package/dist/transport/msgid-cache.js.map +1 -0
  147. package/dist/transport/outbound-buffer.d.ts +9 -6
  148. package/dist/transport/outbound-buffer.d.ts.map +1 -1
  149. package/dist/transport/outbound-buffer.js +5 -5
  150. package/dist/transport/outbound-buffer.js.map +1 -1
  151. package/dist/transport/outbound.d.ts +9 -9
  152. package/dist/transport/outbound.d.ts.map +1 -1
  153. package/dist/transport/outbound.js +7 -7
  154. package/dist/transport/outbound.js.map +1 -1
  155. package/dist/transport/reply-limiter.d.ts +31 -0
  156. package/dist/transport/reply-limiter.d.ts.map +1 -0
  157. package/dist/transport/reply-limiter.js +50 -0
  158. package/dist/transport/reply-limiter.js.map +1 -0
  159. package/dist/transport/reply-target.d.ts +29 -0
  160. package/dist/transport/reply-target.d.ts.map +1 -0
  161. package/dist/transport/reply-target.js +55 -0
  162. package/dist/transport/reply-target.js.map +1 -0
  163. package/dist/transport/streaming-writer.d.ts +3 -3
  164. package/dist/transport/streaming-writer.d.ts.map +1 -1
  165. package/dist/transport/streaming-writer.js +1 -1
  166. package/dist/transport/streaming-writer.js.map +1 -1
  167. package/dist/transport/tool-presenter.d.ts +0 -1
  168. package/dist/transport/tool-presenter.d.ts.map +1 -1
  169. package/dist/transport/tool-presenter.js +0 -1
  170. package/dist/transport/tool-presenter.js.map +1 -1
  171. package/dist/types.d.ts +9 -15
  172. package/dist/types.d.ts.map +1 -1
  173. package/docs/assets/qrcode.png +0 -0
  174. package/package.json +17 -1
  175. package/a.txt +0 -14
  176. package/tiezi.md +0 -34
@@ -1,7 +1,6 @@
1
1
  /**
2
- * 模型命令:/bot-model — 查看或切换模型
2
+ * 模型命令:/model — 查看或切换模型
3
3
  */
4
- import type { SlashCommand } from '@tencent-connect/qqbot-nodejs';
5
- import type { CommandDeps } from './types.js';
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,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,WAAW,GAAG,YAAY,CAgE3E"}
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"}
@@ -1,15 +1,16 @@
1
- import { getScopePeer, sendMarkdownChunked } from '../shared/index.js';
1
+ import { getScopePeer, sendMarkdownChunked } from "../shared/index.js";
2
2
  export function modelCommand({ manager, config }) {
3
3
  return {
4
- name: 'bot-model',
5
- description: '查看或切换模型(用法: /bot-model [provider/model])',
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="/bot-model ${modelPath}" show="/bot-model ${displayName}"/>`);
30
+ lines.push(`<qqbot-cmd-input text="/model ${modelPath}" show="/model ${displayName}"/>`);
30
31
  }
31
32
  }
32
- lines.push('', '手动指定: `/bot-model provider/model`');
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 '用法: /bot-model provider/model\n示例: /bot-model deepseek-official/deepseek-v4-flash';
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":"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"}
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
- * 会话相关命令:/bot-reset /bot-clear /bot-new
2
+ * 会话相关命令
3
+ *
4
+ * - /new(别名 /reset /clear):开始新会话(换新 sessionId)
5
+ * - /compact:原地压缩会话历史(保留 sessionId,摘要替换旧历史)
6
+ *
7
+ * 两者都对应底层 dsh agent 能力,分类为 agent(通用能力)。
3
8
  */
4
- import type { SlashCommand } from '@tencent-connect/qqbot-nodejs';
5
- import type { CommandDeps } from './types.js';
6
- /** /bot-reset /bot-clear — 重置当前会话 */
7
- export declare function resetCommand({ manager }: CommandDeps): SlashCommand;
8
- /** /bot-new — 开始新会话 */
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;;GAEG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,qCAAqC;AACrC,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,EAAE,WAAW,GAAG,YAAY,CAUnE;AAED,uBAAuB;AACvB,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE,WAAW,GAAG,YAAY,CAUjE"}
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"}
@@ -1,25 +1,41 @@
1
- import { getScopePeer } from '../shared/index.js';
2
- /** /bot-reset /bot-clear — 重置当前会话 */
3
- export function resetCommand({ manager }) {
1
+ import { getScopePeer } from "../shared/index.js";
2
+ /** /new(别名 /reset /clear)— 开始新会话 */
3
+ export function newCommand({ manager }) {
4
4
  return {
5
- name: ['bot-reset', 'bot-clear'],
6
- description: '重置当前会话(清除上下文)',
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
- /** /bot-new — 开始新会话 */
15
- export function newCommand({ manager }) {
15
+ /** /compact — 原地压缩会话历史 */
16
+ export function compactCommand({ manager }) {
16
17
  return {
17
- name: 'bot-new',
18
- description: '开始新会话(清空上下文)',
19
- handler: (cmdCtx) => {
18
+ name: 'compact',
19
+ category: 'agent',
20
+ description: '压缩会话历史(摘要替换旧记录,保留上下文)',
21
+ handler: async (cmdCtx) => {
20
22
  const { scope, peerId } = getScopePeer(cmdCtx);
21
- void manager.remove(scope, peerId);
22
- return '已开启新会话 ✓';
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":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,qCAAqC;AACrC,MAAM,UAAU,YAAY,CAAC,EAAE,OAAO,EAAe;IACnD,OAAO;QACL,IAAI,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC;QAChC,WAAW,EAAE,eAAe;QAC5B,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,SAAS,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,EAAe;IACjD,OAAO;QACL,IAAI,EAAE,SAAS;QACf,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"}
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 { SlashCommand } from '@tencent-connect/qqbot-nodejs';
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): SlashCommand;
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,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,6BAA6B;AAC7B,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,EAAE,WAAW,GAAG,YAAY,CAmBpE"}
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"}
@@ -1,8 +1,9 @@
1
- import { getScopePeer, formatRelativeTime } from '../shared/index.js';
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":"AAKA,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,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"}
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"}
@@ -3,10 +3,17 @@
3
3
  *
4
4
  * 每个命令工厂函数接收 CommandDeps,由 commands/index.ts 统一注入。
5
5
  */
6
- import type { SessionManager } from '../session/index.js';
7
- import type { ImQQBotConfig } from '../config.js';
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
@@ -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;CAChB;AAED,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,aAAa,CA6B7C,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(120000).description('处理超时(ms)'),
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
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
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"}