@hailer/mcp 0.1.8 → 0.1.9

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 (135) hide show
  1. package/.claude/agents/agent-dmitri-activity-crud.md +3 -1
  2. package/.claude/agents/agent-giuseppe-app-builder.md +11 -12
  3. package/.claude/agents/agent-kenji-data-reader.md +5 -3
  4. package/.claude/skills/hailer-app-builder/SKILL.md +506 -0
  5. package/.claude/skills/publish-hailer-app/SKILL.md +169 -0
  6. package/.claude/skills/tool-parameter-usage/SKILL.md +112 -0
  7. package/CLAUDE.md +6 -2
  8. package/REFACTOR_STATUS.md +127 -0
  9. package/dist/cli.js +0 -0
  10. package/dist/client/agents/base.d.ts +202 -0
  11. package/dist/client/agents/base.js +737 -0
  12. package/dist/client/agents/definitions.d.ts +53 -0
  13. package/dist/client/agents/definitions.js +178 -0
  14. package/dist/client/agents/orchestrator.d.ts +119 -0
  15. package/dist/client/agents/orchestrator.js +760 -0
  16. package/dist/client/agents/specialist.d.ts +86 -0
  17. package/dist/client/agents/specialist.js +340 -0
  18. package/dist/client/bot-manager.d.ts +44 -0
  19. package/dist/client/bot-manager.js +173 -0
  20. package/dist/client/chat-agent-daemon.d.ts +464 -0
  21. package/dist/client/chat-agent-daemon.js +1774 -0
  22. package/dist/client/daemon-factory.d.ts +106 -0
  23. package/dist/client/daemon-factory.js +301 -0
  24. package/dist/client/factory.d.ts +107 -0
  25. package/dist/client/factory.js +304 -0
  26. package/dist/client/index.d.ts +17 -0
  27. package/dist/client/index.js +38 -0
  28. package/dist/client/multi-bot-manager.d.ts +18 -0
  29. package/dist/client/multi-bot-manager.js +88 -1
  30. package/dist/client/orchestrator-daemon.d.ts +87 -0
  31. package/dist/client/orchestrator-daemon.js +444 -0
  32. package/dist/client/services/agent-registry.d.ts +108 -0
  33. package/dist/client/services/agent-registry.js +630 -0
  34. package/dist/client/services/conversation-manager.d.ts +50 -0
  35. package/dist/client/services/conversation-manager.js +136 -0
  36. package/dist/client/services/mcp-client.d.ts +48 -0
  37. package/dist/client/services/mcp-client.js +105 -0
  38. package/dist/client/services/message-classifier.d.ts +37 -0
  39. package/dist/client/services/message-classifier.js +187 -0
  40. package/dist/client/services/message-formatter.d.ts +84 -0
  41. package/dist/client/services/message-formatter.js +353 -0
  42. package/dist/client/services/session-logger.d.ts +106 -0
  43. package/dist/client/services/session-logger.js +446 -0
  44. package/dist/client/services/tool-executor.d.ts +41 -0
  45. package/dist/client/services/tool-executor.js +169 -0
  46. package/dist/client/services/workspace-schema-cache.d.ts +149 -0
  47. package/dist/client/services/workspace-schema-cache.js +732 -0
  48. package/dist/client/specialist-daemon.d.ts +77 -0
  49. package/dist/client/specialist-daemon.js +197 -0
  50. package/dist/client/specialists.d.ts +53 -0
  51. package/dist/client/specialists.js +178 -0
  52. package/dist/client/tool-schema-loader.d.ts +4 -3
  53. package/dist/client/tool-schema-loader.js +54 -8
  54. package/dist/client/types.d.ts +283 -55
  55. package/dist/client/types.js +113 -2
  56. package/dist/config.d.ts +1 -1
  57. package/dist/config.js +1 -1
  58. package/dist/core.d.ts +10 -2
  59. package/dist/core.js +43 -27
  60. package/dist/lib/logger.js +15 -3
  61. package/dist/mcp/UserContextCache.js +2 -2
  62. package/dist/mcp/hailer-clients.js +5 -5
  63. package/dist/mcp/signal-handler.js +27 -5
  64. package/dist/mcp/tools/activity.js +137 -65
  65. package/dist/mcp/tools/app-core.js +4 -140
  66. package/dist/mcp/tools/app-marketplace.js +15 -260
  67. package/dist/mcp/tools/app-member.js +2 -73
  68. package/dist/mcp/tools/app-scaffold.js +146 -87
  69. package/dist/mcp/tools/discussion.js +348 -73
  70. package/dist/mcp/tools/insight.js +74 -190
  71. package/dist/mcp/tools/workflow.js +20 -94
  72. package/dist/mcp/utils/hailer-api-client.d.ts +4 -2
  73. package/dist/mcp/utils/hailer-api-client.js +24 -10
  74. package/dist/mcp-server.d.ts +4 -0
  75. package/dist/mcp-server.js +24 -4
  76. package/dist/routes/agents.d.ts +44 -0
  77. package/dist/routes/agents.js +311 -0
  78. package/dist/services/agent-credential-store.d.ts +73 -0
  79. package/dist/services/agent-credential-store.js +212 -0
  80. package/lineup-manager/dist/assets/index-8ce6041d.css +1 -0
  81. package/lineup-manager/dist/assets/index-e168f265.js +600 -0
  82. package/lineup-manager/dist/index.html +15 -0
  83. package/lineup-manager/dist/manifest.json +17 -0
  84. package/lineup-manager/dist/vite.svg +1 -0
  85. package/package.json +1 -1
  86. package/dist/client/adaptive-documentation-bot.d.ts +0 -106
  87. package/dist/client/adaptive-documentation-bot.js +0 -464
  88. package/dist/client/adaptive-documentation-types.d.ts +0 -66
  89. package/dist/client/adaptive-documentation-types.js +0 -9
  90. package/dist/client/agent-activity-bot.d.ts +0 -51
  91. package/dist/client/agent-activity-bot.js +0 -166
  92. package/dist/client/agent-tracker.d.ts +0 -499
  93. package/dist/client/agent-tracker.js +0 -659
  94. package/dist/client/description-updater.d.ts +0 -56
  95. package/dist/client/description-updater.js +0 -259
  96. package/dist/client/log-parser.d.ts +0 -72
  97. package/dist/client/log-parser.js +0 -387
  98. package/dist/client/mcp-assistant.d.ts +0 -21
  99. package/dist/client/mcp-assistant.js +0 -58
  100. package/dist/client/mcp-client.d.ts +0 -50
  101. package/dist/client/mcp-client.js +0 -538
  102. package/dist/client/message-processor.d.ts +0 -35
  103. package/dist/client/message-processor.js +0 -357
  104. package/dist/client/providers/anthropic-provider.d.ts +0 -19
  105. package/dist/client/providers/anthropic-provider.js +0 -645
  106. package/dist/client/providers/assistant-provider.d.ts +0 -17
  107. package/dist/client/providers/assistant-provider.js +0 -51
  108. package/dist/client/providers/llm-provider.d.ts +0 -47
  109. package/dist/client/providers/llm-provider.js +0 -367
  110. package/dist/client/providers/openai-provider.d.ts +0 -23
  111. package/dist/client/providers/openai-provider.js +0 -630
  112. package/dist/client/simple-llm-caller.d.ts +0 -19
  113. package/dist/client/simple-llm-caller.js +0 -100
  114. package/dist/client/skill-generator.d.ts +0 -81
  115. package/dist/client/skill-generator.js +0 -386
  116. package/dist/client/test-adaptive-bot.d.ts +0 -9
  117. package/dist/client/test-adaptive-bot.js +0 -82
  118. package/dist/client/token-pricing.d.ts +0 -38
  119. package/dist/client/token-pricing.js +0 -127
  120. package/dist/client/token-tracker.d.ts +0 -232
  121. package/dist/client/token-tracker.js +0 -457
  122. package/dist/client/token-usage-bot.d.ts +0 -53
  123. package/dist/client/token-usage-bot.js +0 -153
  124. package/dist/client/tool-executor.d.ts +0 -69
  125. package/dist/client/tool-executor.js +0 -159
  126. package/dist/lib/materialize.d.ts +0 -3
  127. package/dist/lib/materialize.js +0 -101
  128. package/dist/lib/normalizedName.d.ts +0 -7
  129. package/dist/lib/normalizedName.js +0 -48
  130. package/dist/lib/terminal-prompt.d.ts +0 -9
  131. package/dist/lib/terminal-prompt.js +0 -108
  132. package/dist/mcp/tools/skill.d.ts +0 -10
  133. package/dist/mcp/tools/skill.js +0 -279
  134. package/dist/mcp/tools/workflow-template.d.ts +0 -19
  135. package/dist/mcp/tools/workflow-template.js +0 -822
@@ -1,538 +0,0 @@
1
- "use strict";
2
- /**
3
- * Main MCP Client
4
- * Orchestrates signal handling, message processing, and LLM provider interaction
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.McpClient = void 0;
8
- const message_processor_1 = require("./message-processor");
9
- const openai_provider_1 = require("./providers/openai-provider");
10
- const anthropic_provider_1 = require("./providers/anthropic-provider");
11
- const assistant_provider_1 = require("./providers/assistant-provider");
12
- const multi_bot_manager_1 = require("./multi-bot-manager");
13
- const agent_tracker_1 = require("./agent-tracker");
14
- const token_tracker_1 = require("./token-tracker");
15
- const token_usage_bot_1 = require("./token-usage-bot");
16
- const agent_activity_bot_1 = require("./agent-activity-bot");
17
- const adaptive_documentation_bot_1 = require("./adaptive-documentation-bot");
18
- const config_1 = require("../config");
19
- class McpClient {
20
- multiBotManager;
21
- messageProcessor;
22
- providers = new Map();
23
- config;
24
- isActive = false;
25
- processedMessages = new Set(); // Global message deduplication
26
- activeSubscriptions = new Set(); // Track active subscriptions
27
- agentTracker = (0, agent_tracker_1.createAgentTracker)();
28
- tokenTracker = (0, token_tracker_1.createTokenTracker)();
29
- tokenUsageBot;
30
- agentActivityBot;
31
- adaptiveDocBot;
32
- constructor(config) {
33
- this.config = config;
34
- this.multiBotManager = new multi_bot_manager_1.MultiBotManager(config.botConfigs);
35
- this.messageProcessor = new message_processor_1.HailerMessageProcessor(this.multiBotManager, config.mcpAgentIds, config.enableDirectMessages);
36
- // Initialize Token Usage Bot
37
- this.tokenUsageBot = (0, token_usage_bot_1.createTokenUsageBot)(this.tokenTracker, this.agentTracker, {
38
- enabled: config.tokenUsageBotEnabled,
39
- postSummaryAfterConversation: config.tokenUsageBotEnabled,
40
- minCostThreshold: 0, // Post summary for every conversation
41
- });
42
- // Initialize Agent Activity Bot
43
- this.agentActivityBot = (0, agent_activity_bot_1.createAgentActivityBot)(this.agentTracker, {
44
- enabled: config.agentActivityBotEnabled,
45
- postSummaryAfterConversation: config.agentActivityBotEnabled,
46
- minDurationThreshold: 1000, // Only post if duration > 1s
47
- });
48
- // Initialize Adaptive Documentation Bot
49
- const appConfig = (0, config_1.createApplicationConfig)();
50
- if (appConfig.adaptiveDocumentation.enabled && this.config.providers.length > 0) {
51
- // Use the first available provider's API key for the adaptive bot
52
- const firstProviderConfig = this.config.providers[0];
53
- if (firstProviderConfig.apiKey) {
54
- this.adaptiveDocBot = new adaptive_documentation_bot_1.AdaptiveDocumentationBot(firstProviderConfig.apiKey, firstProviderConfig.type === 'openai' ? 'openai' : 'anthropic', {
55
- enabled: appConfig.adaptiveDocumentation.enabled,
56
- autoUpdate: appConfig.adaptiveDocumentation.autoUpdate,
57
- updateInterval: appConfig.adaptiveDocumentation.updateInterval,
58
- minErrorCount: appConfig.adaptiveDocumentation.minErrorCount,
59
- skillGeneration: appConfig.adaptiveDocumentation.skillGeneration,
60
- });
61
- console.log('🔧 Adaptive Documentation Bot initialized');
62
- }
63
- }
64
- // Initialize providers after adaptive bot
65
- this.initializeProviders();
66
- }
67
- async initialize() {
68
- await this.multiBotManager.initializeAllHailerClientsFromConfig();
69
- // Update agent IDs with the actual user IDs retrieved from authentication
70
- const actualAgentIds = this.multiBotManager.getBotIds();
71
- if (actualAgentIds.length > 0) {
72
- console.log(`🤖 Updated MCP Agent IDs: ${actualAgentIds.join(", ")}`);
73
- // Update the message processor with the actual agent IDs
74
- this.messageProcessor = new message_processor_1.HailerMessageProcessor(this.multiBotManager, actualAgentIds, this.config.enableDirectMessages);
75
- // Log successful initialization
76
- this.agentTracker.logSystem({
77
- success: true,
78
- message: "MCP Client Initialized",
79
- details: `Successfully initialized with ${actualAgentIds.length} bot agent(s): ${actualAgentIds.map((id) => id.substring(0, 8)).join(", ")}`,
80
- });
81
- }
82
- else {
83
- // Log failed initialization
84
- this.agentTracker.logSystem({
85
- success: false,
86
- message: "MCP Client Initialization Failed",
87
- error: "No bot agents configured or authentication failed",
88
- });
89
- }
90
- // Start adaptive documentation monitoring
91
- if (this.adaptiveDocBot) {
92
- this.adaptiveDocBot.startMonitoring();
93
- }
94
- }
95
- initializeProviders() {
96
- for (const providerConfig of this.config.providers) {
97
- try {
98
- let provider;
99
- switch (providerConfig.type) {
100
- case "openai":
101
- provider = new openai_provider_1.OpenAIProvider(providerConfig);
102
- break;
103
- case "anthropic":
104
- provider = new anthropic_provider_1.AnthropicProvider(providerConfig);
105
- break;
106
- case "assistant":
107
- provider = new assistant_provider_1.AssistantProvider(providerConfig);
108
- break;
109
- case "gemini":
110
- // TODO: Implement GeminiProvider
111
- console.warn(`⚠️ Provider type ${providerConfig.type} not yet implemented`);
112
- continue;
113
- default:
114
- console.warn(`⚠️ Unknown provider type: ${providerConfig.type}`);
115
- continue;
116
- }
117
- if (provider.isEnabled()) {
118
- this.providers.set(providerConfig.name, provider);
119
- }
120
- else {
121
- console.warn(`⚠️ Provider "${providerConfig.name}" is disabled or missing API key`);
122
- }
123
- }
124
- catch (error) {
125
- console.error(`❌ Failed to initialize provider "${providerConfig.name}":`, error);
126
- }
127
- }
128
- }
129
- start() {
130
- if (this.isActive) {
131
- console.log("🤖 MCP Client already active, skipping start");
132
- return;
133
- }
134
- // Subscribe to signals from ALL bot clients since each bot has access to different discussions
135
- const botClients = this.multiBotManager.getAllBotClients();
136
- if (botClients.length === 0) {
137
- console.error("❌ No bot clients available for signal subscription");
138
- return;
139
- }
140
- // Subscribe to signals from each bot client
141
- for (const botClient of botClients) {
142
- const subscriptionId = `mcp-client-${botClient.userId}`;
143
- botClient.signalHandler.subscribe(subscriptionId, ["messenger.new"], this.handleSignal.bind(this));
144
- this.activeSubscriptions.add(subscriptionId);
145
- console.log(`🤖 Subscribed to signals for bot: ${botClient.config.email} (${botClient.userId})`);
146
- }
147
- this.isActive = true;
148
- console.log(`🤖 MCP Client started with ${botClients.length} bot signal handlers (direct messages: enabled)`);
149
- }
150
- /**
151
- * Get adaptive documentation bot instance (for error reporting)
152
- */
153
- getAdaptiveBot() {
154
- return this.adaptiveDocBot;
155
- }
156
- stop() {
157
- if (!this.isActive) {
158
- return;
159
- }
160
- console.log("🤖 Stopping MCP Client...");
161
- // Unsubscribe from all bot signal handlers
162
- const botClients = this.multiBotManager.getAllBotClients();
163
- for (const botClient of botClients) {
164
- const subscriptionId = `mcp-client-${botClient.userId}`;
165
- if (this.activeSubscriptions.has(subscriptionId)) {
166
- botClient.signalHandler.unsubscribe(subscriptionId);
167
- this.activeSubscriptions.delete(subscriptionId);
168
- console.log(`🤖 Unsubscribed from signals for bot: ${botClient.config.email}`);
169
- }
170
- }
171
- // Stop adaptive documentation monitoring
172
- if (this.adaptiveDocBot) {
173
- this.adaptiveDocBot.stopMonitoring();
174
- }
175
- this.isActive = false;
176
- console.log("🤖 MCP Client stopped");
177
- }
178
- async handleSignal(signal) {
179
- let requestId = null;
180
- const startTime = Date.now();
181
- try {
182
- // Early deduplication check - prevent race conditions from multiple bot subscriptions
183
- const msgId = signal.data?.msg_id;
184
- if (msgId) {
185
- if (this.processedMessages.has(msgId)) {
186
- console.log(`🔄 MCP Client: Message ${msgId} already being processed, skipping`);
187
- return;
188
- }
189
- // Mark as processing immediately to prevent race conditions
190
- this.processedMessages.add(msgId);
191
- // Clean up old processed message IDs (keep only last 1000)
192
- if (this.processedMessages.size > 1000) {
193
- const entries = Array.from(this.processedMessages);
194
- this.processedMessages.clear();
195
- entries.slice(-500).forEach((id) => this.processedMessages.add(id)); // Keep last 500
196
- }
197
- }
198
- const messages = await this.messageProcessor.extractMessage(signal);
199
- if (!messages || messages.length === 0) {
200
- // If message extraction failed, remove from processed set
201
- if (msgId) {
202
- this.processedMessages.delete(msgId);
203
- }
204
- return; // Signal doesn't contain a valid MCP agent message
205
- }
206
- // Process each message (one per mentioned bot)
207
- const processingPromises = messages.map(async (message) => {
208
- // Ensure we have a mentioned bot
209
- if (!message.mentionedOrDirectMessagedBotId) {
210
- console.warn(`⚠️ MCP Client: No bot mentioned in message, skipping processing`);
211
- return;
212
- }
213
- // Double-check that the mentioned bot exists
214
- const mentionedBot = this.multiBotManager.getBotClient(message.mentionedOrDirectMessagedBotId);
215
- if (!mentionedBot) {
216
- console.error(`❌ MCP Client: Mentioned bot ${message.mentionedOrDirectMessagedBotId} not found`);
217
- return;
218
- }
219
- // LOG TRIGGER EVENT - Bot was successfully triggered (only for the first message to avoid duplicate logs)
220
- let messageRequestId = null;
221
- if (!requestId) {
222
- requestId = this.agentTracker.logTrigger({
223
- triggerType: this.determineTriggerType(message.content),
224
- discussionId: message.discussionId,
225
- userId: message.userId,
226
- userName: message.userName,
227
- botId: message.mentionedOrDirectMessagedBotId,
228
- messageContent: message.content,
229
- workspaceId: message.workspaceId,
230
- });
231
- messageRequestId = requestId;
232
- }
233
- else {
234
- // Log additional triggers for multiple bots
235
- messageRequestId = this.agentTracker.logTrigger({
236
- triggerType: this.determineTriggerType(message.content),
237
- discussionId: message.discussionId,
238
- userId: message.userId,
239
- userName: message.userName,
240
- botId: message.mentionedOrDirectMessagedBotId,
241
- messageContent: message.content,
242
- workspaceId: message.workspaceId,
243
- });
244
- }
245
- // Process with the first enabled provider (can be enhanced to support multiple or selection)
246
- const provider = this.getFirstEnabledProvider();
247
- if (!provider) {
248
- console.error(`❌ MCP Client: No LLM providers are available`);
249
- // Log completion failure
250
- if (messageRequestId) {
251
- this.agentTracker.logCompletion({
252
- requestId: messageRequestId,
253
- success: false,
254
- duration: Date.now() - startTime,
255
- error: "No LLM providers are available",
256
- });
257
- }
258
- await this.messageProcessor.postErrorMessage(message.discussionId, "No LLM providers are available", message.workspaceId, message.mentionedOrDirectMessagedBotId);
259
- return;
260
- }
261
- console.log(`🤖 Processing request from ${message.userName} with ${provider.name} (Bot: ${message.mentionedOrDirectMessagedBotId})`);
262
- // Check if Token Bot is mentioned with a token usage query - handle directly without LLM
263
- // For other bots (like Manager Bot), they'll use LLM + tools to invite Token Bot
264
- const tokenBotUserId = '691c07ad702e78dc33797c97';
265
- if (this.config.tokenUsageBotEnabled &&
266
- this.tokenUsageBot.isTokenQuery(message.content) &&
267
- message.mentionedOrDirectMessagedBotId === tokenBotUserId) {
268
- console.log('📊 Token Bot query detected - generating report with direct JSON access');
269
- const detailedReport = this.tokenUsageBot.generateDetailedReport(message.discussionId);
270
- await this.messageProcessor.postMessage(message.discussionId, detailedReport, message.workspaceId, message.mentionedOrDirectMessagedBotId);
271
- // Token Bot leaves the discussion after posting report
272
- const tokenBotClient = this.multiBotManager.getBotClient(message.mentionedOrDirectMessagedBotId);
273
- if (tokenBotClient) {
274
- try {
275
- await tokenBotClient.client.socket.request('messenger.leave_discussion', [message.discussionId]);
276
- console.log('👋 Token Bot left the discussion after posting report');
277
- }
278
- catch (error) {
279
- console.error('❌ Failed to leave discussion:', error);
280
- }
281
- }
282
- // Log completion for token query
283
- if (messageRequestId) {
284
- this.agentTracker.logCompletion({
285
- requestId: messageRequestId,
286
- success: true,
287
- provider: 'token-usage-bot',
288
- toolsCalled: ['generate_detailed_report', 'leave_discussion'],
289
- responseContent: 'Token usage report generated and left discussion',
290
- duration: Date.now() - startTime,
291
- });
292
- }
293
- return; // Skip LLM processing
294
- }
295
- // Check if this is an agent activity query - handle directly without LLM (only if bot is enabled)
296
- if (this.config.agentActivityBotEnabled && this.agentActivityBot.isActivityQuery(message.content)) {
297
- console.log('🤖 Agent activity query detected - generating report');
298
- const detailedReport = this.agentActivityBot.generateDetailedReport(message.discussionId);
299
- await this.messageProcessor.postMessage(message.discussionId, detailedReport, message.workspaceId, message.mentionedOrDirectMessagedBotId);
300
- // Log completion for activity query
301
- if (messageRequestId) {
302
- this.agentTracker.logCompletion({
303
- requestId: messageRequestId,
304
- success: true,
305
- provider: 'agent-activity-bot',
306
- toolsCalled: ['generate_detailed_report'],
307
- responseContent: 'Agent activity report generated',
308
- duration: Date.now() - startTime,
309
- });
310
- }
311
- return; // Skip LLM processing
312
- }
313
- // Generate and post personalized confirmation message (skip if empty)
314
- const confirmationMessage = await provider.generateConfirmationMessage(message);
315
- if (confirmationMessage) {
316
- await this.messageProcessor.postMessage(message.discussionId, confirmationMessage, message.workspaceId, message.mentionedOrDirectMessagedBotId);
317
- }
318
- const response = await this.processMessage(message, provider);
319
- await this.handleResponse(message, response);
320
- // LOG COMPLETION EVENT - Bot finished processing
321
- if (messageRequestId) {
322
- const duration = Date.now() - startTime;
323
- this.agentTracker.logCompletion({
324
- requestId: messageRequestId,
325
- success: response.success,
326
- provider: provider.name,
327
- toolsCalled: response.toolCalls?.map((tc) => tc.toolName) || [],
328
- responseContent: response.response,
329
- duration: duration,
330
- error: response.error,
331
- });
332
- // ANALYZE LOGS - Check for tool call errors after conversation completes
333
- if (this.adaptiveDocBot) {
334
- this.adaptiveDocBot.analyzeAfterConversation().catch(error => {
335
- console.error('❌ Failed to analyze conversation errors:', error);
336
- });
337
- }
338
- // POST AGENT ACTIVITY SUMMARY - Automatically post summary if duration threshold met
339
- if (this.agentActivityBot.shouldPostSummary(message.discussionId, duration)) {
340
- try {
341
- const summary = this.agentActivityBot.generateSummary(messageRequestId, message.discussionId, duration, response.toolCalls?.map((tc) => tc.toolName) || []);
342
- await this.messageProcessor.postMessage(message.discussionId, summary, message.workspaceId, message.mentionedOrDirectMessagedBotId);
343
- this.agentActivityBot.markPosted(message.discussionId);
344
- console.log('🤖 Agent activity summary posted to discussion');
345
- }
346
- catch (error) {
347
- console.error('❌ Failed to post agent activity summary:', error);
348
- }
349
- }
350
- // LOG TOKEN USAGE - Track costs and usage for optimization
351
- if (response.tokens && response.tokens.cost !== undefined && response.success) {
352
- this.tokenTracker.logUsage({
353
- botId: message.mentionedOrDirectMessagedBotId,
354
- botName: mentionedBot.config.email, // Use email as bot name
355
- provider: provider.name,
356
- conversationId: message.discussionId,
357
- toolsCalled: response.toolCalls?.map((tc) => tc.toolName) || [],
358
- tokens: {
359
- input: response.tokens.input,
360
- output: response.tokens.output,
361
- total: response.tokens.total,
362
- cacheCreation: response.tokens.cacheCreation,
363
- cacheRead: response.tokens.cacheRead,
364
- cost: response.tokens.cost,
365
- },
366
- duration: Date.now() - startTime,
367
- success: true,
368
- });
369
- // POST TOKEN USAGE SUMMARY - Automatically post summary if cost threshold met
370
- if (this.tokenUsageBot.shouldPostSummary(message.discussionId, response.tokens.cost)) {
371
- try {
372
- const summary = await this.tokenUsageBot.generateSummary(message.discussionId, response.tokens.cost, response.tokens.total);
373
- await this.messageProcessor.postMessage(message.discussionId, summary, message.workspaceId, message.mentionedOrDirectMessagedBotId);
374
- this.tokenUsageBot.markPosted(message.discussionId);
375
- console.log('💰 Token usage summary posted to discussion');
376
- }
377
- catch (error) {
378
- console.error('❌ Failed to post token usage summary:', error);
379
- }
380
- }
381
- }
382
- }
383
- });
384
- // Wait for all bot processing to complete
385
- await Promise.all(processingPromises);
386
- }
387
- catch (error) {
388
- console.error("❌ MCP Client: Error handling signal:", error);
389
- // Log completion failure
390
- if (requestId) {
391
- this.agentTracker.logCompletion({
392
- requestId,
393
- success: false,
394
- duration: Date.now() - startTime,
395
- error: error instanceof Error ? error.message : String(error),
396
- });
397
- }
398
- // Remove from processed set on error
399
- const msgId = signal.data?.msg_id;
400
- if (msgId) {
401
- this.processedMessages.delete(msgId);
402
- }
403
- }
404
- }
405
- getFirstEnabledProvider() {
406
- for (const provider of this.providers.values()) {
407
- if (provider.isEnabled()) {
408
- return provider;
409
- }
410
- }
411
- return null;
412
- }
413
- determineTriggerType(messageContent) {
414
- // Check if message contains hailerTag mentions
415
- const hailerTagPattern = /\[hailerTag\|[^\]]+\]\(([^)]+)\)/g;
416
- if (hailerTagPattern.test(messageContent)) {
417
- return "mention";
418
- }
419
- // Check for old @mcp-agent format (fallback)
420
- if (messageContent.toLowerCase().includes("@mcp-agent")) {
421
- return "mention";
422
- }
423
- // Otherwise it's a direct message
424
- return "direct";
425
- }
426
- async processMessage(message, provider) {
427
- try {
428
- const botClient = this.multiBotManager.getBotClient(message.mentionedOrDirectMessagedBotId);
429
- if (!botClient) {
430
- throw new Error(`Bot client not found for mentionedOrDirectMessagedBotId '${message.mentionedOrDirectMessagedBotId}'`);
431
- }
432
- const result = await provider.processMessage(message, this.config.mcpServerUrl, botClient.config.mcpServerApiKey, botClient.config.email);
433
- return result;
434
- }
435
- catch (error) {
436
- console.error(`❌ MCP Client: Provider "${provider.name}" failed to process message:`, error);
437
- return {
438
- success: false,
439
- error: `Processing failed: ${error instanceof Error ? error.message : String(error)}`,
440
- };
441
- }
442
- }
443
- async handleResponse(message, response) {
444
- // Build complete message with tool usage info and main response
445
- let combinedMessage = "";
446
- // Add tool usage information if any tools were called
447
- // COMMENTED OUT FOR SALES DEMO - uncomment to re-enable tool logs for developmen/debugging
448
- // if (response.toolCalls && response.toolCalls.length > 0) {
449
- // const toolSummary = this.buildToolUsageSummary(response.toolCalls);
450
- // if (toolSummary) {
451
- // combinedMessage += `${toolSummary}\n\n`;
452
- // }
453
- // }
454
- // Add main response or error
455
- if (response.success && response.response) {
456
- combinedMessage += response.response;
457
- await this.postSuccessResponse(message, combinedMessage.trim());
458
- }
459
- else if (!response.success && response.error) {
460
- combinedMessage += `❌ Error: ${response.error}`;
461
- await this.postErrorResponse(message, combinedMessage.trim());
462
- }
463
- else {
464
- console.log(`❌Unhandled case while handling the message, response.success: ${response.success}; response.error: ${response.error}`);
465
- }
466
- }
467
- async postSuccessResponse(message, content) {
468
- await this.messageProcessor.postMessage(message.discussionId, content, message.workspaceId, message.mentionedOrDirectMessagedBotId);
469
- }
470
- buildToolUsageSummary(toolCalls) {
471
- if (!toolCalls || toolCalls.length === 0) {
472
- return "";
473
- }
474
- const successfulTools = toolCalls.filter((tc) => !tc.error);
475
- const failedTools = toolCalls.filter((tc) => tc.error);
476
- let summary = "";
477
- if (successfulTools.length > 0) {
478
- successfulTools.forEach((tc, index) => {
479
- if (index > 0)
480
- summary += "\n\n";
481
- summary += `🔧 Using tool: **${tc.toolName}**`;
482
- if (tc.args && Object.keys(tc.args).length > 0) {
483
- summary += `\n\`\`\`json\n${JSON.stringify(tc.args, null, 2)}\n\`\`\``;
484
- }
485
- });
486
- }
487
- if (failedTools.length > 0) {
488
- if (summary)
489
- summary += "\n\n";
490
- failedTools.forEach((tc, index) => {
491
- if (index > 0)
492
- summary += "\n\n";
493
- summary += `❌ Tool **${tc.toolName}** failed: ${tc.error}`;
494
- if (tc.args && Object.keys(tc.args).length > 0) {
495
- summary += `\nArguments:\n\`\`\`json\n${JSON.stringify(tc.args, null, 2)}\n\`\`\``;
496
- }
497
- });
498
- }
499
- return summary;
500
- }
501
- async postErrorResponse(message, error) {
502
- try {
503
- await this.messageProcessor.postErrorMessage(message.discussionId, error, message.workspaceId, message.mentionedOrDirectMessagedBotId);
504
- }
505
- catch (postError) {
506
- console.error(`❌ MCP Client: Failed to post error response:`, postError);
507
- }
508
- }
509
- /** Shutdown the dependency: MultiBotManager */
510
- async shutdownMultiBotManager() {
511
- await this.multiBotManager.shutdown();
512
- }
513
- /** Shutdown the McpClient and MultiBotManager */
514
- async shutdown() {
515
- console.log('Shutting down MCP Client');
516
- this.stop();
517
- await this.shutdownMultiBotManager();
518
- console.log('MCP Client shut down successfully');
519
- }
520
- getStatus() {
521
- const enabledProviders = [];
522
- for (const [name, provider] of this.providers) {
523
- if (provider.isEnabled()) {
524
- enabledProviders.push(name);
525
- }
526
- }
527
- return {
528
- active: this.isActive,
529
- providersCount: this.providers.size,
530
- enabledProviders,
531
- activeSubscriptions: this.activeSubscriptions.size,
532
- botClientsCount: this.multiBotManager.getAllBotClients().length,
533
- directMessagesEnabled: this.config.enableDirectMessages,
534
- };
535
- }
536
- }
537
- exports.McpClient = McpClient;
538
- //# sourceMappingURL=mcp-client.js.map
@@ -1,35 +0,0 @@
1
- /**
2
- * Message Processor for MCP Client
3
- * Handles incoming socket.io signals and processes messages that mention MCP agents
4
- * or are sent directly in one-on-one conversations with MCP agents
5
- */
6
- import { HailerSignal } from "../mcp/signal-handler";
7
- import { ChatMessage, MessageProcessor } from "./types";
8
- import { MultiBotManager } from "./multi-bot-manager";
9
- export declare class HailerMessageProcessor implements MessageProcessor {
10
- private multiBotManager;
11
- private mcpAgentIds;
12
- private enableDirectMessages;
13
- constructor(multiBotManager: MultiBotManager, mcpAgentIds?: string[], enableDirectMessages?: boolean);
14
- shouldProcess(signal: HailerSignal): boolean;
15
- private containsMcpAgentMention;
16
- /**
17
- * Fetch discussion participants to determine if it's a one-on-one conversation
18
- * Uses messenger.load_discussions API to get actual member count
19
- */
20
- private fetchDiscussionParticipants;
21
- /**
22
- * Check if a discussion is a one-on-one conversation with a specific MCP agent
23
- * @param discussionId - The discussion to check
24
- * @param senderId - The user who sent the message
25
- * @param botIdToCheck - The specific bot ID to check for direct message
26
- * @returns The bot ID if it's a 1:1 conversation with that bot, null otherwise
27
- */
28
- private isDirectMessageToBot;
29
- extractMessage(signal: HailerSignal): Promise<ChatMessage[]>;
30
- private extractFromMessengerNew;
31
- postMessage(discussionId: string, content: string, workspaceId?: string, botId?: string): Promise<boolean>;
32
- postInfoMessage(discussionId: string, toolName: string, args: any, workspaceId?: string, botId?: string): Promise<boolean>;
33
- postErrorMessage(discussionId: string, error: string, workspaceId?: string, botId?: string): Promise<boolean>;
34
- }
35
- //# sourceMappingURL=message-processor.d.ts.map