@zaofan/dsh-qqbot 1.10.11 → 1.10.12

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.
@@ -1 +1 @@
1
- {"version":3,"file":"channel-tools.d.ts","sourceRoot":"","sources":["../src/channel-tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channel-tools.d.ts","sourceRoot":"","sources":["../src/channel-tools.ts"],"names":[],"mappings":"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"}
@@ -8,8 +8,9 @@
8
8
  * 复制进共享 node_modules,也不得在 dependencies 里自带 dsh-tools(避免双包)。
9
9
  */
10
10
  import { defineTool } from '@deepseek-ai/dsh-tools';
11
- import { appendFileSync, existsSync, mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
11
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs';
12
12
  import { join, dirname } from 'node:path';
13
+ import { homedir } from 'node:os';
13
14
  import { getStickerStore } from './features/sticker-store.js';
14
15
  import { autoTagImage } from './features/sticker-tagger.js';
15
16
  import { isStickerGateDenied } from './features/sticker-gate.js';
@@ -2197,6 +2198,87 @@ export async function apply(ctx) {
2197
2198
  /**
2198
2199
  * 批量撤回 + 可选批量禁言(2026-10-20 主人需求)
2199
2200
  */
2201
+ /**
2202
+ * 自动撤回关键词管理(2026-10-20 主人要求:让 AI 自己维护"命中即撤/禁言"的关键词)。
2203
+ * 直接读写当前 profile 的 settings json,改完 live 生效(中间件读的是盘上兜底)。
2204
+ */
2205
+ const recallKeywordsTool = defineTool({
2206
+ name: 'recall_keywords',
2207
+ description: '自动撤回关键词管理(写): 查看/添加/删除「命中即撤回(可顺带禁言)」的关键词。全局规则(不分群)。' +
2208
+ '\naction: list(默认) / add(追加) / remove(删除) / set(整体替换) / clear(清空)' +
2209
+ '\nwords: 关键词, 多个用逗号/顿号/换行分隔' +
2210
+ '\nmuteSeconds/enable: 可选, 一起改「命中后禁言秒数」和「是否启用」;不传就不动' +
2211
+ '\n改完立刻生效(live),不需要重启。',
2212
+ parameters: {
2213
+ action: { type: 'string', description: 'list / add / remove / set / clear', enum: ['list', 'add', 'remove', 'set', 'clear'] },
2214
+ words: { type: 'string', description: '关键词(多个用逗号/顿号/换行分隔)' },
2215
+ muteSeconds: { type: 'integer', description: '可选: 命中后顺带禁言秒数(0=不禁言); 不传则不改' },
2216
+ enable: { type: 'boolean', description: '可选: 同时开启/关闭自动撤回; 不传则不改' },
2217
+ },
2218
+ output: {
2219
+ schema: {
2220
+ type: 'object',
2221
+ properties: { ok: { type: 'boolean' }, msg: { type: 'string' }, keywords: { type: 'array', items: { type: 'string' } } },
2222
+ additionalProperties: false,
2223
+ },
2224
+ render: (_a, v) => [{ type: 'text', text: v.ok ? String(v.msg || '') : `失败: ${String(v.msg || '')}` }],
2225
+ },
2226
+ execute: async (args) => {
2227
+ try {
2228
+ const prof = process.env.DSH_PROFILE || 'web';
2229
+ const base = join(homedir(), '.dsh', 'qqbot-settings', prof);
2230
+ let file = join(base, 'im-qqbot-2.json');
2231
+ if (!existsSync(file)) {
2232
+ const cands = existsSync(base) ? readdirSync(base).filter((f) => /^im-qqbot-.*\.json$/.test(f)) : [];
2233
+ if (cands.length === 0)
2234
+ return { ok: false, msg: '找不到设置文件: ' + base, keywords: [] };
2235
+ cands.sort((a, b) => statSync(join(base, b)).mtimeMs - statSync(join(base, a)).mtimeMs);
2236
+ file = join(base, String(cands[0]));
2237
+ }
2238
+ const raw = JSON.parse(readFileSync(file, 'utf8'));
2239
+ const ga = (raw.groupAdmin = (raw.groupAdmin || {}));
2240
+ const ar = (ga.autoRecall = Object.assign({ enabled: false, mode: 'keep', keywords: [], kinds: [], muteSeconds: 0, dryRun: false }, (ga.autoRecall || {})));
2241
+ let list = Array.isArray(ar.keywords) ? ar.keywords.map(String) : [];
2242
+ const action = String(args.action || 'list');
2243
+ const words = String(args.words || '').split(/[,,、\r\n]+/u).map((x) => x.trim()).filter(Boolean);
2244
+ if (action === 'add') {
2245
+ if (words.length === 0)
2246
+ return { ok: false, msg: 'add 需要 words', keywords: list };
2247
+ const set = new Set(list);
2248
+ for (const w of words)
2249
+ set.add(w);
2250
+ list = Array.from(set);
2251
+ }
2252
+ else if (action === 'remove') {
2253
+ if (words.length === 0)
2254
+ return { ok: false, msg: 'remove 需要 words', keywords: list };
2255
+ const rm = new Set(words);
2256
+ list = list.filter((w) => !rm.has(w));
2257
+ }
2258
+ else if (action === 'set') {
2259
+ list = words;
2260
+ }
2261
+ else if (action === 'clear') {
2262
+ list = [];
2263
+ }
2264
+ ar.keywords = list;
2265
+ if (typeof args.muteSeconds === 'number')
2266
+ ar.muteSeconds = Math.max(0, Math.round(args.muteSeconds));
2267
+ if (typeof args.enable === 'boolean')
2268
+ ar.enabled = args.enable;
2269
+ writeFileSync(file, JSON.stringify(raw, null, 2), 'utf8');
2270
+ const head = action === 'list' ? '当前关键词' : '已更新';
2271
+ return {
2272
+ ok: true,
2273
+ msg: head + '(' + list.length + ' 个, 启用=' + String(ar.enabled === true) + ', 禁言=' + String(ar.muteSeconds || 0) + 's): ' + (list.join(' / ') || '(空)'),
2274
+ keywords: list,
2275
+ };
2276
+ }
2277
+ catch (e) {
2278
+ return { ok: false, msg: '操作失败: ' + (e instanceof Error ? e.message : String(e)), keywords: [] };
2279
+ }
2280
+ },
2281
+ });
2200
2282
  const recallBatchTool = defineTool({
2201
2283
  name: 'group_recall_batch',
2202
2284
  description: '群管理(写,危险): 批量撤回消息 + 可选批量禁言发送者。'
@@ -2619,6 +2701,7 @@ export async function apply(ctx) {
2619
2701
  { name: 'group_recall', tool: groupRecallTool },
2620
2702
  { name: 'group_msg_search', tool: msgSearchTool },
2621
2703
  { name: 'group_recall_batch', tool: recallBatchTool },
2704
+ { name: 'recall_keywords', tool: recallKeywordsTool },
2622
2705
  { name: 'id_lookup', tool: idLookupTool },
2623
2706
  { name: 'session_list', tool: sessionListTool },
2624
2707
  { name: 'session_wake', tool: sessionWakeTool },