@hailer/mcp 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 (163) hide show
  1. package/.claude/commands/tool-builder.md +37 -0
  2. package/.claude/commands/ws-pull.md +44 -0
  3. package/.claude/settings.json +8 -0
  4. package/.claude/settings.local.json +49 -0
  5. package/.claude/skills/activity-api/SKILL.md +96 -0
  6. package/.claude/skills/activity-api/references/activity-endpoints.md +845 -0
  7. package/.claude/skills/add-app-member-skill/SKILL.md +977 -0
  8. package/.claude/skills/agent-building/SKILL.md +243 -0
  9. package/.claude/skills/agent-building/references/architecture-patterns.md +446 -0
  10. package/.claude/skills/agent-building/references/code-examples.md +587 -0
  11. package/.claude/skills/agent-building/references/implementation-guide.md +619 -0
  12. package/.claude/skills/app-api/SKILL.md +219 -0
  13. package/.claude/skills/app-api/references/app-endpoints.md +759 -0
  14. package/.claude/skills/building-hailer-apps-skill/SKILL.md +548 -0
  15. package/.claude/skills/create-app-skill/SKILL.md +1101 -0
  16. package/.claude/skills/create-insight-skill/SKILL.md +1317 -0
  17. package/.claude/skills/get-insight-data-skill/SKILL.md +1053 -0
  18. package/.claude/skills/hailer-api/SKILL.md +283 -0
  19. package/.claude/skills/hailer-api/references/activities.md +620 -0
  20. package/.claude/skills/hailer-api/references/authentication.md +216 -0
  21. package/.claude/skills/hailer-api/references/datasets.md +437 -0
  22. package/.claude/skills/hailer-api/references/files.md +301 -0
  23. package/.claude/skills/hailer-api/references/insights.md +469 -0
  24. package/.claude/skills/hailer-api/references/workflows.md +720 -0
  25. package/.claude/skills/hailer-api/references/workspaces-users.md +445 -0
  26. package/.claude/skills/insight-api/SKILL.md +185 -0
  27. package/.claude/skills/insight-api/references/insight-endpoints.md +514 -0
  28. package/.claude/skills/install-workflow-skill/SKILL.md +1056 -0
  29. package/.claude/skills/list-apps-skill/SKILL.md +1010 -0
  30. package/.claude/skills/list-workflows-minimal-skill/SKILL.md +992 -0
  31. package/.claude/skills/local-first-skill/SKILL.md +570 -0
  32. package/.claude/skills/mcp-tools/SKILL.md +419 -0
  33. package/.claude/skills/mcp-tools/references/api-endpoints.md +499 -0
  34. package/.claude/skills/mcp-tools/references/data-structures.md +554 -0
  35. package/.claude/skills/mcp-tools/references/implementation-patterns.md +717 -0
  36. package/.claude/skills/preview-insight-skill/SKILL.md +1290 -0
  37. package/.claude/skills/publish-hailer-app-skill/SKILL.md +453 -0
  38. package/.claude/skills/remove-app-member-skill/SKILL.md +671 -0
  39. package/.claude/skills/remove-app-skill/SKILL.md +985 -0
  40. package/.claude/skills/remove-insight-skill/SKILL.md +1011 -0
  41. package/.claude/skills/remove-workflow-skill/SKILL.md +920 -0
  42. package/.claude/skills/scaffold-hailer-app-skill/SKILL.md +1034 -0
  43. package/.claude/skills/skill-testing/README.md +137 -0
  44. package/.claude/skills/skill-testing/SKILL.md +348 -0
  45. package/.claude/skills/skill-testing/references/test-patterns.md +705 -0
  46. package/.claude/skills/skill-testing/references/testing-guide.md +603 -0
  47. package/.claude/skills/skill-testing/references/validation-checklist.md +537 -0
  48. package/.claude/skills/tool-builder/SKILL.md +328 -0
  49. package/.claude/skills/update-app-skill/SKILL.md +970 -0
  50. package/.claude/skills/update-workflow-field-skill/SKILL.md +1098 -0
  51. package/.env.example +81 -0
  52. package/.mcp.json +13 -0
  53. package/README.md +297 -0
  54. package/dist/app.d.ts +4 -0
  55. package/dist/app.js +74 -0
  56. package/dist/cli.d.ts +3 -0
  57. package/dist/cli.js +5 -0
  58. package/dist/client/adaptive-documentation-bot.d.ts +108 -0
  59. package/dist/client/adaptive-documentation-bot.js +475 -0
  60. package/dist/client/adaptive-documentation-types.d.ts +66 -0
  61. package/dist/client/adaptive-documentation-types.js +9 -0
  62. package/dist/client/agent-activity-bot.d.ts +51 -0
  63. package/dist/client/agent-activity-bot.js +166 -0
  64. package/dist/client/agent-tracker.d.ts +499 -0
  65. package/dist/client/agent-tracker.js +659 -0
  66. package/dist/client/description-updater.d.ts +56 -0
  67. package/dist/client/description-updater.js +259 -0
  68. package/dist/client/log-parser.d.ts +72 -0
  69. package/dist/client/log-parser.js +387 -0
  70. package/dist/client/mcp-client.d.ts +50 -0
  71. package/dist/client/mcp-client.js +532 -0
  72. package/dist/client/message-processor.d.ts +35 -0
  73. package/dist/client/message-processor.js +352 -0
  74. package/dist/client/multi-bot-manager.d.ts +24 -0
  75. package/dist/client/multi-bot-manager.js +74 -0
  76. package/dist/client/providers/anthropic-provider.d.ts +19 -0
  77. package/dist/client/providers/anthropic-provider.js +631 -0
  78. package/dist/client/providers/llm-provider.d.ts +47 -0
  79. package/dist/client/providers/llm-provider.js +367 -0
  80. package/dist/client/providers/openai-provider.d.ts +23 -0
  81. package/dist/client/providers/openai-provider.js +621 -0
  82. package/dist/client/simple-llm-caller.d.ts +19 -0
  83. package/dist/client/simple-llm-caller.js +100 -0
  84. package/dist/client/skill-generator.d.ts +81 -0
  85. package/dist/client/skill-generator.js +386 -0
  86. package/dist/client/test-adaptive-bot.d.ts +9 -0
  87. package/dist/client/test-adaptive-bot.js +82 -0
  88. package/dist/client/token-pricing.d.ts +38 -0
  89. package/dist/client/token-pricing.js +127 -0
  90. package/dist/client/token-tracker.d.ts +232 -0
  91. package/dist/client/token-tracker.js +457 -0
  92. package/dist/client/token-usage-bot.d.ts +53 -0
  93. package/dist/client/token-usage-bot.js +153 -0
  94. package/dist/client/tool-executor.d.ts +69 -0
  95. package/dist/client/tool-executor.js +159 -0
  96. package/dist/client/tool-schema-loader.d.ts +60 -0
  97. package/dist/client/tool-schema-loader.js +178 -0
  98. package/dist/client/types.d.ts +69 -0
  99. package/dist/client/types.js +7 -0
  100. package/dist/config.d.ts +162 -0
  101. package/dist/config.js +296 -0
  102. package/dist/core.d.ts +26 -0
  103. package/dist/core.js +147 -0
  104. package/dist/lib/context-manager.d.ts +111 -0
  105. package/dist/lib/context-manager.js +431 -0
  106. package/dist/lib/logger.d.ts +74 -0
  107. package/dist/lib/logger.js +277 -0
  108. package/dist/lib/materialize.d.ts +3 -0
  109. package/dist/lib/materialize.js +101 -0
  110. package/dist/lib/normalizedName.d.ts +7 -0
  111. package/dist/lib/normalizedName.js +48 -0
  112. package/dist/lib/prompt-length-manager.d.ts +81 -0
  113. package/dist/lib/prompt-length-manager.js +457 -0
  114. package/dist/lib/terminal-prompt.d.ts +9 -0
  115. package/dist/lib/terminal-prompt.js +108 -0
  116. package/dist/mcp/UserContextCache.d.ts +56 -0
  117. package/dist/mcp/UserContextCache.js +163 -0
  118. package/dist/mcp/auth.d.ts +2 -0
  119. package/dist/mcp/auth.js +29 -0
  120. package/dist/mcp/hailer-clients.d.ts +42 -0
  121. package/dist/mcp/hailer-clients.js +246 -0
  122. package/dist/mcp/signal-handler.d.ts +45 -0
  123. package/dist/mcp/signal-handler.js +317 -0
  124. package/dist/mcp/tool-registry.d.ts +100 -0
  125. package/dist/mcp/tool-registry.js +306 -0
  126. package/dist/mcp/tools/activity.d.ts +15 -0
  127. package/dist/mcp/tools/activity.js +955 -0
  128. package/dist/mcp/tools/app.d.ts +20 -0
  129. package/dist/mcp/tools/app.js +1488 -0
  130. package/dist/mcp/tools/discussion.d.ts +19 -0
  131. package/dist/mcp/tools/discussion.js +950 -0
  132. package/dist/mcp/tools/file.d.ts +15 -0
  133. package/dist/mcp/tools/file.js +119 -0
  134. package/dist/mcp/tools/insight.d.ts +17 -0
  135. package/dist/mcp/tools/insight.js +806 -0
  136. package/dist/mcp/tools/skill.d.ts +10 -0
  137. package/dist/mcp/tools/skill.js +279 -0
  138. package/dist/mcp/tools/user.d.ts +10 -0
  139. package/dist/mcp/tools/user.js +108 -0
  140. package/dist/mcp/tools/workflow-template.d.ts +19 -0
  141. package/dist/mcp/tools/workflow-template.js +822 -0
  142. package/dist/mcp/tools/workflow.d.ts +18 -0
  143. package/dist/mcp/tools/workflow.js +1362 -0
  144. package/dist/mcp/utils/api-errors.d.ts +45 -0
  145. package/dist/mcp/utils/api-errors.js +160 -0
  146. package/dist/mcp/utils/data-transformers.d.ts +102 -0
  147. package/dist/mcp/utils/data-transformers.js +194 -0
  148. package/dist/mcp/utils/file-upload.d.ts +33 -0
  149. package/dist/mcp/utils/file-upload.js +148 -0
  150. package/dist/mcp/utils/hailer-api-client.d.ts +120 -0
  151. package/dist/mcp/utils/hailer-api-client.js +323 -0
  152. package/dist/mcp/utils/index.d.ts +13 -0
  153. package/dist/mcp/utils/index.js +39 -0
  154. package/dist/mcp/utils/logger.d.ts +42 -0
  155. package/dist/mcp/utils/logger.js +103 -0
  156. package/dist/mcp/utils/types.d.ts +286 -0
  157. package/dist/mcp/utils/types.js +7 -0
  158. package/dist/mcp/workspace-cache.d.ts +42 -0
  159. package/dist/mcp/workspace-cache.js +97 -0
  160. package/dist/mcp-server.d.ts +42 -0
  161. package/dist/mcp-server.js +280 -0
  162. package/package.json +56 -0
  163. package/tsconfig.json +23 -0
@@ -0,0 +1,352 @@
1
+ "use strict";
2
+ /**
3
+ * Message Processor for MCP Client
4
+ * Handles incoming socket.io signals and processes messages that mention MCP agents
5
+ * or are sent directly in one-on-one conversations with MCP agents
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.HailerMessageProcessor = void 0;
9
+ class HailerMessageProcessor {
10
+ multiBotManager;
11
+ mcpAgentIds;
12
+ enableDirectMessages;
13
+ constructor(multiBotManager, mcpAgentIds = [], enableDirectMessages = false) {
14
+ this.multiBotManager = multiBotManager;
15
+ this.mcpAgentIds = mcpAgentIds;
16
+ this.enableDirectMessages = enableDirectMessages;
17
+ }
18
+ shouldProcess(signal) {
19
+ // Only process discussion.message and messenger.new signals
20
+ if (signal.type !== "discussion.message" &&
21
+ signal.type !== "messenger.new") {
22
+ return false;
23
+ }
24
+ // For messenger.new signals, we'll check both hailerTag mentions and direct messages in extractMessage
25
+ if (signal.type === "messenger.new") {
26
+ return true; // Let extractMessage handle all the logic
27
+ }
28
+ // For discussion.message signals, check here
29
+ const messageContent = signal.data?.message?.content || "";
30
+ return this.containsMcpAgentMention(messageContent).found;
31
+ }
32
+ containsMcpAgentMention(content) {
33
+ if (this.mcpAgentIds.length === 0) {
34
+ // Fallback to old @mcp-agent detection if no agent IDs configured
35
+ return {
36
+ found: content.toLowerCase().includes("@mcp-agent"),
37
+ mentionedBotIds: [],
38
+ };
39
+ }
40
+ // Check for hailerTag mentions of our MCP agents
41
+ // Pattern: [hailerTag|Agent Name](agentUserId)
42
+ const hailerTagPattern = /\[hailerTag\|[^\]]+\]\(([^)]+)\)/g;
43
+ let match;
44
+ const mentionedBotIds = [];
45
+ while ((match = hailerTagPattern.exec(content)) !== null) {
46
+ const mentionedUserId = match[1];
47
+ if (this.mcpAgentIds.includes(mentionedUserId)) {
48
+ mentionedBotIds.push(mentionedUserId);
49
+ console.log(`✅ MCP Client: Found mention of bot: ${mentionedUserId}`);
50
+ }
51
+ }
52
+ return { found: mentionedBotIds.length > 0, mentionedBotIds };
53
+ }
54
+ /**
55
+ * Fetch discussion participants to determine if it's a one-on-one conversation
56
+ * Uses messenger.load_discussions API to get actual member count
57
+ */
58
+ async fetchDiscussionParticipants(discussionId, botClient) {
59
+ try {
60
+ // Try messenger.load_discussions - it expects an array of discussion IDs
61
+ const response = await botClient.client.socket.request("messenger.load_discussions", [[discussionId]]);
62
+ // Response is an object with discussionId as key
63
+ if (response && response[discussionId]) {
64
+ const discussion = response[discussionId];
65
+ // First try: Use the 'participants' array which has plain user IDs
66
+ if (discussion.participants && Array.isArray(discussion.participants)) {
67
+ console.log(`📊 MCP Client: Discussion has ${discussion.participants.length} participant(s)`);
68
+ return discussion.participants;
69
+ }
70
+ // Fallback: Use 'members' array and extract IDs
71
+ if (discussion.members && Array.isArray(discussion.members)) {
72
+ const memberIds = [];
73
+ for (const member of discussion.members) {
74
+ // Members have format: { id: "user_USERID", ... }
75
+ if (member && member.id && typeof member.id === "string") {
76
+ // Extract the actual user ID from "user_USERID" format
77
+ const userId = member.id.replace(/^user_/, "");
78
+ memberIds.push(userId);
79
+ }
80
+ else if (typeof member === "string") {
81
+ memberIds.push(member);
82
+ }
83
+ else if (member && member._id) {
84
+ memberIds.push(member._id);
85
+ }
86
+ }
87
+ console.log(`📊 MCP Client: Discussion has ${memberIds.length} member(s)`);
88
+ return memberIds;
89
+ }
90
+ }
91
+ const messagesResponse = await botClient.client.socket.request("v3.discussion.message.latest", [discussionId]);
92
+ const messages = messagesResponse?.messages || [];
93
+ const participantIds = new Set();
94
+ // Extract unique participant IDs from messages
95
+ for (const message of messages) {
96
+ if (message.uid) {
97
+ participantIds.add(message.uid);
98
+ }
99
+ }
100
+ // Add the bot itself as a participant
101
+ participantIds.add(botClient.userId);
102
+ const participants = Array.from(participantIds);
103
+ console.log(`📊 MCP Client: Discussion has ${participants.length} participant(s) (message-based fallback)`);
104
+ return participants;
105
+ }
106
+ catch (error) {
107
+ console.error(`❌ MCP Client: Failed to fetch discussion participants:`, error);
108
+ // On error, also try fallback
109
+ try {
110
+ const messagesResponse = await botClient.client.socket.request("v3.discussion.message.latest", [discussionId]);
111
+ const messages = messagesResponse?.messages || [];
112
+ const participantIds = new Set();
113
+ for (const message of messages) {
114
+ if (message.uid) {
115
+ participantIds.add(message.uid);
116
+ }
117
+ }
118
+ participantIds.add(botClient.userId);
119
+ const participants = Array.from(participantIds);
120
+ console.log(`📊 MCP Client: Discussion has ${participants.length} participant(s) (error recovery)`);
121
+ return participants;
122
+ }
123
+ catch (fallbackError) {
124
+ console.error(`❌ MCP Client: All participant detection methods failed`);
125
+ return [];
126
+ }
127
+ }
128
+ }
129
+ /**
130
+ * Check if a discussion is a one-on-one conversation with a specific MCP agent
131
+ * @param discussionId - The discussion to check
132
+ * @param senderId - The user who sent the message
133
+ * @param botIdToCheck - The specific bot ID to check for direct message
134
+ * @returns The bot ID if it's a 1:1 conversation with that bot, null otherwise
135
+ */
136
+ async isDirectMessageToBot(discussionId, senderId, botIdToCheck) {
137
+ // Get the bot client for the specific bot we're checking
138
+ const botClient = this.multiBotManager.getBotClient(botIdToCheck);
139
+ if (!botClient) {
140
+ console.warn(`⚠️ MCP Client: No bot client found for bot ID: ${botIdToCheck}`);
141
+ return null;
142
+ }
143
+ const participants = await this.fetchDiscussionParticipants(discussionId, botClient);
144
+ // For a one-on-one conversation, we expect exactly 2 participants
145
+ if (participants.length !== 2) {
146
+ return null;
147
+ }
148
+ // Check if the two participants are the sender and the bot we're checking for
149
+ const includesSender = participants.includes(senderId);
150
+ const includesBot = participants.includes(botIdToCheck);
151
+ if (includesSender && includesBot) {
152
+ console.log(`✅ MCP Client: 1:1 chat detected - will respond without tag`);
153
+ return botIdToCheck;
154
+ }
155
+ return null;
156
+ }
157
+ async extractMessage(signal) {
158
+ try {
159
+ if (!this.shouldProcess(signal)) {
160
+ return [];
161
+ }
162
+ if (signal.type === "messenger.new") {
163
+ return await this.extractFromMessengerNew(signal);
164
+ }
165
+ else {
166
+ // For discussion.message signals
167
+ const messageData = signal.data?.message;
168
+ if (!messageData) {
169
+ console.warn("❌ MCP Client: No message data in signal");
170
+ return [];
171
+ }
172
+ const messageContent = messageData.content || "";
173
+ const mentionResult = this.containsMcpAgentMention(messageContent);
174
+ if (!mentionResult.found) {
175
+ return [];
176
+ }
177
+ // Create a message for each mentioned bot
178
+ const messages = [];
179
+ for (const botId of mentionResult.mentionedBotIds) {
180
+ const extractedMessage = {
181
+ id: messageData._id || `msg-${Date.now()}`,
182
+ content: messageContent,
183
+ timestamp: signal.timestamp,
184
+ discussionId: messageData.discussion || "",
185
+ userId: messageData.user || "",
186
+ userName: messageData.userName || "Unknown User",
187
+ workspaceId: signal.workspaceId,
188
+ mentionedOrDirectMessagedBotId: botId,
189
+ };
190
+ messages.push(extractedMessage);
191
+ }
192
+ console.log(`🤖 MCP Client: Processing message from ${messages[0]?.userName} for ${messages.length} bot(s)`);
193
+ return messages;
194
+ }
195
+ }
196
+ catch (error) {
197
+ console.error("❌ MCP Client: Failed to extract message from signal:", error);
198
+ return [];
199
+ }
200
+ }
201
+ async extractFromMessengerNew(signal) {
202
+ try {
203
+ const { discussion, msg_id, uid } = signal.data;
204
+ // IMPORTANT: Ignore messages from our own bots to prevent loops
205
+ if (this.mcpAgentIds.includes(uid)) {
206
+ console.log(`🔇 MCP Client: Ignoring message from bot ${uid} (preventing self-trigger loop)`);
207
+ return [];
208
+ }
209
+ // Try to fetch the message with the first available bot client to check mentions
210
+ const botClients = this.multiBotManager.getAllBotClients();
211
+ let targetMessage = null;
212
+ let messageContent = "";
213
+ let workingBotClient = null;
214
+ // Try each bot client until we find the message
215
+ for (const botClient of botClients) {
216
+ try {
217
+ // Fetch the message content using the discussion message API
218
+ const response = await botClient.client.socket.request("v3.discussion.message.latest", [discussion]);
219
+ // Extract messages from the response object
220
+ const messages = response?.messages || [];
221
+ // Find the specific message by ID
222
+ targetMessage = messages.find((msg) => msg._id === msg_id);
223
+ if (targetMessage) {
224
+ messageContent = targetMessage.msg || targetMessage.content || "";
225
+ workingBotClient = botClient;
226
+ break; // Found the message, no need to try other bots
227
+ }
228
+ }
229
+ catch (error) {
230
+ // Continue with next bot client if this one fails
231
+ continue;
232
+ }
233
+ }
234
+ if (!targetMessage || !workingBotClient) {
235
+ console.warn(`❌ MCP Client: Could not find message ${msg_id} in discussion ${discussion} with any bot client`);
236
+ return [];
237
+ }
238
+ // Filter out system messages (like "Hi, I created this group!" or user invites)
239
+ const msgType = targetMessage.type;
240
+ if (msgType && msgType !== "user") {
241
+ console.log(`🔇 MCP Client: Ignoring system message type "${msgType}" (discussion: ${discussion})`);
242
+ return [];
243
+ }
244
+ // Also check for common system message patterns
245
+ const systemMessagePatterns = [
246
+ /^Hi, I created this group!$/i,
247
+ /^I invited .+ to this group\.?$/i,
248
+ /^.+ was invited to this group\.?$/i,
249
+ /^.+ joined the group\.?$/i,
250
+ /^.+ left the group\.?$/i,
251
+ ];
252
+ for (const pattern of systemMessagePatterns) {
253
+ if (pattern.test(messageContent.trim())) {
254
+ console.log(`🔇 MCP Client: Ignoring system message pattern: "${messageContent}" (discussion: ${discussion})`);
255
+ return [];
256
+ }
257
+ }
258
+ // First, check if the message contains an explicit mention of one of our MCP agents
259
+ const mentionResult = this.containsMcpAgentMention(messageContent);
260
+ let handlingBotIds = mentionResult.mentionedBotIds;
261
+ // If no explicit mention found, check if this is a direct message to one of our bots (if enabled)
262
+ if (handlingBotIds.length === 0 && this.enableDirectMessages) {
263
+ // Check each bot to see if this is a 1:1 conversation with that specific bot
264
+ for (const botId of this.mcpAgentIds) {
265
+ const directMessageBotId = await this.isDirectMessageToBot(discussion, uid, botId);
266
+ if (directMessageBotId) {
267
+ handlingBotIds = [directMessageBotId];
268
+ break; // Found a 1:1 conversation, no need to check other bots
269
+ }
270
+ }
271
+ }
272
+ if (handlingBotIds.length === 0) {
273
+ return []; // No mention and not a direct message to our bot
274
+ }
275
+ // Validate that all bot clients exist
276
+ const validBotIds = [];
277
+ for (const botId of handlingBotIds) {
278
+ const botClient = this.multiBotManager.getBotClient(botId);
279
+ if (botClient) {
280
+ validBotIds.push(botId);
281
+ }
282
+ else {
283
+ console.warn(`❌ MCP Client: No bot client found for bot ID: ${botId}`);
284
+ }
285
+ }
286
+ if (validBotIds.length === 0) {
287
+ console.warn(`❌ MCP Client: No valid bot clients found for processing`);
288
+ return [];
289
+ }
290
+ // Fetch user info if needed
291
+ const userName = targetMessage.userName || "Unknown User";
292
+ // Create messages for each mentioned bot
293
+ const messages = [];
294
+ for (const botId of validBotIds) {
295
+ const extractedMessage = {
296
+ id: targetMessage._id,
297
+ content: messageContent,
298
+ timestamp: signal.timestamp,
299
+ discussionId: discussion,
300
+ userId: uid,
301
+ userName: userName,
302
+ workspaceId: signal.workspaceId,
303
+ mentionedOrDirectMessagedBotId: botId,
304
+ };
305
+ messages.push(extractedMessage);
306
+ }
307
+ // Clean content for logging (remove hailerTag mentions)
308
+ const cleanContent = messageContent
309
+ .replace(/\[hailerTag\|[^\]]+\]\([^)]+\)/g, "")
310
+ .trim();
311
+ const messageType = mentionResult.found ? "mentioned" : "direct message";
312
+ console.log(`🤖 MCP Client: Processing ${messageType} from ${messages[0]?.userName} for ${messages.length} bot(s): "${cleanContent}"`);
313
+ return messages;
314
+ }
315
+ catch (error) {
316
+ console.error("❌ MCP Client: Failed to extract messenger.new message:", error);
317
+ return [];
318
+ }
319
+ }
320
+ async postMessage(discussionId, content, workspaceId, botId) {
321
+ try {
322
+ // Use the specified bot or fall back to the first available bot
323
+ const botClient = botId
324
+ ? this.multiBotManager.getBotClient(botId)
325
+ : this.multiBotManager.getAllBotClients()[0];
326
+ if (!botClient) {
327
+ console.error(`❌ MCP Client: No bot client available for posting message (botId: ${botId})`);
328
+ return false;
329
+ }
330
+ // Use the bot's socket client to post the message
331
+ const result = await botClient.client.socket.request("messenger.send", [
332
+ { msg: content },
333
+ discussionId,
334
+ ]);
335
+ return true;
336
+ }
337
+ catch (error) {
338
+ console.error("❌ MCP Client: Failed to post message via socket:", error);
339
+ return false;
340
+ }
341
+ }
342
+ async postInfoMessage(discussionId, toolName, args, workspaceId, botId) {
343
+ const infoContent = `🔧 Using tool: **${toolName}**\n\`\`\`json\n${JSON.stringify(args, null, 2)}\n\`\`\``;
344
+ return this.postMessage(discussionId, infoContent, workspaceId, botId);
345
+ }
346
+ async postErrorMessage(discussionId, error, workspaceId, botId) {
347
+ const errorContent = `❌ Error: ${error}`;
348
+ return this.postMessage(discussionId, errorContent, workspaceId, botId);
349
+ }
350
+ }
351
+ exports.HailerMessageProcessor = HailerMessageProcessor;
352
+ //# sourceMappingURL=message-processor.js.map
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Multi-Bot Client Manager
3
+ * Manages multiple bot clients, each with their own Hailer connection
4
+ */
5
+ import { HailerClient } from "../mcp/hailer-clients";
6
+ import { SignalHandler } from "../mcp/signal-handler";
7
+ import { BotClientConfig } from "./types";
8
+ export interface BotClient {
9
+ userId: string;
10
+ config: BotClientConfig;
11
+ client: HailerClient;
12
+ signalHandler: SignalHandler;
13
+ }
14
+ export declare class MultiBotManager {
15
+ private botConfigs;
16
+ private botClients;
17
+ constructor(botConfigs: BotClientConfig[]);
18
+ initializeAllHailerClientsFromConfig(): Promise<void>;
19
+ getBotClient(userId: string): BotClient | undefined;
20
+ getAllBotClients(): BotClient[];
21
+ getBotIds(): string[];
22
+ shutdown(): Promise<void>;
23
+ }
24
+ //# sourceMappingURL=multi-bot-manager.d.ts.map
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ /**
3
+ * Multi-Bot Client Manager
4
+ * Manages multiple bot clients, each with their own Hailer connection
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.MultiBotManager = void 0;
8
+ const hailer_clients_1 = require("../mcp/hailer-clients");
9
+ const signal_handler_1 = require("../mcp/signal-handler");
10
+ class MultiBotManager {
11
+ botConfigs;
12
+ botClients = new Map();
13
+ constructor(botConfigs) {
14
+ this.botConfigs = botConfigs;
15
+ }
16
+ // for client we may put initializeAllConfigClients method to do it at once
17
+ // in case we only use MCP Server:
18
+ // for MCP Server it may just get a specific client and this class initialize it specifically and even kill it later if not needed
19
+ async initializeAllHailerClientsFromConfig() {
20
+ console.log(`🤖 Initializing ${this.botConfigs.length} bot clients...`);
21
+ for (const config of this.botConfigs) {
22
+ try {
23
+ // Use shared connection pool via API key lookup
24
+ const client = await (0, hailer_clients_1.createHailerClientByApiKey)(config.mcpServerApiKey);
25
+ // Get user ID automatically from authenticated session
26
+ const userId = await (0, hailer_clients_1.getCurrentUserId)(client);
27
+ const signalHandler = new signal_handler_1.SignalHandler(client, undefined);
28
+ const botClient = {
29
+ userId,
30
+ config,
31
+ client,
32
+ signalHandler,
33
+ };
34
+ this.botClients.set(userId, botClient);
35
+ console.log(`✅ Bot client initialized for ${config.email} (${userId}) via API key ${config.mcpServerApiKey.substring(0, 8)}...`);
36
+ }
37
+ catch (error) {
38
+ console.error(`❌ Failed to initialize bot client for ${config.email}:`, error);
39
+ // Continue with other bots even if one fails
40
+ }
41
+ }
42
+ console.log(`✅ Initialized ${this.botClients.size} bot clients successfully`);
43
+ }
44
+ getBotClient(userId) {
45
+ const botClient = this.botClients.get(userId);
46
+ if (!botClient) {
47
+ console.warn(`❌ No bot client found for userId: ${userId}`);
48
+ }
49
+ return botClient;
50
+ }
51
+ getAllBotClients() {
52
+ return Array.from(this.botClients.values());
53
+ }
54
+ getBotIds() {
55
+ return Array.from(this.botClients.keys());
56
+ }
57
+ async shutdown() {
58
+ console.log("🤖 Shutting down all bot clients...");
59
+ for (const [userId, botClient] of this.botClients) {
60
+ try {
61
+ // Properly disconnect from shared connection pool
62
+ (0, hailer_clients_1.disconnectHailerClientByApiKey)(botClient.config.mcpServerApiKey);
63
+ console.log(`✅ Bot client ${userId} shut down (API key: ${botClient.config.mcpServerApiKey.substring(0, 8)}...)`);
64
+ }
65
+ catch (error) {
66
+ console.error(`❌ Error shutting down bot client ${userId}:`, error);
67
+ }
68
+ }
69
+ this.botClients.clear();
70
+ console.log("✅ All bot clients shut down");
71
+ }
72
+ }
73
+ exports.MultiBotManager = MultiBotManager;
74
+ //# sourceMappingURL=multi-bot-manager.js.map
@@ -0,0 +1,19 @@
1
+ import { ChatMessage, McpResponse } from "../types";
2
+ import { LlmProvider } from "./llm-provider";
3
+ export declare class AnthropicProvider extends LlmProvider {
4
+ private client;
5
+ private contextManager;
6
+ private toolSchemaLoader;
7
+ private toolExecutor;
8
+ private toolSchemaCache;
9
+ constructor(config: any);
10
+ generateConfirmationMessage(userMessage: ChatMessage): Promise<string>;
11
+ processMessage(userMessage: ChatMessage, mcpServerUrl: string, botMcpApiKey: string, botEmail: string): Promise<McpResponse>;
12
+ /**
13
+ * Fetch specific tool schema on-demand
14
+ * Token-efficient: ~690 tokens per tool vs loading all tools upfront
15
+ */
16
+ private fetchMcpToolSchema;
17
+ protected callMcpTool(mcpServerUrl: string, mcpServerApiKey: string, request: any): Promise<any>;
18
+ }
19
+ //# sourceMappingURL=anthropic-provider.d.ts.map