@herdctl/discord 0.0.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.
Files changed (137) hide show
  1. package/dist/__tests__/auto-mode-handler.test.d.ts +2 -0
  2. package/dist/__tests__/auto-mode-handler.test.d.ts.map +1 -0
  3. package/dist/__tests__/auto-mode-handler.test.js +362 -0
  4. package/dist/__tests__/auto-mode-handler.test.js.map +1 -0
  5. package/dist/__tests__/discord-connector.test.d.ts +2 -0
  6. package/dist/__tests__/discord-connector.test.d.ts.map +1 -0
  7. package/dist/__tests__/discord-connector.test.js +958 -0
  8. package/dist/__tests__/discord-connector.test.js.map +1 -0
  9. package/dist/__tests__/error-handler.test.d.ts +2 -0
  10. package/dist/__tests__/error-handler.test.d.ts.map +1 -0
  11. package/dist/__tests__/error-handler.test.js +509 -0
  12. package/dist/__tests__/error-handler.test.js.map +1 -0
  13. package/dist/__tests__/errors.test.d.ts +2 -0
  14. package/dist/__tests__/errors.test.d.ts.map +1 -0
  15. package/dist/__tests__/errors.test.js +152 -0
  16. package/dist/__tests__/errors.test.js.map +1 -0
  17. package/dist/__tests__/logger.test.d.ts +2 -0
  18. package/dist/__tests__/logger.test.d.ts.map +1 -0
  19. package/dist/__tests__/logger.test.js +282 -0
  20. package/dist/__tests__/logger.test.js.map +1 -0
  21. package/dist/__tests__/mention-handler.test.d.ts +2 -0
  22. package/dist/__tests__/mention-handler.test.d.ts.map +1 -0
  23. package/dist/__tests__/mention-handler.test.js +547 -0
  24. package/dist/__tests__/mention-handler.test.js.map +1 -0
  25. package/dist/auto-mode-handler.d.ts +145 -0
  26. package/dist/auto-mode-handler.d.ts.map +1 -0
  27. package/dist/auto-mode-handler.js +211 -0
  28. package/dist/auto-mode-handler.js.map +1 -0
  29. package/dist/commands/__tests__/command-manager.test.d.ts +2 -0
  30. package/dist/commands/__tests__/command-manager.test.d.ts.map +1 -0
  31. package/dist/commands/__tests__/command-manager.test.js +307 -0
  32. package/dist/commands/__tests__/command-manager.test.js.map +1 -0
  33. package/dist/commands/__tests__/help.test.d.ts +2 -0
  34. package/dist/commands/__tests__/help.test.d.ts.map +1 -0
  35. package/dist/commands/__tests__/help.test.js +105 -0
  36. package/dist/commands/__tests__/help.test.js.map +1 -0
  37. package/dist/commands/__tests__/reset.test.d.ts +2 -0
  38. package/dist/commands/__tests__/reset.test.d.ts.map +1 -0
  39. package/dist/commands/__tests__/reset.test.js +140 -0
  40. package/dist/commands/__tests__/reset.test.js.map +1 -0
  41. package/dist/commands/__tests__/status.test.d.ts +2 -0
  42. package/dist/commands/__tests__/status.test.d.ts.map +1 -0
  43. package/dist/commands/__tests__/status.test.js +205 -0
  44. package/dist/commands/__tests__/status.test.js.map +1 -0
  45. package/dist/commands/command-manager.d.ts +66 -0
  46. package/dist/commands/command-manager.d.ts.map +1 -0
  47. package/dist/commands/command-manager.js +191 -0
  48. package/dist/commands/command-manager.js.map +1 -0
  49. package/dist/commands/help.d.ts +8 -0
  50. package/dist/commands/help.d.ts.map +1 -0
  51. package/dist/commands/help.js +27 -0
  52. package/dist/commands/help.js.map +1 -0
  53. package/dist/commands/index.d.ts +12 -0
  54. package/dist/commands/index.d.ts.map +1 -0
  55. package/dist/commands/index.js +13 -0
  56. package/dist/commands/index.js.map +1 -0
  57. package/dist/commands/reset.d.ts +9 -0
  58. package/dist/commands/reset.d.ts.map +1 -0
  59. package/dist/commands/reset.js +28 -0
  60. package/dist/commands/reset.js.map +1 -0
  61. package/dist/commands/status.d.ts +9 -0
  62. package/dist/commands/status.d.ts.map +1 -0
  63. package/dist/commands/status.js +102 -0
  64. package/dist/commands/status.js.map +1 -0
  65. package/dist/commands/types.d.ts +87 -0
  66. package/dist/commands/types.d.ts.map +1 -0
  67. package/dist/commands/types.js +8 -0
  68. package/dist/commands/types.js.map +1 -0
  69. package/dist/discord-connector.d.ts +154 -0
  70. package/dist/discord-connector.d.ts.map +1 -0
  71. package/dist/discord-connector.js +638 -0
  72. package/dist/discord-connector.js.map +1 -0
  73. package/dist/error-handler.d.ts +237 -0
  74. package/dist/error-handler.d.ts.map +1 -0
  75. package/dist/error-handler.js +433 -0
  76. package/dist/error-handler.js.map +1 -0
  77. package/dist/errors.d.ts +61 -0
  78. package/dist/errors.d.ts.map +1 -0
  79. package/dist/errors.js +77 -0
  80. package/dist/errors.js.map +1 -0
  81. package/dist/index.d.ts +34 -0
  82. package/dist/index.d.ts.map +1 -0
  83. package/dist/index.js +36 -0
  84. package/dist/index.js.map +1 -0
  85. package/dist/logger.d.ts +119 -0
  86. package/dist/logger.d.ts.map +1 -0
  87. package/dist/logger.js +198 -0
  88. package/dist/logger.js.map +1 -0
  89. package/dist/mention-handler.d.ts +176 -0
  90. package/dist/mention-handler.d.ts.map +1 -0
  91. package/dist/mention-handler.js +236 -0
  92. package/dist/mention-handler.js.map +1 -0
  93. package/dist/session-manager/__tests__/errors.test.d.ts +2 -0
  94. package/dist/session-manager/__tests__/errors.test.d.ts.map +1 -0
  95. package/dist/session-manager/__tests__/errors.test.js +124 -0
  96. package/dist/session-manager/__tests__/errors.test.js.map +1 -0
  97. package/dist/session-manager/__tests__/session-manager.test.d.ts +2 -0
  98. package/dist/session-manager/__tests__/session-manager.test.d.ts.map +1 -0
  99. package/dist/session-manager/__tests__/session-manager.test.js +517 -0
  100. package/dist/session-manager/__tests__/session-manager.test.js.map +1 -0
  101. package/dist/session-manager/__tests__/types.test.d.ts +2 -0
  102. package/dist/session-manager/__tests__/types.test.d.ts.map +1 -0
  103. package/dist/session-manager/__tests__/types.test.js +169 -0
  104. package/dist/session-manager/__tests__/types.test.js.map +1 -0
  105. package/dist/session-manager/errors.d.ts +58 -0
  106. package/dist/session-manager/errors.d.ts.map +1 -0
  107. package/dist/session-manager/errors.js +70 -0
  108. package/dist/session-manager/errors.js.map +1 -0
  109. package/dist/session-manager/index.d.ts +11 -0
  110. package/dist/session-manager/index.d.ts.map +1 -0
  111. package/dist/session-manager/index.js +12 -0
  112. package/dist/session-manager/index.js.map +1 -0
  113. package/dist/session-manager/session-manager.d.ts +107 -0
  114. package/dist/session-manager/session-manager.d.ts.map +1 -0
  115. package/dist/session-manager/session-manager.js +347 -0
  116. package/dist/session-manager/session-manager.js.map +1 -0
  117. package/dist/session-manager/types.d.ts +167 -0
  118. package/dist/session-manager/types.d.ts.map +1 -0
  119. package/dist/session-manager/types.js +57 -0
  120. package/dist/session-manager/types.js.map +1 -0
  121. package/dist/types.d.ts +323 -0
  122. package/dist/types.d.ts.map +1 -0
  123. package/dist/types.js +8 -0
  124. package/dist/types.js.map +1 -0
  125. package/dist/utils/__tests__/formatting.test.d.ts +2 -0
  126. package/dist/utils/__tests__/formatting.test.d.ts.map +1 -0
  127. package/dist/utils/__tests__/formatting.test.js +571 -0
  128. package/dist/utils/__tests__/formatting.test.js.map +1 -0
  129. package/dist/utils/formatting.d.ts +211 -0
  130. package/dist/utils/formatting.d.ts.map +1 -0
  131. package/dist/utils/formatting.js +305 -0
  132. package/dist/utils/formatting.js.map +1 -0
  133. package/dist/utils/index.d.ts +5 -0
  134. package/dist/utils/index.d.ts.map +1 -0
  135. package/dist/utils/index.js +9 -0
  136. package/dist/utils/index.js.map +1 -0
  137. package/package.json +49 -0
@@ -0,0 +1,638 @@
1
+ /**
2
+ * DiscordConnector - Connects an agent to Discord
3
+ *
4
+ * Each agent has its own DiscordConnector instance with its own bot identity.
5
+ * The connector uses discord.js v14 to connect to the Discord gateway and
6
+ * handles connection lifecycle events.
7
+ */
8
+ import { EventEmitter } from "events";
9
+ import { Client, GatewayIntentBits, Events, } from "discord.js";
10
+ import { RESTEvents } from "@discordjs/rest";
11
+ import { DiscordConnectionError, AlreadyConnectedError, InvalidTokenError, } from "./errors.js";
12
+ import { ErrorHandler, } from "./error-handler.js";
13
+ import { shouldProcessMessage, buildConversationContext, } from "./mention-handler.js";
14
+ import { checkDMUserFilter, resolveChannelConfig, } from "./auto-mode-handler.js";
15
+ import { CommandManager } from "./commands/index.js";
16
+ import { createLoggerFromConfig } from "./logger.js";
17
+ /**
18
+ * DiscordConnector class - Connects a single agent to Discord
19
+ *
20
+ * Each agent has its own connector instance with:
21
+ * - Its own discord.js Client
22
+ * - Its own bot token and identity
23
+ * - Connection lifecycle management
24
+ * - Event emission for monitoring
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const connector = new DiscordConnector({
29
+ * agentConfig,
30
+ * discordConfig: agentConfig.chat.discord,
31
+ * botToken: process.env.MY_BOT_TOKEN,
32
+ * fleetManager,
33
+ * });
34
+ *
35
+ * await connector.connect();
36
+ * console.log(`Connected as ${connector.getState().botUser?.username}`);
37
+ *
38
+ * // Later...
39
+ * await connector.disconnect();
40
+ * ```
41
+ */
42
+ export class DiscordConnector extends EventEmitter {
43
+ _agentConfig;
44
+ _discordConfig;
45
+ _botToken;
46
+ _fleetManager;
47
+ _logger;
48
+ _sessionManager;
49
+ _errorHandler;
50
+ _client = null;
51
+ _commandManager = null;
52
+ _status = "disconnected";
53
+ _connectedAt = null;
54
+ _disconnectedAt = null;
55
+ _reconnectAttempts = 0;
56
+ _lastError = null;
57
+ _botUser = null;
58
+ // Rate limit tracking
59
+ _rateLimitCount = 0;
60
+ _lastRateLimitAt = null;
61
+ _rateLimitResetTime = 0;
62
+ _rateLimitResetTimer = null;
63
+ // Message count tracking for standard logging
64
+ _messagesReceived = 0;
65
+ _messagesSent = 0;
66
+ _messagesIgnored = 0;
67
+ constructor(options) {
68
+ super();
69
+ this._agentConfig = options.agentConfig;
70
+ this._discordConfig = options.discordConfig;
71
+ this._botToken = options.botToken;
72
+ this._fleetManager = options.fleetManager;
73
+ this._sessionManager = options.sessionManager;
74
+ // Create logger from config if not provided
75
+ this._logger =
76
+ options.logger ?? createLoggerFromConfig(options.agentConfig.name, options.discordConfig);
77
+ // Initialize error handler for user-friendly error messages
78
+ this._errorHandler = new ErrorHandler({
79
+ logger: this._logger,
80
+ agentName: options.agentConfig.name,
81
+ });
82
+ // Validate token is provided
83
+ if (!this._botToken || this._botToken.trim() === "") {
84
+ throw new InvalidTokenError(this.agentName, "Bot token cannot be empty");
85
+ }
86
+ }
87
+ /**
88
+ * Get the session manager instance
89
+ */
90
+ get sessionManager() {
91
+ return this._sessionManager;
92
+ }
93
+ /**
94
+ * Get the command manager instance (available after connect)
95
+ */
96
+ get commandManager() {
97
+ return this._commandManager;
98
+ }
99
+ /**
100
+ * Name of the agent this connector is for
101
+ */
102
+ get agentName() {
103
+ return this._agentConfig.name;
104
+ }
105
+ /**
106
+ * Get the discord.js Client instance (for testing)
107
+ */
108
+ get client() {
109
+ return this._client;
110
+ }
111
+ /**
112
+ * Connect to Discord gateway
113
+ *
114
+ * Creates a new discord.js Client and connects to the gateway.
115
+ * Registers event handlers for connection lifecycle events.
116
+ *
117
+ * @throws AlreadyConnectedError if already connected
118
+ * @throws DiscordConnectionError on connection failure
119
+ */
120
+ async connect() {
121
+ // Check if already connected or connecting
122
+ if (this._status === "connected" ||
123
+ this._status === "connecting") {
124
+ throw new AlreadyConnectedError(this.agentName);
125
+ }
126
+ this._status = "connecting";
127
+ this._lastError = null;
128
+ this._logger.info("Connecting to Discord...");
129
+ try {
130
+ // Create client with necessary intents
131
+ const clientOptions = {
132
+ intents: [
133
+ GatewayIntentBits.Guilds,
134
+ GatewayIntentBits.GuildMessages,
135
+ GatewayIntentBits.DirectMessages,
136
+ GatewayIntentBits.MessageContent,
137
+ ],
138
+ };
139
+ this._client = new Client(clientOptions);
140
+ // Set up event handlers before connecting
141
+ this._setupEventHandlers();
142
+ // Connect to Discord
143
+ await this._client.login(this._botToken);
144
+ // Note: The 'ready' event handler will update status to 'connected'
145
+ }
146
+ catch (error) {
147
+ this._status = "error";
148
+ const errorMessage = error instanceof Error ? error.message : String(error);
149
+ this._lastError = errorMessage;
150
+ this._logger.error("Connection failed", { error: errorMessage });
151
+ // Clean up client on failure
152
+ if (this._client) {
153
+ this._client.destroy();
154
+ this._client = null;
155
+ }
156
+ throw new DiscordConnectionError(this.agentName, errorMessage, {
157
+ cause: error instanceof Error ? error : undefined,
158
+ });
159
+ }
160
+ }
161
+ /**
162
+ * Disconnect from Discord gateway
163
+ *
164
+ * Performs graceful shutdown by destroying the client.
165
+ * Does not throw on failure - logs errors and completes.
166
+ */
167
+ async disconnect() {
168
+ if (this._status === "disconnected" || this._status === "disconnecting") {
169
+ this._logger.debug("Already disconnected or disconnecting");
170
+ return;
171
+ }
172
+ this._status = "disconnecting";
173
+ this._logger.info("Disconnecting from Discord...");
174
+ try {
175
+ if (this._client) {
176
+ this._client.destroy();
177
+ this._client = null;
178
+ }
179
+ // Clear rate limit timer on disconnect
180
+ if (this._rateLimitResetTimer) {
181
+ clearTimeout(this._rateLimitResetTimer);
182
+ this._rateLimitResetTimer = null;
183
+ }
184
+ this._commandManager = null;
185
+ this._status = "disconnected";
186
+ this._disconnectedAt = new Date().toISOString();
187
+ this._botUser = null;
188
+ this._rateLimitResetTime = 0;
189
+ // Log session stats on disconnect (standard level)
190
+ this._logger.info("Disconnected from Discord", {
191
+ messagesReceived: this._messagesReceived,
192
+ messagesSent: this._messagesSent,
193
+ messagesIgnored: this._messagesIgnored,
194
+ rateLimitsEncountered: this._rateLimitCount,
195
+ });
196
+ }
197
+ catch (error) {
198
+ // Log but don't throw - we want graceful shutdown
199
+ const errorMessage = error instanceof Error ? error.message : String(error);
200
+ this._logger.error("Error during disconnect", { error: errorMessage });
201
+ this._status = "disconnected";
202
+ this._disconnectedAt = new Date().toISOString();
203
+ this._client = null;
204
+ this._commandManager = null;
205
+ this._botUser = null;
206
+ // Clear rate limit timer on error path too
207
+ if (this._rateLimitResetTimer) {
208
+ clearTimeout(this._rateLimitResetTimer);
209
+ this._rateLimitResetTimer = null;
210
+ }
211
+ this._rateLimitResetTime = 0;
212
+ }
213
+ }
214
+ /**
215
+ * Check if currently connected to Discord
216
+ *
217
+ * @returns true if connected and ready, false otherwise
218
+ */
219
+ isConnected() {
220
+ return this._status === "connected" && this._client !== null;
221
+ }
222
+ /**
223
+ * Get current connector state
224
+ *
225
+ * @returns Current state including connection status and metadata
226
+ */
227
+ getState() {
228
+ return {
229
+ status: this._status,
230
+ connectedAt: this._connectedAt,
231
+ disconnectedAt: this._disconnectedAt,
232
+ reconnectAttempts: this._reconnectAttempts,
233
+ lastError: this._lastError,
234
+ botUser: this._botUser,
235
+ rateLimits: {
236
+ totalCount: this._rateLimitCount,
237
+ lastRateLimitAt: this._lastRateLimitAt,
238
+ isRateLimited: this._rateLimitResetTime > 0,
239
+ currentResetTime: this._rateLimitResetTime,
240
+ },
241
+ messageStats: {
242
+ received: this._messagesReceived,
243
+ sent: this._messagesSent,
244
+ ignored: this._messagesIgnored,
245
+ },
246
+ };
247
+ }
248
+ /**
249
+ * Set up event handlers for the discord.js client
250
+ */
251
+ _setupEventHandlers() {
252
+ if (!this._client)
253
+ return;
254
+ // Ready event - connection established
255
+ this._client.once(Events.ClientReady, async (client) => {
256
+ this._status = "connected";
257
+ this._connectedAt = new Date().toISOString();
258
+ this._reconnectAttempts = 0;
259
+ this._botUser = {
260
+ id: client.user.id,
261
+ username: client.user.username,
262
+ discriminator: client.user.discriminator,
263
+ };
264
+ this._logger.info("Connected to Discord", {
265
+ username: client.user.username,
266
+ id: client.user.id,
267
+ });
268
+ // Set presence if configured
269
+ this._setPresence();
270
+ // Initialize and register slash commands
271
+ await this._initializeCommands();
272
+ // Emit ready event
273
+ const payload = {
274
+ agentName: this.agentName,
275
+ botUser: this._botUser,
276
+ };
277
+ this.emit("ready", payload);
278
+ });
279
+ // Disconnect event - connection lost
280
+ this._client.on(Events.ShardDisconnect, (event) => {
281
+ // Only handle if we weren't intentionally disconnecting
282
+ if (this._status !== "disconnecting") {
283
+ this._logger.warn("Disconnected from Discord", {
284
+ code: event.code,
285
+ });
286
+ // Emit disconnect event
287
+ const payload = {
288
+ agentName: this.agentName,
289
+ code: event.code,
290
+ reason: "Shard disconnected",
291
+ };
292
+ this.emit("disconnect", payload);
293
+ }
294
+ });
295
+ // Reconnecting event - discord.js auto-reconnect
296
+ this._client.on(Events.ShardReconnecting, () => {
297
+ this._status = "reconnecting";
298
+ this._reconnectAttempts++;
299
+ this._logger.info("Reconnecting to Discord...", {
300
+ attempt: this._reconnectAttempts,
301
+ });
302
+ // Emit reconnecting event
303
+ const payload = {
304
+ agentName: this.agentName,
305
+ attempt: this._reconnectAttempts,
306
+ };
307
+ this.emit("reconnecting", payload);
308
+ });
309
+ // Resume event - successfully reconnected
310
+ this._client.on(Events.ShardResume, () => {
311
+ this._status = "connected";
312
+ this._logger.info("Reconnected to Discord");
313
+ // Emit reconnected event
314
+ const payload = {
315
+ agentName: this.agentName,
316
+ };
317
+ this.emit("reconnected", payload);
318
+ });
319
+ // Error event
320
+ this._client.on(Events.Error, (error) => {
321
+ this._lastError = error.message;
322
+ this._logger.error("Discord client error", { error: error.message });
323
+ // Emit error event
324
+ const payload = {
325
+ agentName: this.agentName,
326
+ error,
327
+ };
328
+ this.emit("error", payload);
329
+ });
330
+ // Warn event
331
+ this._client.on(Events.Warn, (message) => {
332
+ this._logger.warn("Discord client warning", { message });
333
+ });
334
+ // Debug event (only log if verbose)
335
+ if (this._discordConfig.log_level === "verbose") {
336
+ this._client.on(Events.Debug, (message) => {
337
+ this._logger.debug("Discord debug", { message });
338
+ });
339
+ }
340
+ // Rate limit event - discord.js handles rate limits automatically
341
+ // We emit events for monitoring and logging purposes
342
+ this._client.rest.on(RESTEvents.RateLimited, (rateLimitData) => {
343
+ this._handleRateLimit(rateLimitData);
344
+ });
345
+ // Message create event - handle incoming messages
346
+ this._client.on(Events.MessageCreate, (message) => {
347
+ this._handleMessage(message).catch(async (error) => {
348
+ // Use error handler for detailed logging and user-friendly messages
349
+ const userMessage = this._errorHandler.handleError(error, "handling message");
350
+ // Attempt to reply with user-friendly error if we can
351
+ try {
352
+ const channel = message.channel;
353
+ if ("send" in channel) {
354
+ await channel.send(userMessage);
355
+ }
356
+ }
357
+ catch (replyError) {
358
+ // Log but don't escalate - we tried our best
359
+ this._logger.debug("Could not send error reply to channel", {
360
+ error: replyError instanceof Error ? replyError.message : String(replyError),
361
+ });
362
+ }
363
+ });
364
+ });
365
+ // Interaction create event - handle slash commands
366
+ this._client.on(Events.InteractionCreate, (interaction) => {
367
+ this._handleInteraction(interaction).catch((error) => {
368
+ // Use error handler for detailed logging
369
+ this._errorHandler.handleError(error, "handling interaction");
370
+ });
371
+ });
372
+ }
373
+ /**
374
+ * Initialize and register slash commands
375
+ */
376
+ async _initializeCommands() {
377
+ if (!this._client) {
378
+ this._logger.warn("Cannot initialize commands: client not available");
379
+ return;
380
+ }
381
+ try {
382
+ this._commandManager = new CommandManager({
383
+ agentName: this.agentName,
384
+ client: this._client,
385
+ botToken: this._botToken,
386
+ sessionManager: this._sessionManager,
387
+ getConnectorState: () => this.getState(),
388
+ logger: this._logger,
389
+ });
390
+ await this._commandManager.registerCommands();
391
+ this._logger.info("Slash commands registered successfully");
392
+ }
393
+ catch (error) {
394
+ const errorMessage = error instanceof Error ? error.message : String(error);
395
+ this._logger.error("Failed to register slash commands", {
396
+ error: errorMessage,
397
+ });
398
+ // Don't throw - command registration failure shouldn't prevent connection
399
+ }
400
+ }
401
+ /**
402
+ * Handle an incoming interaction (slash command)
403
+ */
404
+ async _handleInteraction(interaction) {
405
+ // Only handle chat input (slash) commands
406
+ if (!interaction.isChatInputCommand()) {
407
+ return;
408
+ }
409
+ if (!this._commandManager) {
410
+ this._logger.warn("Received command but command manager not initialized");
411
+ await interaction.reply({
412
+ content: "Commands are not available at this time.",
413
+ ephemeral: true,
414
+ });
415
+ return;
416
+ }
417
+ await this._commandManager.handleInteraction(interaction);
418
+ // Emit commandExecuted event
419
+ const payload = {
420
+ agentName: this.agentName,
421
+ commandName: interaction.commandName,
422
+ userId: interaction.user.id,
423
+ channelId: interaction.channelId,
424
+ };
425
+ this.emit("commandExecuted", payload);
426
+ }
427
+ /**
428
+ * Handle an incoming message
429
+ *
430
+ * Determines if the message should be processed based on channel configuration
431
+ * and mention mode settings. If the message should be processed, builds
432
+ * conversation context and emits a 'message' event.
433
+ *
434
+ * For DMs:
435
+ * - DMs default to auto mode (no mention required)
436
+ * - Allowlist/blocklist filtering is applied
437
+ *
438
+ * For guild channels:
439
+ * - Mode is determined by channel configuration
440
+ * - Only configured channels are processed
441
+ */
442
+ async _handleMessage(message) {
443
+ // Ignore messages from bots (including self)
444
+ if (message.author.bot) {
445
+ return;
446
+ }
447
+ // Get bot user ID
448
+ const botUserId = this._botUser?.id;
449
+ if (!botUserId) {
450
+ this._logger.warn("Received message but bot user ID is not available");
451
+ return;
452
+ }
453
+ const isDM = !message.guildId;
454
+ // For DMs, check user filtering (allowlist/blocklist)
455
+ if (isDM) {
456
+ const dmConfig = this._discordConfig.dm;
457
+ const filterResult = checkDMUserFilter(message.author.id, dmConfig);
458
+ if (!filterResult.allowed) {
459
+ this._messagesIgnored++;
460
+ const payload = {
461
+ agentName: this.agentName,
462
+ reason: filterResult.reason === "dm_disabled" ? "not_configured" : "not_configured",
463
+ channelId: message.channel.id,
464
+ messageId: message.id,
465
+ };
466
+ this.emit("messageIgnored", payload);
467
+ this._logger.debug("DM filtered", {
468
+ userId: message.author.id,
469
+ reason: filterResult.reason,
470
+ });
471
+ return;
472
+ }
473
+ }
474
+ // Get channel configuration using the new resolver
475
+ const resolvedConfig = resolveChannelConfig(message.channel.id, message.guildId, this._discordConfig.guilds, this._discordConfig.dm);
476
+ if (!resolvedConfig) {
477
+ // Channel not configured for this agent
478
+ this._messagesIgnored++;
479
+ const payload = {
480
+ agentName: this.agentName,
481
+ reason: isDM ? "not_configured" : "unknown_channel",
482
+ channelId: message.channel.id,
483
+ messageId: message.id,
484
+ };
485
+ this.emit("messageIgnored", payload);
486
+ return;
487
+ }
488
+ const { mode, contextMessages, guildId } = resolvedConfig;
489
+ // Check if message should be processed based on mode
490
+ if (!shouldProcessMessage(message, botUserId, mode)) {
491
+ this._messagesIgnored++;
492
+ const payload = {
493
+ agentName: this.agentName,
494
+ reason: "not_mentioned",
495
+ channelId: message.channel.id,
496
+ messageId: message.id,
497
+ };
498
+ this.emit("messageIgnored", payload);
499
+ return;
500
+ }
501
+ // Build conversation context
502
+ const channel = message.channel;
503
+ const context = await buildConversationContext(message, channel, botUserId, {
504
+ maxMessages: contextMessages,
505
+ includeBotMessages: true,
506
+ prioritizeUserMessages: true,
507
+ });
508
+ // Track message received
509
+ this._messagesReceived++;
510
+ // Log at info level for standard mode (message counts)
511
+ this._logger.info("Message received", {
512
+ channelId: message.channel.id,
513
+ userId: message.author.id,
514
+ isDM,
515
+ mode,
516
+ totalReceived: this._messagesReceived,
517
+ });
518
+ // More detailed debug logging for verbose mode
519
+ this._logger.debug("Processing message details", {
520
+ channelId: message.channel.id,
521
+ messageId: message.id,
522
+ mode,
523
+ isDM,
524
+ wasMentioned: context.wasMentioned,
525
+ contextMessageCount: context.messages.length,
526
+ });
527
+ // Create reply function for this channel that tracks sent messages
528
+ const reply = async (content) => {
529
+ // TextBasedChannel is a union type that includes channels with send() method
530
+ const textChannel = channel;
531
+ await textChannel.send(content);
532
+ this._messagesSent++;
533
+ this._logger.info("Message sent", {
534
+ channelId: message.channel.id,
535
+ totalSent: this._messagesSent,
536
+ });
537
+ };
538
+ // Emit message event
539
+ const payload = {
540
+ agentName: this.agentName,
541
+ prompt: context.prompt,
542
+ context,
543
+ metadata: {
544
+ guildId,
545
+ channelId: message.channel.id,
546
+ messageId: message.id,
547
+ userId: message.author.id,
548
+ username: message.author.username,
549
+ wasMentioned: context.wasMentioned,
550
+ mode,
551
+ },
552
+ reply,
553
+ };
554
+ this.emit("message", payload);
555
+ }
556
+ /**
557
+ * Set bot presence based on configuration
558
+ */
559
+ _setPresence() {
560
+ if (!this._client?.user || !this._discordConfig.presence) {
561
+ return;
562
+ }
563
+ const { activity_type, activity_message } = this._discordConfig.presence;
564
+ if (activity_type && activity_message) {
565
+ const activityTypeMap = {
566
+ playing: 0,
567
+ streaming: 1,
568
+ listening: 2,
569
+ watching: 3,
570
+ competing: 5,
571
+ };
572
+ this._client.user.setActivity(activity_message, {
573
+ type: activityTypeMap[activity_type],
574
+ });
575
+ this._logger.debug("Set presence", {
576
+ activity_type,
577
+ activity_message,
578
+ });
579
+ }
580
+ }
581
+ /**
582
+ * Handle rate limit events from discord.js REST client
583
+ *
584
+ * Discord.js automatically queues and retries requests when rate limited.
585
+ * This method tracks rate limit occurrences and emits events for monitoring.
586
+ */
587
+ _handleRateLimit(rateLimitData) {
588
+ // Update rate limit tracking state
589
+ this._rateLimitCount++;
590
+ this._lastRateLimitAt = new Date().toISOString();
591
+ this._rateLimitResetTime = rateLimitData.timeToReset;
592
+ // Clear any existing reset timer
593
+ if (this._rateLimitResetTimer) {
594
+ clearTimeout(this._rateLimitResetTimer);
595
+ }
596
+ // Set timer to clear rate limit status when it resets
597
+ this._rateLimitResetTimer = setTimeout(() => {
598
+ this._rateLimitResetTime = 0;
599
+ this._rateLimitResetTimer = null;
600
+ }, rateLimitData.timeToReset);
601
+ // Log at standard level (info) as per acceptance criteria
602
+ this._logger.info("Rate limited by Discord API", {
603
+ route: rateLimitData.route,
604
+ method: rateLimitData.method,
605
+ timeToReset: rateLimitData.timeToReset,
606
+ limit: rateLimitData.limit,
607
+ global: rateLimitData.global,
608
+ hash: rateLimitData.hash,
609
+ });
610
+ // Emit rate limit event for FleetManager tracking
611
+ const payload = {
612
+ agentName: this.agentName,
613
+ timeToReset: rateLimitData.timeToReset,
614
+ limit: rateLimitData.limit,
615
+ method: rateLimitData.method,
616
+ hash: rateLimitData.hash,
617
+ route: rateLimitData.route,
618
+ global: rateLimitData.global,
619
+ };
620
+ this.emit("rateLimit", payload);
621
+ }
622
+ /**
623
+ * Type-safe event emitter methods
624
+ */
625
+ emit(event, payload) {
626
+ return super.emit(event, payload);
627
+ }
628
+ on(event, listener) {
629
+ return super.on(event, listener);
630
+ }
631
+ once(event, listener) {
632
+ return super.once(event, listener);
633
+ }
634
+ off(event, listener) {
635
+ return super.off(event, listener);
636
+ }
637
+ }
638
+ //# sourceMappingURL=discord-connector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discord-connector.js","sourceRoot":"","sources":["../src/discord-connector.ts"],"names":[],"mappings":"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"}