mioku-plugin-chat 2.5.2 → 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.
@@ -0,0 +1,5 @@
1
+ import type { ChatGroupsFile } from "../types";
2
+
3
+ export const DEFAULT_GROUPS_CONFIG: ChatGroupsFile = {
4
+ groups: {},
5
+ };
@@ -119,7 +119,7 @@ export const PERSONALIZATION_CONFIG: {
119
119
  emoji: {
120
120
  enabled: true,
121
121
  characters: [],
122
- useAISelection: true,
122
+ stickers: [],
123
123
  },
124
124
 
125
125
  expression: {
package/context.ts CHANGED
@@ -2,7 +2,7 @@ import type { MiokiContext } from "mioki";
2
2
  import type { AIInstance, AIService } from "mioku";
3
3
  import type { ChatConfig } from "./types";
4
4
  import type { ChatDatabase } from "./db";
5
- import type { HumanizeEngine } from "./humanize";
5
+ import type { HumanizeEngine, ChatConfigProvider } from "./humanize";
6
6
  import type { SessionManager } from "./manage/session";
7
7
  import type { SkillSessionManager } from "./manage/skill-session";
8
8
  import type { RateLimiter } from "./manage/rate-limiter";
@@ -11,6 +11,7 @@ import type { GroupStructuredHistoryManager } from "./manage/group-structured-hi
11
11
  import type { CooldownManager } from "./manage/cooldown";
12
12
  import type { IdleCheckManager } from "./manage/idle-check";
13
13
  import type { QueueProcessor } from "./manage/queue-processor";
14
+ import type { SessionTurnScheduler } from "./manage/session-turn-scheduler";
14
15
  import type {
15
16
  RunRateLimitGuard,
16
17
  GetGroupHistoryMessages,
@@ -39,7 +40,9 @@ import type { ChatMessage } from "./types";
39
40
  export interface ChatPluginContext {
40
41
  // Core context
41
42
  ctx: MiokiContext;
42
- config: ChatConfig;
43
+ defaultConfig: ChatConfig;
44
+ configProvider: ChatConfigProvider;
45
+ getConfig: (groupId?: number) => Promise<ChatConfig>;
43
46
  db: ChatDatabase;
44
47
  aiInstance: AIInstance;
45
48
  workAIInstance: AIInstance;
@@ -56,6 +59,7 @@ export interface ChatPluginContext {
56
59
  cooldownManager: CooldownManager;
57
60
  idleCheckManager: IdleCheckManager;
58
61
  queueProcessor: QueueProcessor;
62
+ sessionTurnScheduler: SessionTurnScheduler;
59
63
 
60
64
  // Utility
61
65
  runWithRateLimitGuard: RunRateLimitGuard;
@@ -98,7 +102,7 @@ export interface ChatRuntimeState {
98
102
  * Closure state shared with the extracted message/poke handlers.
99
103
  */
100
104
  export interface ChatHandlerState {
101
- getConfig: () => Promise<ChatConfig>;
105
+ getConfig: (groupId?: number) => Promise<ChatConfig>;
102
106
  matchMessageCommands?: (
103
107
  text: string,
104
108
  ) => Array<{ plugin: string; command: string }>;
package/core/base.ts CHANGED
@@ -518,7 +518,7 @@ function expandOutgoingLines(text: string): string[] {
518
518
 
519
519
  function normalizeActionLineBreaks(text: string): string {
520
520
  return String(text || "").replace(
521
- /\\\s*(?=(?:\[meme:[^\]]+\]|\[emotion:[^\]]+\]|\[audio:[^\]]+\]|\[reply:-?\d+\]))/gi,
521
+ /\\\s*(?=(?:\[\]|\[emotion:[^\]]+\]|\[audio:[^\]]+\]|\[reply:-?\d+\]))/gi,
522
522
  "\n",
523
523
  );
524
524
  }
@@ -180,8 +180,7 @@ export async function runChat(
180
180
  segment: string,
181
181
  unitIndex: number,
182
182
  ): Promise<void> => {
183
- const text = cleanMarkers(segment)
184
- .replace(/\[meme:[^\]]+\]/gi, "")
183
+ const text = removeStickerIntentLines(cleanMarkers(segment))
185
184
  .replace(/\[emotion:[^\]]+\]/gi, "")
186
185
  .replace(/\r/g, "")
187
186
  .trim();
@@ -348,13 +347,18 @@ export async function runChat(
348
347
  let emojiPath: string | null = null;
349
348
  let finalText = cleanedText;
350
349
  if (cleanedText.trim()) {
351
- const memeResult = await humanize.emojiAgent.processMemeResponse(
350
+ const stickerResult = await humanize.emojiAgent.processStickerResponse(
352
351
  cleanedText,
353
- toolCtx.sessionId,
352
+ {
353
+ sessionId: toolCtx.sessionId,
354
+ botNickname: promptCtx.botNickname,
355
+ chatHistory: history,
356
+ targetMessage,
357
+ },
354
358
  );
355
- if (memeResult.success && memeResult.emojiPath) {
356
- emojiPath = memeResult.emojiPath;
357
- finalText = memeResult.cleanedText || cleanedText;
359
+ finalText = stickerResult.cleanedText;
360
+ if (stickerResult.success && stickerResult.emojiPath) {
361
+ emojiPath = stickerResult.emojiPath;
358
362
  }
359
363
  }
360
364
 
@@ -723,6 +727,13 @@ function cleanMarkers(text: string): string {
723
727
  return cleaned;
724
728
  }
725
729
 
730
+ function removeStickerIntentLines(text: string): string {
731
+ return String(text || "")
732
+ .split(/\r?\n/)
733
+ .filter((line) => !/^\s*\[\]\s*$/.test(line))
734
+ .join("\n");
735
+ }
736
+
726
737
  function stripThinkBlocks(text: string): string {
727
738
  let source = String(text || "");
728
739
  let output = "";
package/core/chat-turn.ts CHANGED
@@ -124,7 +124,7 @@ function resolveRuntimeContext(
124
124
  }
125
125
 
126
126
  // Shared send/save/cooldown tail for both live and runtime turns.
127
- async function finalizeTurn(
127
+ export async function finalizeChatTurn(
128
128
  pluginCtx: ChatPluginContext,
129
129
  args: {
130
130
  event: any;
@@ -190,11 +190,12 @@ export async function processChat(
190
190
  pluginCtx: ChatPluginContext,
191
191
  runtimeState: ChatRuntimeState,
192
192
  ): Promise<void> {
193
- const { ctx, config: cfg } = pluginCtx;
193
+ const { ctx } = pluginCtx;
194
194
  const isGroup = e.message_type === "group";
195
195
  const groupId: number | undefined = isGroup ? e.group_id : undefined;
196
196
  const userId: number = e.user_id || e.sender?.user_id;
197
197
  const selfId = e.self_id;
198
+ const cfg = await pluginCtx.getConfig(groupId);
198
199
 
199
200
  const personalSessionId = `personal:${userId}`;
200
201
  const groupSessionId = groupId ? `group:${groupId}` : personalSessionId;
@@ -357,7 +358,7 @@ export async function processChat(
357
358
  return;
358
359
  }
359
360
 
360
- await finalizeTurn(pluginCtx, {
361
+ await finalizeChatTurn(pluginCtx, {
361
362
  event: e,
362
363
  cfg,
363
364
  result,
@@ -375,15 +376,32 @@ export async function processChat(
375
376
  }
376
377
  }
377
378
 
378
- // Runtime turn — triggered by ChatRuntime.generateNotice / requestInformation.
379
- export async function executeChatRuntimeRequest(
380
- options: ExecuteChatRuntimeRequestOptions,
381
- pluginCtx: ChatPluginContext,
382
- ): Promise<{
379
+ type ChatRuntimeExecutionResult = {
383
380
  messages: string[];
384
381
  toolCalls: Array<{ name: string; arguments: any; result: any }>;
385
382
  collectedInfo: null;
386
- }> {
383
+ };
384
+
385
+ export async function executeChatRuntimeRequest(
386
+ options: ExecuteChatRuntimeRequestOptions,
387
+ pluginCtx: ChatPluginContext,
388
+ ): Promise<ChatRuntimeExecutionResult> {
389
+ const runtimeCtx = resolveRuntimeContext(pluginCtx.ctx, options);
390
+ if (!runtimeCtx.isGroup) {
391
+ return executeChatRuntimeRequestNow(options, pluginCtx);
392
+ }
393
+ return pluginCtx.sessionTurnScheduler.run(
394
+ runtimeCtx.sessionId,
395
+ "chat-runtime",
396
+ () => executeChatRuntimeRequestNow(options, pluginCtx),
397
+ );
398
+ }
399
+
400
+ // Runtime turn — triggered by ChatRuntime.generateNotice / requestInformation.
401
+ async function executeChatRuntimeRequestNow(
402
+ options: ExecuteChatRuntimeRequestOptions,
403
+ pluginCtx: ChatPluginContext,
404
+ ): Promise<ChatRuntimeExecutionResult> {
387
405
  const cfg = options.config;
388
406
  const runtimeCtx = resolveRuntimeContext(pluginCtx.ctx, options);
389
407
  const {
@@ -515,7 +533,7 @@ export async function executeChatRuntimeRequest(
515
533
  { extraTools: options.extraTools },
516
534
  );
517
535
 
518
- await finalizeTurn(pluginCtx, {
536
+ await finalizeChatTurn(pluginCtx, {
519
537
  event,
520
538
  cfg,
521
539
  result,