mioku-plugin-chat 2.10.0 → 3.0.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/configs/base.ts +1 -1
- package/context.ts +2 -2
- package/core/base.ts +57 -62
- package/core/chat-engine.ts +10 -27
- package/core/chat-turn.ts +9 -9
- package/core/media/audio.ts +4 -4
- package/core/media/gif-extractor.ts +4 -4
- package/core/media/history-media.ts +9 -14
- package/core/media/image-analyzer.ts +1 -1
- package/core/media/image-compress.ts +1 -1
- package/core/media/segment.ts +10 -14
- package/core/multimodal.ts +15 -10
- package/core/prompt.ts +3 -3
- package/core/tools/info.ts +8 -7
- package/core/tools/web.ts +86 -56
- package/core/tools.ts +1 -1
- package/core/web/searxng.ts +1 -1
- package/core/web/web-reader.ts +2 -2
- package/handlers/idle-debug.ts +3 -3
- package/handlers/message.ts +44 -29
- package/handlers/poke.ts +22 -16
- package/humanize/emoji-agent.ts +1 -1
- package/humanize/emotion-agent.ts +1 -1
- package/humanize/expression.ts +1 -1
- package/humanize/memory.ts +1 -1
- package/humanize/planner.ts +1 -1
- package/humanize/topic.ts +1 -1
- package/index.ts +3 -3
- package/manage/cleanup.ts +1 -1
- package/manage/cooldown.ts +4 -4
- package/manage/idle-check.ts +4 -4
- package/manage/queue-processor.ts +4 -4
- package/manage/types.ts +37 -14
- package/package.json +3 -5
- package/types.ts +2 -2
- package/utils/message.ts +92 -60
package/handlers/poke.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ChatPluginContext, ChatHandlerState } from "../context";
|
|
2
2
|
import type { TargetMessage } from "../types";
|
|
3
|
-
import type {
|
|
3
|
+
import type { Bot, NoticeEvent } from "mioku";
|
|
4
|
+
|
|
4
5
|
import { getBotRole, isGroupAllowed } from "../utils";
|
|
5
6
|
import { buildStructuredUserInputFromTarget } from "../manage/group-structured-history";
|
|
6
7
|
import { finalizeChatTurn } from "../core/chat-turn";
|
|
@@ -13,9 +14,13 @@ export function createPokeHandler(
|
|
|
13
14
|
const { ctx } = pluginCtx;
|
|
14
15
|
const { getConfig, runtimeState, pokeCooldowns } = state;
|
|
15
16
|
|
|
16
|
-
return async (e:
|
|
17
|
-
|
|
18
|
-
const
|
|
17
|
+
return async (e: NoticeEvent) => {
|
|
18
|
+
const selfId = Number(e.self_id || 0);
|
|
19
|
+
const targetId = Number(
|
|
20
|
+
(e.raw as { target_id?: string } | undefined)?.target_id ?? 0,
|
|
21
|
+
);
|
|
22
|
+
if (targetId !== selfId) return;
|
|
23
|
+
const groupId = Number(e.group_id || 0);
|
|
19
24
|
const cfg = groupId ? await getConfig(groupId) : await getConfig();
|
|
20
25
|
if (!cfg.model && !cfg.apiKey) return;
|
|
21
26
|
if (!groupId || !isGroupAllowed(groupId, cfg)) return;
|
|
@@ -37,19 +42,20 @@ export function createPokeHandler(
|
|
|
37
42
|
"group",
|
|
38
43
|
groupId,
|
|
39
44
|
);
|
|
40
|
-
const userId = e.user_id;
|
|
41
|
-
const botRole = await getBotRole(groupId, ctx,
|
|
45
|
+
const userId = Number(e.user_id || 0);
|
|
46
|
+
const botRole = await getBotRole(groupId, ctx, selfId);
|
|
42
47
|
const botNickname =
|
|
43
|
-
cfg.nicknames[0] ||
|
|
48
|
+
cfg.nicknames[0] || e.bot?.nickname || "Bot";
|
|
44
49
|
|
|
45
50
|
let senderName = String(userId);
|
|
46
51
|
try {
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
.
|
|
52
|
+
const bot: Bot | undefined = e.bot;
|
|
53
|
+
const memberInfo = bot
|
|
54
|
+
? await bot.getMemberInfo(groupId, userId)
|
|
55
|
+
: undefined;
|
|
50
56
|
senderName =
|
|
51
|
-
|
|
52
|
-
|
|
57
|
+
memberInfo?.card ||
|
|
58
|
+
memberInfo?.nickname ||
|
|
53
59
|
String(userId);
|
|
54
60
|
} catch {}
|
|
55
61
|
|
|
@@ -67,11 +73,11 @@ export function createPokeHandler(
|
|
|
67
73
|
ctx,
|
|
68
74
|
cfg.historyCount,
|
|
69
75
|
pluginCtx.db,
|
|
70
|
-
|
|
76
|
+
selfId,
|
|
71
77
|
pluginCtx.buildHistoryMediaOptions(pluginCtx.aiInstance, cfg),
|
|
72
78
|
);
|
|
73
79
|
const { groupName, memberCount } =
|
|
74
|
-
await pluginCtx.getGroupInfoData(ctx, groupId,
|
|
80
|
+
await pluginCtx.getGroupInfoData(ctx, groupId, selfId);
|
|
75
81
|
|
|
76
82
|
const toolCtx = pluginCtx.buildToolContext({
|
|
77
83
|
ctx,
|
|
@@ -85,7 +91,7 @@ export function createPokeHandler(
|
|
|
85
91
|
botRole,
|
|
86
92
|
humanize: pluginCtx.humanize,
|
|
87
93
|
targetMessage,
|
|
88
|
-
selfId
|
|
94
|
+
selfId,
|
|
89
95
|
audioService: pluginCtx.audioService,
|
|
90
96
|
});
|
|
91
97
|
|
|
@@ -131,7 +137,7 @@ export function createPokeHandler(
|
|
|
131
137
|
groupId,
|
|
132
138
|
groupSessionId,
|
|
133
139
|
userId,
|
|
134
|
-
selfId
|
|
140
|
+
selfId,
|
|
135
141
|
toolCtx,
|
|
136
142
|
send: true,
|
|
137
143
|
isLive: true,
|
package/humanize/emoji-agent.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { existsSync, readdirSync } from "fs";
|
|
|
2
2
|
import * as fs from "fs/promises";
|
|
3
3
|
import * as path from "path";
|
|
4
4
|
import { getPluginDataDir, type AIInstance } from "mioku";
|
|
5
|
-
import { logger } from "
|
|
5
|
+
import { logger } from "mioku";
|
|
6
6
|
import type { ChatConfig, ChatMessage, TargetMessage } from "../types";
|
|
7
7
|
import { extractGroupIdFromSession } from "../utils/group-config";
|
|
8
8
|
import { extractJsonObject } from "../utils/json";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AIInstance } from "mioku";
|
|
2
|
-
import { logger } from "
|
|
2
|
+
import { logger } from "mioku";
|
|
3
3
|
import { extractJsonObject } from "../utils/json";
|
|
4
4
|
import type { ChatConfig, ChatMessage, TargetMessage } from "../types";
|
|
5
5
|
import { extractGroupIdFromSession } from "../utils/group-config";
|
package/humanize/expression.ts
CHANGED
package/humanize/memory.ts
CHANGED
package/humanize/planner.ts
CHANGED
package/humanize/topic.ts
CHANGED
package/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { definePlugin, type
|
|
1
|
+
import { definePlugin, type MiokuContext } from "mioku";
|
|
2
2
|
import type { AIInstance, AIModelRole, AIService } from "mioku";
|
|
3
3
|
import type { AudioServiceApi } from "mioku-service-audio";
|
|
4
4
|
import { getPluginRuntimeState, getService, Services } from "mioku";
|
|
@@ -117,7 +117,7 @@ export default definePlugin({
|
|
|
117
117
|
name: "chat",
|
|
118
118
|
version: "1.1.0",
|
|
119
119
|
description: "AI 智能聊天插件",
|
|
120
|
-
async setup(ctx:
|
|
120
|
+
async setup(ctx: MiokuContext) {
|
|
121
121
|
ctx.logger.info("聊天插件正在初始化...");
|
|
122
122
|
|
|
123
123
|
const aiService = getService(ctx, Services.AI);
|
|
@@ -497,7 +497,7 @@ roleModels = resolved.models;
|
|
|
497
497
|
processingSet,
|
|
498
498
|
},
|
|
499
499
|
matchMessageCommands: (
|
|
500
|
-
getPluginRuntimeState("
|
|
500
|
+
getPluginRuntimeState("core") as
|
|
501
501
|
| {
|
|
502
502
|
matchMessageCommands?: (
|
|
503
503
|
text: string,
|
package/manage/cleanup.ts
CHANGED
package/manage/cooldown.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MiokuContext } from "mioku";
|
|
2
2
|
import type { AIInstance } from "mioku";
|
|
3
3
|
import type { ChatConfig, TargetMessage } from "../types";
|
|
4
4
|
import type { ChatDatabase } from "../db";
|
|
@@ -39,7 +39,7 @@ export class CooldownManager {
|
|
|
39
39
|
private pluginCtx: ChatPluginContext;
|
|
40
40
|
private sessionTurnScheduler: SessionTurnScheduler;
|
|
41
41
|
|
|
42
|
-
private ctx:
|
|
42
|
+
private ctx: MiokuContext;
|
|
43
43
|
private configProvider: ChatConfigProvider;
|
|
44
44
|
private defaultConfig: ChatConfig;
|
|
45
45
|
private db: ChatDatabase;
|
|
@@ -206,7 +206,7 @@ export class CooldownManager {
|
|
|
206
206
|
this.buildHistoryMediaOptions(this.aiInstance, cfg),
|
|
207
207
|
);
|
|
208
208
|
const botNickname =
|
|
209
|
-
cfg.nicknames[0] || this.ctx.pickBot(selfId)
|
|
209
|
+
cfg.nicknames[0] || this.ctx.pickBot(selfId)?.nickname || "Bot";
|
|
210
210
|
const botRole = await getBotRole(groupId, this.ctx, selfId);
|
|
211
211
|
const { groupName, memberCount } = await this.getGroupInfoData(
|
|
212
212
|
this.ctx,
|
|
@@ -316,7 +316,7 @@ export class CooldownManager {
|
|
|
316
316
|
this.buildHistoryMediaOptions(this.aiInstance, cfg),
|
|
317
317
|
);
|
|
318
318
|
const botNickname =
|
|
319
|
-
cfg.nicknames[0] || this.ctx.pickBot(selfId)
|
|
319
|
+
cfg.nicknames[0] || this.ctx.pickBot(selfId)?.nickname || "Bot";
|
|
320
320
|
|
|
321
321
|
const planResult = await this.humanize.actionPlanner.plan(
|
|
322
322
|
groupSessionId,
|
package/manage/idle-check.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MiokuContext } from "mioku";
|
|
2
2
|
import type { AIInstance } from "mioku";
|
|
3
3
|
import type { ChatConfig, TargetMessage } from "../types";
|
|
4
4
|
import type { ChatDatabase } from "../db";
|
|
@@ -28,7 +28,7 @@ export class IdleCheckManager {
|
|
|
28
28
|
private groupBotsMapping = new Map<string, Set<number>>();
|
|
29
29
|
private intervalHandle: NodeJS.Timeout | null = null;
|
|
30
30
|
|
|
31
|
-
private ctx:
|
|
31
|
+
private ctx: MiokuContext;
|
|
32
32
|
private configProvider: ChatConfigProvider;
|
|
33
33
|
private defaultConfig: ChatConfig;
|
|
34
34
|
private db: ChatDatabase;
|
|
@@ -106,7 +106,7 @@ export class IdleCheckManager {
|
|
|
106
106
|
|
|
107
107
|
const now = Date.now();
|
|
108
108
|
const checkInterval = 60_000;
|
|
109
|
-
const allBotIds = Array.from(this.ctx.bots).map((bot) => bot.
|
|
109
|
+
const allBotIds = Array.from(this.ctx.bots).map((bot) => Number(bot.bot_id));
|
|
110
110
|
|
|
111
111
|
for (const [groupSessionId, lastTime] of this.groupLastActivityTime) {
|
|
112
112
|
const lastCheckTime =
|
|
@@ -216,7 +216,7 @@ export class IdleCheckManager {
|
|
|
216
216
|
this.buildHistoryMediaOptions(this.aiInstance, cfg),
|
|
217
217
|
);
|
|
218
218
|
const botNickname =
|
|
219
|
-
cfg.nicknames[0] || this.ctx.pickBot(selfId)
|
|
219
|
+
cfg.nicknames[0] || this.ctx.pickBot(selfId)?.nickname || "Bot";
|
|
220
220
|
const planResult = await this.humanize.actionPlanner.plan(
|
|
221
221
|
groupSessionId,
|
|
222
222
|
botNickname,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MiokuContext } from "mioku";
|
|
2
2
|
import type { AIInstance } from "mioku";
|
|
3
3
|
import type { ChatConfig, TargetMessage } from "../types";
|
|
4
4
|
import type { ChatDatabase } from "../db";
|
|
@@ -34,7 +34,7 @@ export class QueueProcessor {
|
|
|
34
34
|
private dynamicDelayQueues = new Map<string, DynamicDelayQueueData>();
|
|
35
35
|
private pluginCtx: ChatPluginContext;
|
|
36
36
|
|
|
37
|
-
private ctx:
|
|
37
|
+
private ctx: MiokuContext;
|
|
38
38
|
private configProvider: ChatConfigProvider;
|
|
39
39
|
private defaultConfig: ChatConfig;
|
|
40
40
|
private db: ChatDatabase;
|
|
@@ -177,7 +177,7 @@ export class QueueProcessor {
|
|
|
177
177
|
|
|
178
178
|
const cfg = this.configProvider(groupId);
|
|
179
179
|
const botRole = await getBotRole(groupId, this.ctx, selfId);
|
|
180
|
-
const botNickname = cfg.nicknames[0] || this.ctx.pickBot(selfId)
|
|
180
|
+
const botNickname = cfg.nicknames[0] || this.ctx.pickBot(selfId)?.nickname || "Bot";
|
|
181
181
|
const { groupName, memberCount } = await this.getGroupInfoData(this.ctx, groupId, selfId, String(groupId));
|
|
182
182
|
const { history } = await this.getGroupHistoryMessages(groupId, groupSessionId, this.ctx, cfg.historyCount, this.db, selfId, this.buildHistoryMediaOptions(this.aiInstance, cfg));
|
|
183
183
|
|
|
@@ -261,7 +261,7 @@ export class QueueProcessor {
|
|
|
261
261
|
};
|
|
262
262
|
|
|
263
263
|
const botRole = await getBotRole(groupId, this.ctx, selfId);
|
|
264
|
-
const botNickname = cfg.nicknames[0] || this.ctx.pickBot(selfId)
|
|
264
|
+
const botNickname = cfg.nicknames[0] || this.ctx.pickBot(selfId)?.nickname || "Bot";
|
|
265
265
|
const toolCtx = this.buildToolContext({
|
|
266
266
|
ctx: this.ctx, event: null, groupSessionId, groupId, userId: targetMessage.userId,
|
|
267
267
|
config: cfg, aiService: this.aiService, db: this.db, botRole, humanize: this.humanize, targetMessage, selfId,
|
package/manage/types.ts
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Bot, MiokuContext } from "mioku";
|
|
2
2
|
import type { AIInstance, AIService } from "mioku";
|
|
3
3
|
import type { SkillPermissionRole } from "mioku";
|
|
4
4
|
import type { ChatRuntimePromptInjection } from "mioku";
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
ChatConfig,
|
|
7
|
+
ChatMessage,
|
|
8
|
+
TargetMessage,
|
|
9
|
+
ToolContext,
|
|
10
|
+
ChatResult,
|
|
11
|
+
} from "../types";
|
|
6
12
|
import type { ChatDatabase } from "../db";
|
|
7
13
|
import type { HumanizeEngine } from "../humanize";
|
|
8
14
|
import type { EmojiAgent } from "../humanize";
|
|
9
15
|
import type { SkillSessionManager } from "./skill-session";
|
|
10
|
-
import type {
|
|
16
|
+
import type {
|
|
17
|
+
GroupStructuredHistoryManager,
|
|
18
|
+
StructuredUserInput,
|
|
19
|
+
} from "./group-structured-history";
|
|
11
20
|
import type { SendAIResponseOptions } from "../core/base";
|
|
12
21
|
import type { GroupInfoResult, HumanizeContextsResult } from "../core/base";
|
|
13
22
|
|
|
@@ -32,7 +41,7 @@ export type RunRateLimitGuard = <T>(
|
|
|
32
41
|
export type GetGroupHistoryMessages = (
|
|
33
42
|
groupId: number,
|
|
34
43
|
groupSessionId: string,
|
|
35
|
-
ctx:
|
|
44
|
+
ctx: MiokuContext,
|
|
36
45
|
historyCount: number,
|
|
37
46
|
db: ChatDatabase,
|
|
38
47
|
selfId: number,
|
|
@@ -40,7 +49,7 @@ export type GetGroupHistoryMessages = (
|
|
|
40
49
|
) => Promise<{ history: ChatMessage[] }>;
|
|
41
50
|
|
|
42
51
|
export type GetGroupInfoData = (
|
|
43
|
-
ctx:
|
|
52
|
+
ctx: MiokuContext,
|
|
44
53
|
groupId: number,
|
|
45
54
|
selfId: number,
|
|
46
55
|
fallbackGroupName?: string,
|
|
@@ -54,7 +63,10 @@ export type GetHumanizeContexts = (
|
|
|
54
63
|
triggerUserId?: number,
|
|
55
64
|
) => Promise<HumanizeContextsResult>;
|
|
56
65
|
|
|
57
|
-
export type SendAIResponse = (
|
|
66
|
+
export type SendAIResponse = (
|
|
67
|
+
options: SendAIResponseOptions,
|
|
68
|
+
selfId: number,
|
|
69
|
+
) => Promise<void>;
|
|
58
70
|
|
|
59
71
|
export type SaveBotMessages = (
|
|
60
72
|
groupId: number,
|
|
@@ -63,14 +75,19 @@ export type SaveBotMessages = (
|
|
|
63
75
|
timestamp: number,
|
|
64
76
|
config: ChatConfig,
|
|
65
77
|
db: ChatDatabase,
|
|
66
|
-
ctx:
|
|
67
|
-
|
|
78
|
+
ctx: MiokuContext,
|
|
79
|
+
bot?: Bot,
|
|
68
80
|
) => void;
|
|
69
81
|
|
|
70
|
-
export type SendEmoji = (
|
|
82
|
+
export type SendEmoji = (
|
|
83
|
+
ctx: MiokuContext,
|
|
84
|
+
groupId: number,
|
|
85
|
+
emojiPath: string | null | undefined,
|
|
86
|
+
bot?: import("mioku").Bot,
|
|
87
|
+
) => Promise<void>;
|
|
71
88
|
|
|
72
89
|
export type SendMessage = (
|
|
73
|
-
ctx:
|
|
90
|
+
ctx: MiokuContext,
|
|
74
91
|
groupId: number | undefined,
|
|
75
92
|
userId: number,
|
|
76
93
|
text: string,
|
|
@@ -80,7 +97,7 @@ export type SendMessage = (
|
|
|
80
97
|
) => Promise<void>;
|
|
81
98
|
|
|
82
99
|
export type BuildToolContext = (options: {
|
|
83
|
-
ctx:
|
|
100
|
+
ctx: MiokuContext;
|
|
84
101
|
event: any;
|
|
85
102
|
selfId: number;
|
|
86
103
|
groupSessionId: string;
|
|
@@ -96,9 +113,15 @@ export type BuildToolContext = (options: {
|
|
|
96
113
|
audioService?: import("mioku-service-audio").AudioServiceApi;
|
|
97
114
|
}) => ToolContext;
|
|
98
115
|
|
|
99
|
-
export type BuildStructuredUserInput = (
|
|
116
|
+
export type BuildStructuredUserInput = (
|
|
117
|
+
event: any,
|
|
118
|
+
content: string,
|
|
119
|
+
fallbackTimestamp?: number,
|
|
120
|
+
) => StructuredUserInput;
|
|
100
121
|
|
|
101
|
-
export type BuildStructuredUserInputFromTarget = (
|
|
122
|
+
export type BuildStructuredUserInputFromTarget = (
|
|
123
|
+
targetMessage: TargetMessage,
|
|
124
|
+
) => StructuredUserInput;
|
|
102
125
|
|
|
103
126
|
export type PromptCtxForRunChat = {
|
|
104
127
|
config: ChatConfig;
|
|
@@ -143,4 +166,4 @@ export type RunChat = (
|
|
|
143
166
|
currentUserInputs: StructuredUserInput[];
|
|
144
167
|
},
|
|
145
168
|
runtimeOptions?: { extraTools?: any[] },
|
|
146
|
-
) => Promise<ChatResult>;
|
|
169
|
+
) => Promise<ChatResult>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mioku-plugin-chat",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "AI 智能聊天插件",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -54,12 +54,10 @@
|
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/bun": "^1.3.14",
|
|
57
|
-
"mioki": "^0.16.0",
|
|
58
57
|
"mioku": "workspace:*"
|
|
59
58
|
},
|
|
60
59
|
"peerDependencies": {
|
|
61
|
-
"mioku": "^0.
|
|
62
|
-
"mioku-service-audio": "workspace:*"
|
|
63
|
-
"mioki": "^0.16.0"
|
|
60
|
+
"mioku": "^1.0.0",
|
|
61
|
+
"mioku-service-audio": "workspace:*"
|
|
64
62
|
}
|
|
65
63
|
}
|
package/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ChatCompletionMessageParam } from "openai/resources/chat/completions";
|
|
2
|
-
import type {
|
|
2
|
+
import type { MiokuContext } from "mioku";
|
|
3
3
|
import type { AITool, AIService, SkillPermissionRole } from "mioku";
|
|
4
4
|
import type { ChatDatabase } from "./db";
|
|
5
5
|
|
|
@@ -300,7 +300,7 @@ export interface SkillSession {
|
|
|
300
300
|
* 工具上下文
|
|
301
301
|
*/
|
|
302
302
|
export interface ToolContext {
|
|
303
|
-
ctx:
|
|
303
|
+
ctx: MiokuContext;
|
|
304
304
|
event: any;
|
|
305
305
|
sessionId: string;
|
|
306
306
|
groupId?: number;
|