@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.
- package/dist/__tests__/auto-mode-handler.test.d.ts +2 -0
- package/dist/__tests__/auto-mode-handler.test.d.ts.map +1 -0
- package/dist/__tests__/auto-mode-handler.test.js +362 -0
- package/dist/__tests__/auto-mode-handler.test.js.map +1 -0
- package/dist/__tests__/discord-connector.test.d.ts +2 -0
- package/dist/__tests__/discord-connector.test.d.ts.map +1 -0
- package/dist/__tests__/discord-connector.test.js +958 -0
- package/dist/__tests__/discord-connector.test.js.map +1 -0
- package/dist/__tests__/error-handler.test.d.ts +2 -0
- package/dist/__tests__/error-handler.test.d.ts.map +1 -0
- package/dist/__tests__/error-handler.test.js +509 -0
- package/dist/__tests__/error-handler.test.js.map +1 -0
- package/dist/__tests__/errors.test.d.ts +2 -0
- package/dist/__tests__/errors.test.d.ts.map +1 -0
- package/dist/__tests__/errors.test.js +152 -0
- package/dist/__tests__/errors.test.js.map +1 -0
- package/dist/__tests__/logger.test.d.ts +2 -0
- package/dist/__tests__/logger.test.d.ts.map +1 -0
- package/dist/__tests__/logger.test.js +282 -0
- package/dist/__tests__/logger.test.js.map +1 -0
- package/dist/__tests__/mention-handler.test.d.ts +2 -0
- package/dist/__tests__/mention-handler.test.d.ts.map +1 -0
- package/dist/__tests__/mention-handler.test.js +547 -0
- package/dist/__tests__/mention-handler.test.js.map +1 -0
- package/dist/auto-mode-handler.d.ts +145 -0
- package/dist/auto-mode-handler.d.ts.map +1 -0
- package/dist/auto-mode-handler.js +211 -0
- package/dist/auto-mode-handler.js.map +1 -0
- package/dist/commands/__tests__/command-manager.test.d.ts +2 -0
- package/dist/commands/__tests__/command-manager.test.d.ts.map +1 -0
- package/dist/commands/__tests__/command-manager.test.js +307 -0
- package/dist/commands/__tests__/command-manager.test.js.map +1 -0
- package/dist/commands/__tests__/help.test.d.ts +2 -0
- package/dist/commands/__tests__/help.test.d.ts.map +1 -0
- package/dist/commands/__tests__/help.test.js +105 -0
- package/dist/commands/__tests__/help.test.js.map +1 -0
- package/dist/commands/__tests__/reset.test.d.ts +2 -0
- package/dist/commands/__tests__/reset.test.d.ts.map +1 -0
- package/dist/commands/__tests__/reset.test.js +140 -0
- package/dist/commands/__tests__/reset.test.js.map +1 -0
- package/dist/commands/__tests__/status.test.d.ts +2 -0
- package/dist/commands/__tests__/status.test.d.ts.map +1 -0
- package/dist/commands/__tests__/status.test.js +205 -0
- package/dist/commands/__tests__/status.test.js.map +1 -0
- package/dist/commands/command-manager.d.ts +66 -0
- package/dist/commands/command-manager.d.ts.map +1 -0
- package/dist/commands/command-manager.js +191 -0
- package/dist/commands/command-manager.js.map +1 -0
- package/dist/commands/help.d.ts +8 -0
- package/dist/commands/help.d.ts.map +1 -0
- package/dist/commands/help.js +27 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/index.d.ts +12 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +13 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/reset.d.ts +9 -0
- package/dist/commands/reset.d.ts.map +1 -0
- package/dist/commands/reset.js +28 -0
- package/dist/commands/reset.js.map +1 -0
- package/dist/commands/status.d.ts +9 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +102 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/types.d.ts +87 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +8 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/discord-connector.d.ts +154 -0
- package/dist/discord-connector.d.ts.map +1 -0
- package/dist/discord-connector.js +638 -0
- package/dist/discord-connector.js.map +1 -0
- package/dist/error-handler.d.ts +237 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +433 -0
- package/dist/error-handler.js.map +1 -0
- package/dist/errors.d.ts +61 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +77 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +119 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +198 -0
- package/dist/logger.js.map +1 -0
- package/dist/mention-handler.d.ts +176 -0
- package/dist/mention-handler.d.ts.map +1 -0
- package/dist/mention-handler.js +236 -0
- package/dist/mention-handler.js.map +1 -0
- package/dist/session-manager/__tests__/errors.test.d.ts +2 -0
- package/dist/session-manager/__tests__/errors.test.d.ts.map +1 -0
- package/dist/session-manager/__tests__/errors.test.js +124 -0
- package/dist/session-manager/__tests__/errors.test.js.map +1 -0
- package/dist/session-manager/__tests__/session-manager.test.d.ts +2 -0
- package/dist/session-manager/__tests__/session-manager.test.d.ts.map +1 -0
- package/dist/session-manager/__tests__/session-manager.test.js +517 -0
- package/dist/session-manager/__tests__/session-manager.test.js.map +1 -0
- package/dist/session-manager/__tests__/types.test.d.ts +2 -0
- package/dist/session-manager/__tests__/types.test.d.ts.map +1 -0
- package/dist/session-manager/__tests__/types.test.js +169 -0
- package/dist/session-manager/__tests__/types.test.js.map +1 -0
- package/dist/session-manager/errors.d.ts +58 -0
- package/dist/session-manager/errors.d.ts.map +1 -0
- package/dist/session-manager/errors.js +70 -0
- package/dist/session-manager/errors.js.map +1 -0
- package/dist/session-manager/index.d.ts +11 -0
- package/dist/session-manager/index.d.ts.map +1 -0
- package/dist/session-manager/index.js +12 -0
- package/dist/session-manager/index.js.map +1 -0
- package/dist/session-manager/session-manager.d.ts +107 -0
- package/dist/session-manager/session-manager.d.ts.map +1 -0
- package/dist/session-manager/session-manager.js +347 -0
- package/dist/session-manager/session-manager.js.map +1 -0
- package/dist/session-manager/types.d.ts +167 -0
- package/dist/session-manager/types.d.ts.map +1 -0
- package/dist/session-manager/types.js +57 -0
- package/dist/session-manager/types.js.map +1 -0
- package/dist/types.d.ts +323 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/__tests__/formatting.test.d.ts +2 -0
- package/dist/utils/__tests__/formatting.test.d.ts.map +1 -0
- package/dist/utils/__tests__/formatting.test.js +571 -0
- package/dist/utils/__tests__/formatting.test.js.map +1 -0
- package/dist/utils/formatting.d.ts +211 -0
- package/dist/utils/formatting.d.ts.map +1 -0
- package/dist/utils/formatting.js +305 -0
- package/dist/utils/formatting.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- 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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"}
|