@elizaos/plugin-discord 1.2.5 → 1.3.1
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/dist/index.js +575 -582
- package/dist/index.js.map +1 -1
- package/package.json +22 -3
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
6
6
|
});
|
|
7
7
|
|
|
8
8
|
// src/index.ts
|
|
9
|
-
import { logger as
|
|
9
|
+
import { logger as logger15 } from "@elizaos/core";
|
|
10
10
|
|
|
11
11
|
// src/actions/chatWithAttachments.ts
|
|
12
12
|
import fs from "node:fs";
|
|
@@ -148,28 +148,20 @@ var chatWithAttachments = {
|
|
|
148
148
|
count: conversationLength,
|
|
149
149
|
unique: false
|
|
150
150
|
});
|
|
151
|
-
const attachments = recentMessages.filter(
|
|
152
|
-
(msg) => msg.content.attachments && msg.content.attachments.length > 0
|
|
153
|
-
).flatMap((msg) => msg.content.attachments).filter(
|
|
151
|
+
const attachments = recentMessages.filter((msg) => msg.content.attachments && msg.content.attachments.length > 0).flatMap((msg) => msg.content.attachments).filter(
|
|
154
152
|
(attachment) => attachment && (attachmentIds.map((attch) => attch.toLowerCase().slice(0, 5)).includes(attachment.id.toLowerCase().slice(0, 5)) || // or check the other way
|
|
155
153
|
attachmentIds.some((id) => {
|
|
156
154
|
const attachmentId = id.toLowerCase().slice(0, 5);
|
|
157
155
|
return attachment && attachment.id.toLowerCase().includes(attachmentId);
|
|
158
156
|
}))
|
|
159
157
|
);
|
|
160
|
-
const attachmentsWithText = attachments.filter(
|
|
161
|
-
(attachment) => !!attachment
|
|
162
|
-
).map((attachment) => `# ${attachment.title}
|
|
158
|
+
const attachmentsWithText = attachments.filter((attachment) => !!attachment).map((attachment) => `# ${attachment.title}
|
|
163
159
|
${attachment.text}`).join("\n\n");
|
|
164
160
|
let currentSummary = "";
|
|
165
161
|
const chunkSize = 8192;
|
|
166
162
|
state.values.attachmentsWithText = attachmentsWithText;
|
|
167
163
|
state.values.objective = objective;
|
|
168
|
-
const template = await trimTokens(
|
|
169
|
-
summarizationTemplate,
|
|
170
|
-
chunkSize,
|
|
171
|
-
runtime
|
|
172
|
-
);
|
|
164
|
+
const template = await trimTokens(summarizationTemplate, chunkSize, runtime);
|
|
173
165
|
const prompt = composePromptFromState({
|
|
174
166
|
state,
|
|
175
167
|
// make sure it fits, we can pad the tokens a bit
|
|
@@ -228,9 +220,7 @@ ${currentSummary.trim()}
|
|
|
228
220
|
throw error;
|
|
229
221
|
}
|
|
230
222
|
} else {
|
|
231
|
-
console.warn(
|
|
232
|
-
"Empty response from chat with attachments action, skipping"
|
|
233
|
-
);
|
|
223
|
+
console.warn("Empty response from chat with attachments action, skipping");
|
|
234
224
|
}
|
|
235
225
|
return callbackData;
|
|
236
226
|
},
|
|
@@ -400,9 +390,7 @@ var downloadMedia = {
|
|
|
400
390
|
retries++;
|
|
401
391
|
console.error(`Error sending message (attempt ${retries}):`, error);
|
|
402
392
|
if (retries === maxRetries) {
|
|
403
|
-
console.error(
|
|
404
|
-
"Max retries reached. Failed to send message with attachment."
|
|
405
|
-
);
|
|
393
|
+
console.error("Max retries reached. Failed to send message with attachment.");
|
|
406
394
|
break;
|
|
407
395
|
}
|
|
408
396
|
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
@@ -596,9 +584,7 @@ var joinChannel = {
|
|
|
596
584
|
return true;
|
|
597
585
|
},
|
|
598
586
|
handler: async (runtime, message, state, _options, callback) => {
|
|
599
|
-
const discordService = runtime.getService(
|
|
600
|
-
DISCORD_SERVICE_NAME
|
|
601
|
-
);
|
|
587
|
+
const discordService = runtime.getService(DISCORD_SERVICE_NAME);
|
|
602
588
|
if (!discordService || !discordService.client) {
|
|
603
589
|
console.error("Discord service not found or not initialized");
|
|
604
590
|
return;
|
|
@@ -791,7 +777,7 @@ import {
|
|
|
791
777
|
ModelType as ModelType4,
|
|
792
778
|
composePromptFromState as composePromptFromState4,
|
|
793
779
|
parseJSONObjectFromText as parseJSONObjectFromText4,
|
|
794
|
-
logger
|
|
780
|
+
logger,
|
|
795
781
|
createUniqueUuid as createUniqueUuid2
|
|
796
782
|
} from "@elizaos/core";
|
|
797
783
|
import { BaseGuildVoiceChannel } from "discord.js";
|
|
@@ -925,29 +911,27 @@ var leaveChannel = {
|
|
|
925
911
|
],
|
|
926
912
|
description: "Leave a Discord channel - either text (stop monitoring messages) or voice (disconnect from voice chat). Use this when asked to leave, exit, or disconnect from any Discord channel.",
|
|
927
913
|
validate: async (_runtime, message, _state) => {
|
|
928
|
-
|
|
914
|
+
logger.debug(`[LEAVE_CHANNEL] Validating message: ${message.content.text}`);
|
|
929
915
|
if (message.content.source !== "discord") {
|
|
930
|
-
|
|
916
|
+
logger.debug("[LEAVE_CHANNEL] Not a discord message");
|
|
931
917
|
return false;
|
|
932
918
|
}
|
|
933
|
-
|
|
919
|
+
logger.debug("[LEAVE_CHANNEL] Validation passed");
|
|
934
920
|
return true;
|
|
935
921
|
},
|
|
936
922
|
handler: async (runtime, message, state, _options, callback) => {
|
|
937
|
-
|
|
938
|
-
const discordService = runtime.getService(
|
|
939
|
-
DISCORD_SERVICE_NAME
|
|
940
|
-
);
|
|
923
|
+
logger.info(`[LEAVE_CHANNEL] Handler called with message: ${message.content.text}`);
|
|
924
|
+
const discordService = runtime.getService(DISCORD_SERVICE_NAME);
|
|
941
925
|
if (!discordService || !discordService.client) {
|
|
942
926
|
console.error("Discord service not found or not initialized");
|
|
943
927
|
await callback({
|
|
944
928
|
text: "Discord service is not available.",
|
|
945
929
|
source: "discord"
|
|
946
930
|
});
|
|
947
|
-
return
|
|
931
|
+
return void 0;
|
|
948
932
|
}
|
|
949
933
|
const channelInfo = await getLeaveChannelInfo(runtime, message, state);
|
|
950
|
-
|
|
934
|
+
logger.debug(`[LEAVE_CHANNEL] Parsed channel info:`, channelInfo);
|
|
951
935
|
try {
|
|
952
936
|
const room = state.data?.room || await runtime.getRoom(message.roomId);
|
|
953
937
|
const currentServerId = room?.serverId;
|
|
@@ -961,7 +945,7 @@ var leaveChannel = {
|
|
|
961
945
|
text: "Voice functionality is not available at the moment.",
|
|
962
946
|
source: "discord"
|
|
963
947
|
});
|
|
964
|
-
return
|
|
948
|
+
return void 0;
|
|
965
949
|
}
|
|
966
950
|
if (currentServerId) {
|
|
967
951
|
const guild = discordService.client.guilds.cache.get(currentServerId);
|
|
@@ -971,7 +955,7 @@ var leaveChannel = {
|
|
|
971
955
|
text: "I'm not currently in a voice channel.",
|
|
972
956
|
source: "discord"
|
|
973
957
|
});
|
|
974
|
-
return
|
|
958
|
+
return void 0;
|
|
975
959
|
}
|
|
976
960
|
const connection = voiceManager.getVoiceConnection(guild.id);
|
|
977
961
|
if (!connection) {
|
|
@@ -979,7 +963,7 @@ var leaveChannel = {
|
|
|
979
963
|
text: "No active voice connection found.",
|
|
980
964
|
source: "discord"
|
|
981
965
|
});
|
|
982
|
-
return
|
|
966
|
+
return void 0;
|
|
983
967
|
}
|
|
984
968
|
voiceManager.leaveChannel(voiceChannel);
|
|
985
969
|
await runtime.createMemory(
|
|
@@ -1002,7 +986,7 @@ var leaveChannel = {
|
|
|
1002
986
|
text: `I've left the voice channel ${voiceChannel.name}.`,
|
|
1003
987
|
source: "discord"
|
|
1004
988
|
});
|
|
1005
|
-
return
|
|
989
|
+
return;
|
|
1006
990
|
}
|
|
1007
991
|
}
|
|
1008
992
|
if (!channelInfo) {
|
|
@@ -1011,18 +995,42 @@ var leaveChannel = {
|
|
|
1011
995
|
text: "I couldn't understand which channel you want me to leave. Please specify the channel name or ID.",
|
|
1012
996
|
source: "discord"
|
|
1013
997
|
});
|
|
1014
|
-
return
|
|
998
|
+
return void 0;
|
|
1015
999
|
}
|
|
1016
|
-
let targetChannel = isVoiceRequest ? await findChannel2(
|
|
1000
|
+
let targetChannel = isVoiceRequest ? await findChannel2(
|
|
1001
|
+
discordService,
|
|
1002
|
+
channelInfo.channelIdentifier,
|
|
1003
|
+
currentChannelId,
|
|
1004
|
+
currentServerId,
|
|
1005
|
+
true
|
|
1006
|
+
) : await findChannel2(
|
|
1007
|
+
discordService,
|
|
1008
|
+
channelInfo.channelIdentifier,
|
|
1009
|
+
currentChannelId,
|
|
1010
|
+
currentServerId,
|
|
1011
|
+
false
|
|
1012
|
+
);
|
|
1017
1013
|
if (!targetChannel) {
|
|
1018
|
-
targetChannel = isVoiceRequest ? await findChannel2(
|
|
1014
|
+
targetChannel = isVoiceRequest ? await findChannel2(
|
|
1015
|
+
discordService,
|
|
1016
|
+
channelInfo.channelIdentifier,
|
|
1017
|
+
currentChannelId,
|
|
1018
|
+
currentServerId,
|
|
1019
|
+
false
|
|
1020
|
+
) : await findChannel2(
|
|
1021
|
+
discordService,
|
|
1022
|
+
channelInfo.channelIdentifier,
|
|
1023
|
+
currentChannelId,
|
|
1024
|
+
currentServerId,
|
|
1025
|
+
true
|
|
1026
|
+
);
|
|
1019
1027
|
}
|
|
1020
1028
|
if (!targetChannel) {
|
|
1021
1029
|
await callback({
|
|
1022
1030
|
text: `I couldn't find a channel with the identifier "${channelInfo.channelIdentifier}". Please make sure the channel name or ID is correct.`,
|
|
1023
1031
|
source: "discord"
|
|
1024
1032
|
});
|
|
1025
|
-
return
|
|
1033
|
+
return void 0;
|
|
1026
1034
|
}
|
|
1027
1035
|
if (targetChannel.type === DiscordChannelType2.GuildVoice) {
|
|
1028
1036
|
const voiceChannel = targetChannel;
|
|
@@ -1032,7 +1040,7 @@ var leaveChannel = {
|
|
|
1032
1040
|
text: "Voice functionality is not available at the moment.",
|
|
1033
1041
|
source: "discord"
|
|
1034
1042
|
});
|
|
1035
|
-
return
|
|
1043
|
+
return void 0;
|
|
1036
1044
|
}
|
|
1037
1045
|
const guild = voiceChannel.guild;
|
|
1038
1046
|
const currentVoiceChannel = guild.members.me?.voice.channel;
|
|
@@ -1041,7 +1049,7 @@ var leaveChannel = {
|
|
|
1041
1049
|
text: `I'm not currently in the voice channel ${voiceChannel.name}.`,
|
|
1042
1050
|
source: "discord"
|
|
1043
1051
|
});
|
|
1044
|
-
return
|
|
1052
|
+
return void 0;
|
|
1045
1053
|
}
|
|
1046
1054
|
voiceManager.leaveChannel(voiceChannel);
|
|
1047
1055
|
await runtime.createMemory(
|
|
@@ -1066,7 +1074,7 @@ var leaveChannel = {
|
|
|
1066
1074
|
source: message.content.source
|
|
1067
1075
|
};
|
|
1068
1076
|
await callback(response);
|
|
1069
|
-
return
|
|
1077
|
+
return;
|
|
1070
1078
|
} else {
|
|
1071
1079
|
const textChannel = targetChannel;
|
|
1072
1080
|
const currentChannels = discordService.getAllowedChannels();
|
|
@@ -1075,7 +1083,7 @@ var leaveChannel = {
|
|
|
1075
1083
|
text: `I'm not currently listening to ${textChannel.name} (<#${textChannel.id}>).`,
|
|
1076
1084
|
source: "discord"
|
|
1077
1085
|
});
|
|
1078
|
-
return
|
|
1086
|
+
return void 0;
|
|
1079
1087
|
}
|
|
1080
1088
|
const success = discordService.removeAllowedChannel(textChannel.id);
|
|
1081
1089
|
if (success) {
|
|
@@ -1085,23 +1093,23 @@ var leaveChannel = {
|
|
|
1085
1093
|
source: message.content.source
|
|
1086
1094
|
};
|
|
1087
1095
|
await callback(response);
|
|
1088
|
-
return
|
|
1096
|
+
return;
|
|
1089
1097
|
} else {
|
|
1090
1098
|
await callback({
|
|
1091
1099
|
text: `I couldn't remove ${textChannel.name} from my listening list. This channel might be configured in my environment settings and cannot be removed dynamically.`,
|
|
1092
1100
|
source: "discord"
|
|
1093
1101
|
});
|
|
1094
|
-
return
|
|
1102
|
+
return void 0;
|
|
1095
1103
|
}
|
|
1096
1104
|
}
|
|
1097
|
-
return
|
|
1105
|
+
return;
|
|
1098
1106
|
} catch (error) {
|
|
1099
1107
|
console.error("Error leaving channel:", error);
|
|
1100
1108
|
await callback({
|
|
1101
1109
|
text: "I encountered an error while trying to leave the channel. Please try again.",
|
|
1102
1110
|
source: "discord"
|
|
1103
1111
|
});
|
|
1104
|
-
return
|
|
1112
|
+
return void 0;
|
|
1105
1113
|
}
|
|
1106
1114
|
},
|
|
1107
1115
|
examples: [
|
|
@@ -1233,9 +1241,7 @@ var listChannels = {
|
|
|
1233
1241
|
return true;
|
|
1234
1242
|
},
|
|
1235
1243
|
handler: async (runtime, message, _state, _options, callback) => {
|
|
1236
|
-
const discordService = runtime.getService(
|
|
1237
|
-
DISCORD_SERVICE_NAME
|
|
1238
|
-
);
|
|
1244
|
+
const discordService = runtime.getService(DISCORD_SERVICE_NAME);
|
|
1239
1245
|
if (!discordService || !discordService.client) {
|
|
1240
1246
|
console.error("Discord service not found or not initialized");
|
|
1241
1247
|
return;
|
|
@@ -1275,14 +1281,17 @@ var listChannels = {
|
|
|
1275
1281
|
let responseText = `I'm currently listening to ${channelInfos.length} channel${channelInfos.length !== 1 ? "s" : ""}:
|
|
1276
1282
|
|
|
1277
1283
|
`;
|
|
1278
|
-
const channelsByServer = channelInfos.reduce(
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
acc[channel.server]
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1284
|
+
const channelsByServer = channelInfos.reduce(
|
|
1285
|
+
(acc, channel) => {
|
|
1286
|
+
if (!channel) return acc;
|
|
1287
|
+
if (!acc[channel.server]) {
|
|
1288
|
+
acc[channel.server] = [];
|
|
1289
|
+
}
|
|
1290
|
+
acc[channel.server].push(channel);
|
|
1291
|
+
return acc;
|
|
1292
|
+
},
|
|
1293
|
+
{}
|
|
1294
|
+
);
|
|
1286
1295
|
for (const [serverName, channels] of Object.entries(channelsByServer)) {
|
|
1287
1296
|
responseText += `**${serverName}**
|
|
1288
1297
|
`;
|
|
@@ -1368,7 +1377,7 @@ import {
|
|
|
1368
1377
|
ModelType as ModelType5,
|
|
1369
1378
|
composePromptFromState as composePromptFromState5,
|
|
1370
1379
|
parseJSONObjectFromText as parseJSONObjectFromText5,
|
|
1371
|
-
logger as
|
|
1380
|
+
logger as logger2
|
|
1372
1381
|
} from "@elizaos/core";
|
|
1373
1382
|
import { PermissionsBitField } from "discord.js";
|
|
1374
1383
|
var channelInfoTemplate = `# Messages we are searching for channel information
|
|
@@ -1405,10 +1414,7 @@ var getChannelInfo = async (runtime, _message, state) => {
|
|
|
1405
1414
|
});
|
|
1406
1415
|
const parsedResponse = parseJSONObjectFromText5(response);
|
|
1407
1416
|
if (parsedResponse?.channelIdentifier) {
|
|
1408
|
-
const messageCount = Math.min(
|
|
1409
|
-
Math.max(parsedResponse.messageCount || 10, 1),
|
|
1410
|
-
50
|
|
1411
|
-
);
|
|
1417
|
+
const messageCount = Math.min(Math.max(parsedResponse.messageCount || 10, 1), 50);
|
|
1412
1418
|
return {
|
|
1413
1419
|
channelIdentifier: parsedResponse.channelIdentifier,
|
|
1414
1420
|
messageCount,
|
|
@@ -1437,9 +1443,7 @@ var readChannel = {
|
|
|
1437
1443
|
return true;
|
|
1438
1444
|
},
|
|
1439
1445
|
handler: async (runtime, message, state, _options, callback) => {
|
|
1440
|
-
const discordService = runtime.getService(
|
|
1441
|
-
DISCORD_SERVICE_NAME
|
|
1442
|
-
);
|
|
1446
|
+
const discordService = runtime.getService(DISCORD_SERVICE_NAME);
|
|
1443
1447
|
if (!discordService || !discordService.client) {
|
|
1444
1448
|
console.error("Discord service not found or not initialized");
|
|
1445
1449
|
return;
|
|
@@ -1480,9 +1484,7 @@ var readChannel = {
|
|
|
1480
1484
|
});
|
|
1481
1485
|
return;
|
|
1482
1486
|
}
|
|
1483
|
-
const botMember = targetChannel.guild?.members.cache.get(
|
|
1484
|
-
discordService.client.user.id
|
|
1485
|
-
);
|
|
1487
|
+
const botMember = targetChannel.guild?.members.cache.get(discordService.client.user.id);
|
|
1486
1488
|
if (botMember) {
|
|
1487
1489
|
const permissions = targetChannel.permissionsFor(botMember);
|
|
1488
1490
|
if (!permissions?.has(PermissionsBitField.Flags.ReadMessageHistory)) {
|
|
@@ -1495,7 +1497,9 @@ var readChannel = {
|
|
|
1495
1497
|
}
|
|
1496
1498
|
const requestedLimit = channelInfo.summarize ? Math.max(channelInfo.messageCount * 2, 50) : channelInfo.messageCount;
|
|
1497
1499
|
const fetchLimit = Math.min(requestedLimit, 100);
|
|
1498
|
-
|
|
1500
|
+
logger2.debug(
|
|
1501
|
+
`[READ_CHANNEL] Fetching ${fetchLimit} messages from ${targetChannel.name} (requested: ${requestedLimit}), summarize: ${channelInfo.summarize}, focusUser: ${channelInfo.focusUser}`
|
|
1502
|
+
);
|
|
1499
1503
|
const messages = await targetChannel.messages.fetch({
|
|
1500
1504
|
limit: fetchLimit
|
|
1501
1505
|
});
|
|
@@ -1526,7 +1530,9 @@ var readChannel = {
|
|
|
1526
1530
|
}));
|
|
1527
1531
|
const summaryPrompt = channelInfo.focusUser ? `Please summarize what ${channelInfo.focusUser} has been discussing based on these messages from the Discord channel "${targetChannel.name}":
|
|
1528
1532
|
|
|
1529
|
-
${messagesToSummarize.map((m) => `${m.author} (${m.timestamp}): ${m.content}`).join(
|
|
1533
|
+
${messagesToSummarize.map((m) => `${m.author} (${m.timestamp}): ${m.content}`).join(
|
|
1534
|
+
"\n\n"
|
|
1535
|
+
)}
|
|
1530
1536
|
|
|
1531
1537
|
Provide a concise summary focusing on:
|
|
1532
1538
|
1. Main topics ${channelInfo.focusUser} discussed
|
|
@@ -1535,7 +1541,9 @@ Provide a concise summary focusing on:
|
|
|
1535
1541
|
|
|
1536
1542
|
If ${channelInfo.focusUser} didn't appear in these messages, please note that.` : `Please summarize the recent conversation in the Discord channel "${targetChannel.name}" based on these messages:
|
|
1537
1543
|
|
|
1538
|
-
${messagesToSummarize.map((m) => `${m.author} (${m.timestamp}): ${m.content}`).join(
|
|
1544
|
+
${messagesToSummarize.map((m) => `${m.author} (${m.timestamp}): ${m.content}`).join(
|
|
1545
|
+
"\n\n"
|
|
1546
|
+
)}
|
|
1539
1547
|
|
|
1540
1548
|
Provide a concise summary that includes:
|
|
1541
1549
|
1. Main topics discussed
|
|
@@ -1763,9 +1771,7 @@ var sendDM = {
|
|
|
1763
1771
|
return true;
|
|
1764
1772
|
},
|
|
1765
1773
|
handler: async (runtime, message, state, _options, callback) => {
|
|
1766
|
-
const discordService = runtime.getService(
|
|
1767
|
-
DISCORD_SERVICE_NAME
|
|
1768
|
-
);
|
|
1774
|
+
const discordService = runtime.getService(DISCORD_SERVICE_NAME);
|
|
1769
1775
|
if (!discordService || !discordService.client) {
|
|
1770
1776
|
console.error("Discord service not found or not initialized");
|
|
1771
1777
|
return;
|
|
@@ -1925,12 +1931,8 @@ var getDateRange = async (runtime, _message, state) => {
|
|
|
1925
1931
|
const parsedResponse = parseJSONObjectFromText7(response);
|
|
1926
1932
|
if (parsedResponse) {
|
|
1927
1933
|
if (parsedResponse.objective && parsedResponse.start && parsedResponse.end) {
|
|
1928
|
-
const startIntegerString = parsedResponse.start.match(
|
|
1929
|
-
|
|
1930
|
-
)?.[0];
|
|
1931
|
-
const endIntegerString = parsedResponse.end.match(
|
|
1932
|
-
/\d+/
|
|
1933
|
-
)?.[0];
|
|
1934
|
+
const startIntegerString = parsedResponse.start.match(/\d+/)?.[0];
|
|
1935
|
+
const endIntegerString = parsedResponse.end.match(/\d+/)?.[0];
|
|
1934
1936
|
const multipliers = {
|
|
1935
1937
|
second: 1 * 1e3,
|
|
1936
1938
|
minute: 60 * 1e3,
|
|
@@ -1940,9 +1942,7 @@ var getDateRange = async (runtime, _message, state) => {
|
|
|
1940
1942
|
const startMultiplier = parsedResponse.start.match(
|
|
1941
1943
|
/second|minute|hour|day/
|
|
1942
1944
|
)?.[0];
|
|
1943
|
-
const endMultiplier = parsedResponse.end.match(
|
|
1944
|
-
/second|minute|hour|day/
|
|
1945
|
-
)?.[0];
|
|
1945
|
+
const endMultiplier = parsedResponse.end.match(/second|minute|hour|day/)?.[0];
|
|
1946
1946
|
const startInteger = startIntegerString ? Number.parseInt(startIntegerString) : 0;
|
|
1947
1947
|
const endInteger = endIntegerString ? Number.parseInt(endIntegerString) : 0;
|
|
1948
1948
|
const startTime = startInteger * multipliers[startMultiplier];
|
|
@@ -2075,11 +2075,7 @@ ${attachments}`;
|
|
|
2075
2075
|
const chunk = chunks[i];
|
|
2076
2076
|
state.values.currentSummary = currentSummary;
|
|
2077
2077
|
state.values.currentChunk = chunk;
|
|
2078
|
-
const template = await trimTokens2(
|
|
2079
|
-
summarizationTemplate2,
|
|
2080
|
-
chunkSize + 500,
|
|
2081
|
-
runtime
|
|
2082
|
-
);
|
|
2078
|
+
const template = await trimTokens2(summarizationTemplate2, chunkSize + 500, runtime);
|
|
2083
2079
|
const prompt = composePromptFromState7({
|
|
2084
2080
|
state,
|
|
2085
2081
|
// make sure it fits, we can pad the tokens a bit
|
|
@@ -2133,9 +2129,7 @@ ${currentSummary.trim()}
|
|
|
2133
2129
|
[summaryFilename]
|
|
2134
2130
|
);
|
|
2135
2131
|
} else {
|
|
2136
|
-
console.warn(
|
|
2137
|
-
"Empty response from summarize conversation action, skipping"
|
|
2138
|
-
);
|
|
2132
|
+
console.warn("Empty response from summarize conversation action, skipping");
|
|
2139
2133
|
}
|
|
2140
2134
|
return callbackData;
|
|
2141
2135
|
},
|
|
@@ -2315,11 +2309,7 @@ var transcribeMedia = {
|
|
|
2315
2309
|
count: conversationLength,
|
|
2316
2310
|
unique: false
|
|
2317
2311
|
});
|
|
2318
|
-
const attachment = recentMessages.filter(
|
|
2319
|
-
(msg) => msg.content.attachments && msg.content.attachments.length > 0
|
|
2320
|
-
).flatMap((msg) => msg.content.attachments).find(
|
|
2321
|
-
(attachment2) => attachment2?.id.toLowerCase() === attachmentId.toLowerCase()
|
|
2322
|
-
);
|
|
2312
|
+
const attachment = recentMessages.filter((msg) => msg.content.attachments && msg.content.attachments.length > 0).flatMap((msg) => msg.content.attachments).find((attachment2) => attachment2?.id.toLowerCase() === attachmentId.toLowerCase());
|
|
2323
2313
|
if (!attachment) {
|
|
2324
2314
|
console.error(`Couldn't find attachment with ID ${attachmentId}`);
|
|
2325
2315
|
await runtime.createMemory(
|
|
@@ -2403,7 +2393,7 @@ import {
|
|
|
2403
2393
|
ModelType as ModelType9,
|
|
2404
2394
|
composePromptFromState as composePromptFromState9,
|
|
2405
2395
|
parseJSONObjectFromText as parseJSONObjectFromText9,
|
|
2406
|
-
logger as
|
|
2396
|
+
logger as logger3
|
|
2407
2397
|
} from "@elizaos/core";
|
|
2408
2398
|
var searchMessagesTemplate = `# Searching for Discord messages
|
|
2409
2399
|
{{recentMessages}}
|
|
@@ -2498,9 +2488,7 @@ var searchMessages = {
|
|
|
2498
2488
|
return message.content.source === "discord";
|
|
2499
2489
|
},
|
|
2500
2490
|
handler: async (runtime, message, state, _options, callback) => {
|
|
2501
|
-
const discordService = runtime.getService(
|
|
2502
|
-
DISCORD_SERVICE_NAME
|
|
2503
|
-
);
|
|
2491
|
+
const discordService = runtime.getService(DISCORD_SERVICE_NAME);
|
|
2504
2492
|
if (!discordService || !discordService.client) {
|
|
2505
2493
|
await callback({
|
|
2506
2494
|
text: "Discord service is not available.",
|
|
@@ -2561,10 +2549,14 @@ var searchMessages = {
|
|
|
2561
2549
|
// Discord API max limit
|
|
2562
2550
|
before: before?.toString()
|
|
2563
2551
|
});
|
|
2564
|
-
|
|
2565
|
-
|
|
2552
|
+
logger3.debug(
|
|
2553
|
+
`[SEARCH_MESSAGES] Fetched ${messages.size} messages from channel ${targetChannel.name}`
|
|
2554
|
+
);
|
|
2555
|
+
logger3.debug(
|
|
2556
|
+
`[SEARCH_MESSAGES] Searching for: "${searchParams.query}", author: ${searchParams.author || "any"}`
|
|
2557
|
+
);
|
|
2566
2558
|
const results = searchInMessages(messages, searchParams.query, searchParams.author);
|
|
2567
|
-
|
|
2559
|
+
logger3.debug(`[SEARCH_MESSAGES] Found ${results.length} matching messages`);
|
|
2568
2560
|
const sortedResults = results.sort((a, b) => b.createdTimestamp - a.createdTimestamp);
|
|
2569
2561
|
const limitedResults = sortedResults.slice(0, searchParams.limit);
|
|
2570
2562
|
if (limitedResults.length === 0) {
|
|
@@ -2591,7 +2583,7 @@ ${formattedResults}`,
|
|
|
2591
2583
|
};
|
|
2592
2584
|
await callback(response);
|
|
2593
2585
|
} catch (error) {
|
|
2594
|
-
|
|
2586
|
+
logger3.error("Error searching messages:", error);
|
|
2595
2587
|
await callback({
|
|
2596
2588
|
text: "I encountered an error while searching for messages. Please try again.",
|
|
2597
2589
|
source: "discord"
|
|
@@ -2653,7 +2645,7 @@ import {
|
|
|
2653
2645
|
ModelType as ModelType10,
|
|
2654
2646
|
composePromptFromState as composePromptFromState10,
|
|
2655
2647
|
parseJSONObjectFromText as parseJSONObjectFromText10,
|
|
2656
|
-
logger as
|
|
2648
|
+
logger as logger4
|
|
2657
2649
|
} from "@elizaos/core";
|
|
2658
2650
|
var createPollTemplate = `# Creating a Discord poll
|
|
2659
2651
|
{{recentMessages}}
|
|
@@ -2719,9 +2711,7 @@ var createPoll = {
|
|
|
2719
2711
|
return message.content.source === "discord";
|
|
2720
2712
|
},
|
|
2721
2713
|
handler: async (runtime, message, state, _options, callback) => {
|
|
2722
|
-
const discordService = runtime.getService(
|
|
2723
|
-
DISCORD_SERVICE_NAME
|
|
2724
|
-
);
|
|
2714
|
+
const discordService = runtime.getService(DISCORD_SERVICE_NAME);
|
|
2725
2715
|
if (!discordService || !discordService.client) {
|
|
2726
2716
|
await callback({
|
|
2727
2717
|
text: "Discord service is not available.",
|
|
@@ -2776,7 +2766,7 @@ var createPoll = {
|
|
|
2776
2766
|
await sentMessage.react(emojis[i]);
|
|
2777
2767
|
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
2778
2768
|
} catch (error) {
|
|
2779
|
-
|
|
2769
|
+
logger4.error(`Failed to add reaction ${emojis[i]}:`, error);
|
|
2780
2770
|
}
|
|
2781
2771
|
}
|
|
2782
2772
|
const response = {
|
|
@@ -2785,7 +2775,7 @@ var createPoll = {
|
|
|
2785
2775
|
};
|
|
2786
2776
|
await callback(response);
|
|
2787
2777
|
} catch (error) {
|
|
2788
|
-
|
|
2778
|
+
logger4.error("Error creating poll:", error);
|
|
2789
2779
|
await callback({
|
|
2790
2780
|
text: "I encountered an error while creating the poll. Please make sure I have permission to send messages and add reactions.",
|
|
2791
2781
|
source: "discord"
|
|
@@ -2847,7 +2837,7 @@ import {
|
|
|
2847
2837
|
ModelType as ModelType11,
|
|
2848
2838
|
composePromptFromState as composePromptFromState11,
|
|
2849
2839
|
parseJSONObjectFromText as parseJSONObjectFromText11,
|
|
2850
|
-
logger as
|
|
2840
|
+
logger as logger5
|
|
2851
2841
|
} from "@elizaos/core";
|
|
2852
2842
|
var getUserInfoTemplate = `# Getting Discord user information
|
|
2853
2843
|
{{recentMessages}}
|
|
@@ -2934,9 +2924,7 @@ var getUserInfo = {
|
|
|
2934
2924
|
return message.content.source === "discord";
|
|
2935
2925
|
},
|
|
2936
2926
|
handler: async (runtime, message, state, _options, callback) => {
|
|
2937
|
-
const discordService = runtime.getService(
|
|
2938
|
-
DISCORD_SERVICE_NAME
|
|
2939
|
-
);
|
|
2927
|
+
const discordService = runtime.getService(DISCORD_SERVICE_NAME);
|
|
2940
2928
|
if (!discordService || !discordService.client) {
|
|
2941
2929
|
await callback({
|
|
2942
2930
|
text: "Discord service is not available.",
|
|
@@ -3001,7 +2989,7 @@ var getUserInfo = {
|
|
|
3001
2989
|
};
|
|
3002
2990
|
await callback(response);
|
|
3003
2991
|
} catch (error) {
|
|
3004
|
-
|
|
2992
|
+
logger5.error("Error getting user info:", error);
|
|
3005
2993
|
await callback({
|
|
3006
2994
|
text: "I encountered an error while getting user information. Please try again.",
|
|
3007
2995
|
source: "discord"
|
|
@@ -3063,7 +3051,7 @@ import {
|
|
|
3063
3051
|
ModelType as ModelType12,
|
|
3064
3052
|
composePromptFromState as composePromptFromState12,
|
|
3065
3053
|
parseJSONObjectFromText as parseJSONObjectFromText12,
|
|
3066
|
-
logger as
|
|
3054
|
+
logger as logger6
|
|
3067
3055
|
} from "@elizaos/core";
|
|
3068
3056
|
var reactToMessageTemplate = `# Adding reactions to Discord messages
|
|
3069
3057
|
{{recentMessages}}
|
|
@@ -3161,9 +3149,7 @@ var reactToMessage = {
|
|
|
3161
3149
|
return message.content.source === "discord";
|
|
3162
3150
|
},
|
|
3163
3151
|
handler: async (runtime, message, state, _options, callback) => {
|
|
3164
|
-
const discordService = runtime.getService(
|
|
3165
|
-
DISCORD_SERVICE_NAME
|
|
3166
|
-
);
|
|
3152
|
+
const discordService = runtime.getService(DISCORD_SERVICE_NAME);
|
|
3167
3153
|
if (!discordService || !discordService.client) {
|
|
3168
3154
|
await callback({
|
|
3169
3155
|
text: "Discord service is not available.",
|
|
@@ -3200,7 +3186,9 @@ var reactToMessage = {
|
|
|
3200
3186
|
let targetMessage = null;
|
|
3201
3187
|
if (reactionInfo.messageRef === "last" || reactionInfo.messageRef === "previous") {
|
|
3202
3188
|
const messages = await textChannel.messages.fetch({ limit: 100 });
|
|
3203
|
-
const sortedMessages = Array.from(messages.values()).sort(
|
|
3189
|
+
const sortedMessages = Array.from(messages.values()).sort(
|
|
3190
|
+
(a, b) => b.createdTimestamp - a.createdTimestamp
|
|
3191
|
+
);
|
|
3204
3192
|
targetMessage = sortedMessages.find(
|
|
3205
3193
|
(msg) => msg.id !== message.content.id && msg.author.id !== discordService.client.user.id
|
|
3206
3194
|
) || null;
|
|
@@ -3234,14 +3222,14 @@ var reactToMessage = {
|
|
|
3234
3222
|
};
|
|
3235
3223
|
await callback(response);
|
|
3236
3224
|
} catch (error) {
|
|
3237
|
-
|
|
3225
|
+
logger6.error("Failed to add reaction:", error);
|
|
3238
3226
|
await callback({
|
|
3239
3227
|
text: `I couldn't add that reaction. Make sure the emoji "${reactionInfo.emoji}" is valid and I have permission to add reactions.`,
|
|
3240
3228
|
source: "discord"
|
|
3241
3229
|
});
|
|
3242
3230
|
}
|
|
3243
3231
|
} catch (error) {
|
|
3244
|
-
|
|
3232
|
+
logger6.error("Error in react to message:", error);
|
|
3245
3233
|
await callback({
|
|
3246
3234
|
text: "I encountered an error while trying to react to the message. Please make sure I have the necessary permissions.",
|
|
3247
3235
|
source: "discord"
|
|
@@ -3303,7 +3291,7 @@ import {
|
|
|
3303
3291
|
ModelType as ModelType13,
|
|
3304
3292
|
composePromptFromState as composePromptFromState13,
|
|
3305
3293
|
parseJSONObjectFromText as parseJSONObjectFromText13,
|
|
3306
|
-
logger as
|
|
3294
|
+
logger as logger7
|
|
3307
3295
|
} from "@elizaos/core";
|
|
3308
3296
|
import { PermissionsBitField as PermissionsBitField2 } from "discord.js";
|
|
3309
3297
|
var pinMessageTemplate = `# Pinning a Discord message
|
|
@@ -3344,22 +3332,13 @@ var getMessageRef = async (runtime, _message, state) => {
|
|
|
3344
3332
|
};
|
|
3345
3333
|
var pinMessage = {
|
|
3346
3334
|
name: "PIN_MESSAGE",
|
|
3347
|
-
similes: [
|
|
3348
|
-
"PIN_MESSAGE",
|
|
3349
|
-
"PIN_MSG",
|
|
3350
|
-
"PIN_THIS",
|
|
3351
|
-
"PIN_THAT",
|
|
3352
|
-
"MAKE_PINNED",
|
|
3353
|
-
"ADD_PIN"
|
|
3354
|
-
],
|
|
3335
|
+
similes: ["PIN_MESSAGE", "PIN_MSG", "PIN_THIS", "PIN_THAT", "MAKE_PINNED", "ADD_PIN"],
|
|
3355
3336
|
description: "Pin an important message in a Discord channel.",
|
|
3356
3337
|
validate: async (_runtime, message, _state) => {
|
|
3357
3338
|
return message.content.source === "discord";
|
|
3358
3339
|
},
|
|
3359
3340
|
handler: async (runtime, message, state, _options, callback) => {
|
|
3360
|
-
const discordService = runtime.getService(
|
|
3361
|
-
DISCORD_SERVICE_NAME
|
|
3362
|
-
);
|
|
3341
|
+
const discordService = runtime.getService(DISCORD_SERVICE_NAME);
|
|
3363
3342
|
if (!discordService || !discordService.client) {
|
|
3364
3343
|
await callback({
|
|
3365
3344
|
text: "Discord service is not available.",
|
|
@@ -3393,9 +3372,7 @@ var pinMessage = {
|
|
|
3393
3372
|
return;
|
|
3394
3373
|
}
|
|
3395
3374
|
const textChannel = channel;
|
|
3396
|
-
const botMember = textChannel.guild?.members.cache.get(
|
|
3397
|
-
discordService.client.user.id
|
|
3398
|
-
);
|
|
3375
|
+
const botMember = textChannel.guild?.members.cache.get(discordService.client.user.id);
|
|
3399
3376
|
if (botMember) {
|
|
3400
3377
|
const permissions = textChannel.permissionsFor(botMember);
|
|
3401
3378
|
if (!permissions?.has(PermissionsBitField2.Flags.ManageMessages)) {
|
|
@@ -3409,7 +3386,9 @@ var pinMessage = {
|
|
|
3409
3386
|
let targetMessage = null;
|
|
3410
3387
|
if (messageInfo.messageRef === "last" || messageInfo.messageRef === "previous") {
|
|
3411
3388
|
const messages = await textChannel.messages.fetch({ limit: 100 });
|
|
3412
|
-
const sortedMessages = Array.from(messages.values()).sort(
|
|
3389
|
+
const sortedMessages = Array.from(messages.values()).sort(
|
|
3390
|
+
(a, b) => b.createdTimestamp - a.createdTimestamp
|
|
3391
|
+
);
|
|
3413
3392
|
targetMessage = sortedMessages.find(
|
|
3414
3393
|
(msg) => msg.id !== message.content.id && msg.author.id !== discordService.client.user.id
|
|
3415
3394
|
) || null;
|
|
@@ -3449,14 +3428,14 @@ var pinMessage = {
|
|
|
3449
3428
|
};
|
|
3450
3429
|
await callback(response);
|
|
3451
3430
|
} catch (error) {
|
|
3452
|
-
|
|
3431
|
+
logger7.error("Failed to pin message:", error);
|
|
3453
3432
|
await callback({
|
|
3454
3433
|
text: "I couldn't pin that message. The channel might have reached the maximum number of pinned messages (50).",
|
|
3455
3434
|
source: "discord"
|
|
3456
3435
|
});
|
|
3457
3436
|
}
|
|
3458
3437
|
} catch (error) {
|
|
3459
|
-
|
|
3438
|
+
logger7.error("Error pinning message:", error);
|
|
3460
3439
|
await callback({
|
|
3461
3440
|
text: "I encountered an error while trying to pin the message. Please make sure I have the necessary permissions.",
|
|
3462
3441
|
source: "discord"
|
|
@@ -3518,7 +3497,7 @@ import {
|
|
|
3518
3497
|
ModelType as ModelType14,
|
|
3519
3498
|
composePromptFromState as composePromptFromState14,
|
|
3520
3499
|
parseJSONObjectFromText as parseJSONObjectFromText14,
|
|
3521
|
-
logger as
|
|
3500
|
+
logger as logger8
|
|
3522
3501
|
} from "@elizaos/core";
|
|
3523
3502
|
import { PermissionsBitField as PermissionsBitField3 } from "discord.js";
|
|
3524
3503
|
var unpinMessageTemplate = `# Unpinning a Discord message
|
|
@@ -3559,22 +3538,13 @@ var getMessageRef2 = async (runtime, _message, state) => {
|
|
|
3559
3538
|
};
|
|
3560
3539
|
var unpinMessage = {
|
|
3561
3540
|
name: "UNPIN_MESSAGE",
|
|
3562
|
-
similes: [
|
|
3563
|
-
"UNPIN_MESSAGE",
|
|
3564
|
-
"UNPIN_MSG",
|
|
3565
|
-
"UNPIN_THIS",
|
|
3566
|
-
"UNPIN_THAT",
|
|
3567
|
-
"REMOVE_PIN",
|
|
3568
|
-
"DELETE_PIN"
|
|
3569
|
-
],
|
|
3541
|
+
similes: ["UNPIN_MESSAGE", "UNPIN_MSG", "UNPIN_THIS", "UNPIN_THAT", "REMOVE_PIN", "DELETE_PIN"],
|
|
3570
3542
|
description: "Unpin a message in a Discord channel.",
|
|
3571
3543
|
validate: async (_runtime, message, _state) => {
|
|
3572
3544
|
return message.content.source === "discord";
|
|
3573
3545
|
},
|
|
3574
3546
|
handler: async (runtime, message, state, _options, callback) => {
|
|
3575
|
-
const discordService = runtime.getService(
|
|
3576
|
-
DISCORD_SERVICE_NAME
|
|
3577
|
-
);
|
|
3547
|
+
const discordService = runtime.getService(DISCORD_SERVICE_NAME);
|
|
3578
3548
|
if (!discordService || !discordService.client) {
|
|
3579
3549
|
await callback({
|
|
3580
3550
|
text: "Discord service is not available.",
|
|
@@ -3608,9 +3578,7 @@ var unpinMessage = {
|
|
|
3608
3578
|
return;
|
|
3609
3579
|
}
|
|
3610
3580
|
const textChannel = channel;
|
|
3611
|
-
const botMember = textChannel.guild?.members.cache.get(
|
|
3612
|
-
discordService.client.user.id
|
|
3613
|
-
);
|
|
3581
|
+
const botMember = textChannel.guild?.members.cache.get(discordService.client.user.id);
|
|
3614
3582
|
if (botMember) {
|
|
3615
3583
|
const permissions = textChannel.permissionsFor(botMember);
|
|
3616
3584
|
if (!permissions?.has(PermissionsBitField3.Flags.ManageMessages)) {
|
|
@@ -3631,7 +3599,9 @@ var unpinMessage = {
|
|
|
3631
3599
|
return;
|
|
3632
3600
|
}
|
|
3633
3601
|
if (messageInfo.messageRef === "last_pinned" || messageInfo.messageRef === "last") {
|
|
3634
|
-
targetMessage = Array.from(pinnedMessages.values()).sort(
|
|
3602
|
+
targetMessage = Array.from(pinnedMessages.values()).sort(
|
|
3603
|
+
(a, b) => b.createdTimestamp - a.createdTimestamp
|
|
3604
|
+
)[0];
|
|
3635
3605
|
} else if (/^\d+$/.test(messageInfo.messageRef)) {
|
|
3636
3606
|
targetMessage = pinnedMessages.get(messageInfo.messageRef) || null;
|
|
3637
3607
|
} else {
|
|
@@ -3657,14 +3627,14 @@ var unpinMessage = {
|
|
|
3657
3627
|
};
|
|
3658
3628
|
await callback(response);
|
|
3659
3629
|
} catch (error) {
|
|
3660
|
-
|
|
3630
|
+
logger8.error("Failed to unpin message:", error);
|
|
3661
3631
|
await callback({
|
|
3662
3632
|
text: "I couldn't unpin that message. Please try again.",
|
|
3663
3633
|
source: "discord"
|
|
3664
3634
|
});
|
|
3665
3635
|
}
|
|
3666
3636
|
} catch (error) {
|
|
3667
|
-
|
|
3637
|
+
logger8.error("Error unpinning message:", error);
|
|
3668
3638
|
await callback({
|
|
3669
3639
|
text: "I encountered an error while trying to unpin the message. Please make sure I have the necessary permissions.",
|
|
3670
3640
|
source: "discord"
|
|
@@ -3723,7 +3693,7 @@ var unpinMessage_default = unpinMessage;
|
|
|
3723
3693
|
|
|
3724
3694
|
// src/actions/serverInfo.ts
|
|
3725
3695
|
import {
|
|
3726
|
-
logger as
|
|
3696
|
+
logger as logger9
|
|
3727
3697
|
} from "@elizaos/core";
|
|
3728
3698
|
var formatServerInfo = (guild, detailed = false) => {
|
|
3729
3699
|
const createdAt = new Date(guild.createdAt).toLocaleDateString();
|
|
@@ -3791,9 +3761,7 @@ var serverInfo = {
|
|
|
3791
3761
|
return message.content.source === "discord";
|
|
3792
3762
|
},
|
|
3793
3763
|
handler: async (runtime, message, state, _options, callback) => {
|
|
3794
|
-
const discordService = runtime.getService(
|
|
3795
|
-
DISCORD_SERVICE_NAME
|
|
3796
|
-
);
|
|
3764
|
+
const discordService = runtime.getService(DISCORD_SERVICE_NAME);
|
|
3797
3765
|
if (!discordService || !discordService.client) {
|
|
3798
3766
|
await callback({
|
|
3799
3767
|
text: "Discord service is not available.",
|
|
@@ -3820,7 +3788,7 @@ var serverInfo = {
|
|
|
3820
3788
|
};
|
|
3821
3789
|
await callback(response);
|
|
3822
3790
|
} catch (error) {
|
|
3823
|
-
|
|
3791
|
+
logger9.error("Error getting server info:", error);
|
|
3824
3792
|
await callback({
|
|
3825
3793
|
text: "I encountered an error while getting server information. Please try again.",
|
|
3826
3794
|
source: "discord"
|
|
@@ -3926,9 +3894,7 @@ var channelStateProvider = {
|
|
|
3926
3894
|
};
|
|
3927
3895
|
}
|
|
3928
3896
|
channelId = room.channelId;
|
|
3929
|
-
const discordService = runtime.getService(
|
|
3930
|
-
ServiceType2.DISCORD
|
|
3931
|
-
);
|
|
3897
|
+
const discordService = runtime.getService(ServiceType2.DISCORD);
|
|
3932
3898
|
if (!discordService) {
|
|
3933
3899
|
console.warn("No discord client found");
|
|
3934
3900
|
return {
|
|
@@ -4085,7 +4051,7 @@ import {
|
|
|
4085
4051
|
Role,
|
|
4086
4052
|
Service,
|
|
4087
4053
|
createUniqueUuid as createUniqueUuid5,
|
|
4088
|
-
logger as
|
|
4054
|
+
logger as logger13
|
|
4089
4055
|
} from "@elizaos/core";
|
|
4090
4056
|
import {
|
|
4091
4057
|
ChannelType as DiscordChannelType5,
|
|
@@ -4096,13 +4062,89 @@ import {
|
|
|
4096
4062
|
PermissionsBitField as PermissionsBitField5
|
|
4097
4063
|
} from "discord.js";
|
|
4098
4064
|
|
|
4065
|
+
// src/environment.ts
|
|
4066
|
+
import { parseBooleanFromText } from "@elizaos/core";
|
|
4067
|
+
import { z } from "zod";
|
|
4068
|
+
function getEnvBoolean(name, fallback) {
|
|
4069
|
+
const value = process.env?.[name];
|
|
4070
|
+
if (!value) return fallback;
|
|
4071
|
+
return value.toLowerCase() === "true";
|
|
4072
|
+
}
|
|
4073
|
+
function getEnvArray(name, fallback) {
|
|
4074
|
+
const value = process.env?.[name];
|
|
4075
|
+
if (!value || value.trim() === "") return fallback;
|
|
4076
|
+
return value.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
|
|
4077
|
+
}
|
|
4078
|
+
var DISCORD_DEFAULTS = {
|
|
4079
|
+
SHOULD_IGNORE_BOT_MESSAGES: getEnvBoolean("DISCORD_SHOULD_IGNORE_BOT_MESSAGES", false),
|
|
4080
|
+
SHOULD_IGNORE_DIRECT_MESSAGES: getEnvBoolean("DISCORD_SHOULD_IGNORE_DIRECT_MESSAGES", false),
|
|
4081
|
+
SHOULD_RESPOND_ONLY_TO_MENTIONS: getEnvBoolean("DISCORD_SHOULD_RESPOND_ONLY_TO_MENTIONS", false),
|
|
4082
|
+
ALLOWED_CHANNEL_IDS: getEnvArray("CHANNEL_IDS", [])
|
|
4083
|
+
};
|
|
4084
|
+
var discordEnvSchema = z.object({
|
|
4085
|
+
DISCORD_API_TOKEN: z.string().min(1, "Discord API token is required"),
|
|
4086
|
+
/**
|
|
4087
|
+
* Comma-separated list of channel IDs to restrict the bot to.
|
|
4088
|
+
* If not set, the bot operates in all channels as usual.
|
|
4089
|
+
* These channels cannot be removed via the leaveChannel action.
|
|
4090
|
+
* Additional channels can be added dynamically via the joinChannel action.
|
|
4091
|
+
*/
|
|
4092
|
+
CHANNEL_IDS: z.string().nullish().transform(
|
|
4093
|
+
(val) => val ? val.split(",").map((s) => s.trim()).filter((s) => s.length > 0) : void 0
|
|
4094
|
+
),
|
|
4095
|
+
DISCORD_SHOULD_IGNORE_BOT_MESSAGES: z.string().nullish().transform((val) => val ? parseBooleanFromText(val) : void 0),
|
|
4096
|
+
DISCORD_SHOULD_IGNORE_DIRECT_MESSAGES: z.string().nullish().transform((val) => val ? parseBooleanFromText(val) : void 0),
|
|
4097
|
+
DISCORD_SHOULD_RESPOND_ONLY_TO_MENTIONS: z.string().nullish().transform((val) => val ? parseBooleanFromText(val) : void 0)
|
|
4098
|
+
});
|
|
4099
|
+
function getDiscordSettings(runtime) {
|
|
4100
|
+
const characterSettings = runtime.character.settings?.discord || {};
|
|
4101
|
+
const resolveSetting = (envKey, characterValue, defaultValue, transform) => {
|
|
4102
|
+
const runtimeValue = runtime.getSetting(envKey);
|
|
4103
|
+
if (runtimeValue !== void 0 && runtimeValue !== null) {
|
|
4104
|
+
const normalized = typeof runtimeValue === "string" ? runtimeValue : String(runtimeValue);
|
|
4105
|
+
return transform ? transform(normalized) : runtimeValue;
|
|
4106
|
+
}
|
|
4107
|
+
return characterValue ?? defaultValue;
|
|
4108
|
+
};
|
|
4109
|
+
const resolvedAllowedChannelIds = resolveSetting(
|
|
4110
|
+
"CHANNEL_IDS",
|
|
4111
|
+
characterSettings.allowedChannelIds,
|
|
4112
|
+
DISCORD_DEFAULTS.ALLOWED_CHANNEL_IDS,
|
|
4113
|
+
(value) => value.split(",").map((s) => s.trim()).filter((s) => s.length > 0)
|
|
4114
|
+
);
|
|
4115
|
+
return {
|
|
4116
|
+
...characterSettings,
|
|
4117
|
+
shouldIgnoreBotMessages: resolveSetting(
|
|
4118
|
+
"DISCORD_SHOULD_IGNORE_BOT_MESSAGES",
|
|
4119
|
+
characterSettings.shouldIgnoreBotMessages,
|
|
4120
|
+
DISCORD_DEFAULTS.SHOULD_IGNORE_BOT_MESSAGES,
|
|
4121
|
+
parseBooleanFromText
|
|
4122
|
+
),
|
|
4123
|
+
shouldIgnoreDirectMessages: resolveSetting(
|
|
4124
|
+
"DISCORD_SHOULD_IGNORE_DIRECT_MESSAGES",
|
|
4125
|
+
characterSettings.shouldIgnoreDirectMessages,
|
|
4126
|
+
DISCORD_DEFAULTS.SHOULD_IGNORE_DIRECT_MESSAGES,
|
|
4127
|
+
parseBooleanFromText
|
|
4128
|
+
),
|
|
4129
|
+
shouldRespondOnlyToMentions: resolveSetting(
|
|
4130
|
+
"DISCORD_SHOULD_RESPOND_ONLY_TO_MENTIONS",
|
|
4131
|
+
characterSettings.shouldRespondOnlyToMentions,
|
|
4132
|
+
DISCORD_DEFAULTS.SHOULD_RESPOND_ONLY_TO_MENTIONS,
|
|
4133
|
+
parseBooleanFromText
|
|
4134
|
+
),
|
|
4135
|
+
// Collapse empty allow-lists back to undefined to keep default open behavior
|
|
4136
|
+
allowedChannelIds: resolvedAllowedChannelIds.length > 0 ? resolvedAllowedChannelIds : void 0
|
|
4137
|
+
};
|
|
4138
|
+
}
|
|
4139
|
+
|
|
4099
4140
|
// src/messages.ts
|
|
4100
4141
|
import {
|
|
4101
4142
|
ChannelType as ChannelType5,
|
|
4102
4143
|
EventType,
|
|
4103
4144
|
ServiceType as ServiceType4,
|
|
4145
|
+
MemoryType,
|
|
4104
4146
|
createUniqueUuid as createUniqueUuid3,
|
|
4105
|
-
logger as
|
|
4147
|
+
logger as logger11
|
|
4106
4148
|
} from "@elizaos/core";
|
|
4107
4149
|
import {
|
|
4108
4150
|
ChannelType as DiscordChannelType3
|
|
@@ -4112,10 +4154,7 @@ import {
|
|
|
4112
4154
|
import fs3 from "node:fs";
|
|
4113
4155
|
import { trimTokens as trimTokens3 } from "@elizaos/core";
|
|
4114
4156
|
import { parseJSONObjectFromText as parseJSONObjectFromText15 } from "@elizaos/core";
|
|
4115
|
-
import {
|
|
4116
|
-
ModelType as ModelType15,
|
|
4117
|
-
ServiceType as ServiceType3
|
|
4118
|
-
} from "@elizaos/core";
|
|
4157
|
+
import { ModelType as ModelType15, ServiceType as ServiceType3 } from "@elizaos/core";
|
|
4119
4158
|
import { Collection } from "discord.js";
|
|
4120
4159
|
import ffmpeg from "fluent-ffmpeg";
|
|
4121
4160
|
async function generateSummary(runtime, text) {
|
|
@@ -4197,9 +4236,7 @@ var AttachmentManager = class {
|
|
|
4197
4236
|
media = await this.processAudioVideoAttachment(attachment);
|
|
4198
4237
|
} else if (attachment.contentType?.startsWith("image/")) {
|
|
4199
4238
|
media = await this.processImageAttachment(attachment);
|
|
4200
|
-
} else if (attachment.contentType?.startsWith("video/") || this.runtime.getService(ServiceType3.VIDEO)?.isVideoUrl(
|
|
4201
|
-
attachment.url
|
|
4202
|
-
)) {
|
|
4239
|
+
} else if (attachment.contentType?.startsWith("video/") || this.runtime.getService(ServiceType3.VIDEO)?.isVideoUrl(attachment.url)) {
|
|
4203
4240
|
media = await this.processVideoAttachment(attachment);
|
|
4204
4241
|
} else {
|
|
4205
4242
|
media = await this.processGenericAttachment(attachment);
|
|
@@ -4226,14 +4263,8 @@ var AttachmentManager = class {
|
|
|
4226
4263
|
} else {
|
|
4227
4264
|
throw new Error("Unsupported audio/video format");
|
|
4228
4265
|
}
|
|
4229
|
-
const transcription = await this.runtime.useModel(
|
|
4230
|
-
|
|
4231
|
-
audioBuffer
|
|
4232
|
-
);
|
|
4233
|
-
const { title, description } = await generateSummary(
|
|
4234
|
-
this.runtime,
|
|
4235
|
-
transcription
|
|
4236
|
-
);
|
|
4266
|
+
const transcription = await this.runtime.useModel(ModelType15.TRANSCRIPTION, audioBuffer);
|
|
4267
|
+
const { title, description } = await generateSummary(this.runtime, transcription);
|
|
4237
4268
|
return {
|
|
4238
4269
|
id: attachment.id,
|
|
4239
4270
|
url: attachment.url,
|
|
@@ -4244,9 +4275,7 @@ var AttachmentManager = class {
|
|
|
4244
4275
|
};
|
|
4245
4276
|
} catch (error) {
|
|
4246
4277
|
if (error instanceof Error) {
|
|
4247
|
-
console.error(
|
|
4248
|
-
`Error processing audio/video attachment: ${error.message}`
|
|
4249
|
-
);
|
|
4278
|
+
console.error(`Error processing audio/video attachment: ${error.message}`);
|
|
4250
4279
|
}
|
|
4251
4280
|
return {
|
|
4252
4281
|
id: attachment.id,
|
|
@@ -4350,13 +4379,9 @@ var AttachmentManager = class {
|
|
|
4350
4379
|
};
|
|
4351
4380
|
} catch (error) {
|
|
4352
4381
|
if (error instanceof Error) {
|
|
4353
|
-
console.error(
|
|
4354
|
-
`Error processing plaintext attachment: ${error.message}`
|
|
4355
|
-
);
|
|
4382
|
+
console.error(`Error processing plaintext attachment: ${error.message}`);
|
|
4356
4383
|
} else {
|
|
4357
|
-
console.error(
|
|
4358
|
-
`An unknown error occurred during plaintext attachment processing`
|
|
4359
|
-
);
|
|
4384
|
+
console.error(`An unknown error occurred during plaintext attachment processing`);
|
|
4360
4385
|
}
|
|
4361
4386
|
return {
|
|
4362
4387
|
id: attachment.id,
|
|
@@ -4432,10 +4457,7 @@ var AttachmentManager = class {
|
|
|
4432
4457
|
};
|
|
4433
4458
|
}
|
|
4434
4459
|
if (typeof videoService.isVideoUrl === "function" && videoService.isVideoUrl(attachment.url)) {
|
|
4435
|
-
const videoInfo = await videoService.processVideo(
|
|
4436
|
-
attachment.url,
|
|
4437
|
-
this.runtime
|
|
4438
|
-
);
|
|
4460
|
+
const videoInfo = await videoService.processVideo(attachment.url, this.runtime);
|
|
4439
4461
|
return {
|
|
4440
4462
|
id: attachment.id,
|
|
4441
4463
|
url: attachment.url,
|
|
@@ -4474,7 +4496,7 @@ var AttachmentManager = class {
|
|
|
4474
4496
|
// src/utils.ts
|
|
4475
4497
|
import {
|
|
4476
4498
|
ModelType as ModelType16,
|
|
4477
|
-
logger as
|
|
4499
|
+
logger as logger10,
|
|
4478
4500
|
parseJSONObjectFromText as parseJSONObjectFromText16,
|
|
4479
4501
|
trimTokens as trimTokens4
|
|
4480
4502
|
} from "@elizaos/core";
|
|
@@ -4505,11 +4527,9 @@ async function sendMessageInChunks(channel, content, _inReplyTo, files, componen
|
|
|
4505
4527
|
(_, value) => typeof value === "bigint" ? value.toString() : value
|
|
4506
4528
|
);
|
|
4507
4529
|
};
|
|
4508
|
-
|
|
4530
|
+
logger10.info(`Components received: ${safeStringify(components)}`);
|
|
4509
4531
|
if (!Array.isArray(components)) {
|
|
4510
|
-
|
|
4511
|
-
"Components is not an array, skipping component processing"
|
|
4512
|
-
);
|
|
4532
|
+
logger10.warn("Components is not an array, skipping component processing");
|
|
4513
4533
|
} else if (components.length > 0 && components[0] && typeof components[0].toJSON === "function") {
|
|
4514
4534
|
options.components = components;
|
|
4515
4535
|
} else {
|
|
@@ -4520,18 +4540,18 @@ async function sendMessageInChunks(channel, content, _inReplyTo, files, componen
|
|
|
4520
4540
|
} = __require("discord.js");
|
|
4521
4541
|
const discordComponents = components.map((row) => {
|
|
4522
4542
|
if (!row || typeof row !== "object" || row.type !== 1) {
|
|
4523
|
-
|
|
4543
|
+
logger10.warn("Invalid component row structure, skipping");
|
|
4524
4544
|
return null;
|
|
4525
4545
|
}
|
|
4526
4546
|
if (row.type === 1) {
|
|
4527
4547
|
const actionRow = new ActionRowBuilder();
|
|
4528
4548
|
if (!Array.isArray(row.components)) {
|
|
4529
|
-
|
|
4549
|
+
logger10.warn("Row components is not an array, skipping");
|
|
4530
4550
|
return null;
|
|
4531
4551
|
}
|
|
4532
4552
|
const validComponents = row.components.map((comp) => {
|
|
4533
4553
|
if (!comp || typeof comp !== "object") {
|
|
4534
|
-
|
|
4554
|
+
logger10.warn("Invalid component, skipping");
|
|
4535
4555
|
return null;
|
|
4536
4556
|
}
|
|
4537
4557
|
try {
|
|
@@ -4539,9 +4559,7 @@ async function sendMessageInChunks(channel, content, _inReplyTo, files, componen
|
|
|
4539
4559
|
return new ButtonBuilder().setCustomId(comp.custom_id).setLabel(comp.label || "").setStyle(comp.style || 1);
|
|
4540
4560
|
}
|
|
4541
4561
|
if (comp.type === 3) {
|
|
4542
|
-
const selectMenu = new StringSelectMenuBuilder().setCustomId(comp.custom_id).setPlaceholder(
|
|
4543
|
-
comp.placeholder || "Select an option"
|
|
4544
|
-
);
|
|
4562
|
+
const selectMenu = new StringSelectMenuBuilder().setCustomId(comp.custom_id).setPlaceholder(comp.placeholder || "Select an option");
|
|
4545
4563
|
if (typeof comp.min_values === "number")
|
|
4546
4564
|
selectMenu.setMinValues(comp.min_values);
|
|
4547
4565
|
if (typeof comp.max_values === "number")
|
|
@@ -4558,7 +4576,7 @@ async function sendMessageInChunks(channel, content, _inReplyTo, files, componen
|
|
|
4558
4576
|
return selectMenu;
|
|
4559
4577
|
}
|
|
4560
4578
|
} catch (err) {
|
|
4561
|
-
|
|
4579
|
+
logger10.error(`Error creating component: ${err}`);
|
|
4562
4580
|
return null;
|
|
4563
4581
|
}
|
|
4564
4582
|
return null;
|
|
@@ -4575,7 +4593,7 @@ async function sendMessageInChunks(channel, content, _inReplyTo, files, componen
|
|
|
4575
4593
|
}
|
|
4576
4594
|
}
|
|
4577
4595
|
} catch (error) {
|
|
4578
|
-
|
|
4596
|
+
logger10.error(`Error processing components: ${error}`);
|
|
4579
4597
|
}
|
|
4580
4598
|
}
|
|
4581
4599
|
const m = await channel.send(options);
|
|
@@ -4583,7 +4601,7 @@ async function sendMessageInChunks(channel, content, _inReplyTo, files, componen
|
|
|
4583
4601
|
}
|
|
4584
4602
|
}
|
|
4585
4603
|
} catch (error) {
|
|
4586
|
-
|
|
4604
|
+
logger10.error(`Error sending message: ${error}`);
|
|
4587
4605
|
}
|
|
4588
4606
|
return sentMessages;
|
|
4589
4607
|
}
|
|
@@ -4648,9 +4666,7 @@ function canSendMessage(channel) {
|
|
|
4648
4666
|
reason: "Could not retrieve permissions"
|
|
4649
4667
|
};
|
|
4650
4668
|
}
|
|
4651
|
-
const missingPermissions = requiredPermissions.filter(
|
|
4652
|
-
(perm) => !permissions.has(perm)
|
|
4653
|
-
);
|
|
4669
|
+
const missingPermissions = requiredPermissions.filter((perm) => !permissions.has(perm));
|
|
4654
4670
|
return {
|
|
4655
4671
|
canSend: missingPermissions.length === 0,
|
|
4656
4672
|
missingPermissions,
|
|
@@ -4664,6 +4680,7 @@ var MessageManager = class {
|
|
|
4664
4680
|
runtime;
|
|
4665
4681
|
attachmentManager;
|
|
4666
4682
|
getChannelType;
|
|
4683
|
+
discordSettings;
|
|
4667
4684
|
/**
|
|
4668
4685
|
* Constructor for a new instance of MyClass.
|
|
4669
4686
|
* @param {any} discordClient - The Discord client object.
|
|
@@ -4673,6 +4690,7 @@ var MessageManager = class {
|
|
|
4673
4690
|
this.runtime = discordClient.runtime;
|
|
4674
4691
|
this.attachmentManager = new AttachmentManager(this.runtime);
|
|
4675
4692
|
this.getChannelType = discordClient.getChannelType;
|
|
4693
|
+
this.discordSettings = getDiscordSettings(this.runtime);
|
|
4676
4694
|
}
|
|
4677
4695
|
/**
|
|
4678
4696
|
* Handles incoming Discord messages and processes them accordingly.
|
|
@@ -4680,22 +4698,30 @@ var MessageManager = class {
|
|
|
4680
4698
|
* @param {DiscordMessage} message - The Discord message to be handled
|
|
4681
4699
|
*/
|
|
4682
4700
|
async handleMessage(message) {
|
|
4683
|
-
if (this.runtime.character.settings?.discord?.allowedChannelIds && !this.runtime.character.settings.discord.allowedChannelIds.some(
|
|
4684
|
-
(id) => id === message.channel.id
|
|
4685
|
-
)) {
|
|
4686
|
-
return;
|
|
4687
|
-
}
|
|
4688
4701
|
if (message.interaction || message.author.id === this.client.user?.id) {
|
|
4689
4702
|
return;
|
|
4690
4703
|
}
|
|
4691
|
-
if (this.
|
|
4704
|
+
if (this.discordSettings.shouldIgnoreBotMessages && message.author?.bot) {
|
|
4692
4705
|
return;
|
|
4693
4706
|
}
|
|
4694
|
-
if (this.
|
|
4707
|
+
if (this.discordSettings.shouldIgnoreDirectMessages && message.channel.type === DiscordChannelType3.DM) {
|
|
4695
4708
|
return;
|
|
4696
4709
|
}
|
|
4697
|
-
|
|
4698
|
-
|
|
4710
|
+
const isBotMentioned = !!(this.client.user?.id && message.mentions.users?.has(this.client.user.id));
|
|
4711
|
+
const isReplyToBot = !!message.reference?.messageId && message.mentions.repliedUser?.id === this.client.user?.id;
|
|
4712
|
+
const isInThread = message.channel.isThread();
|
|
4713
|
+
const isDM = message.channel.type === DiscordChannelType3.DM;
|
|
4714
|
+
if (this.discordSettings.shouldRespondOnlyToMentions) {
|
|
4715
|
+
const shouldProcess = isDM || isBotMentioned || isReplyToBot;
|
|
4716
|
+
if (!shouldProcess) {
|
|
4717
|
+
logger11.debug(
|
|
4718
|
+
"[Discord] Strict mode: ignoring message (no @mention or reply)"
|
|
4719
|
+
);
|
|
4720
|
+
return;
|
|
4721
|
+
}
|
|
4722
|
+
logger11.debug(
|
|
4723
|
+
"[Discord] Strict mode: processing message (has @mention or reply)"
|
|
4724
|
+
);
|
|
4699
4725
|
}
|
|
4700
4726
|
const entityId = createUniqueUuid3(this.runtime, message.author.id);
|
|
4701
4727
|
const userName = message.author.bot ? `${message.author.username}#${message.author.discriminator}` : message.author.username;
|
|
@@ -4708,7 +4734,7 @@ var MessageManager = class {
|
|
|
4708
4734
|
const guild = await message.guild.fetch();
|
|
4709
4735
|
type = await this.getChannelType(message.channel);
|
|
4710
4736
|
if (type === null) {
|
|
4711
|
-
|
|
4737
|
+
logger11.warn("null channel type, discord message", message.id);
|
|
4712
4738
|
}
|
|
4713
4739
|
serverId = guild.id;
|
|
4714
4740
|
} else {
|
|
@@ -4730,10 +4756,7 @@ var MessageManager = class {
|
|
|
4730
4756
|
try {
|
|
4731
4757
|
const canSendResult = canSendMessage(message.channel);
|
|
4732
4758
|
if (!canSendResult.canSend) {
|
|
4733
|
-
return
|
|
4734
|
-
`Cannot send message to channel ${message.channel}`,
|
|
4735
|
-
canSendResult
|
|
4736
|
-
);
|
|
4759
|
+
return logger11.warn(`Cannot send message to channel ${message.channel}`, canSendResult.reason || void 0);
|
|
4737
4760
|
}
|
|
4738
4761
|
const { processedContent, attachments } = await this.processMessage(message);
|
|
4739
4762
|
const audioAttachments = message.attachments.filter(
|
|
@@ -4746,7 +4769,6 @@ var MessageManager = class {
|
|
|
4746
4769
|
if (!processedContent && !attachments?.length) {
|
|
4747
4770
|
return;
|
|
4748
4771
|
}
|
|
4749
|
-
const entityId2 = createUniqueUuid3(this.runtime, message.author.id);
|
|
4750
4772
|
const messageId = createUniqueUuid3(this.runtime, message.id);
|
|
4751
4773
|
const channel = message.channel;
|
|
4752
4774
|
const typingData = {
|
|
@@ -4754,21 +4776,25 @@ var MessageManager = class {
|
|
|
4754
4776
|
cleared: false,
|
|
4755
4777
|
started: false
|
|
4756
4778
|
};
|
|
4757
|
-
const sourceId =
|
|
4779
|
+
const sourceId = entityId;
|
|
4758
4780
|
const newMessage = {
|
|
4759
4781
|
id: messageId,
|
|
4760
|
-
entityId
|
|
4782
|
+
entityId,
|
|
4761
4783
|
agentId: this.runtime.agentId,
|
|
4762
4784
|
roomId,
|
|
4763
4785
|
content: {
|
|
4764
|
-
// name: name,
|
|
4765
|
-
// userName: userName,
|
|
4766
4786
|
text: processedContent || " ",
|
|
4767
4787
|
attachments,
|
|
4768
4788
|
source: "discord",
|
|
4769
4789
|
channelType: type,
|
|
4770
4790
|
url: message.url,
|
|
4771
|
-
inReplyTo: message.reference?.messageId ? createUniqueUuid3(this.runtime, message.reference?.messageId) : void 0
|
|
4791
|
+
inReplyTo: message.reference?.messageId ? createUniqueUuid3(this.runtime, message.reference?.messageId) : void 0,
|
|
4792
|
+
mentionContext: {
|
|
4793
|
+
isMention: isBotMentioned,
|
|
4794
|
+
isReply: isReplyToBot,
|
|
4795
|
+
isThread: isInThread,
|
|
4796
|
+
mentionType: isBotMentioned ? "platform_mention" : isReplyToBot ? "reply" : isInThread ? "thread" : "none"
|
|
4797
|
+
}
|
|
4772
4798
|
},
|
|
4773
4799
|
// metadata of memory
|
|
4774
4800
|
metadata: {
|
|
@@ -4782,8 +4808,7 @@ var MessageManager = class {
|
|
|
4782
4808
|
sourceId,
|
|
4783
4809
|
// why message? all Memories contain content (which is basically a message)
|
|
4784
4810
|
// what are the other types? see MemoryType
|
|
4785
|
-
type:
|
|
4786
|
-
// MemoryType.MESSAGE
|
|
4811
|
+
type: MemoryType.MESSAGE
|
|
4787
4812
|
// scope: `shared`, `private`, or `room
|
|
4788
4813
|
// timestamp
|
|
4789
4814
|
// tags
|
|
@@ -4803,7 +4828,7 @@ var MessageManager = class {
|
|
|
4803
4828
|
channel.sendTyping();
|
|
4804
4829
|
}
|
|
4805
4830
|
} catch (err) {
|
|
4806
|
-
|
|
4831
|
+
logger11.warn("Error sending typing indicator:", String(err));
|
|
4807
4832
|
}
|
|
4808
4833
|
};
|
|
4809
4834
|
startTyping();
|
|
@@ -4817,18 +4842,13 @@ var MessageManager = class {
|
|
|
4817
4842
|
if (content?.channelType === "DM") {
|
|
4818
4843
|
const u = await this.client.users.fetch(message.author.id);
|
|
4819
4844
|
if (!u) {
|
|
4820
|
-
|
|
4845
|
+
logger11.warn("Discord - User not found", message.author.id);
|
|
4821
4846
|
return [];
|
|
4822
4847
|
}
|
|
4823
4848
|
await u.send(content.text || "");
|
|
4824
4849
|
messages = [content];
|
|
4825
4850
|
} else {
|
|
4826
|
-
messages = await sendMessageInChunks(
|
|
4827
|
-
channel,
|
|
4828
|
-
content.text ?? "",
|
|
4829
|
-
message.id,
|
|
4830
|
-
files
|
|
4831
|
-
);
|
|
4851
|
+
messages = await sendMessageInChunks(channel, content.text ?? "", message.id, files || []);
|
|
4832
4852
|
}
|
|
4833
4853
|
const memories = [];
|
|
4834
4854
|
for (const m of messages) {
|
|
@@ -4866,19 +4886,16 @@ var MessageManager = class {
|
|
|
4866
4886
|
return [];
|
|
4867
4887
|
}
|
|
4868
4888
|
};
|
|
4869
|
-
this.runtime.emitEvent(
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
callback
|
|
4875
|
-
}
|
|
4876
|
-
);
|
|
4889
|
+
this.runtime.emitEvent(["DISCORD_MESSAGE_RECEIVED" /* MESSAGE_RECEIVED */, EventType.MESSAGE_RECEIVED], {
|
|
4890
|
+
runtime: this.runtime,
|
|
4891
|
+
message: newMessage,
|
|
4892
|
+
callback
|
|
4893
|
+
});
|
|
4877
4894
|
setTimeout(() => {
|
|
4878
4895
|
if (typingData.started && typingData.interval && !typingData.cleared) {
|
|
4879
4896
|
clearInterval(typingData.interval);
|
|
4880
4897
|
typingData.cleared = true;
|
|
4881
|
-
|
|
4898
|
+
logger11.warn("Typing indicator failsafe timeout triggered");
|
|
4882
4899
|
}
|
|
4883
4900
|
}, 3e4);
|
|
4884
4901
|
} catch (error) {
|
|
@@ -4895,17 +4912,34 @@ var MessageManager = class {
|
|
|
4895
4912
|
async processMessage(message) {
|
|
4896
4913
|
let processedContent = message.content;
|
|
4897
4914
|
let attachments = [];
|
|
4915
|
+
if (message.embeds.length) {
|
|
4916
|
+
for (const i in message.embeds) {
|
|
4917
|
+
const embed = message.embeds[i];
|
|
4918
|
+
processedContent += "\nEmbed #" + (parseInt(i) + 1) + ":\n";
|
|
4919
|
+
processedContent += " Title:" + (embed.title ?? "(none)") + "\n";
|
|
4920
|
+
processedContent += " Description:" + (embed.description ?? "(none)") + "\n";
|
|
4921
|
+
}
|
|
4922
|
+
}
|
|
4923
|
+
if (message.reference) {
|
|
4924
|
+
const messageId = createUniqueUuid3(this.runtime, message.reference.messageId);
|
|
4925
|
+
processedContent += "\nReferencing MessageID " + messageId + " (discord: " + message.reference.messageId + ")";
|
|
4926
|
+
if (message.reference.channelId !== message.channel.id) {
|
|
4927
|
+
const roomId = createUniqueUuid3(this.runtime, message.reference.channelId);
|
|
4928
|
+
processedContent += " in channel " + roomId;
|
|
4929
|
+
}
|
|
4930
|
+
if (message.reference.guildId && message.guild && message.reference.guildId !== message.guild.id) {
|
|
4931
|
+
processedContent += " in guild " + message.reference.guildId;
|
|
4932
|
+
}
|
|
4933
|
+
processedContent += "\n";
|
|
4934
|
+
}
|
|
4898
4935
|
const mentionRegex = /<@!?(\d+)>/g;
|
|
4899
|
-
processedContent = processedContent.replace(
|
|
4900
|
-
|
|
4901
|
-
(
|
|
4902
|
-
|
|
4903
|
-
if (user) {
|
|
4904
|
-
return `${user.username} (@${entityId})`;
|
|
4905
|
-
}
|
|
4906
|
-
return match2;
|
|
4936
|
+
processedContent = processedContent.replace(mentionRegex, (match2, entityId) => {
|
|
4937
|
+
const user = message.mentions.users.get(entityId);
|
|
4938
|
+
if (user) {
|
|
4939
|
+
return `${user.username} (@${entityId})`;
|
|
4907
4940
|
}
|
|
4908
|
-
|
|
4941
|
+
return match2;
|
|
4942
|
+
});
|
|
4909
4943
|
const codeBlockRegex = /```([\s\S]*?)```/g;
|
|
4910
4944
|
let match;
|
|
4911
4945
|
while (match = codeBlockRegex.exec(processedContent)) {
|
|
@@ -4922,15 +4956,10 @@ var MessageManager = class {
|
|
|
4922
4956
|
description,
|
|
4923
4957
|
text: codeBlock
|
|
4924
4958
|
});
|
|
4925
|
-
processedContent = processedContent.replace(
|
|
4926
|
-
match[0],
|
|
4927
|
-
`Code Block (${attachmentId})`
|
|
4928
|
-
);
|
|
4959
|
+
processedContent = processedContent.replace(match[0], `Code Block (${attachmentId})`);
|
|
4929
4960
|
}
|
|
4930
4961
|
if (message.attachments.size > 0) {
|
|
4931
|
-
attachments = await this.attachmentManager.processAttachments(
|
|
4932
|
-
message.attachments
|
|
4933
|
-
);
|
|
4962
|
+
attachments = await this.attachmentManager.processAttachments(message.attachments);
|
|
4934
4963
|
}
|
|
4935
4964
|
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
|
4936
4965
|
const urls = processedContent.match(urlRegex) || [];
|
|
@@ -4947,14 +4976,15 @@ var MessageManager = class {
|
|
|
4947
4976
|
text: videoInfo.text
|
|
4948
4977
|
});
|
|
4949
4978
|
} else {
|
|
4950
|
-
const browserService = this.runtime.getService(
|
|
4951
|
-
ServiceType4.BROWSER
|
|
4952
|
-
);
|
|
4979
|
+
const browserService = this.runtime.getService(ServiceType4.BROWSER);
|
|
4953
4980
|
if (!browserService) {
|
|
4954
|
-
|
|
4981
|
+
logger11.warn("Browser service not found");
|
|
4955
4982
|
continue;
|
|
4956
4983
|
}
|
|
4957
|
-
const { title, description: summary } = await browserService.getPageContent(
|
|
4984
|
+
const { title, description: summary } = await browserService.getPageContent(
|
|
4985
|
+
url,
|
|
4986
|
+
this.runtime
|
|
4987
|
+
);
|
|
4958
4988
|
attachments.push({
|
|
4959
4989
|
id: `webpage-${Date.now()}`,
|
|
4960
4990
|
url,
|
|
@@ -5006,7 +5036,7 @@ import {
|
|
|
5006
5036
|
ChannelType as ChannelType6,
|
|
5007
5037
|
ModelType as ModelType17,
|
|
5008
5038
|
createUniqueUuid as createUniqueUuid4,
|
|
5009
|
-
logger as
|
|
5039
|
+
logger as logger12
|
|
5010
5040
|
} from "@elizaos/core";
|
|
5011
5041
|
import {
|
|
5012
5042
|
ChannelType as DiscordChannelType4
|
|
@@ -5020,13 +5050,13 @@ function createOpusDecoder(options) {
|
|
|
5020
5050
|
try {
|
|
5021
5051
|
return new prism.opus.Decoder(options);
|
|
5022
5052
|
} catch (error) {
|
|
5023
|
-
|
|
5053
|
+
logger12.warn(`Failed to create opus decoder with prism-media: ${error}`);
|
|
5024
5054
|
try {
|
|
5025
5055
|
const { generateDependencyReport } = __require("@discordjs/voice");
|
|
5026
5056
|
const report = generateDependencyReport();
|
|
5027
|
-
|
|
5057
|
+
logger12.debug("Voice dependency report:", report);
|
|
5028
5058
|
} catch (reportError) {
|
|
5029
|
-
|
|
5059
|
+
logger12.warn("Could not generate dependency report:", reportError);
|
|
5030
5060
|
}
|
|
5031
5061
|
throw error;
|
|
5032
5062
|
}
|
|
@@ -5069,17 +5099,14 @@ var AudioMonitor = class {
|
|
|
5069
5099
|
this.lastFlagged = this.buffers.length;
|
|
5070
5100
|
}
|
|
5071
5101
|
this.buffers.push(chunk);
|
|
5072
|
-
const currentSize = this.buffers.reduce(
|
|
5073
|
-
(acc, cur) => acc + cur.length,
|
|
5074
|
-
0
|
|
5075
|
-
);
|
|
5102
|
+
const currentSize = this.buffers.reduce((acc, cur) => acc + cur.length, 0);
|
|
5076
5103
|
while (currentSize > this.maxSize) {
|
|
5077
5104
|
this.buffers.shift();
|
|
5078
5105
|
this.lastFlagged--;
|
|
5079
5106
|
}
|
|
5080
5107
|
});
|
|
5081
5108
|
this.readable.on("end", () => {
|
|
5082
|
-
|
|
5109
|
+
logger12.log("AudioMonitor ended");
|
|
5083
5110
|
this.ended = true;
|
|
5084
5111
|
if (this.lastFlagged < 0) return;
|
|
5085
5112
|
callback(this.getBufferFromStart());
|
|
@@ -5087,14 +5114,14 @@ var AudioMonitor = class {
|
|
|
5087
5114
|
});
|
|
5088
5115
|
this.readable.on("speakingStopped", () => {
|
|
5089
5116
|
if (this.ended) return;
|
|
5090
|
-
|
|
5117
|
+
logger12.log("Speaking stopped");
|
|
5091
5118
|
if (this.lastFlagged < 0) return;
|
|
5092
5119
|
callback(this.getBufferFromStart());
|
|
5093
5120
|
});
|
|
5094
5121
|
this.readable.on("speakingStarted", () => {
|
|
5095
5122
|
if (this.ended) return;
|
|
5096
5123
|
onStart();
|
|
5097
|
-
|
|
5124
|
+
logger12.log("Speaking started");
|
|
5098
5125
|
this.reset();
|
|
5099
5126
|
});
|
|
5100
5127
|
}
|
|
@@ -5178,7 +5205,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5178
5205
|
this.setReady(true);
|
|
5179
5206
|
});
|
|
5180
5207
|
} else {
|
|
5181
|
-
|
|
5208
|
+
logger12.error(
|
|
5182
5209
|
"Discord client is not available in VoiceManager constructor for voiceManagerReady event"
|
|
5183
5210
|
);
|
|
5184
5211
|
this.ready = false;
|
|
@@ -5195,7 +5222,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5195
5222
|
case DiscordChannelType4.GuildStageVoice:
|
|
5196
5223
|
return ChannelType6.VOICE_GROUP;
|
|
5197
5224
|
default:
|
|
5198
|
-
|
|
5225
|
+
logger12.error(
|
|
5199
5226
|
`getChannelType received unexpected channel type: ${channel.type} for channel ${channel.id}`
|
|
5200
5227
|
);
|
|
5201
5228
|
throw new Error(`Unexpected channel type encountered: ${channel.type}`);
|
|
@@ -5208,7 +5235,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5208
5235
|
setReady(status) {
|
|
5209
5236
|
this.ready = status;
|
|
5210
5237
|
this.emit("ready");
|
|
5211
|
-
|
|
5238
|
+
logger12.debug(`VoiceManager is now ready: ${this.ready}`);
|
|
5212
5239
|
}
|
|
5213
5240
|
/**
|
|
5214
5241
|
* Check if the object is ready.
|
|
@@ -5239,10 +5266,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5239
5266
|
this.stopMonitoringMember(member.id);
|
|
5240
5267
|
}
|
|
5241
5268
|
if (newChannelId && this.connections.has(newChannelId)) {
|
|
5242
|
-
await this.monitorMember(
|
|
5243
|
-
member,
|
|
5244
|
-
newState.channel
|
|
5245
|
-
);
|
|
5269
|
+
await this.monitorMember(member, newState.channel);
|
|
5246
5270
|
}
|
|
5247
5271
|
}
|
|
5248
5272
|
/**
|
|
@@ -5273,23 +5297,19 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5273
5297
|
entersState(connection, VoiceConnectionStatus.Ready, 2e4),
|
|
5274
5298
|
entersState(connection, VoiceConnectionStatus.Signalling, 2e4)
|
|
5275
5299
|
]);
|
|
5276
|
-
|
|
5277
|
-
`Voice connection established in state: ${connection.state.status}`
|
|
5278
|
-
);
|
|
5300
|
+
logger12.log(`Voice connection established in state: ${connection.state.status}`);
|
|
5279
5301
|
connection.on("stateChange", async (oldState, newState) => {
|
|
5280
|
-
|
|
5281
|
-
`Voice connection state changed from ${oldState.status} to ${newState.status}`
|
|
5282
|
-
);
|
|
5302
|
+
logger12.log(`Voice connection state changed from ${oldState.status} to ${newState.status}`);
|
|
5283
5303
|
if (newState.status === VoiceConnectionStatus.Disconnected) {
|
|
5284
|
-
|
|
5304
|
+
logger12.log("Handling disconnection...");
|
|
5285
5305
|
try {
|
|
5286
5306
|
await Promise.race([
|
|
5287
5307
|
entersState(connection, VoiceConnectionStatus.Signalling, 5e3),
|
|
5288
5308
|
entersState(connection, VoiceConnectionStatus.Connecting, 5e3)
|
|
5289
5309
|
]);
|
|
5290
|
-
|
|
5310
|
+
logger12.log("Reconnecting to channel...");
|
|
5291
5311
|
} catch (e) {
|
|
5292
|
-
|
|
5312
|
+
logger12.log(`Disconnection confirmed - cleaning up...${e}`);
|
|
5293
5313
|
connection.destroy();
|
|
5294
5314
|
this.connections.delete(channel.id);
|
|
5295
5315
|
}
|
|
@@ -5300,8 +5320,8 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5300
5320
|
}
|
|
5301
5321
|
});
|
|
5302
5322
|
connection.on("error", (error) => {
|
|
5303
|
-
|
|
5304
|
-
|
|
5323
|
+
logger12.log("Voice connection error:", error);
|
|
5324
|
+
logger12.log("Connection error - will attempt to recover...");
|
|
5305
5325
|
});
|
|
5306
5326
|
this.connections.set(channel.id, connection);
|
|
5307
5327
|
const me = channel.guild.members.me;
|
|
@@ -5310,7 +5330,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5310
5330
|
await me.voice.setDeaf(false);
|
|
5311
5331
|
await me.voice.setMute(false);
|
|
5312
5332
|
} catch (error) {
|
|
5313
|
-
|
|
5333
|
+
logger12.log("Failed to modify voice state:", error);
|
|
5314
5334
|
}
|
|
5315
5335
|
}
|
|
5316
5336
|
connection.receiver.speaking.on("start", async (entityId) => {
|
|
@@ -5334,7 +5354,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5334
5354
|
}
|
|
5335
5355
|
});
|
|
5336
5356
|
} catch (error) {
|
|
5337
|
-
|
|
5357
|
+
logger12.log("Failed to establish voice connection:", error);
|
|
5338
5358
|
connection.destroy();
|
|
5339
5359
|
this.connections.delete(channel.id);
|
|
5340
5360
|
throw error;
|
|
@@ -5348,7 +5368,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5348
5368
|
getVoiceConnection(guildId) {
|
|
5349
5369
|
const userId = this.client?.user?.id;
|
|
5350
5370
|
if (!userId) {
|
|
5351
|
-
|
|
5371
|
+
logger12.error("Client user ID is not available.");
|
|
5352
5372
|
return void 0;
|
|
5353
5373
|
}
|
|
5354
5374
|
const connections = getVoiceConnections(userId);
|
|
@@ -5376,9 +5396,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5376
5396
|
emitClose: true
|
|
5377
5397
|
});
|
|
5378
5398
|
if (!receiveStream || receiveStream.readableLength === 0) {
|
|
5379
|
-
|
|
5380
|
-
`[monitorMember] No receiveStream or empty stream for user ${entityId}`
|
|
5381
|
-
);
|
|
5399
|
+
logger12.warn(`[monitorMember] No receiveStream or empty stream for user ${entityId}`);
|
|
5382
5400
|
return;
|
|
5383
5401
|
}
|
|
5384
5402
|
let opusDecoder;
|
|
@@ -5389,9 +5407,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5389
5407
|
frameSize: DECODE_FRAME_SIZE
|
|
5390
5408
|
});
|
|
5391
5409
|
} catch (error) {
|
|
5392
|
-
|
|
5393
|
-
`[monitorMember] Failed to create opus decoder for user ${entityId}: ${error}`
|
|
5394
|
-
);
|
|
5410
|
+
logger12.error(`[monitorMember] Failed to create opus decoder for user ${entityId}: ${error}`);
|
|
5395
5411
|
return;
|
|
5396
5412
|
}
|
|
5397
5413
|
const volumeBuffer = [];
|
|
@@ -5399,11 +5415,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5399
5415
|
const SPEAKING_THRESHOLD = 0.05;
|
|
5400
5416
|
opusDecoder.on("data", (pcmData) => {
|
|
5401
5417
|
if (this.activeAudioPlayer) {
|
|
5402
|
-
const samples = new Int16Array(
|
|
5403
|
-
pcmData.buffer,
|
|
5404
|
-
pcmData.byteOffset,
|
|
5405
|
-
pcmData.length / 2
|
|
5406
|
-
);
|
|
5418
|
+
const samples = new Int16Array(pcmData.buffer, pcmData.byteOffset, pcmData.length / 2);
|
|
5407
5419
|
const maxAmplitude = Math.max(...samples.map(Math.abs)) / 32768;
|
|
5408
5420
|
volumeBuffer.push(maxAmplitude);
|
|
5409
5421
|
if (volumeBuffer.length > VOLUME_WINDOW_SIZE) {
|
|
@@ -5417,36 +5429,30 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5417
5429
|
}
|
|
5418
5430
|
}
|
|
5419
5431
|
});
|
|
5420
|
-
pipeline(
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
);
|
|
5428
|
-
} else {
|
|
5429
|
-
logger13.debug(
|
|
5430
|
-
`[monitorMember] Opus decoding pipeline finished successfully for user ${entityId}`
|
|
5431
|
-
);
|
|
5432
|
-
}
|
|
5432
|
+
pipeline(receiveStream, opusDecoder, (err) => {
|
|
5433
|
+
if (err) {
|
|
5434
|
+
logger12.debug(`[monitorMember] Opus decoding pipeline error for user ${entityId}: ${err}`);
|
|
5435
|
+
} else {
|
|
5436
|
+
logger12.debug(
|
|
5437
|
+
`[monitorMember] Opus decoding pipeline finished successfully for user ${entityId}`
|
|
5438
|
+
);
|
|
5433
5439
|
}
|
|
5434
|
-
);
|
|
5440
|
+
});
|
|
5435
5441
|
this.streams.set(entityId, opusDecoder);
|
|
5436
5442
|
this.connections.set(entityId, connection);
|
|
5437
5443
|
opusDecoder.on("error", (err) => {
|
|
5438
|
-
|
|
5444
|
+
logger12.debug(`Opus decoding error: ${err}`);
|
|
5439
5445
|
});
|
|
5440
5446
|
const errorHandler = (err) => {
|
|
5441
|
-
|
|
5447
|
+
logger12.debug(`Opus decoding error: ${err}`);
|
|
5442
5448
|
};
|
|
5443
5449
|
const streamCloseHandler = () => {
|
|
5444
|
-
|
|
5450
|
+
logger12.debug(`voice stream from ${member?.displayName} closed`);
|
|
5445
5451
|
this.streams.delete(entityId);
|
|
5446
5452
|
this.connections.delete(entityId);
|
|
5447
5453
|
};
|
|
5448
5454
|
const closeHandler = () => {
|
|
5449
|
-
|
|
5455
|
+
logger12.debug(`Opus decoder for ${member?.displayName} closed`);
|
|
5450
5456
|
opusDecoder.removeListener("error", errorHandler);
|
|
5451
5457
|
opusDecoder.removeListener("close", closeHandler);
|
|
5452
5458
|
receiveStream?.removeListener("close", streamCloseHandler);
|
|
@@ -5454,14 +5460,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5454
5460
|
opusDecoder.on("error", errorHandler);
|
|
5455
5461
|
opusDecoder.on("close", closeHandler);
|
|
5456
5462
|
receiveStream?.on("close", streamCloseHandler);
|
|
5457
|
-
this.client?.emit(
|
|
5458
|
-
"userStream",
|
|
5459
|
-
entityId,
|
|
5460
|
-
name,
|
|
5461
|
-
userName,
|
|
5462
|
-
channel,
|
|
5463
|
-
opusDecoder
|
|
5464
|
-
);
|
|
5463
|
+
this.client?.emit("userStream", entityId, name, userName, channel, opusDecoder);
|
|
5465
5464
|
}
|
|
5466
5465
|
/**
|
|
5467
5466
|
* Leaves the specified voice channel and stops monitoring all members in that channel.
|
|
@@ -5480,7 +5479,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5480
5479
|
this.stopMonitoringMember(memberId);
|
|
5481
5480
|
}
|
|
5482
5481
|
}
|
|
5483
|
-
|
|
5482
|
+
logger12.debug(`Left voice channel: ${channel.name} (${channel.id})`);
|
|
5484
5483
|
}
|
|
5485
5484
|
/**
|
|
5486
5485
|
* Stop monitoring a specific member by their member ID.
|
|
@@ -5492,7 +5491,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5492
5491
|
monitorInfo.monitor.stop();
|
|
5493
5492
|
this.activeMonitors.delete(memberId);
|
|
5494
5493
|
this.streams.delete(memberId);
|
|
5495
|
-
|
|
5494
|
+
logger12.debug(`Stopped monitoring user ${memberId}`);
|
|
5496
5495
|
}
|
|
5497
5496
|
}
|
|
5498
5497
|
/**
|
|
@@ -5506,7 +5505,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5506
5505
|
async debouncedProcessTranscription(entityId, name, userName, channel) {
|
|
5507
5506
|
const DEBOUNCE_TRANSCRIPTION_THRESHOLD = 1500;
|
|
5508
5507
|
if (this.activeAudioPlayer?.state?.status === "idle") {
|
|
5509
|
-
|
|
5508
|
+
logger12.log("Cleaning up idle audio player.");
|
|
5510
5509
|
this.cleanupAudioPlayer(this.activeAudioPlayer);
|
|
5511
5510
|
}
|
|
5512
5511
|
if (this.activeAudioPlayer || this.processingVoice) {
|
|
@@ -5523,13 +5522,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5523
5522
|
this.transcriptionTimeout = setTimeout(async () => {
|
|
5524
5523
|
this.processingVoice = true;
|
|
5525
5524
|
try {
|
|
5526
|
-
await this.processTranscription(
|
|
5527
|
-
entityId,
|
|
5528
|
-
channel.id,
|
|
5529
|
-
channel,
|
|
5530
|
-
name,
|
|
5531
|
-
userName
|
|
5532
|
-
);
|
|
5525
|
+
await this.processTranscription(entityId, channel.id, channel, name, userName);
|
|
5533
5526
|
this.userStates.forEach((state, _) => {
|
|
5534
5527
|
state.buffers.length = 0;
|
|
5535
5528
|
state.totalLength = 0;
|
|
@@ -5549,7 +5542,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5549
5542
|
* @param {Readable} audioStream - The audio stream to monitor.
|
|
5550
5543
|
*/
|
|
5551
5544
|
async handleUserStream(entityId, name, userName, channel, audioStream) {
|
|
5552
|
-
|
|
5545
|
+
logger12.debug(`Starting audio monitor for user: ${entityId}`);
|
|
5553
5546
|
if (!this.userStates.has(entityId)) {
|
|
5554
5547
|
this.userStates.set(entityId, {
|
|
5555
5548
|
buffers: [],
|
|
@@ -5609,11 +5602,8 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5609
5602
|
state.buffers.length = 0;
|
|
5610
5603
|
state.totalLength = 0;
|
|
5611
5604
|
const wavBuffer = await this.convertOpusToWav(inputBuffer);
|
|
5612
|
-
|
|
5613
|
-
const transcriptionText = await this.runtime.useModel(
|
|
5614
|
-
ModelType17.TRANSCRIPTION,
|
|
5615
|
-
wavBuffer
|
|
5616
|
-
);
|
|
5605
|
+
logger12.debug("Starting transcription...");
|
|
5606
|
+
const transcriptionText = await this.runtime.useModel(ModelType17.TRANSCRIPTION, wavBuffer);
|
|
5617
5607
|
if (transcriptionText && isValidTranscription2(transcriptionText)) {
|
|
5618
5608
|
state.transcriptionText += transcriptionText;
|
|
5619
5609
|
}
|
|
@@ -5621,14 +5611,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5621
5611
|
this.cleanupAudioPlayer(this.activeAudioPlayer);
|
|
5622
5612
|
const finalText = state.transcriptionText;
|
|
5623
5613
|
state.transcriptionText = "";
|
|
5624
|
-
await this.handleMessage(
|
|
5625
|
-
finalText,
|
|
5626
|
-
entityId,
|
|
5627
|
-
channelId,
|
|
5628
|
-
channel,
|
|
5629
|
-
name,
|
|
5630
|
-
userName
|
|
5631
|
-
);
|
|
5614
|
+
await this.handleMessage(finalText, entityId, channelId, channel, name, userName);
|
|
5632
5615
|
}
|
|
5633
5616
|
} catch (error) {
|
|
5634
5617
|
console.error(`Error transcribing audio for user ${entityId}:`, error);
|
|
@@ -5666,10 +5649,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5666
5649
|
worldName: channel.guild.name
|
|
5667
5650
|
});
|
|
5668
5651
|
const memory = {
|
|
5669
|
-
id: createUniqueUuid4(
|
|
5670
|
-
this.runtime,
|
|
5671
|
-
`${channelId}-voice-message-${Date.now()}`
|
|
5672
|
-
),
|
|
5652
|
+
id: createUniqueUuid4(this.runtime, `${channelId}-voice-message-${Date.now()}`),
|
|
5673
5653
|
agentId: this.runtime.agentId,
|
|
5674
5654
|
entityId: uniqueEntityId,
|
|
5675
5655
|
roomId,
|
|
@@ -5687,10 +5667,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5687
5667
|
const callback = async (content, _files = []) => {
|
|
5688
5668
|
try {
|
|
5689
5669
|
const responseMemory = {
|
|
5690
|
-
id: createUniqueUuid4(
|
|
5691
|
-
this.runtime,
|
|
5692
|
-
`${memory.id}-voice-response-${Date.now()}`
|
|
5693
|
-
),
|
|
5670
|
+
id: createUniqueUuid4(this.runtime, `${memory.id}-voice-response-${Date.now()}`),
|
|
5694
5671
|
entityId: this.runtime.agentId,
|
|
5695
5672
|
agentId: this.runtime.agentId,
|
|
5696
5673
|
content: {
|
|
@@ -5719,14 +5696,11 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5719
5696
|
return [];
|
|
5720
5697
|
}
|
|
5721
5698
|
};
|
|
5722
|
-
this.runtime.emitEvent(
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
callback
|
|
5728
|
-
}
|
|
5729
|
-
);
|
|
5699
|
+
this.runtime.emitEvent(["DISCORD_VOICE_MESSAGE_RECEIVED", "VOICE_MESSAGE_RECEIVED"], {
|
|
5700
|
+
runtime: this.runtime,
|
|
5701
|
+
message: memory,
|
|
5702
|
+
callback
|
|
5703
|
+
});
|
|
5730
5704
|
} catch (error) {
|
|
5731
5705
|
console.error("Error processing voice message:", error);
|
|
5732
5706
|
}
|
|
@@ -5755,9 +5729,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5755
5729
|
async scanGuild(guild) {
|
|
5756
5730
|
let chosenChannel = null;
|
|
5757
5731
|
try {
|
|
5758
|
-
const channelId = this.runtime.getSetting(
|
|
5759
|
-
"DISCORD_VOICE_CHANNEL_ID"
|
|
5760
|
-
);
|
|
5732
|
+
const channelId = this.runtime.getSetting("DISCORD_VOICE_CHANNEL_ID");
|
|
5761
5733
|
if (channelId) {
|
|
5762
5734
|
const channel = await guild.channels.fetch(channelId);
|
|
5763
5735
|
if (channel?.isVoiceBased()) {
|
|
@@ -5776,10 +5748,10 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5776
5748
|
}
|
|
5777
5749
|
}
|
|
5778
5750
|
if (chosenChannel) {
|
|
5779
|
-
|
|
5751
|
+
logger12.debug(`Joining channel: ${chosenChannel.name}`);
|
|
5780
5752
|
await this.joinChannel(chosenChannel);
|
|
5781
5753
|
} else {
|
|
5782
|
-
|
|
5754
|
+
logger12.debug("Warning: No suitable voice channel found to join.");
|
|
5783
5755
|
}
|
|
5784
5756
|
} catch (error) {
|
|
5785
5757
|
console.error("Error selecting or joining a voice channel:", error);
|
|
@@ -5795,7 +5767,7 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5795
5767
|
async playAudioStream(entityId, audioStream) {
|
|
5796
5768
|
const connection = this.connections.get(entityId);
|
|
5797
5769
|
if (connection == null) {
|
|
5798
|
-
|
|
5770
|
+
logger12.debug(`No connection for user ${entityId}`);
|
|
5799
5771
|
return;
|
|
5800
5772
|
}
|
|
5801
5773
|
this.cleanupAudioPlayer(this.activeAudioPlayer);
|
|
@@ -5812,17 +5784,14 @@ var VoiceManager = class extends EventEmitter {
|
|
|
5812
5784
|
});
|
|
5813
5785
|
audioPlayer.play(resource);
|
|
5814
5786
|
audioPlayer.on("error", (err) => {
|
|
5815
|
-
|
|
5787
|
+
logger12.debug(`Audio player error: ${err}`);
|
|
5816
5788
|
});
|
|
5817
|
-
audioPlayer.on(
|
|
5818
|
-
"
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
const idleTime = Date.now();
|
|
5822
|
-
logger13.debug(`Audio playback took: ${idleTime - audioStartTime}ms`);
|
|
5823
|
-
}
|
|
5789
|
+
audioPlayer.on("stateChange", (_oldState, newState) => {
|
|
5790
|
+
if (newState.status === "idle") {
|
|
5791
|
+
const idleTime = Date.now();
|
|
5792
|
+
logger12.debug(`Audio playback took: ${idleTime - audioStartTime}ms`);
|
|
5824
5793
|
}
|
|
5825
|
-
);
|
|
5794
|
+
});
|
|
5826
5795
|
}
|
|
5827
5796
|
/**
|
|
5828
5797
|
* Cleans up the provided audio player by stopping it, removing all listeners,
|
|
@@ -5901,8 +5870,10 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
5901
5870
|
character;
|
|
5902
5871
|
messageManager;
|
|
5903
5872
|
voiceManager;
|
|
5873
|
+
discordSettings;
|
|
5904
5874
|
userSelections = /* @__PURE__ */ new Map();
|
|
5905
5875
|
timeouts = [];
|
|
5876
|
+
clientReadyPromise;
|
|
5906
5877
|
/**
|
|
5907
5878
|
* List of allowed channel IDs (parsed from CHANNEL_IDS env var).
|
|
5908
5879
|
* If undefined, all channels are allowed.
|
|
@@ -5922,14 +5893,16 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
5922
5893
|
*/
|
|
5923
5894
|
constructor(runtime) {
|
|
5924
5895
|
super(runtime);
|
|
5896
|
+
this.discordSettings = getDiscordSettings(runtime);
|
|
5925
5897
|
this.character = runtime.character;
|
|
5926
5898
|
const channelIdsRaw = runtime.getSetting("CHANNEL_IDS");
|
|
5927
|
-
if (channelIdsRaw && channelIdsRaw.trim()) {
|
|
5899
|
+
if (channelIdsRaw?.trim && channelIdsRaw.trim()) {
|
|
5928
5900
|
this.allowedChannelIds = channelIdsRaw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
5901
|
+
this.runtime.logger.debug("Locking down discord to", this.allowedChannelIds);
|
|
5929
5902
|
}
|
|
5930
5903
|
const token = runtime.getSetting("DISCORD_API_TOKEN");
|
|
5931
|
-
if (!token || token.trim() === "") {
|
|
5932
|
-
|
|
5904
|
+
if (!token || token?.trim && token.trim() === "") {
|
|
5905
|
+
this.runtime.logger.warn("Discord API Token not provided - Discord functionality will be unavailable");
|
|
5933
5906
|
this.client = null;
|
|
5934
5907
|
return;
|
|
5935
5908
|
}
|
|
@@ -5947,22 +5920,22 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
5947
5920
|
GatewayIntentBits.GuildMessageTyping,
|
|
5948
5921
|
GatewayIntentBits.GuildMessageReactions
|
|
5949
5922
|
],
|
|
5950
|
-
partials: [
|
|
5951
|
-
Partials.Channel,
|
|
5952
|
-
Partials.Message,
|
|
5953
|
-
Partials.User,
|
|
5954
|
-
Partials.Reaction
|
|
5955
|
-
]
|
|
5923
|
+
partials: [Partials.Channel, Partials.Message, Partials.User, Partials.Reaction]
|
|
5956
5924
|
});
|
|
5957
5925
|
this.runtime = runtime;
|
|
5958
5926
|
this.voiceManager = new VoiceManager(this, runtime);
|
|
5959
5927
|
this.messageManager = new MessageManager(this);
|
|
5960
|
-
this.
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
);
|
|
5965
|
-
this.client
|
|
5928
|
+
this.clientReadyPromise = new Promise((resolver) => {
|
|
5929
|
+
this.client.once(Events.ClientReady, (readyClient) => {
|
|
5930
|
+
resolver();
|
|
5931
|
+
this.onReady(readyClient);
|
|
5932
|
+
});
|
|
5933
|
+
this.client.login(token).catch((error) => {
|
|
5934
|
+
this.runtime.logger.error(
|
|
5935
|
+
`Failed to login to Discord: ${error instanceof Error ? error.message : String(error)}`
|
|
5936
|
+
);
|
|
5937
|
+
this.client = null;
|
|
5938
|
+
});
|
|
5966
5939
|
});
|
|
5967
5940
|
this.setupEventListeners();
|
|
5968
5941
|
this.registerSendHandler();
|
|
@@ -5983,10 +5956,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
5983
5956
|
*/
|
|
5984
5957
|
registerSendHandler() {
|
|
5985
5958
|
if (this.runtime) {
|
|
5986
|
-
this.runtime.registerSendHandler(
|
|
5987
|
-
"discord",
|
|
5988
|
-
this.handleSendMessage.bind(this)
|
|
5989
|
-
);
|
|
5959
|
+
this.runtime.registerSendHandler("discord", this.handleSendMessage.bind(this));
|
|
5990
5960
|
}
|
|
5991
5961
|
}
|
|
5992
5962
|
/**
|
|
@@ -6034,14 +6004,10 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6034
6004
|
await targetChannel.send(chunk);
|
|
6035
6005
|
}
|
|
6036
6006
|
} else {
|
|
6037
|
-
runtime.logger.warn(
|
|
6038
|
-
"[Discord SendHandler] No text content provided to send."
|
|
6039
|
-
);
|
|
6007
|
+
runtime.logger.warn("[Discord SendHandler] No text content provided to send.");
|
|
6040
6008
|
}
|
|
6041
6009
|
} else {
|
|
6042
|
-
throw new Error(
|
|
6043
|
-
`Target channel ${targetChannel.id} does not have a send method.`
|
|
6044
|
-
);
|
|
6010
|
+
throw new Error(`Target channel ${targetChannel.id} does not have a send method.`);
|
|
6045
6011
|
}
|
|
6046
6012
|
} else {
|
|
6047
6013
|
throw new Error(
|
|
@@ -6050,11 +6016,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6050
6016
|
}
|
|
6051
6017
|
} catch (error) {
|
|
6052
6018
|
runtime.logger.error(
|
|
6053
|
-
`[Discord SendHandler] Error sending message: ${error instanceof Error ? error.message : String(error)}
|
|
6054
|
-
{
|
|
6055
|
-
target,
|
|
6056
|
-
content
|
|
6057
|
-
}
|
|
6019
|
+
`[Discord SendHandler] Error sending message: ${error instanceof Error ? error.message : String(error)} - Target: ${JSON.stringify(target)}, Content: ${JSON.stringify(content)}`
|
|
6058
6020
|
);
|
|
6059
6021
|
throw error;
|
|
6060
6022
|
}
|
|
@@ -6098,30 +6060,103 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6098
6060
|
if (!this.client) {
|
|
6099
6061
|
return;
|
|
6100
6062
|
}
|
|
6063
|
+
const listenCidsRaw = this.runtime.getSetting("DISCORD_LISTEN_CHANNEL_IDS");
|
|
6064
|
+
const listenCids = Array.isArray(listenCidsRaw) ? listenCidsRaw : listenCidsRaw && typeof listenCidsRaw === "string" && listenCidsRaw.trim() ? listenCidsRaw.trim().split(",").map((s) => s.trim()).filter((s) => s.length > 0) : [];
|
|
6065
|
+
const talkCids = this.allowedChannelIds ?? [];
|
|
6066
|
+
const allowedCids = [...listenCids, ...talkCids];
|
|
6101
6067
|
this.client.on("messageCreate", async (message) => {
|
|
6102
|
-
if (message.author.id === this.client?.user?.id || message.author.bot && this.
|
|
6103
|
-
|
|
6104
|
-
`Got message where author is ${message.author.bot && this.
|
|
6068
|
+
if (message.author.id === this.client?.user?.id || message.author.bot && this.discordSettings.shouldIgnoreBotMessages) {
|
|
6069
|
+
this.runtime.logger.info(
|
|
6070
|
+
`Got message where author is ${message.author.bot && this.discordSettings.shouldIgnoreBotMessages ? "a bot. To reply anyway, set `shouldIgnoreBotMessages=true`." : "the current user. Ignore!"}`
|
|
6105
6071
|
);
|
|
6106
6072
|
return;
|
|
6107
6073
|
}
|
|
6074
|
+
if (listenCids.includes(message.channel.id)) {
|
|
6075
|
+
const entityId = createUniqueUuid5(this.runtime, message.author.id);
|
|
6076
|
+
const userName = message.author.bot ? `${message.author.username}#${message.author.discriminator}` : message.author.username;
|
|
6077
|
+
const name = message.author.displayName;
|
|
6078
|
+
const channelId = message.channel.id;
|
|
6079
|
+
const roomId = createUniqueUuid5(this.runtime, channelId);
|
|
6080
|
+
let type;
|
|
6081
|
+
let serverId;
|
|
6082
|
+
if (message.guild) {
|
|
6083
|
+
const guild = await message.guild.fetch();
|
|
6084
|
+
type = await this.getChannelType(message.channel);
|
|
6085
|
+
if (type === null) {
|
|
6086
|
+
this.runtime.logger.warn("null channel type, discord message", message);
|
|
6087
|
+
}
|
|
6088
|
+
serverId = guild.id;
|
|
6089
|
+
} else {
|
|
6090
|
+
type = ChannelType7.DM;
|
|
6091
|
+
serverId = message.channel.id;
|
|
6092
|
+
}
|
|
6093
|
+
const { processedContent, attachments } = await this.messageManager.processMessage(message);
|
|
6094
|
+
const messageId = createUniqueUuid5(this.runtime, message.id);
|
|
6095
|
+
const sourceId = entityId;
|
|
6096
|
+
const newMessage = {
|
|
6097
|
+
id: messageId,
|
|
6098
|
+
entityId,
|
|
6099
|
+
agentId: this.runtime.agentId,
|
|
6100
|
+
roomId,
|
|
6101
|
+
content: {
|
|
6102
|
+
// name: name,
|
|
6103
|
+
// userName: userName,
|
|
6104
|
+
text: processedContent || " ",
|
|
6105
|
+
attachments,
|
|
6106
|
+
source: "discord",
|
|
6107
|
+
channelType: type,
|
|
6108
|
+
url: message.url,
|
|
6109
|
+
inReplyTo: message.reference?.messageId ? createUniqueUuid5(this.runtime, message.reference?.messageId) : void 0
|
|
6110
|
+
},
|
|
6111
|
+
// metadata of memory
|
|
6112
|
+
metadata: {
|
|
6113
|
+
entityName: name,
|
|
6114
|
+
fromBot: message.author.bot,
|
|
6115
|
+
// include very technical/exact reference to this user for security reasons
|
|
6116
|
+
// don't remove or change this, spartan needs this
|
|
6117
|
+
fromId: message.author.id,
|
|
6118
|
+
// do we need to duplicate this, we have it in content
|
|
6119
|
+
// source: "discord",
|
|
6120
|
+
sourceId,
|
|
6121
|
+
// why message? all Memories contain content (which is basically a message)
|
|
6122
|
+
// what are the other types? see MemoryType
|
|
6123
|
+
type: "message"
|
|
6124
|
+
// MemoryType.MESSAGE
|
|
6125
|
+
// scope: `shared`, `private`, or `room
|
|
6126
|
+
// timestamp
|
|
6127
|
+
// tags
|
|
6128
|
+
},
|
|
6129
|
+
createdAt: message.createdTimestamp
|
|
6130
|
+
};
|
|
6131
|
+
this.runtime.emitEvent("DISCORD_LISTEN_CHANNEL_MESSAGE", {
|
|
6132
|
+
runtime: this.runtime,
|
|
6133
|
+
message: newMessage
|
|
6134
|
+
});
|
|
6135
|
+
}
|
|
6108
6136
|
if (this.allowedChannelIds && !this.isChannelAllowed(message.channel.id)) {
|
|
6109
6137
|
const channel = await this.client?.channels.fetch(message.channel.id);
|
|
6138
|
+
this.runtime.emitEvent("DISCORD_NOT_IN_CHANNELS_MESSAGE", {
|
|
6139
|
+
runtime: this.runtime,
|
|
6140
|
+
message
|
|
6141
|
+
});
|
|
6110
6142
|
if (!channel) {
|
|
6111
|
-
|
|
6143
|
+
this.runtime.logger.error(`Channel id ${message.channel.id} not found. Ignore!`);
|
|
6112
6144
|
return;
|
|
6113
6145
|
}
|
|
6114
6146
|
if (channel.isThread()) {
|
|
6115
6147
|
if (!channel.parentId || !this.isChannelAllowed(channel.parentId)) {
|
|
6116
|
-
|
|
6148
|
+
this.runtime.logger.info(
|
|
6117
6149
|
`Thread not in an allowed channel. Add the channel ${channel.parentId} to CHANNEL_IDS to enable replies.`
|
|
6118
6150
|
);
|
|
6119
6151
|
return;
|
|
6120
6152
|
}
|
|
6121
6153
|
} else {
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6154
|
+
if (channel?.isTextBased()) {
|
|
6155
|
+
const channelLabel = "name" in channel ? channel.name : channel.id;
|
|
6156
|
+
this.runtime.logger.debug(
|
|
6157
|
+
`Channel ${channelLabel} not allowed. Add the channel ${channel.id} to CHANNEL_IDS to enable replies.`
|
|
6158
|
+
);
|
|
6159
|
+
}
|
|
6125
6160
|
return;
|
|
6126
6161
|
}
|
|
6127
6162
|
}
|
|
@@ -6181,21 +6216,11 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6181
6216
|
this.runtime.logger.error(`Error handling interaction: ${error}`);
|
|
6182
6217
|
}
|
|
6183
6218
|
});
|
|
6184
|
-
this.client.on(
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
console.log("userStream", entityId, name, userName, channel.id);
|
|
6188
|
-
if (entityId !== this.client?.user?.id) {
|
|
6189
|
-
this.voiceManager?.handleUserStream(
|
|
6190
|
-
entityId,
|
|
6191
|
-
name,
|
|
6192
|
-
userName,
|
|
6193
|
-
channel,
|
|
6194
|
-
opusDecoder
|
|
6195
|
-
);
|
|
6196
|
-
}
|
|
6219
|
+
this.client.on("userStream", (entityId, name, userName, channel, opusDecoder) => {
|
|
6220
|
+
if (entityId !== this.client?.user?.id) {
|
|
6221
|
+
this.voiceManager?.handleUserStream(entityId, name, userName, channel, opusDecoder);
|
|
6197
6222
|
}
|
|
6198
|
-
);
|
|
6223
|
+
});
|
|
6199
6224
|
}
|
|
6200
6225
|
/**
|
|
6201
6226
|
* Handles the event when a new member joins a guild.
|
|
@@ -6276,6 +6301,13 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6276
6301
|
async handleInteractionCreate(interaction) {
|
|
6277
6302
|
if (interaction.isCommand()) {
|
|
6278
6303
|
switch (interaction.commandName) {
|
|
6304
|
+
case "start":
|
|
6305
|
+
await interaction.deferReply();
|
|
6306
|
+
this.runtime.emitEvent(["DISCORD_SLASH_START" /* SLASH_START */], {
|
|
6307
|
+
interaction,
|
|
6308
|
+
client: this.client
|
|
6309
|
+
});
|
|
6310
|
+
break;
|
|
6279
6311
|
case "joinchannel":
|
|
6280
6312
|
await this.voiceManager?.handleJoinChannelCommand(interaction);
|
|
6281
6313
|
break;
|
|
@@ -6293,9 +6325,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6293
6325
|
}
|
|
6294
6326
|
const userSelections = this.userSelections.get(userId);
|
|
6295
6327
|
if (!userSelections) {
|
|
6296
|
-
this.runtime.logger.error(
|
|
6297
|
-
`User selections map unexpectedly missing for user ${userId}`
|
|
6298
|
-
);
|
|
6328
|
+
this.runtime.logger.error(`User selections map unexpectedly missing for user ${userId}`);
|
|
6299
6329
|
return;
|
|
6300
6330
|
}
|
|
6301
6331
|
try {
|
|
@@ -6315,13 +6345,9 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6315
6345
|
}
|
|
6316
6346
|
if (interaction.isButton()) {
|
|
6317
6347
|
this.runtime.logger.info("Button interaction detected");
|
|
6318
|
-
this.runtime.logger.info(
|
|
6319
|
-
`Button pressed by user ${userId}: ${interaction.customId}`
|
|
6320
|
-
);
|
|
6348
|
+
this.runtime.logger.info(`Button pressed by user ${userId}: ${interaction.customId}`);
|
|
6321
6349
|
const formSelections = userSelections[messageId] || {};
|
|
6322
|
-
this.runtime.logger.info(
|
|
6323
|
-
`Form data being submitted: ${JSON.stringify(formSelections)}`
|
|
6324
|
-
);
|
|
6350
|
+
this.runtime.logger.info(`Form data being submitted: ${JSON.stringify(formSelections)}`);
|
|
6325
6351
|
this.runtime.emitEvent(["DISCORD_INTERACTION"], {
|
|
6326
6352
|
interaction: {
|
|
6327
6353
|
customId: interaction.customId,
|
|
@@ -6386,8 +6412,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6386
6412
|
).map((member) => createUniqueUuid5(this.runtime, member.id));
|
|
6387
6413
|
} catch (error) {
|
|
6388
6414
|
this.runtime.logger.warn(
|
|
6389
|
-
`Failed to get participants for channel ${channel.name}
|
|
6390
|
-
error
|
|
6415
|
+
`Failed to get participants for channel ${channel.name}: ${error instanceof Error ? error.message : String(error)}`
|
|
6391
6416
|
);
|
|
6392
6417
|
}
|
|
6393
6418
|
}
|
|
@@ -6425,11 +6450,9 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6425
6450
|
id: createUniqueUuid5(this.runtime, member.id),
|
|
6426
6451
|
names: Array.from(
|
|
6427
6452
|
new Set(
|
|
6428
|
-
[
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
member.user.globalName
|
|
6432
|
-
].filter(Boolean)
|
|
6453
|
+
[member.user.username, member.displayName, member.user.globalName].filter(
|
|
6454
|
+
Boolean
|
|
6455
|
+
)
|
|
6433
6456
|
)
|
|
6434
6457
|
),
|
|
6435
6458
|
agentId: this.runtime.agentId,
|
|
@@ -6464,11 +6487,9 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6464
6487
|
id: entityId,
|
|
6465
6488
|
names: Array.from(
|
|
6466
6489
|
new Set(
|
|
6467
|
-
[
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
member.user.globalName
|
|
6471
|
-
].filter(Boolean)
|
|
6490
|
+
[member.user.username, member.displayName, member.user.globalName].filter(
|
|
6491
|
+
Boolean
|
|
6492
|
+
)
|
|
6472
6493
|
)
|
|
6473
6494
|
),
|
|
6474
6495
|
agentId: this.runtime.agentId,
|
|
@@ -6494,7 +6515,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6494
6515
|
}
|
|
6495
6516
|
}
|
|
6496
6517
|
} catch (error) {
|
|
6497
|
-
this.runtime.logger.error(`Error fetching members for ${guild.name}
|
|
6518
|
+
this.runtime.logger.error(`Error fetching members for ${guild.name}: ${error instanceof Error ? error.message : String(error)}`);
|
|
6498
6519
|
}
|
|
6499
6520
|
} else {
|
|
6500
6521
|
try {
|
|
@@ -6509,11 +6530,9 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6509
6530
|
id: createUniqueUuid5(this.runtime, member.id),
|
|
6510
6531
|
names: Array.from(
|
|
6511
6532
|
new Set(
|
|
6512
|
-
[
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
member.user.globalName
|
|
6516
|
-
].filter(Boolean)
|
|
6533
|
+
[member.user.username, member.displayName, member.user.globalName].filter(
|
|
6534
|
+
Boolean
|
|
6535
|
+
)
|
|
6517
6536
|
)
|
|
6518
6537
|
),
|
|
6519
6538
|
agentId: this.runtime.agentId,
|
|
@@ -6537,7 +6556,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6537
6556
|
}
|
|
6538
6557
|
}
|
|
6539
6558
|
} catch (error) {
|
|
6540
|
-
this.runtime.logger.error(`Error fetching members for ${guild.name}
|
|
6559
|
+
this.runtime.logger.error(`Error fetching members for ${guild.name}: ${error instanceof Error ? error.message : String(error)}`);
|
|
6541
6560
|
}
|
|
6542
6561
|
}
|
|
6543
6562
|
return entities;
|
|
@@ -6550,6 +6569,40 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6550
6569
|
*/
|
|
6551
6570
|
async onReady(readyClient) {
|
|
6552
6571
|
this.runtime.logger.success("DISCORD ON READY");
|
|
6572
|
+
const commands = [
|
|
6573
|
+
{
|
|
6574
|
+
name: "start",
|
|
6575
|
+
description: "Perhaps get bot information"
|
|
6576
|
+
}
|
|
6577
|
+
// actions control access better
|
|
6578
|
+
/*
|
|
6579
|
+
{
|
|
6580
|
+
name: "joinchannel",
|
|
6581
|
+
description: "Join a voice channel",
|
|
6582
|
+
options: [
|
|
6583
|
+
{
|
|
6584
|
+
name: "channel",
|
|
6585
|
+
type: 7, // CHANNEL type
|
|
6586
|
+
description: "The voice channel to join",
|
|
6587
|
+
required: true,
|
|
6588
|
+
channel_types: [2], // GuildVoice type
|
|
6589
|
+
},
|
|
6590
|
+
],
|
|
6591
|
+
},
|
|
6592
|
+
{
|
|
6593
|
+
name: "leavechannel",
|
|
6594
|
+
description: "Leave the current voice channel",
|
|
6595
|
+
},
|
|
6596
|
+
*/
|
|
6597
|
+
];
|
|
6598
|
+
try {
|
|
6599
|
+
if (this.client?.application) {
|
|
6600
|
+
await this.client.application.commands.set(commands);
|
|
6601
|
+
}
|
|
6602
|
+
this.runtime.logger.success("Slash commands registered");
|
|
6603
|
+
} catch (error) {
|
|
6604
|
+
console.error("Error registering slash commands:", error);
|
|
6605
|
+
}
|
|
6553
6606
|
const requiredPermissions = [
|
|
6554
6607
|
// Text Permissions
|
|
6555
6608
|
PermissionsBitField5.Flags.ViewChannel,
|
|
@@ -6582,6 +6635,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6582
6635
|
}
|
|
6583
6636
|
for (const [, guild] of guilds) {
|
|
6584
6637
|
const fullGuild = await guild.fetch();
|
|
6638
|
+
await fullGuild.commands.set(commands);
|
|
6585
6639
|
const timeoutId = setTimeout(async () => {
|
|
6586
6640
|
try {
|
|
6587
6641
|
const fullGuild2 = await guild.fetch();
|
|
@@ -6614,7 +6668,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6614
6668
|
};
|
|
6615
6669
|
this.runtime.emitEvent([EventType2.WORLD_CONNECTED], standardizedData);
|
|
6616
6670
|
} catch (error) {
|
|
6617
|
-
this.runtime.logger.error(
|
|
6671
|
+
this.runtime.logger.error(`Error during Discord world connection: ${error instanceof Error ? error.message : String(error)}`);
|
|
6618
6672
|
}
|
|
6619
6673
|
}, 1e3);
|
|
6620
6674
|
this.timeouts.push(timeoutId);
|
|
@@ -6649,9 +6703,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6649
6703
|
`Fetching members for text channel ${channelId}, useCache=${useCache}`
|
|
6650
6704
|
);
|
|
6651
6705
|
try {
|
|
6652
|
-
const channel = await this.client?.channels.fetch(
|
|
6653
|
-
channelId
|
|
6654
|
-
);
|
|
6706
|
+
const channel = await this.client?.channels.fetch(channelId);
|
|
6655
6707
|
if (!channel) {
|
|
6656
6708
|
this.runtime.logger.error(`Channel not found: ${channelId}`);
|
|
6657
6709
|
return [];
|
|
@@ -6675,14 +6727,12 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6675
6727
|
} else {
|
|
6676
6728
|
try {
|
|
6677
6729
|
if (useCache && guild.members.cache.size > 0) {
|
|
6678
|
-
this.runtime.logger.info(
|
|
6679
|
-
`Using cached members (${guild.members.cache.size} members)`
|
|
6680
|
-
);
|
|
6730
|
+
this.runtime.logger.info(`Using cached members (${guild.members.cache.size} members)`);
|
|
6681
6731
|
members = guild.members.cache;
|
|
6682
6732
|
} else {
|
|
6683
6733
|
this.runtime.logger.info(`Fetching members for guild ${guild.name}`);
|
|
6684
6734
|
members = await guild.members.fetch();
|
|
6685
|
-
|
|
6735
|
+
logger13.info(`Fetched ${members.size} members`);
|
|
6686
6736
|
}
|
|
6687
6737
|
} catch (error) {
|
|
6688
6738
|
this.runtime.logger.error(`Error fetching members: ${error}`);
|
|
@@ -6730,25 +6780,19 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6730
6780
|
try {
|
|
6731
6781
|
await reaction.fetch();
|
|
6732
6782
|
} catch (error) {
|
|
6733
|
-
this.runtime.logger.error(
|
|
6783
|
+
this.runtime.logger.error(`Failed to fetch partial reaction: ${error instanceof Error ? error.message : String(error)}`);
|
|
6734
6784
|
return;
|
|
6735
6785
|
}
|
|
6736
6786
|
}
|
|
6737
6787
|
const timestamp = Date.now();
|
|
6738
|
-
const roomId = createUniqueUuid5(
|
|
6739
|
-
this.runtime,
|
|
6740
|
-
reaction.message.channel.id
|
|
6741
|
-
);
|
|
6788
|
+
const roomId = createUniqueUuid5(this.runtime, reaction.message.channel.id);
|
|
6742
6789
|
const entityId = createUniqueUuid5(this.runtime, user.id);
|
|
6743
6790
|
const reactionUUID = createUniqueUuid5(
|
|
6744
6791
|
this.runtime,
|
|
6745
6792
|
`${reaction.message.id}-${user.id}-${emoji}-${timestamp}`
|
|
6746
6793
|
);
|
|
6747
6794
|
if (!entityId || !roomId) {
|
|
6748
|
-
this.runtime.logger.error(
|
|
6749
|
-
entityId,
|
|
6750
|
-
roomId
|
|
6751
|
-
});
|
|
6795
|
+
this.runtime.logger.error(`Invalid user ID or room ID: ${entityId} ${roomId}`);
|
|
6752
6796
|
return;
|
|
6753
6797
|
}
|
|
6754
6798
|
const messageContent = reaction.message.content || "";
|
|
@@ -6760,10 +6804,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6760
6804
|
entityId,
|
|
6761
6805
|
roomId,
|
|
6762
6806
|
userName,
|
|
6763
|
-
worldId: createUniqueUuid5(
|
|
6764
|
-
this.runtime,
|
|
6765
|
-
reaction.message.guild?.id ?? roomId
|
|
6766
|
-
),
|
|
6807
|
+
worldId: createUniqueUuid5(this.runtime, reaction.message.guild?.id ?? roomId),
|
|
6767
6808
|
worldName: reaction.message.guild?.name,
|
|
6768
6809
|
name,
|
|
6769
6810
|
source: "discord",
|
|
@@ -6782,9 +6823,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6782
6823
|
text: reactionMessage,
|
|
6783
6824
|
source: "discord",
|
|
6784
6825
|
inReplyTo,
|
|
6785
|
-
channelType: await this.getChannelType(
|
|
6786
|
-
reaction.message.channel
|
|
6787
|
-
)
|
|
6826
|
+
channelType: await this.getChannelType(reaction.message.channel)
|
|
6788
6827
|
},
|
|
6789
6828
|
roomId,
|
|
6790
6829
|
createdAt: timestamp
|
|
@@ -6794,21 +6833,16 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6794
6833
|
this.runtime.logger.error("No channel found for reaction message");
|
|
6795
6834
|
return [];
|
|
6796
6835
|
}
|
|
6797
|
-
await reaction.message.channel.send(
|
|
6798
|
-
content.text ?? ""
|
|
6799
|
-
);
|
|
6836
|
+
await reaction.message.channel.send(content.text ?? "");
|
|
6800
6837
|
return [];
|
|
6801
6838
|
};
|
|
6802
|
-
this.runtime.emitEvent(
|
|
6803
|
-
|
|
6804
|
-
|
|
6805
|
-
|
|
6806
|
-
|
|
6807
|
-
callback
|
|
6808
|
-
}
|
|
6809
|
-
);
|
|
6839
|
+
this.runtime.emitEvent(["DISCORD_REACTION_RECEIVED", "REACTION_RECEIVED"], {
|
|
6840
|
+
runtime: this.runtime,
|
|
6841
|
+
message: memory,
|
|
6842
|
+
callback
|
|
6843
|
+
});
|
|
6810
6844
|
} catch (error) {
|
|
6811
|
-
this.runtime.logger.error(
|
|
6845
|
+
this.runtime.logger.error(`Error handling reaction: ${error instanceof Error ? error.message : String(error)}`);
|
|
6812
6846
|
}
|
|
6813
6847
|
}
|
|
6814
6848
|
/**
|
|
@@ -6826,20 +6860,14 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6826
6860
|
try {
|
|
6827
6861
|
await reaction.fetch();
|
|
6828
6862
|
} catch (error) {
|
|
6829
|
-
this.runtime.logger.error(
|
|
6830
|
-
"Something went wrong when fetching the message:",
|
|
6831
|
-
error
|
|
6832
|
-
);
|
|
6863
|
+
this.runtime.logger.error(`Something went wrong when fetching the message: ${error instanceof Error ? error.message : String(error)}`);
|
|
6833
6864
|
return;
|
|
6834
6865
|
}
|
|
6835
6866
|
}
|
|
6836
6867
|
const messageContent = reaction.message.content || "";
|
|
6837
6868
|
const truncatedContent = messageContent.length > 50 ? `${messageContent.substring(0, 50)}...` : messageContent;
|
|
6838
6869
|
const reactionMessage = `*Removed <${emoji}> from: \\"${truncatedContent}\\"*`;
|
|
6839
|
-
const roomId = createUniqueUuid5(
|
|
6840
|
-
this.runtime,
|
|
6841
|
-
reaction.message.channel.id
|
|
6842
|
-
);
|
|
6870
|
+
const roomId = createUniqueUuid5(this.runtime, reaction.message.channel.id);
|
|
6843
6871
|
const entityId = createUniqueUuid5(this.runtime, user.id);
|
|
6844
6872
|
const timestamp = Date.now();
|
|
6845
6873
|
const reactionUUID = createUniqueUuid5(
|
|
@@ -6852,10 +6880,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6852
6880
|
entityId,
|
|
6853
6881
|
roomId,
|
|
6854
6882
|
userName,
|
|
6855
|
-
worldId: createUniqueUuid5(
|
|
6856
|
-
this.runtime,
|
|
6857
|
-
reaction.message.guild?.id ?? roomId
|
|
6858
|
-
),
|
|
6883
|
+
worldId: createUniqueUuid5(this.runtime, reaction.message.guild?.id ?? roomId),
|
|
6859
6884
|
worldName: reaction.message.guild?.name,
|
|
6860
6885
|
name,
|
|
6861
6886
|
source: "discord",
|
|
@@ -6873,9 +6898,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6873
6898
|
text: reactionMessage,
|
|
6874
6899
|
source: "discord",
|
|
6875
6900
|
inReplyTo: createUniqueUuid5(this.runtime, reaction.message.id),
|
|
6876
|
-
channelType: await this.getChannelType(
|
|
6877
|
-
reaction.message.channel
|
|
6878
|
-
)
|
|
6901
|
+
channelType: await this.getChannelType(reaction.message.channel)
|
|
6879
6902
|
},
|
|
6880
6903
|
roomId,
|
|
6881
6904
|
createdAt: Date.now()
|
|
@@ -6885,9 +6908,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6885
6908
|
this.runtime.logger.error("No channel found for reaction message");
|
|
6886
6909
|
return [];
|
|
6887
6910
|
}
|
|
6888
|
-
await reaction.message.channel.send(
|
|
6889
|
-
content.text ?? ""
|
|
6890
|
-
);
|
|
6911
|
+
await reaction.message.channel.send(content.text ?? "");
|
|
6891
6912
|
return [];
|
|
6892
6913
|
};
|
|
6893
6914
|
this.runtime.emitEvent(["DISCORD_REACTION_RECEIVED" /* REACTION_RECEIVED */], {
|
|
@@ -6896,7 +6917,7 @@ var DiscordService = class _DiscordService extends Service {
|
|
|
6896
6917
|
callback
|
|
6897
6918
|
});
|
|
6898
6919
|
} catch (error) {
|
|
6899
|
-
this.runtime.logger.error(
|
|
6920
|
+
this.runtime.logger.error(`Error handling reaction removal: ${error instanceof Error ? error.message : String(error)}`);
|
|
6900
6921
|
}
|
|
6901
6922
|
}
|
|
6902
6923
|
/**
|
|
@@ -6989,15 +7010,8 @@ import {
|
|
|
6989
7010
|
createAudioResource as createAudioResource2,
|
|
6990
7011
|
entersState as entersState2
|
|
6991
7012
|
} from "@discordjs/voice";
|
|
6992
|
-
import {
|
|
6993
|
-
|
|
6994
|
-
logger as logger15
|
|
6995
|
-
} from "@elizaos/core";
|
|
6996
|
-
import {
|
|
6997
|
-
ChannelType as ChannelType8,
|
|
6998
|
-
Events as Events2,
|
|
6999
|
-
AttachmentBuilder
|
|
7000
|
-
} from "discord.js";
|
|
7013
|
+
import { ModelType as ModelType18, logger as logger14 } from "@elizaos/core";
|
|
7014
|
+
import { ChannelType as ChannelType8, Events as Events2, AttachmentBuilder } from "discord.js";
|
|
7001
7015
|
var TEST_IMAGE_URL = "https://github.com/elizaOS/awesome-eliza/blob/main/assets/eliza-logo.jpg?raw=true";
|
|
7002
7016
|
var DiscordTestSuite = class {
|
|
7003
7017
|
name = "discord";
|
|
@@ -7047,20 +7061,16 @@ var DiscordTestSuite = class {
|
|
|
7047
7061
|
*/
|
|
7048
7062
|
async testCreatingDiscordClient(runtime) {
|
|
7049
7063
|
try {
|
|
7050
|
-
this.discordClient = runtime.getService(
|
|
7051
|
-
ServiceType2.DISCORD
|
|
7052
|
-
);
|
|
7064
|
+
this.discordClient = runtime.getService(ServiceType2.DISCORD);
|
|
7053
7065
|
if (!this.discordClient) {
|
|
7054
7066
|
throw new Error("Failed to get DiscordService from runtime.");
|
|
7055
7067
|
}
|
|
7056
7068
|
if (this.discordClient.client?.isReady()) {
|
|
7057
|
-
|
|
7069
|
+
logger14.success("DiscordService is already ready.");
|
|
7058
7070
|
} else {
|
|
7059
|
-
|
|
7071
|
+
logger14.info("Waiting for DiscordService to be ready...");
|
|
7060
7072
|
if (!this.discordClient.client) {
|
|
7061
|
-
throw new Error(
|
|
7062
|
-
"Discord client instance is missing within the service."
|
|
7063
|
-
);
|
|
7073
|
+
throw new Error("Discord client instance is missing within the service.");
|
|
7064
7074
|
}
|
|
7065
7075
|
await new Promise((resolve, reject) => {
|
|
7066
7076
|
this.discordClient.client?.once(Events2.ClientReady, resolve);
|
|
@@ -7096,16 +7106,14 @@ var DiscordTestSuite = class {
|
|
|
7096
7106
|
deferReply: async () => {
|
|
7097
7107
|
},
|
|
7098
7108
|
editReply: async (message) => {
|
|
7099
|
-
|
|
7109
|
+
logger14.info(`JoinChannel Slash Command Response: ${message}`);
|
|
7100
7110
|
}
|
|
7101
7111
|
};
|
|
7102
7112
|
if (!this.discordClient.voiceManager) {
|
|
7103
7113
|
throw new Error("VoiceManager is not available on the Discord client.");
|
|
7104
7114
|
}
|
|
7105
|
-
await this.discordClient.voiceManager.handleJoinChannelCommand(
|
|
7106
|
-
|
|
7107
|
-
);
|
|
7108
|
-
logger15.success("Join voice slash command test completed successfully.");
|
|
7115
|
+
await this.discordClient.voiceManager.handleJoinChannelCommand(fakeJoinInteraction);
|
|
7116
|
+
logger14.success("Join voice slash command test completed successfully.");
|
|
7109
7117
|
} catch (error) {
|
|
7110
7118
|
throw new Error(`Error in join voice slash commands test: ${error}`);
|
|
7111
7119
|
}
|
|
@@ -7129,16 +7137,14 @@ var DiscordTestSuite = class {
|
|
|
7129
7137
|
commandName: "leavechannel",
|
|
7130
7138
|
guildId: channel.guildId,
|
|
7131
7139
|
reply: async (message) => {
|
|
7132
|
-
|
|
7140
|
+
logger14.info(`LeaveChannel Slash Command Response: ${message}`);
|
|
7133
7141
|
}
|
|
7134
7142
|
};
|
|
7135
7143
|
if (!this.discordClient.voiceManager) {
|
|
7136
7144
|
throw new Error("VoiceManager is not available on the Discord client.");
|
|
7137
7145
|
}
|
|
7138
|
-
await this.discordClient.voiceManager.handleLeaveChannelCommand(
|
|
7139
|
-
|
|
7140
|
-
);
|
|
7141
|
-
logger15.success("Leave voice slash command test completed successfully.");
|
|
7146
|
+
await this.discordClient.voiceManager.handleLeaveChannelCommand(fakeLeaveInteraction);
|
|
7147
|
+
logger14.success("Leave voice slash command test completed successfully.");
|
|
7142
7148
|
} catch (error) {
|
|
7143
7149
|
throw new Error(`Error in leave voice slash commands test: ${error}`);
|
|
7144
7150
|
}
|
|
@@ -7171,7 +7177,7 @@ var DiscordTestSuite = class {
|
|
|
7171
7177
|
}
|
|
7172
7178
|
try {
|
|
7173
7179
|
await entersState2(connection, VoiceConnectionStatus2.Ready, 1e4);
|
|
7174
|
-
|
|
7180
|
+
logger14.success(`Voice connection is ready in guild: ${guildId}`);
|
|
7175
7181
|
} catch (error) {
|
|
7176
7182
|
throw new Error(`Voice connection failed to become ready: ${error}`);
|
|
7177
7183
|
}
|
|
@@ -7207,11 +7213,7 @@ var DiscordTestSuite = class {
|
|
|
7207
7213
|
throw new Error("Cannot send message to a non-text channel.");
|
|
7208
7214
|
}
|
|
7209
7215
|
const attachment = new AttachmentBuilder(TEST_IMAGE_URL);
|
|
7210
|
-
await this.sendMessageToChannel(
|
|
7211
|
-
channel,
|
|
7212
|
-
"Testing Message",
|
|
7213
|
-
[attachment]
|
|
7214
|
-
);
|
|
7216
|
+
await this.sendMessageToChannel(channel, "Testing Message", [attachment]);
|
|
7215
7217
|
} catch (error) {
|
|
7216
7218
|
throw new Error(`Error in sending text message: ${error}`);
|
|
7217
7219
|
}
|
|
@@ -7243,9 +7245,7 @@ var DiscordTestSuite = class {
|
|
|
7243
7245
|
attachments: []
|
|
7244
7246
|
};
|
|
7245
7247
|
if (!this.discordClient.messageManager) {
|
|
7246
|
-
throw new Error(
|
|
7247
|
-
"MessageManager is not available on the Discord client."
|
|
7248
|
-
);
|
|
7248
|
+
throw new Error("MessageManager is not available on the Discord client.");
|
|
7249
7249
|
}
|
|
7250
7250
|
await this.discordClient.messageManager.handleMessage(fakeMessage);
|
|
7251
7251
|
} catch (error) {
|
|
@@ -7281,16 +7281,9 @@ var DiscordTestSuite = class {
|
|
|
7281
7281
|
async sendMessageToChannel(channel, messageContent, files) {
|
|
7282
7282
|
try {
|
|
7283
7283
|
if (!channel || !channel.isTextBased()) {
|
|
7284
|
-
throw new Error(
|
|
7285
|
-
"Channel is not a text-based channel or does not exist."
|
|
7286
|
-
);
|
|
7284
|
+
throw new Error("Channel is not a text-based channel or does not exist.");
|
|
7287
7285
|
}
|
|
7288
|
-
await sendMessageInChunks(
|
|
7289
|
-
channel,
|
|
7290
|
-
messageContent,
|
|
7291
|
-
"",
|
|
7292
|
-
files
|
|
7293
|
-
);
|
|
7286
|
+
await sendMessageInChunks(channel, messageContent, "", files);
|
|
7294
7287
|
} catch (error) {
|
|
7295
7288
|
throw new Error(`Error sending message: ${error}`);
|
|
7296
7289
|
}
|
|
@@ -7311,10 +7304,10 @@ var DiscordTestSuite = class {
|
|
|
7311
7304
|
const audioResource = createAudioResource2(responseStream);
|
|
7312
7305
|
audioPlayer.play(audioResource);
|
|
7313
7306
|
connection.subscribe(audioPlayer);
|
|
7314
|
-
|
|
7307
|
+
logger14.success("TTS playback started successfully.");
|
|
7315
7308
|
await new Promise((resolve, reject) => {
|
|
7316
7309
|
audioPlayer.once(AudioPlayerStatus.Idle, () => {
|
|
7317
|
-
|
|
7310
|
+
logger14.info("TTS playback finished.");
|
|
7318
7311
|
resolve();
|
|
7319
7312
|
});
|
|
7320
7313
|
audioPlayer.once("error", (error) => {
|
|
@@ -7409,10 +7402,10 @@ var discordPlugin = {
|
|
|
7409
7402
|
init: async (_config, runtime) => {
|
|
7410
7403
|
const token = runtime.getSetting("DISCORD_API_TOKEN");
|
|
7411
7404
|
if (!token || token.trim() === "") {
|
|
7412
|
-
|
|
7405
|
+
logger15.warn(
|
|
7413
7406
|
"Discord API Token not provided - Discord plugin is loaded but will not be functional"
|
|
7414
7407
|
);
|
|
7415
|
-
|
|
7408
|
+
logger15.warn(
|
|
7416
7409
|
"To enable Discord functionality, please provide DISCORD_API_TOKEN in your .eliza/.env file"
|
|
7417
7410
|
);
|
|
7418
7411
|
}
|