@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 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 logger16 } from "@elizaos/core";
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 as logger2,
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
- logger2.debug(`[LEAVE_CHANNEL] Validating message: ${message.content.text}`);
914
+ logger.debug(`[LEAVE_CHANNEL] Validating message: ${message.content.text}`);
929
915
  if (message.content.source !== "discord") {
930
- logger2.debug("[LEAVE_CHANNEL] Not a discord message");
916
+ logger.debug("[LEAVE_CHANNEL] Not a discord message");
931
917
  return false;
932
918
  }
933
- logger2.debug("[LEAVE_CHANNEL] Validation passed");
919
+ logger.debug("[LEAVE_CHANNEL] Validation passed");
934
920
  return true;
935
921
  },
936
922
  handler: async (runtime, message, state, _options, callback) => {
937
- logger2.info(`[LEAVE_CHANNEL] Handler called with message: ${message.content.text}`);
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 false;
931
+ return void 0;
948
932
  }
949
933
  const channelInfo = await getLeaveChannelInfo(runtime, message, state);
950
- logger2.debug(`[LEAVE_CHANNEL] Parsed channel info:`, channelInfo);
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 false;
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 false;
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 false;
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 true;
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 false;
998
+ return void 0;
1015
999
  }
1016
- let targetChannel = isVoiceRequest ? await findChannel2(discordService, channelInfo.channelIdentifier, currentChannelId, currentServerId, true) : await findChannel2(discordService, channelInfo.channelIdentifier, currentChannelId, currentServerId, false);
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(discordService, channelInfo.channelIdentifier, currentChannelId, currentServerId, false) : await findChannel2(discordService, channelInfo.channelIdentifier, currentChannelId, currentServerId, true);
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 false;
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 false;
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 false;
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 true;
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 false;
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 true;
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 false;
1102
+ return void 0;
1095
1103
  }
1096
1104
  }
1097
- return true;
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 false;
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((acc, channel) => {
1279
- if (!channel) return acc;
1280
- if (!acc[channel.server]) {
1281
- acc[channel.server] = [];
1282
- }
1283
- acc[channel.server].push(channel);
1284
- return acc;
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 logger3
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
- logger3.debug(`[READ_CHANNEL] Fetching ${fetchLimit} messages from ${targetChannel.name} (requested: ${requestedLimit}), summarize: ${channelInfo.summarize}, focusUser: ${channelInfo.focusUser}`);
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("\n\n")}
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("\n\n")}
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
- /\d+/
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 logger4
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
- logger4.debug(`[SEARCH_MESSAGES] Fetched ${messages.size} messages from channel ${targetChannel.name}`);
2565
- logger4.debug(`[SEARCH_MESSAGES] Searching for: "${searchParams.query}", author: ${searchParams.author || "any"}`);
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
- logger4.debug(`[SEARCH_MESSAGES] Found ${results.length} matching messages`);
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
- logger4.error("Error searching messages:", error);
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 logger5
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
- logger5.error(`Failed to add reaction ${emojis[i]}:`, error);
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
- logger5.error("Error creating poll:", error);
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 logger6
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
- logger6.error("Error getting user info:", error);
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 logger7
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((a, b) => b.createdTimestamp - a.createdTimestamp);
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
- logger7.error("Failed to add reaction:", error);
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
- logger7.error("Error in react to message:", error);
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 logger8
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((a, b) => b.createdTimestamp - a.createdTimestamp);
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
- logger8.error("Failed to pin message:", error);
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
- logger8.error("Error pinning message:", error);
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 logger9
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((a, b) => b.createdTimestamp - a.createdTimestamp)[0];
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
- logger9.error("Failed to unpin message:", error);
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
- logger9.error("Error unpinning message:", error);
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 logger10
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
- logger10.error("Error getting server info:", error);
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 logger14
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 logger12
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
- ModelType15.TRANSCRIPTION,
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 logger11,
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
- logger11.info(`Components received: ${safeStringify(components)}`);
4530
+ logger10.info(`Components received: ${safeStringify(components)}`);
4509
4531
  if (!Array.isArray(components)) {
4510
- logger11.warn(
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
- logger11.warn("Invalid component row structure, skipping");
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
- logger11.warn("Row components is not an array, skipping");
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
- logger11.warn("Invalid component, skipping");
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
- logger11.error(`Error creating component: ${err}`);
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
- logger11.error(`Error processing components: ${error}`);
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
- logger11.error(`Error sending message: ${error}`);
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.runtime.character.settings?.discord?.shouldIgnoreBotMessages && message.author?.bot) {
4704
+ if (this.discordSettings.shouldIgnoreBotMessages && message.author?.bot) {
4692
4705
  return;
4693
4706
  }
4694
- if (this.runtime.character.settings?.discord?.shouldIgnoreDirectMessages && message.channel.type === DiscordChannelType3.DM) {
4707
+ if (this.discordSettings.shouldIgnoreDirectMessages && message.channel.type === DiscordChannelType3.DM) {
4695
4708
  return;
4696
4709
  }
4697
- if (this.runtime.character.settings?.discord?.shouldRespondOnlyToMentions && (!this.client.user?.id || !message.mentions.users?.has(this.client.user.id))) {
4698
- return;
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
- logger12.warn("null channel type, discord message", message);
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 logger12.warn(
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 = createUniqueUuid3(this.runtime, message.author.id);
4779
+ const sourceId = entityId;
4758
4780
  const newMessage = {
4759
4781
  id: messageId,
4760
- entityId: entityId2,
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: "message"
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
- logger12.warn("Error sending typing indicator:", err);
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
- logger12.warn("Discord - User not found", message.author.id);
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
- ["DISCORD_MESSAGE_RECEIVED" /* MESSAGE_RECEIVED */, EventType.MESSAGE_RECEIVED],
4871
- {
4872
- runtime: this.runtime,
4873
- message: newMessage,
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
- logger12.warn("Typing indicator failsafe timeout triggered");
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
- mentionRegex,
4901
- (match2, entityId) => {
4902
- const user = message.mentions.users.get(entityId);
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
- logger12.warn("Browser service not found");
4981
+ logger11.warn("Browser service not found");
4955
4982
  continue;
4956
4983
  }
4957
- const { title, description: summary } = await browserService.getPageContent(url, this.runtime);
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 logger13
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
- logger13.warn(`Failed to create opus decoder with prism-media: ${error}`);
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
- logger13.debug("Voice dependency report:", report);
5057
+ logger12.debug("Voice dependency report:", report);
5028
5058
  } catch (reportError) {
5029
- logger13.warn("Could not generate dependency report:", reportError);
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
- logger13.log("AudioMonitor ended");
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
- logger13.log("Speaking stopped");
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
- logger13.log("Speaking started");
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
- logger13.error(
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
- logger13.error(
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
- logger13.debug(`VoiceManager is now ready: ${this.ready}`);
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
- logger13.log(
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
- logger13.log(
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
- logger13.log("Handling disconnection...");
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
- logger13.log("Reconnecting to channel...");
5310
+ logger12.log("Reconnecting to channel...");
5291
5311
  } catch (e) {
5292
- logger13.log(`Disconnection confirmed - cleaning up...${e}`);
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
- logger13.log("Voice connection error:", error);
5304
- logger13.log("Connection error - will attempt to recover...");
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
- logger13.log("Failed to modify voice state:", error);
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
- logger13.log("Failed to establish voice connection:", error);
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
- logger13.error("Client user ID is not available.");
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
- logger13.warn(
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
- logger13.error(
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
- receiveStream,
5422
- opusDecoder,
5423
- (err) => {
5424
- if (err) {
5425
- logger13.debug(
5426
- `[monitorMember] Opus decoding pipeline error for user ${entityId}: ${err}`
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
- logger13.debug(`Opus decoding error: ${err}`);
5444
+ logger12.debug(`Opus decoding error: ${err}`);
5439
5445
  });
5440
5446
  const errorHandler = (err) => {
5441
- logger13.debug(`Opus decoding error: ${err}`);
5447
+ logger12.debug(`Opus decoding error: ${err}`);
5442
5448
  };
5443
5449
  const streamCloseHandler = () => {
5444
- logger13.debug(`voice stream from ${member?.displayName} closed`);
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
- logger13.debug(`Opus decoder for ${member?.displayName} closed`);
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
- logger13.debug(`Left voice channel: ${channel.name} (${channel.id})`);
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
- logger13.debug(`Stopped monitoring user ${memberId}`);
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
- logger13.log("Cleaning up idle audio player.");
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
- logger13.debug(`Starting audio monitor for user: ${entityId}`);
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
- logger13.debug("Starting transcription...");
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
- ["DISCORD_VOICE_MESSAGE_RECEIVED", "VOICE_MESSAGE_RECEIVED"],
5724
- {
5725
- runtime: this.runtime,
5726
- message: memory,
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
- logger13.debug(`Joining channel: ${chosenChannel.name}`);
5751
+ logger12.debug(`Joining channel: ${chosenChannel.name}`);
5780
5752
  await this.joinChannel(chosenChannel);
5781
5753
  } else {
5782
- logger13.debug("Warning: No suitable voice channel found to join.");
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
- logger13.debug(`No connection for user ${entityId}`);
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
- logger13.debug(`Audio player error: ${err}`);
5787
+ logger12.debug(`Audio player error: ${err}`);
5816
5788
  });
5817
- audioPlayer.on(
5818
- "stateChange",
5819
- (_oldState, newState) => {
5820
- if (newState.status === "idle") {
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
- logger14.warn("Discord API Token not provided - Discord functionality will be unavailable");
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.client.once(Events.ClientReady, this.onReady.bind(this));
5961
- this.client.login(token).catch((error) => {
5962
- logger14.error(
5963
- `Failed to login to Discord: ${error instanceof Error ? error.message : String(error)}`
5964
- );
5965
- this.client = null;
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.runtime.character.settings?.discord?.shouldIgnoreBotMessages) {
6103
- logger14.info(
6104
- `Got message where author is ${message.author.bot && this.runtime.character.settings?.discord?.shouldIgnoreBotMessages ? "a bot. To reply anyway, set `shouldIgnoreBotMessages=true`." : "the current user. Ignore!"}`
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
- logger14.error(`Channel id ${message.channel.id} not found. Ignore!`);
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
- logger14.info(
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
- logger14.info(
6123
- `Channel not allowed. Add the channel ${message.channel.id} to CHANNEL_IDS to enable replies.`
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
- "userStream",
6186
- (entityId, name, userName, channel, opusDecoder) => {
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
- member.user.username,
6430
- member.displayName,
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
- member.user.username,
6469
- member.displayName,
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}:`, error);
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
- member.user.username,
6514
- member.displayName,
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}:`, error);
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("Error during Discord world connection:", 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
- logger14.info(`Fetched ${members.size} members`);
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("Failed to fetch partial reaction:", 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("Invalid user ID or room ID", {
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
- ["DISCORD_REACTION_RECEIVED", "REACTION_RECEIVED"],
6804
- {
6805
- runtime: this.runtime,
6806
- message: memory,
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("Error handling reaction:", 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("Error handling reaction removal:", 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
- ModelType as ModelType18,
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
- logger15.success("DiscordService is already ready.");
7069
+ logger14.success("DiscordService is already ready.");
7058
7070
  } else {
7059
- logger15.info("Waiting for DiscordService to be ready...");
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
- logger15.info(`JoinChannel Slash Command Response: ${message}`);
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
- fakeJoinInteraction
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
- logger15.info(`LeaveChannel Slash Command Response: ${message}`);
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
- fakeLeaveInteraction
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
- logger15.success(`Voice connection is ready in guild: ${guildId}`);
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
- logger15.success("TTS playback started successfully.");
7307
+ logger14.success("TTS playback started successfully.");
7315
7308
  await new Promise((resolve, reject) => {
7316
7309
  audioPlayer.once(AudioPlayerStatus.Idle, () => {
7317
- logger15.info("TTS playback finished.");
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
- logger16.warn(
7405
+ logger15.warn(
7413
7406
  "Discord API Token not provided - Discord plugin is loaded but will not be functional"
7414
7407
  );
7415
- logger16.warn(
7408
+ logger15.warn(
7416
7409
  "To enable Discord functionality, please provide DISCORD_API_TOKEN in your .eliza/.env file"
7417
7410
  );
7418
7411
  }