@herdctl/core 4.2.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/__tests__/schema.test.js +6 -6
- package/dist/config/__tests__/schema.test.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +3 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/schema.d.ts +128 -3
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +8 -4
- package/dist/config/schema.js.map +1 -1
- package/dist/fleet-manager/chat-manager-interface.d.ts +116 -0
- package/dist/fleet-manager/chat-manager-interface.d.ts.map +1 -0
- package/dist/fleet-manager/chat-manager-interface.js +11 -0
- package/dist/fleet-manager/chat-manager-interface.js.map +1 -0
- package/dist/fleet-manager/context.d.ts +24 -5
- package/dist/fleet-manager/context.d.ts.map +1 -1
- package/dist/fleet-manager/event-types.d.ts +0 -92
- package/dist/fleet-manager/event-types.d.ts.map +1 -1
- package/dist/fleet-manager/fleet-manager.d.ts +18 -6
- package/dist/fleet-manager/fleet-manager.d.ts.map +1 -1
- package/dist/fleet-manager/fleet-manager.js +79 -20
- package/dist/fleet-manager/fleet-manager.js.map +1 -1
- package/dist/fleet-manager/index.d.ts +2 -3
- package/dist/fleet-manager/index.d.ts.map +1 -1
- package/dist/fleet-manager/index.js +4 -1
- package/dist/fleet-manager/index.js.map +1 -1
- package/dist/fleet-manager/status-queries.d.ts +5 -6
- package/dist/fleet-manager/status-queries.d.ts.map +1 -1
- package/dist/fleet-manager/status-queries.js +52 -59
- package/dist/fleet-manager/status-queries.js.map +1 -1
- package/dist/fleet-manager/types.d.ts +11 -31
- package/dist/fleet-manager/types.d.ts.map +1 -1
- package/dist/runner/index.d.ts +1 -1
- package/dist/runner/index.d.ts.map +1 -1
- package/dist/runner/index.js.map +1 -1
- package/dist/scheduler/__tests__/scheduler.test.js +9 -7
- package/dist/scheduler/__tests__/scheduler.test.js.map +1 -1
- package/dist/scheduler/scheduler.js +5 -4
- package/dist/scheduler/scheduler.js.map +1 -1
- package/package.json +1 -1
- package/dist/fleet-manager/__tests__/discord-manager.test.d.ts +0 -8
- package/dist/fleet-manager/__tests__/discord-manager.test.d.ts.map +0 -1
- package/dist/fleet-manager/__tests__/discord-manager.test.js +0 -3508
- package/dist/fleet-manager/__tests__/discord-manager.test.js.map +0 -1
- package/dist/fleet-manager/__tests__/slack-manager.test.d.ts +0 -11
- package/dist/fleet-manager/__tests__/slack-manager.test.d.ts.map +0 -1
- package/dist/fleet-manager/__tests__/slack-manager.test.js +0 -983
- package/dist/fleet-manager/__tests__/slack-manager.test.js.map +0 -1
- package/dist/fleet-manager/discord-manager.d.ts +0 -353
- package/dist/fleet-manager/discord-manager.d.ts.map +0 -1
- package/dist/fleet-manager/discord-manager.js +0 -1087
- package/dist/fleet-manager/discord-manager.js.map +0 -1
- package/dist/fleet-manager/slack-manager.d.ts +0 -201
- package/dist/fleet-manager/slack-manager.d.ts.map +0 -1
- package/dist/fleet-manager/slack-manager.js +0 -576
- package/dist/fleet-manager/slack-manager.js.map +0 -1
|
@@ -1,576 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Slack Manager Module
|
|
3
|
-
*
|
|
4
|
-
* Manages Slack connectors for agents that have `chat.slack` configured.
|
|
5
|
-
* This module is responsible for:
|
|
6
|
-
* - Creating one SlackConnector instance per Slack-enabled agent
|
|
7
|
-
* - Managing connector lifecycle (start/stop)
|
|
8
|
-
* - Providing access to connectors for status queries
|
|
9
|
-
*
|
|
10
|
-
* Note: This module dynamically imports @herdctl/slack at runtime to avoid
|
|
11
|
-
* a hard dependency. The @herdctl/core package can be used without Slack support.
|
|
12
|
-
*
|
|
13
|
-
* @module slack-manager
|
|
14
|
-
*/
|
|
15
|
-
import { createFileSenderDef } from "../runner/file-sender-mcp.js";
|
|
16
|
-
import { resolveWorkingDirectory } from "./working-directory-helper.js";
|
|
17
|
-
/**
|
|
18
|
-
* Lazy import the Slack package to avoid hard dependency
|
|
19
|
-
*/
|
|
20
|
-
async function importSlackPackage() {
|
|
21
|
-
try {
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
|
-
const pkg = (await import("@herdctl/slack"));
|
|
24
|
-
return pkg;
|
|
25
|
-
}
|
|
26
|
-
catch {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
class StreamingResponder {
|
|
31
|
-
buffer = "";
|
|
32
|
-
lastSendTime = 0;
|
|
33
|
-
messagesSent = 0;
|
|
34
|
-
reply;
|
|
35
|
-
splitResponse;
|
|
36
|
-
logger;
|
|
37
|
-
agentName;
|
|
38
|
-
minMessageInterval;
|
|
39
|
-
maxBufferSize;
|
|
40
|
-
constructor(options) {
|
|
41
|
-
this.reply = options.reply;
|
|
42
|
-
this.splitResponse = options.splitResponse;
|
|
43
|
-
this.logger = options.logger;
|
|
44
|
-
this.agentName = options.agentName;
|
|
45
|
-
this.minMessageInterval = options.minMessageInterval ?? 1000;
|
|
46
|
-
this.maxBufferSize = options.maxBufferSize ?? 3500; // Leave room for Slack's ~4K practical limit
|
|
47
|
-
}
|
|
48
|
-
async addMessageAndSend(content) {
|
|
49
|
-
if (!content || content.trim().length === 0) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
this.buffer += content;
|
|
53
|
-
await this.sendAll();
|
|
54
|
-
}
|
|
55
|
-
async sendAll() {
|
|
56
|
-
if (this.buffer.trim().length === 0) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
const content = this.buffer.trim();
|
|
60
|
-
this.buffer = "";
|
|
61
|
-
const now = Date.now();
|
|
62
|
-
const timeSinceLastSend = now - this.lastSendTime;
|
|
63
|
-
if (timeSinceLastSend < this.minMessageInterval && this.lastSendTime > 0) {
|
|
64
|
-
const waitTime = this.minMessageInterval - timeSinceLastSend;
|
|
65
|
-
await this.sleep(waitTime);
|
|
66
|
-
}
|
|
67
|
-
const chunks = this.splitResponse(content);
|
|
68
|
-
for (const chunk of chunks) {
|
|
69
|
-
try {
|
|
70
|
-
await this.reply(chunk);
|
|
71
|
-
this.messagesSent++;
|
|
72
|
-
this.lastSendTime = Date.now();
|
|
73
|
-
this.logger.debug(`Streamed message to Slack`, {
|
|
74
|
-
agentName: this.agentName,
|
|
75
|
-
chunkLength: chunk.length,
|
|
76
|
-
totalSent: this.messagesSent,
|
|
77
|
-
});
|
|
78
|
-
if (chunks.length > 1) {
|
|
79
|
-
await this.sleep(500);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
84
|
-
this.logger.error(`Failed to send Slack message`, {
|
|
85
|
-
agentName: this.agentName,
|
|
86
|
-
error: errorMessage,
|
|
87
|
-
});
|
|
88
|
-
throw error;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
async flush() {
|
|
93
|
-
await this.sendAll();
|
|
94
|
-
}
|
|
95
|
-
hasSentMessages() {
|
|
96
|
-
return this.messagesSent > 0;
|
|
97
|
-
}
|
|
98
|
-
sleep(ms) {
|
|
99
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
// =============================================================================
|
|
103
|
-
// Slack Manager
|
|
104
|
-
// =============================================================================
|
|
105
|
-
/**
|
|
106
|
-
* SlackManager handles Slack connections for agents
|
|
107
|
-
*
|
|
108
|
-
* This class encapsulates the creation and lifecycle management of
|
|
109
|
-
* SlackConnector instances for agents that have Slack chat configured.
|
|
110
|
-
*/
|
|
111
|
-
export class SlackManager {
|
|
112
|
-
ctx;
|
|
113
|
-
connectors = new Map();
|
|
114
|
-
initialized = false;
|
|
115
|
-
constructor(ctx) {
|
|
116
|
-
this.ctx = ctx;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Initialize Slack connectors for all configured agents
|
|
120
|
-
*
|
|
121
|
-
* This method:
|
|
122
|
-
* 1. Checks if @herdctl/slack package is available
|
|
123
|
-
* 2. Iterates through agents to find those with Slack configured
|
|
124
|
-
* 3. Creates a SlackConnector for each Slack-enabled agent
|
|
125
|
-
*
|
|
126
|
-
* Should be called during FleetManager initialization.
|
|
127
|
-
*/
|
|
128
|
-
async initialize() {
|
|
129
|
-
if (this.initialized) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
const logger = this.ctx.getLogger();
|
|
133
|
-
const config = this.ctx.getConfig();
|
|
134
|
-
if (!config) {
|
|
135
|
-
logger.debug("No config available, skipping Slack initialization");
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
// Try to import the slack package
|
|
139
|
-
const slackPkg = await importSlackPackage();
|
|
140
|
-
if (!slackPkg) {
|
|
141
|
-
logger.debug("@herdctl/slack not installed, skipping Slack connectors");
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
const { SlackConnector, SessionManager } = slackPkg;
|
|
145
|
-
const stateDir = this.ctx.getStateDir();
|
|
146
|
-
// Find agents with Slack configured
|
|
147
|
-
const slackAgents = config.agents.filter((agent) => agent.chat?.slack !== undefined);
|
|
148
|
-
if (slackAgents.length === 0) {
|
|
149
|
-
logger.debug("No agents with Slack configured");
|
|
150
|
-
this.initialized = true;
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
logger.debug(`Initializing Slack connectors for ${slackAgents.length} agent(s)`);
|
|
154
|
-
for (const agent of slackAgents) {
|
|
155
|
-
try {
|
|
156
|
-
const slackConfig = agent.chat.slack;
|
|
157
|
-
if (!slackConfig)
|
|
158
|
-
continue;
|
|
159
|
-
// Get bot token from environment variable
|
|
160
|
-
const botToken = process.env[slackConfig.bot_token_env];
|
|
161
|
-
if (!botToken) {
|
|
162
|
-
logger.warn(`Slack bot token not found in environment variable '${slackConfig.bot_token_env}' for agent '${agent.name}'`);
|
|
163
|
-
continue;
|
|
164
|
-
}
|
|
165
|
-
// Get app token from environment variable
|
|
166
|
-
const appToken = process.env[slackConfig.app_token_env];
|
|
167
|
-
if (!appToken) {
|
|
168
|
-
logger.warn(`Slack app token not found in environment variable '${slackConfig.app_token_env}' for agent '${agent.name}'`);
|
|
169
|
-
continue;
|
|
170
|
-
}
|
|
171
|
-
// Create logger adapter for this agent
|
|
172
|
-
const createAgentLogger = (prefix) => ({
|
|
173
|
-
debug: (msg, data) => logger.debug(`${prefix} ${msg}${data ? ` ${JSON.stringify(data)}` : ""}`),
|
|
174
|
-
info: (msg, data) => logger.info(`${prefix} ${msg}${data ? ` ${JSON.stringify(data)}` : ""}`),
|
|
175
|
-
warn: (msg, data) => logger.warn(`${prefix} ${msg}${data ? ` ${JSON.stringify(data)}` : ""}`),
|
|
176
|
-
error: (msg, data) => logger.error(`${prefix} ${msg}${data ? ` ${JSON.stringify(data)}` : ""}`),
|
|
177
|
-
});
|
|
178
|
-
// Create session manager for this agent
|
|
179
|
-
const sessionManager = new SessionManager({
|
|
180
|
-
agentName: agent.name,
|
|
181
|
-
stateDir,
|
|
182
|
-
sessionExpiryHours: slackConfig.session_expiry_hours,
|
|
183
|
-
logger: createAgentLogger(`[slack:${agent.name}:session]`),
|
|
184
|
-
});
|
|
185
|
-
// Create the connector with per-agent options
|
|
186
|
-
const connector = new SlackConnector({
|
|
187
|
-
agentName: agent.name,
|
|
188
|
-
botToken,
|
|
189
|
-
appToken,
|
|
190
|
-
channels: slackConfig.channels.map((ch) => ({ id: ch.id, mode: ch.mode })),
|
|
191
|
-
sessionManager,
|
|
192
|
-
logger: createAgentLogger(`[slack:${agent.name}]`),
|
|
193
|
-
});
|
|
194
|
-
this.connectors.set(agent.name, connector);
|
|
195
|
-
logger.debug(`Created Slack connector for agent '${agent.name}'`);
|
|
196
|
-
}
|
|
197
|
-
catch (error) {
|
|
198
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
199
|
-
logger.error(`Failed to create Slack connector for agent '${agent.name}': ${errorMessage}`);
|
|
200
|
-
// Continue with other agents - don't fail the whole initialization
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
this.initialized = true;
|
|
204
|
-
logger.debug(`Slack manager initialized with ${this.connectors.size} connector(s)`);
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Connect all Slack connectors
|
|
208
|
-
*
|
|
209
|
-
* Connects each connector to Slack via Socket Mode and subscribes to events.
|
|
210
|
-
* Errors are logged but don't stop other connectors from connecting.
|
|
211
|
-
*/
|
|
212
|
-
async start() {
|
|
213
|
-
const logger = this.ctx.getLogger();
|
|
214
|
-
if (this.connectors.size === 0) {
|
|
215
|
-
logger.debug("No Slack connectors to start");
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
logger.debug(`Starting ${this.connectors.size} Slack connector(s)...`);
|
|
219
|
-
const connectPromises = [];
|
|
220
|
-
for (const [agentName, connector] of this.connectors) {
|
|
221
|
-
// Subscribe to connector events before connecting
|
|
222
|
-
connector.on("message", (event) => {
|
|
223
|
-
this.handleMessage(agentName, event).catch((error) => {
|
|
224
|
-
this.handleError(agentName, error);
|
|
225
|
-
});
|
|
226
|
-
});
|
|
227
|
-
connector.on("error", (event) => {
|
|
228
|
-
this.handleError(event.agentName, event.error);
|
|
229
|
-
});
|
|
230
|
-
connectPromises.push(connector.connect().catch((error) => {
|
|
231
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
232
|
-
logger.error(`Failed to connect Slack for agent '${agentName}': ${errorMessage}`);
|
|
233
|
-
// Don't re-throw - we want to continue connecting other agents
|
|
234
|
-
}));
|
|
235
|
-
}
|
|
236
|
-
await Promise.all(connectPromises);
|
|
237
|
-
const connectedCount = Array.from(this.connectors.values()).filter((c) => c.isConnected()).length;
|
|
238
|
-
logger.info(`Slack connectors started: ${connectedCount}/${this.connectors.size} connected`);
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Disconnect all Slack connectors gracefully
|
|
242
|
-
*
|
|
243
|
-
* Sessions are automatically persisted to disk on every update,
|
|
244
|
-
* so they survive bot restarts. This method logs session state
|
|
245
|
-
* before disconnecting for monitoring purposes.
|
|
246
|
-
*
|
|
247
|
-
* Errors are logged but don't prevent other connectors from disconnecting.
|
|
248
|
-
*/
|
|
249
|
-
async stop() {
|
|
250
|
-
const logger = this.ctx.getLogger();
|
|
251
|
-
if (this.connectors.size === 0) {
|
|
252
|
-
logger.debug("No Slack connectors to stop");
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
logger.debug(`Stopping ${this.connectors.size} Slack connector(s)...`);
|
|
256
|
-
// Log session state before shutdown (sessions are already persisted to disk)
|
|
257
|
-
for (const [agentName, connector] of this.connectors) {
|
|
258
|
-
try {
|
|
259
|
-
const activeSessionCount = await connector.sessionManager.getActiveSessionCount();
|
|
260
|
-
if (activeSessionCount > 0) {
|
|
261
|
-
logger.debug(`Preserving ${activeSessionCount} active Slack session(s) for agent '${agentName}'`);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
catch (error) {
|
|
265
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
266
|
-
logger.warn(`Failed to get Slack session count for agent '${agentName}': ${errorMessage}`);
|
|
267
|
-
// Continue with shutdown - this is just informational logging
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
const disconnectPromises = [];
|
|
271
|
-
for (const [agentName, connector] of this.connectors) {
|
|
272
|
-
disconnectPromises.push(connector.disconnect().catch((error) => {
|
|
273
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
274
|
-
logger.error(`Error disconnecting Slack for agent '${agentName}': ${errorMessage}`);
|
|
275
|
-
// Don't re-throw - graceful shutdown should continue
|
|
276
|
-
}));
|
|
277
|
-
}
|
|
278
|
-
await Promise.all(disconnectPromises);
|
|
279
|
-
logger.debug("All Slack connectors stopped");
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Get a connector for a specific agent
|
|
283
|
-
*
|
|
284
|
-
* @param agentName - Name of the agent
|
|
285
|
-
* @returns The SlackConnector instance, or undefined if not found
|
|
286
|
-
*/
|
|
287
|
-
getConnector(agentName) {
|
|
288
|
-
return this.connectors.get(agentName);
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* Get all connector names
|
|
292
|
-
*
|
|
293
|
-
* @returns Array of agent names that have Slack connectors
|
|
294
|
-
*/
|
|
295
|
-
getConnectorNames() {
|
|
296
|
-
return Array.from(this.connectors.keys());
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Get the number of active connectors
|
|
300
|
-
*
|
|
301
|
-
* @returns Number of connectors that are currently connected
|
|
302
|
-
*/
|
|
303
|
-
getConnectedCount() {
|
|
304
|
-
return Array.from(this.connectors.values()).filter((c) => c.isConnected()).length;
|
|
305
|
-
}
|
|
306
|
-
/**
|
|
307
|
-
* Check if a specific agent has a Slack connector
|
|
308
|
-
*
|
|
309
|
-
* @param agentName - Name of the agent
|
|
310
|
-
* @returns true if the agent has a Slack connector
|
|
311
|
-
*/
|
|
312
|
-
hasAgent(agentName) {
|
|
313
|
-
return this.connectors.has(agentName);
|
|
314
|
-
}
|
|
315
|
-
/**
|
|
316
|
-
* Get the state of a specific connector
|
|
317
|
-
*
|
|
318
|
-
* @param agentName - Name of the agent
|
|
319
|
-
* @returns The connector state, or null if not found
|
|
320
|
-
*/
|
|
321
|
-
getState(agentName) {
|
|
322
|
-
return this.connectors.get(agentName)?.getState() ?? null;
|
|
323
|
-
}
|
|
324
|
-
// ===========================================================================
|
|
325
|
-
// Message Handling Pipeline
|
|
326
|
-
// ===========================================================================
|
|
327
|
-
async handleMessage(agentName, event) {
|
|
328
|
-
const logger = this.ctx.getLogger();
|
|
329
|
-
const emitter = this.ctx.getEmitter();
|
|
330
|
-
logger.info(`Slack message for agent '${agentName}': ${event.prompt.substring(0, 50)}...`);
|
|
331
|
-
// Get the agent configuration
|
|
332
|
-
const config = this.ctx.getConfig();
|
|
333
|
-
const agent = config?.agents.find((a) => a.name === agentName);
|
|
334
|
-
if (!agent) {
|
|
335
|
-
logger.error(`Agent '${agentName}' not found in configuration`);
|
|
336
|
-
try {
|
|
337
|
-
await event.reply("Sorry, I'm not properly configured. Please contact an administrator.");
|
|
338
|
-
}
|
|
339
|
-
catch (replyError) {
|
|
340
|
-
logger.error(`Failed to send error reply: ${replyError.message}`);
|
|
341
|
-
}
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
|
-
// Get existing session for this channel (for conversation continuity)
|
|
345
|
-
const connector = this.connectors.get(agentName);
|
|
346
|
-
let existingSessionId = null;
|
|
347
|
-
if (connector) {
|
|
348
|
-
try {
|
|
349
|
-
const existingSession = await connector.sessionManager.getSession(event.metadata.channelId);
|
|
350
|
-
if (existingSession) {
|
|
351
|
-
existingSessionId = existingSession.sessionId;
|
|
352
|
-
logger.debug(`Resuming session for channel ${event.metadata.channelId}: ${existingSessionId}`);
|
|
353
|
-
emitter.emit("slack:session:lifecycle", {
|
|
354
|
-
agentName,
|
|
355
|
-
event: "resumed",
|
|
356
|
-
channelId: event.metadata.channelId,
|
|
357
|
-
sessionId: existingSessionId,
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
else {
|
|
361
|
-
logger.debug(`No existing session for channel ${event.metadata.channelId}, starting new conversation`);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
catch (error) {
|
|
365
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
366
|
-
logger.warn(`Failed to get session: ${errorMessage}`);
|
|
367
|
-
// Continue processing - session failure shouldn't block message handling
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
// Create file sender definition for this message context
|
|
371
|
-
let injectedMcpServers;
|
|
372
|
-
const workingDir = resolveWorkingDirectory(agent);
|
|
373
|
-
if (connector && workingDir) {
|
|
374
|
-
const agentConnector = connector;
|
|
375
|
-
const fileSenderContext = {
|
|
376
|
-
workingDirectory: workingDir,
|
|
377
|
-
uploadFile: async (params) => {
|
|
378
|
-
return agentConnector.uploadFile({
|
|
379
|
-
channelId: event.metadata.channelId,
|
|
380
|
-
fileBuffer: params.fileBuffer,
|
|
381
|
-
filename: params.filename,
|
|
382
|
-
message: params.message,
|
|
383
|
-
});
|
|
384
|
-
},
|
|
385
|
-
};
|
|
386
|
-
const fileSenderDef = createFileSenderDef(fileSenderContext);
|
|
387
|
-
injectedMcpServers = { [fileSenderDef.name]: fileSenderDef };
|
|
388
|
-
}
|
|
389
|
-
// Create streaming responder
|
|
390
|
-
const streamer = new StreamingResponder({
|
|
391
|
-
reply: event.reply,
|
|
392
|
-
splitResponse: (text) => this.splitResponse(text),
|
|
393
|
-
logger,
|
|
394
|
-
agentName,
|
|
395
|
-
});
|
|
396
|
-
// Start processing indicator (hourglass emoji)
|
|
397
|
-
const stopProcessing = event.startProcessingIndicator();
|
|
398
|
-
let processingStopped = false;
|
|
399
|
-
try {
|
|
400
|
-
const fleetManager = emitter;
|
|
401
|
-
const result = await fleetManager.trigger(agentName, undefined, {
|
|
402
|
-
prompt: event.prompt,
|
|
403
|
-
resume: existingSessionId,
|
|
404
|
-
injectedMcpServers,
|
|
405
|
-
onMessage: async (message) => {
|
|
406
|
-
if (message.type === "assistant") {
|
|
407
|
-
const content = this.extractMessageContent(message);
|
|
408
|
-
if (content) {
|
|
409
|
-
await streamer.addMessageAndSend(content);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
},
|
|
413
|
-
});
|
|
414
|
-
// Stop processing indicator
|
|
415
|
-
if (!processingStopped) {
|
|
416
|
-
stopProcessing();
|
|
417
|
-
processingStopped = true;
|
|
418
|
-
}
|
|
419
|
-
// Flush remaining content
|
|
420
|
-
await streamer.flush();
|
|
421
|
-
logger.info(`Slack job completed: ${result.jobId} for agent '${agentName}'${result.sessionId ? ` (session: ${result.sessionId})` : ""}`);
|
|
422
|
-
// Fallback message if nothing was sent
|
|
423
|
-
if (!streamer.hasSentMessages()) {
|
|
424
|
-
if (result.success) {
|
|
425
|
-
await event.reply("I've completed the task, but I don't have a specific response to share.");
|
|
426
|
-
}
|
|
427
|
-
else {
|
|
428
|
-
const errorMessage = result.errorDetails?.message ?? result.error?.message ?? "An unknown error occurred";
|
|
429
|
-
await event.reply(`*Error:* ${errorMessage}\n\nThe task could not be completed. Please check the logs for more details.`);
|
|
430
|
-
}
|
|
431
|
-
if (!processingStopped) {
|
|
432
|
-
stopProcessing();
|
|
433
|
-
processingStopped = true;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
// Store the SDK session ID for future conversation continuity
|
|
437
|
-
// Only store if the job succeeded - failed jobs may return invalid session IDs
|
|
438
|
-
if (connector && result.sessionId && result.success) {
|
|
439
|
-
const isNewSession = existingSessionId === null;
|
|
440
|
-
try {
|
|
441
|
-
await connector.sessionManager.setSession(event.metadata.channelId, result.sessionId);
|
|
442
|
-
logger.debug(`Stored session ${result.sessionId} for channel ${event.metadata.channelId}`);
|
|
443
|
-
if (isNewSession) {
|
|
444
|
-
emitter.emit("slack:session:lifecycle", {
|
|
445
|
-
agentName,
|
|
446
|
-
event: "created",
|
|
447
|
-
channelId: event.metadata.channelId,
|
|
448
|
-
sessionId: result.sessionId,
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
catch (sessionError) {
|
|
453
|
-
const errorMessage = sessionError instanceof Error ? sessionError.message : String(sessionError);
|
|
454
|
-
logger.warn(`Failed to store session: ${errorMessage}`);
|
|
455
|
-
// Don't fail the message handling for session storage failure
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
else if (connector && result.sessionId && !result.success) {
|
|
459
|
-
logger.debug(`Not storing session ${result.sessionId} for channel ${event.metadata.channelId} - job failed`);
|
|
460
|
-
}
|
|
461
|
-
// Emit event for tracking
|
|
462
|
-
emitter.emit("slack:message:handled", {
|
|
463
|
-
agentName,
|
|
464
|
-
channelId: event.metadata.channelId,
|
|
465
|
-
messageTs: event.metadata.messageTs,
|
|
466
|
-
jobId: result.jobId,
|
|
467
|
-
timestamp: new Date().toISOString(),
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
catch (error) {
|
|
471
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
472
|
-
logger.error(`Slack message handling failed for agent '${agentName}': ${err.message}`);
|
|
473
|
-
try {
|
|
474
|
-
await event.reply(this.formatErrorMessage(err));
|
|
475
|
-
}
|
|
476
|
-
catch (replyError) {
|
|
477
|
-
logger.error(`Failed to send error reply: ${replyError.message}`);
|
|
478
|
-
}
|
|
479
|
-
emitter.emit("slack:message:error", {
|
|
480
|
-
agentName,
|
|
481
|
-
channelId: event.metadata.channelId,
|
|
482
|
-
messageTs: event.metadata.messageTs,
|
|
483
|
-
error: err.message,
|
|
484
|
-
timestamp: new Date().toISOString(),
|
|
485
|
-
});
|
|
486
|
-
}
|
|
487
|
-
finally {
|
|
488
|
-
if (!processingStopped) {
|
|
489
|
-
stopProcessing();
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
/**
|
|
494
|
-
* Extract text content from an SDK message
|
|
495
|
-
*/
|
|
496
|
-
extractMessageContent(message) {
|
|
497
|
-
if (typeof message.content === "string" && message.content) {
|
|
498
|
-
return message.content;
|
|
499
|
-
}
|
|
500
|
-
const apiMessage = message.message;
|
|
501
|
-
const content = apiMessage?.content;
|
|
502
|
-
if (!content)
|
|
503
|
-
return undefined;
|
|
504
|
-
if (typeof content === "string") {
|
|
505
|
-
return content;
|
|
506
|
-
}
|
|
507
|
-
if (Array.isArray(content)) {
|
|
508
|
-
const textParts = [];
|
|
509
|
-
for (const block of content) {
|
|
510
|
-
if (block && typeof block === "object" && "type" in block) {
|
|
511
|
-
if (block.type === "text" && "text" in block && typeof block.text === "string") {
|
|
512
|
-
textParts.push(block.text);
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
return textParts.length > 0 ? textParts.join("") : undefined;
|
|
517
|
-
}
|
|
518
|
-
return undefined;
|
|
519
|
-
}
|
|
520
|
-
/**
|
|
521
|
-
* Handle errors from the Slack connector
|
|
522
|
-
*/
|
|
523
|
-
handleError(agentName, error) {
|
|
524
|
-
const logger = this.ctx.getLogger();
|
|
525
|
-
const emitter = this.ctx.getEmitter();
|
|
526
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
527
|
-
logger.error(`Slack connector error for agent '${agentName}': ${errorMessage}`);
|
|
528
|
-
emitter.emit("slack:error", {
|
|
529
|
-
agentName,
|
|
530
|
-
error: errorMessage,
|
|
531
|
-
timestamp: new Date().toISOString(),
|
|
532
|
-
});
|
|
533
|
-
}
|
|
534
|
-
// ===========================================================================
|
|
535
|
-
// Response Formatting and Splitting
|
|
536
|
-
// ===========================================================================
|
|
537
|
-
static MAX_MESSAGE_LENGTH = 4000;
|
|
538
|
-
formatErrorMessage(error) {
|
|
539
|
-
return `*Error:* ${error.message}\n\nPlease try again or use \`!reset\` to start a new session.`;
|
|
540
|
-
}
|
|
541
|
-
splitResponse(text) {
|
|
542
|
-
const MAX_LENGTH = SlackManager.MAX_MESSAGE_LENGTH;
|
|
543
|
-
if (text.length <= MAX_LENGTH) {
|
|
544
|
-
return [text];
|
|
545
|
-
}
|
|
546
|
-
const chunks = [];
|
|
547
|
-
let remaining = text;
|
|
548
|
-
while (remaining.length > 0) {
|
|
549
|
-
if (remaining.length <= MAX_LENGTH) {
|
|
550
|
-
chunks.push(remaining);
|
|
551
|
-
break;
|
|
552
|
-
}
|
|
553
|
-
const splitIndex = this.findNaturalBreak(remaining, MAX_LENGTH);
|
|
554
|
-
chunks.push(remaining.substring(0, splitIndex));
|
|
555
|
-
remaining = remaining.substring(splitIndex);
|
|
556
|
-
}
|
|
557
|
-
return chunks;
|
|
558
|
-
}
|
|
559
|
-
findNaturalBreak(text, maxLength) {
|
|
560
|
-
const searchEnd = Math.min(maxLength, text.length);
|
|
561
|
-
const doubleNewline = text.lastIndexOf("\n\n", searchEnd);
|
|
562
|
-
if (doubleNewline > 0 && doubleNewline > searchEnd - 500) {
|
|
563
|
-
return doubleNewline + 2;
|
|
564
|
-
}
|
|
565
|
-
const singleNewline = text.lastIndexOf("\n", searchEnd);
|
|
566
|
-
if (singleNewline > 0 && singleNewline > searchEnd - 200) {
|
|
567
|
-
return singleNewline + 1;
|
|
568
|
-
}
|
|
569
|
-
const space = text.lastIndexOf(" ", searchEnd);
|
|
570
|
-
if (space > 0 && space > searchEnd - 100) {
|
|
571
|
-
return space + 1;
|
|
572
|
-
}
|
|
573
|
-
return searchEnd;
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
//# sourceMappingURL=slack-manager.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"slack-manager.js","sourceRoot":"","sources":["../../src/fleet-manager/slack-manager.ts"],"names":[],"mappings":"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"}
|