mioku-plugin-chat 2.6.0 → 2.7.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/types.ts CHANGED
@@ -65,10 +65,8 @@ export interface PlannerConfig {
65
65
  */
66
66
  export interface EmojiConfig {
67
67
  enabled: boolean;
68
- // 允许的表情包角色
69
68
  characters: string[];
70
- // 使用AI选择表情包发送
71
- useAISelection: boolean;
69
+ stickers: string[];
72
70
  }
73
71
 
74
72
  /**
@@ -376,18 +374,6 @@ export interface ExpressionRecord {
376
374
  createdAt: number;
377
375
  }
378
376
 
379
- /**
380
- * 表情包注册记录
381
- */
382
- export interface EmojiRecord {
383
- id?: number;
384
- fileName: string;
385
- description: string; // AI 生成的描述
386
- emotion: string; // 情感标签
387
- usageCount: number;
388
- createdAt: number;
389
- }
390
-
391
377
  /**
392
378
  * 图片记录
393
379
  */
@@ -395,11 +381,8 @@ export interface ImageRecord {
395
381
  id?: number;
396
382
  hash: string; // 图片哈希
397
383
  url: string; // 原始 URL
398
- type: "meme" | "image"; // 图片类型
384
+ type: "image";
399
385
  description: string; // AI 生成的简要描述
400
- emotion?: string; // 情感标签(仅表情包)
401
- character?: string; // 角色名称(仅表情包)
402
- filePath?: string; // 本地文件路径(仅表情包)
403
386
  createdAt: number;
404
387
  }
405
388
 
@@ -0,0 +1,57 @@
1
+ function isConfigObject(value: unknown): value is Record<string, any> {
2
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3
+ }
4
+
5
+ export function mergeChatConfig<T extends Record<string, any>>(
6
+ defaults: T,
7
+ overrides: Record<string, any>,
8
+ ): T {
9
+ const result: Record<string, any> = {};
10
+
11
+ for (const [key, value] of Object.entries(defaults)) {
12
+ if (isConfigObject(value)) {
13
+ result[key] = mergeChatConfig(value, {});
14
+ } else if (Array.isArray(value)) {
15
+ result[key] = [...value];
16
+ } else {
17
+ result[key] = value;
18
+ }
19
+ }
20
+
21
+ for (const [key, value] of Object.entries(overrides)) {
22
+ if (value === undefined || value === null) continue;
23
+ if (isConfigObject(value)) {
24
+ const baseValue = isConfigObject(result[key]) ? result[key] : {};
25
+ result[key] = mergeChatConfig(baseValue, value);
26
+ } else if (Array.isArray(value)) {
27
+ result[key] = [...value];
28
+ } else {
29
+ result[key] = value;
30
+ }
31
+ }
32
+
33
+ return result as T;
34
+ }
35
+
36
+ export function normalizeIdList(input: unknown): number[] {
37
+ if (!Array.isArray(input)) return [];
38
+ return Array.from(
39
+ new Set(
40
+ input
41
+ .map((item) => Math.floor(Number(item)))
42
+ .filter((id) => Number.isFinite(id) && id > 0),
43
+ ),
44
+ );
45
+ }
46
+
47
+ export function normalizeMediaAnalysisBlacklist(
48
+ config: Record<string, any>,
49
+ ): number[] {
50
+ const current = config.mediaAnalysisBlacklistUsers;
51
+ const legacy = config.imageAnalysisBlacklistUsers;
52
+ const source =
53
+ legacy !== undefined && Array.isArray(current) && current.length === 0
54
+ ? legacy
55
+ : (current ?? legacy);
56
+ return normalizeIdList(source);
57
+ }
package/utils/message.ts CHANGED
@@ -308,12 +308,12 @@ async function getImageTagWithHashCache(
308
308
  ctx: HistoryFormatContext,
309
309
  ): Promise<string> {
310
310
  const exact = db.getImageByUrl?.(imageUrl);
311
- if (exact) return `[${exact.type}:${exact.description}]`;
311
+ if (exact) return `[image:${exact.description}]`;
312
312
 
313
313
  const normalized = normalizeImageUrl(imageUrl);
314
314
  if (normalized && normalized !== imageUrl) {
315
315
  const hit = db.getImageByUrl?.(normalized);
316
- if (hit) return `[${hit.type}:${hit.description}]`;
316
+ if (hit) return `[image:${hit.description}]`;
317
317
  }
318
318
 
319
319
  let hash = ctx.hashLookupCache.get(`hash:${imageUrl}`);
@@ -329,17 +329,14 @@ async function getImageTagWithHashCache(
329
329
  db.saveImage?.({
330
330
  hash: byHash.hash,
331
331
  url: normalized || imageUrl,
332
- type: byHash.type,
332
+ type: "image",
333
333
  description: byHash.description,
334
- emotion: byHash.emotion,
335
- character: byHash.character,
336
- filePath: byHash.filePath,
337
334
  createdAt: byHash.createdAt,
338
335
  });
339
336
  } catch {
340
337
  // best-effort URL caching for next call
341
338
  }
342
- return `[${byHash.type}:${byHash.description}]`;
339
+ return `[image:${byHash.description}]`;
343
340
  }
344
341
 
345
342
  return "[image]";
package/utils/queue.ts CHANGED
@@ -88,6 +88,11 @@ export class MessageQueueManager {
88
88
  const queue = this.pendingMessages.get(groupSessionId);
89
89
  return !!queue && queue.length > 0;
90
90
  }
91
+
92
+ dispose(): void {
93
+ this.pendingMessages.clear();
94
+ this.activeTargetMessages.clear();
95
+ }
91
96
  }
92
97
 
93
98
  /**