@hailer/mcp 0.1.16 → 0.2.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 (202) hide show
  1. package/dist/app.js +24 -20
  2. package/dist/core.d.ts +33 -9
  3. package/dist/core.js +279 -147
  4. package/dist/mcp/UserContextCache.js +18 -0
  5. package/dist/mcp/hailer-clients.d.ts +9 -1
  6. package/dist/mcp/hailer-clients.js +13 -3
  7. package/dist/mcp/signal-handler.js +1 -1
  8. package/dist/mcp/tool-registry.d.ts +3 -1
  9. package/dist/mcp/tool-registry.js +4 -1
  10. package/dist/mcp/tools/activity.js +43 -34
  11. package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
  12. package/dist/mcp/tools/bot-config/constants.js +94 -0
  13. package/dist/mcp/tools/{bot-config.d.ts → bot-config/core.d.ts} +6 -6
  14. package/dist/mcp/tools/{bot-config.js → bot-config/core.js} +15 -15
  15. package/dist/mcp/tools/bot-config/index.d.ts +10 -0
  16. package/dist/mcp/tools/bot-config/index.js +59 -0
  17. package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
  18. package/dist/mcp/tools/bot-config/tools.js +15 -0
  19. package/dist/mcp/tools/bot-config/types.d.ts +50 -0
  20. package/dist/mcp/tools/bot-config/types.js +6 -0
  21. package/dist/mcp/tools/bug-fixer-tools.d.ts +21 -0
  22. package/dist/mcp/tools/{giuseppe-tools.js → bug-fixer-tools.js} +61 -61
  23. package/dist/mcp/tools/user.js +10 -29
  24. package/dist/mcp/tools/workflow.js +36 -2
  25. package/dist/mcp/utils/data-transformers.d.ts +0 -8
  26. package/dist/mcp/utils/data-transformers.js +0 -28
  27. package/dist/mcp/utils/index.d.ts +4 -1
  28. package/dist/mcp/utils/index.js +17 -3
  29. package/dist/mcp/utils/pagination.d.ts +40 -0
  30. package/dist/mcp/utils/pagination.js +55 -0
  31. package/dist/mcp/utils/response-builder.d.ts +53 -0
  32. package/dist/mcp/utils/response-builder.js +110 -0
  33. package/dist/mcp/utils/tool-helpers.d.ts +0 -8
  34. package/dist/mcp/utils/tool-helpers.js +0 -24
  35. package/dist/mcp/utils/types.d.ts +1 -33
  36. package/dist/mcp/webhook-handler.d.ts +2 -2
  37. package/dist/mcp/webhook-handler.js +5 -3
  38. package/dist/mcp-server.d.ts +2 -2
  39. package/dist/mcp-server.js +167 -140
  40. package/package.json +1 -1
  41. package/REFACTOR_STATUS.md +0 -127
  42. package/dist/agents/bot-manager.d.ts +0 -48
  43. package/dist/agents/bot-manager.js +0 -254
  44. package/dist/agents/factory.d.ts +0 -150
  45. package/dist/agents/factory.js +0 -650
  46. package/dist/agents/giuseppe/ai.d.ts +0 -83
  47. package/dist/agents/giuseppe/ai.js +0 -466
  48. package/dist/agents/giuseppe/bot.d.ts +0 -110
  49. package/dist/agents/giuseppe/bot.js +0 -780
  50. package/dist/agents/giuseppe/config.d.ts +0 -25
  51. package/dist/agents/giuseppe/config.js +0 -227
  52. package/dist/agents/giuseppe/files.d.ts +0 -52
  53. package/dist/agents/giuseppe/files.js +0 -338
  54. package/dist/agents/giuseppe/git.d.ts +0 -48
  55. package/dist/agents/giuseppe/git.js +0 -298
  56. package/dist/agents/giuseppe/index.d.ts +0 -97
  57. package/dist/agents/giuseppe/index.js +0 -258
  58. package/dist/agents/giuseppe/lsp.d.ts +0 -113
  59. package/dist/agents/giuseppe/lsp.js +0 -485
  60. package/dist/agents/giuseppe/monitor.d.ts +0 -118
  61. package/dist/agents/giuseppe/monitor.js +0 -621
  62. package/dist/agents/giuseppe/prompt.d.ts +0 -5
  63. package/dist/agents/giuseppe/prompt.js +0 -94
  64. package/dist/agents/giuseppe/registries/pending-classification.d.ts +0 -28
  65. package/dist/agents/giuseppe/registries/pending-classification.js +0 -50
  66. package/dist/agents/giuseppe/registries/pending-fix.d.ts +0 -30
  67. package/dist/agents/giuseppe/registries/pending-fix.js +0 -42
  68. package/dist/agents/giuseppe/registries/pending.d.ts +0 -27
  69. package/dist/agents/giuseppe/registries/pending.js +0 -49
  70. package/dist/agents/giuseppe/specialist.d.ts +0 -47
  71. package/dist/agents/giuseppe/specialist.js +0 -237
  72. package/dist/agents/giuseppe/types.d.ts +0 -123
  73. package/dist/agents/giuseppe/types.js +0 -9
  74. package/dist/agents/hailer-expert/index.d.ts +0 -8
  75. package/dist/agents/hailer-expert/index.js +0 -14
  76. package/dist/agents/hal/daemon.d.ts +0 -142
  77. package/dist/agents/hal/daemon.js +0 -1103
  78. package/dist/agents/hal/definitions.d.ts +0 -55
  79. package/dist/agents/hal/definitions.js +0 -263
  80. package/dist/agents/hal/index.d.ts +0 -3
  81. package/dist/agents/hal/index.js +0 -8
  82. package/dist/agents/index.d.ts +0 -18
  83. package/dist/agents/index.js +0 -48
  84. package/dist/agents/shared/base.d.ts +0 -216
  85. package/dist/agents/shared/base.js +0 -846
  86. package/dist/agents/shared/services/agent-registry.d.ts +0 -107
  87. package/dist/agents/shared/services/agent-registry.js +0 -629
  88. package/dist/agents/shared/services/conversation-manager.d.ts +0 -50
  89. package/dist/agents/shared/services/conversation-manager.js +0 -136
  90. package/dist/agents/shared/services/mcp-client.d.ts +0 -56
  91. package/dist/agents/shared/services/mcp-client.js +0 -124
  92. package/dist/agents/shared/services/message-classifier.d.ts +0 -37
  93. package/dist/agents/shared/services/message-classifier.js +0 -187
  94. package/dist/agents/shared/services/message-formatter.d.ts +0 -89
  95. package/dist/agents/shared/services/message-formatter.js +0 -371
  96. package/dist/agents/shared/services/session-logger.d.ts +0 -106
  97. package/dist/agents/shared/services/session-logger.js +0 -446
  98. package/dist/agents/shared/services/tool-executor.d.ts +0 -41
  99. package/dist/agents/shared/services/tool-executor.js +0 -169
  100. package/dist/agents/shared/services/workspace-schema-cache.d.ts +0 -125
  101. package/dist/agents/shared/services/workspace-schema-cache.js +0 -578
  102. package/dist/agents/shared/specialist.d.ts +0 -91
  103. package/dist/agents/shared/specialist.js +0 -399
  104. package/dist/agents/shared/tool-schema-loader.d.ts +0 -62
  105. package/dist/agents/shared/tool-schema-loader.js +0 -232
  106. package/dist/agents/shared/types.d.ts +0 -327
  107. package/dist/agents/shared/types.js +0 -121
  108. package/dist/client/agents/base.d.ts +0 -207
  109. package/dist/client/agents/base.js +0 -744
  110. package/dist/client/agents/definitions.d.ts +0 -53
  111. package/dist/client/agents/definitions.js +0 -263
  112. package/dist/client/agents/orchestrator.d.ts +0 -141
  113. package/dist/client/agents/orchestrator.js +0 -1062
  114. package/dist/client/agents/specialist.d.ts +0 -86
  115. package/dist/client/agents/specialist.js +0 -340
  116. package/dist/client/bot-entrypoint.d.ts +0 -7
  117. package/dist/client/bot-entrypoint.js +0 -103
  118. package/dist/client/bot-manager.d.ts +0 -44
  119. package/dist/client/bot-manager.js +0 -173
  120. package/dist/client/bot-runner.d.ts +0 -35
  121. package/dist/client/bot-runner.js +0 -188
  122. package/dist/client/chat-agent-daemon.d.ts +0 -464
  123. package/dist/client/chat-agent-daemon.js +0 -1774
  124. package/dist/client/daemon-factory.d.ts +0 -106
  125. package/dist/client/daemon-factory.js +0 -301
  126. package/dist/client/factory.d.ts +0 -111
  127. package/dist/client/factory.js +0 -314
  128. package/dist/client/index.d.ts +0 -17
  129. package/dist/client/index.js +0 -38
  130. package/dist/client/multi-bot-manager.d.ts +0 -42
  131. package/dist/client/multi-bot-manager.js +0 -161
  132. package/dist/client/orchestrator-daemon.d.ts +0 -87
  133. package/dist/client/orchestrator-daemon.js +0 -444
  134. package/dist/client/server.d.ts +0 -8
  135. package/dist/client/server.js +0 -251
  136. package/dist/client/services/agent-registry.d.ts +0 -108
  137. package/dist/client/services/agent-registry.js +0 -630
  138. package/dist/client/services/conversation-manager.d.ts +0 -50
  139. package/dist/client/services/conversation-manager.js +0 -136
  140. package/dist/client/services/mcp-client.d.ts +0 -48
  141. package/dist/client/services/mcp-client.js +0 -105
  142. package/dist/client/services/message-classifier.d.ts +0 -37
  143. package/dist/client/services/message-classifier.js +0 -187
  144. package/dist/client/services/message-formatter.d.ts +0 -84
  145. package/dist/client/services/message-formatter.js +0 -353
  146. package/dist/client/services/session-logger.d.ts +0 -106
  147. package/dist/client/services/session-logger.js +0 -446
  148. package/dist/client/services/tool-executor.d.ts +0 -41
  149. package/dist/client/services/tool-executor.js +0 -169
  150. package/dist/client/services/workspace-schema-cache.d.ts +0 -149
  151. package/dist/client/services/workspace-schema-cache.js +0 -732
  152. package/dist/client/specialist-daemon.d.ts +0 -77
  153. package/dist/client/specialist-daemon.js +0 -197
  154. package/dist/client/specialists.d.ts +0 -53
  155. package/dist/client/specialists.js +0 -178
  156. package/dist/client/tool-schema-loader.d.ts +0 -62
  157. package/dist/client/tool-schema-loader.js +0 -232
  158. package/dist/client/types.d.ts +0 -327
  159. package/dist/client/types.js +0 -121
  160. package/dist/commands/seed-config.d.ts +0 -9
  161. package/dist/commands/seed-config.js +0 -372
  162. package/dist/lib/context-manager.d.ts +0 -111
  163. package/dist/lib/context-manager.js +0 -431
  164. package/dist/lib/prompt-length-manager.d.ts +0 -81
  165. package/dist/lib/prompt-length-manager.js +0 -457
  166. package/dist/mcp/tools/giuseppe-tools.d.ts +0 -21
  167. package/dist/modules/bug-reports/bug-config.d.ts +0 -25
  168. package/dist/modules/bug-reports/bug-config.js +0 -187
  169. package/dist/modules/bug-reports/bug-monitor.d.ts +0 -108
  170. package/dist/modules/bug-reports/bug-monitor.js +0 -510
  171. package/dist/modules/bug-reports/giuseppe-agent.d.ts +0 -58
  172. package/dist/modules/bug-reports/giuseppe-agent.js +0 -467
  173. package/dist/modules/bug-reports/giuseppe-ai.d.ts +0 -83
  174. package/dist/modules/bug-reports/giuseppe-ai.js +0 -466
  175. package/dist/modules/bug-reports/giuseppe-bot.d.ts +0 -110
  176. package/dist/modules/bug-reports/giuseppe-bot.js +0 -804
  177. package/dist/modules/bug-reports/giuseppe-daemon.d.ts +0 -80
  178. package/dist/modules/bug-reports/giuseppe-daemon.js +0 -617
  179. package/dist/modules/bug-reports/giuseppe-files.d.ts +0 -64
  180. package/dist/modules/bug-reports/giuseppe-files.js +0 -375
  181. package/dist/modules/bug-reports/giuseppe-git.d.ts +0 -48
  182. package/dist/modules/bug-reports/giuseppe-git.js +0 -298
  183. package/dist/modules/bug-reports/giuseppe-lsp.d.ts +0 -113
  184. package/dist/modules/bug-reports/giuseppe-lsp.js +0 -485
  185. package/dist/modules/bug-reports/giuseppe-prompt.d.ts +0 -5
  186. package/dist/modules/bug-reports/giuseppe-prompt.js +0 -94
  187. package/dist/modules/bug-reports/index.d.ts +0 -77
  188. package/dist/modules/bug-reports/index.js +0 -215
  189. package/dist/modules/bug-reports/pending-classification-registry.d.ts +0 -28
  190. package/dist/modules/bug-reports/pending-classification-registry.js +0 -50
  191. package/dist/modules/bug-reports/pending-fix-registry.d.ts +0 -30
  192. package/dist/modules/bug-reports/pending-fix-registry.js +0 -42
  193. package/dist/modules/bug-reports/pending-registry.d.ts +0 -27
  194. package/dist/modules/bug-reports/pending-registry.js +0 -49
  195. package/dist/modules/bug-reports/types.d.ts +0 -123
  196. package/dist/modules/bug-reports/types.js +0 -9
  197. package/dist/routes/agents.d.ts +0 -44
  198. package/dist/routes/agents.js +0 -311
  199. package/dist/services/agent-credential-store.d.ts +0 -73
  200. package/dist/services/agent-credential-store.js +0 -212
  201. package/dist/services/bug-monitor.d.ts +0 -23
  202. package/dist/services/bug-monitor.js +0 -275
@@ -1,136 +0,0 @@
1
- "use strict";
2
- /**
3
- * Conversation Manager Service
4
- *
5
- * Manages per-discussion conversation state:
6
- * - LRU cache of conversation histories
7
- * - Context size management with summarization
8
- * - Conversation state access
9
- */
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.ConversationManager = void 0;
12
- class ConversationManager {
13
- maxConversations;
14
- maxContextMessages;
15
- anthropicClient;
16
- logger;
17
- conversationsByDiscussion = new Map();
18
- constructor(maxConversations, maxContextMessages, anthropicClient, logger) {
19
- this.maxConversations = maxConversations;
20
- this.maxContextMessages = maxContextMessages;
21
- this.anthropicClient = anthropicClient;
22
- this.logger = logger;
23
- }
24
- /**
25
- * Get or create conversation history for a specific discussion
26
- * Each discussion has its own isolated context to prevent bloat
27
- * Uses LRU eviction when map exceeds maxConversations
28
- */
29
- getConversation(discussionId) {
30
- let conversation = this.conversationsByDiscussion.get(discussionId);
31
- if (conversation) {
32
- // Move to end for LRU (delete and re-add to update insertion order)
33
- this.conversationsByDiscussion.delete(discussionId);
34
- this.conversationsByDiscussion.set(discussionId, conversation);
35
- return conversation;
36
- }
37
- // Evict oldest conversations if at capacity
38
- if (this.conversationsByDiscussion.size >= this.maxConversations) {
39
- const toEvict = this.conversationsByDiscussion.size - this.maxConversations + 1;
40
- const keys = [...this.conversationsByDiscussion.keys()].slice(0, toEvict);
41
- for (const key of keys) {
42
- this.conversationsByDiscussion.delete(key);
43
- }
44
- this.logger.debug("Evicted old conversations", { evicted: toEvict, remaining: this.conversationsByDiscussion.size });
45
- }
46
- conversation = [];
47
- this.conversationsByDiscussion.set(discussionId, conversation);
48
- this.logger.debug("Created new conversation context", { discussionId });
49
- return conversation;
50
- }
51
- /**
52
- * Add a message to a conversation
53
- */
54
- addMessage(discussionId, message) {
55
- const conversation = this.getConversation(discussionId);
56
- conversation.push(message);
57
- }
58
- /**
59
- * Manage conversation context size - summarize if too large
60
- */
61
- async manageContextSize(discussionId) {
62
- const conversation = this.getConversation(discussionId);
63
- if (conversation.length > this.maxContextMessages) {
64
- this.logger.info("Context size limit reached, summarizing", {
65
- discussionId,
66
- messageCount: conversation.length,
67
- });
68
- // Keep last 10 messages, summarize the rest
69
- const toSummarize = conversation.slice(0, -10);
70
- const toKeep = conversation.slice(-10);
71
- // Create summary using LLM with structured content to mitigate prompt injection
72
- const summaryResponse = await this.anthropicClient.messages.create({
73
- model: "claude-haiku-4-5-20251001",
74
- max_tokens: 1000,
75
- messages: [
76
- {
77
- role: "user",
78
- content: [
79
- { type: "text", text: "Summarize this conversation context concisely, preserving key information. The conversation data follows in JSON format:" },
80
- { type: "text", text: JSON.stringify(toSummarize) },
81
- ],
82
- },
83
- ],
84
- });
85
- const summary = summaryResponse.content
86
- .filter((b) => b.type === "text")
87
- .map(b => b.text)
88
- .join("\n");
89
- // Replace conversation with summary + recent messages
90
- const newConversation = [
91
- {
92
- role: "user",
93
- content: `<context_summary>${summary}</context_summary>`,
94
- },
95
- ...toKeep,
96
- ];
97
- this.conversationsByDiscussion.set(discussionId, newConversation);
98
- this.logger.info("Context summarized", {
99
- discussionId,
100
- originalCount: toSummarize.length + toKeep.length,
101
- newCount: newConversation.length,
102
- });
103
- }
104
- }
105
- /**
106
- * Get conversation state for debugging
107
- */
108
- getState(currentDiscussionId) {
109
- const currentConvo = currentDiscussionId
110
- ? this.conversationsByDiscussion.get(currentDiscussionId)
111
- : null;
112
- return {
113
- discussionCount: this.conversationsByDiscussion.size,
114
- currentMessageCount: currentConvo?.length ?? 0,
115
- };
116
- }
117
- /**
118
- * Get full conversation for a discussion (for debugging)
119
- */
120
- getFullConversation(discussionId) {
121
- if (!discussionId) {
122
- // Return first conversation if no ID specified
123
- const first = this.conversationsByDiscussion.values().next().value;
124
- return first || [];
125
- }
126
- return this.conversationsByDiscussion.get(discussionId) || [];
127
- }
128
- /**
129
- * Clear all conversations
130
- */
131
- clear() {
132
- this.conversationsByDiscussion.clear();
133
- }
134
- }
135
- exports.ConversationManager = ConversationManager;
136
- //# sourceMappingURL=conversation-manager.js.map
@@ -1,56 +0,0 @@
1
- /**
2
- * MCP Client Service
3
- *
4
- * Handles all communication with the MCP server:
5
- * - Tool schema loading
6
- * - Tool execution
7
- * - Response parsing
8
- */
9
- import { Logger } from "../../../lib/logger";
10
- import { ToolInput, McpToolResult } from "../../shared/types";
11
- /** MCP tool schema definition */
12
- export interface McpToolSchema {
13
- name: string;
14
- description?: string;
15
- inputSchema?: {
16
- type: string;
17
- properties?: Record<string, unknown>;
18
- required?: string[];
19
- };
20
- }
21
- export declare class McpClientService {
22
- private mcpServerUrl;
23
- private mcpServerApiKey;
24
- private loadedToolSchemas;
25
- private logger;
26
- constructor(mcpServerUrl: string, mcpServerApiKey: string, logger: Logger);
27
- /**
28
- * Mask sensitive data for safe logging
29
- */
30
- private maskApiKey;
31
- /**
32
- * Create safe error without exposing API key
33
- */
34
- private createSafeError;
35
- /**
36
- * Fetch tool schema from MCP server
37
- */
38
- fetchToolSchema(toolName: string): Promise<any>;
39
- /**
40
- * Call MCP tool
41
- */
42
- callMcpTool(name: string, args: ToolInput): Promise<McpToolResult>;
43
- /**
44
- * Load tool schema if not already loaded
45
- */
46
- loadToolSchemaIfNeeded(toolName: string): Promise<McpToolSchema | undefined>;
47
- /**
48
- * Get cached tool schema
49
- */
50
- getCachedToolSchema(toolName: string): McpToolSchema | undefined;
51
- /**
52
- * Clear tool schema cache
53
- */
54
- clearSchemaCache(): void;
55
- }
56
- //# sourceMappingURL=mcp-client.d.ts.map
@@ -1,124 +0,0 @@
1
- "use strict";
2
- /**
3
- * MCP Client Service
4
- *
5
- * Handles all communication with the MCP server:
6
- * - Tool schema loading
7
- * - Tool execution
8
- * - Response parsing
9
- */
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.McpClientService = void 0;
12
- class McpClientService {
13
- mcpServerUrl;
14
- mcpServerApiKey;
15
- loadedToolSchemas = new Map();
16
- logger;
17
- constructor(mcpServerUrl, mcpServerApiKey, logger) {
18
- this.mcpServerUrl = mcpServerUrl;
19
- this.mcpServerApiKey = mcpServerApiKey;
20
- this.logger = logger;
21
- }
22
- /**
23
- * Mask sensitive data for safe logging
24
- */
25
- maskApiKey(key) {
26
- if (!key || key.length < 8)
27
- return '***';
28
- return `${key.slice(0, 4)}...${key.slice(-4)}`;
29
- }
30
- /**
31
- * Create safe error without exposing API key
32
- */
33
- createSafeError(message, originalError) {
34
- const safeMessage = message.replace(this.mcpServerApiKey, this.maskApiKey(this.mcpServerApiKey));
35
- const error = new Error(safeMessage);
36
- if (originalError instanceof Error) {
37
- error.stack = originalError.stack?.replace(this.mcpServerApiKey, this.maskApiKey(this.mcpServerApiKey));
38
- }
39
- return error;
40
- }
41
- /**
42
- * Fetch tool schema from MCP server
43
- */
44
- async fetchToolSchema(toolName) {
45
- const url = `${this.mcpServerUrl}?apiKey=${this.mcpServerApiKey}`;
46
- const response = await fetch(url, {
47
- method: "POST",
48
- headers: { "Content-Type": "application/json" },
49
- body: JSON.stringify({
50
- jsonrpc: "2.0",
51
- id: Math.random().toString(36).substring(2),
52
- method: "tools/get_schema",
53
- params: { name: toolName },
54
- }),
55
- });
56
- const text = await response.text();
57
- const lines = text.split("\n");
58
- for (const line of lines) {
59
- if (line.startsWith("data: ")) {
60
- const data = JSON.parse(line.substring(6));
61
- if (data.result) {
62
- return {
63
- name: data.result.name,
64
- description: data.result.description,
65
- input_schema: data.result.inputSchema,
66
- };
67
- }
68
- }
69
- }
70
- throw this.createSafeError(`Failed to load schema for ${toolName}`);
71
- }
72
- /**
73
- * Call MCP tool
74
- */
75
- async callMcpTool(name, args) {
76
- const url = `${this.mcpServerUrl}?apiKey=${this.mcpServerApiKey}`;
77
- const response = await fetch(url, {
78
- method: "POST",
79
- headers: { "Content-Type": "application/json" },
80
- body: JSON.stringify({
81
- jsonrpc: "2.0",
82
- id: Math.random().toString(36).substring(2),
83
- method: "tools/call",
84
- params: { name, arguments: args },
85
- }),
86
- });
87
- const text = await response.text();
88
- const lines = text.split("\n");
89
- for (const line of lines) {
90
- if (line.startsWith("data: ")) {
91
- const data = JSON.parse(line.substring(6));
92
- if (data.error) {
93
- throw this.createSafeError(data.error.message || String(data.error));
94
- }
95
- return data.result;
96
- }
97
- }
98
- throw this.createSafeError("Failed to parse MCP response");
99
- }
100
- /**
101
- * Load tool schema if not already loaded
102
- */
103
- async loadToolSchemaIfNeeded(toolName) {
104
- if (!this.loadedToolSchemas.has(toolName)) {
105
- const schema = await this.fetchToolSchema(toolName);
106
- this.loadedToolSchemas.set(toolName, schema);
107
- }
108
- return this.loadedToolSchemas.get(toolName);
109
- }
110
- /**
111
- * Get cached tool schema
112
- */
113
- getCachedToolSchema(toolName) {
114
- return this.loadedToolSchemas.get(toolName);
115
- }
116
- /**
117
- * Clear tool schema cache
118
- */
119
- clearSchemaCache() {
120
- this.loadedToolSchemas.clear();
121
- }
122
- }
123
- exports.McpClientService = McpClientService;
124
- //# sourceMappingURL=mcp-client.js.map
@@ -1,37 +0,0 @@
1
- /**
2
- * Message Classifier Service
3
- *
4
- * Handles incoming message extraction and classification:
5
- * - Extracts message content from Hailer signals
6
- * - Classifies message priority (high/normal)
7
- * - Detects mentions, replies, and DMs
8
- */
9
- import { Logger } from "../../../lib/logger";
10
- import { BotClient } from "../../bot-manager";
11
- import { HailerSignal } from "../../../mcp/signal-handler";
12
- import { IncomingMessage } from "../../shared/types";
13
- export declare class MessageClassifier {
14
- private botUserId;
15
- private botClient;
16
- private logger;
17
- private mentionPattern;
18
- constructor(botUserId: string, botClient: BotClient, logger: Logger);
19
- /**
20
- * Extract and classify incoming message from signal
21
- */
22
- extractIncomingMessage(signal: HailerSignal): Promise<IncomingMessage | null>;
23
- /**
24
- * Check if message mentions this bot
25
- * Uses pre-compiled regex pattern for performance
26
- */
27
- checkMention(content: string): boolean;
28
- /**
29
- * Check if message is a reply to one of our messages
30
- */
31
- checkReplyToBot(discussionId: string, messageId: string): Promise<boolean>;
32
- /**
33
- * Check if this is a 1:1 DM with the bot
34
- */
35
- checkDirectMessage(discussionId: string, senderId: string): Promise<boolean>;
36
- }
37
- //# sourceMappingURL=message-classifier.d.ts.map
@@ -1,187 +0,0 @@
1
- "use strict";
2
- /**
3
- * Message Classifier Service
4
- *
5
- * Handles incoming message extraction and classification:
6
- * - Extracts message content from Hailer signals
7
- * - Classifies message priority (high/normal)
8
- * - Detects mentions, replies, and DMs
9
- */
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.MessageClassifier = void 0;
12
- class MessageClassifier {
13
- botUserId;
14
- botClient;
15
- logger;
16
- // Pre-compiled mention pattern for performance
17
- mentionPattern;
18
- constructor(botUserId, botClient, logger) {
19
- this.botUserId = botUserId;
20
- this.botClient = botClient;
21
- this.logger = logger;
22
- // Compile mention pattern once
23
- this.mentionPattern = new RegExp(`\\[hailerTag\\|[^\\]]+\\]\\(${this.botUserId}\\)`, "i");
24
- }
25
- /**
26
- * Extract and classify incoming message from signal
27
- */
28
- async extractIncomingMessage(signal) {
29
- const { discussion, msg_id, uid } = signal.data;
30
- // Skip our own messages
31
- if (uid === this.botUserId) {
32
- return null;
33
- }
34
- // Fetch the actual message content
35
- let messageContent = "";
36
- let senderName = "Unknown";
37
- try {
38
- const response = await this.botClient.client.socket.request("v3.discussion.message.latest", [discussion]);
39
- const messages = response?.messages || [];
40
- const targetMessage = messages.find((msg) => msg._id === msg_id);
41
- if (!targetMessage) {
42
- return null;
43
- }
44
- messageContent = targetMessage.msg || targetMessage.content || "";
45
- // Get sender name: try workspace cache first, then message field
46
- const cachedUser = this.botClient.workspaceCache?.usersById[uid];
47
- const cachedName = cachedUser?.fullName ?? `${cachedUser?.firstname || ''} ${cachedUser?.lastname || ''}`.trim();
48
- senderName = cachedName || targetMessage.userName || "Unknown";
49
- // Skip system messages
50
- if (targetMessage.type && targetMessage.type !== "user") {
51
- return null;
52
- }
53
- }
54
- catch (error) {
55
- this.logger.warn("Could not fetch message content", { error });
56
- return null;
57
- }
58
- // Classify priority
59
- const isMention = this.checkMention(messageContent);
60
- const isReplyToBot = await this.checkReplyToBot(discussion, msg_id);
61
- const isDirectMessage = await this.checkDirectMessage(discussion, uid);
62
- // Get linked activity ID, name, and workspace ID from discussion metadata
63
- let linkedActivityId;
64
- let linkedActivityName;
65
- let discussionWorkspaceId;
66
- try {
67
- const discussionResponse = await this.botClient.client.socket.request("messenger.load_discussions", [[discussion]]);
68
- if (discussionResponse && discussionResponse[discussion]) {
69
- const discData = discussionResponse[discussion];
70
- linkedActivityId = discData.linked_activity;
71
- linkedActivityName = discData.name; // Discussion name is usually the activity name
72
- discussionWorkspaceId = discData.cid; // Workspace ID (cid = company ID in Hailer)
73
- this.logger.debug("Discussion metadata loaded", {
74
- discussionId: discussion,
75
- linkedActivityId: linkedActivityId || "none",
76
- linkedActivityName: linkedActivityName || "none",
77
- hasLinkedActivity: !!linkedActivityId,
78
- cid: discussionWorkspaceId || "not in response",
79
- discDataKeys: Object.keys(discData).join(","),
80
- });
81
- }
82
- }
83
- catch (error) {
84
- this.logger.debug("Failed to load discussion metadata", {
85
- discussionId: discussion,
86
- error: error instanceof Error ? error.message : String(error),
87
- });
88
- }
89
- let priority = "normal";
90
- let priorityReason = "General chat message";
91
- if (isDirectMessage) {
92
- priority = "high";
93
- priorityReason = "Direct message (1:1 conversation)";
94
- }
95
- else if (isMention) {
96
- priority = "high";
97
- priorityReason = "Bot mentioned in message";
98
- }
99
- else if (isReplyToBot) {
100
- priority = "high";
101
- priorityReason = "Reply to bot's message";
102
- }
103
- // Extract workspaceId - prefer discussion metadata (accurate), fallback to signal
104
- // Discussion metadata contains authoritative workspace ID from Hailer
105
- const workspaceId = discussionWorkspaceId || signal.workspaceId;
106
- if (!workspaceId) {
107
- this.logger.warn("Cannot determine workspace - rejecting message for isolation safety", {
108
- discussionId: discussion,
109
- messageId: msg_id,
110
- discussionWorkspaceId: discussionWorkspaceId || "none",
111
- signalWorkspaceId: signal.workspaceId || "none",
112
- });
113
- return null;
114
- }
115
- // Debug log workspace context (normal in multi-tenant setup)
116
- if (discussionWorkspaceId) {
117
- this.logger.debug("Message workspace context", {
118
- discussionId: discussion,
119
- workspaceId: discussionWorkspaceId,
120
- });
121
- }
122
- return {
123
- id: msg_id,
124
- discussionId: discussion,
125
- workspaceId,
126
- linkedActivityId,
127
- linkedActivityName,
128
- senderId: uid,
129
- senderName,
130
- content: messageContent,
131
- timestamp: signal.timestamp,
132
- priority,
133
- priorityReason,
134
- isReplyToBot,
135
- isMention,
136
- isDirectMessage,
137
- };
138
- }
139
- /**
140
- * Check if message mentions this bot
141
- * Uses pre-compiled regex pattern for performance
142
- */
143
- checkMention(content) {
144
- return this.mentionPattern.test(content);
145
- }
146
- /**
147
- * Check if message is a reply to one of our messages
148
- */
149
- async checkReplyToBot(discussionId, messageId) {
150
- try {
151
- const response = await this.botClient.client.socket.request("v3.discussion.message.latest", [discussionId]);
152
- const messages = response?.messages || [];
153
- const targetMessage = messages.find((msg) => msg._id === messageId);
154
- if (targetMessage?.replyTo) {
155
- const repliedToMessage = messages.find((msg) => msg._id === targetMessage.replyTo);
156
- return repliedToMessage?.uid === this.botUserId;
157
- }
158
- }
159
- catch {
160
- // Ignore errors
161
- }
162
- return false;
163
- }
164
- /**
165
- * Check if this is a 1:1 DM with the bot
166
- */
167
- async checkDirectMessage(discussionId, senderId) {
168
- try {
169
- const response = await this.botClient.client.socket.request("messenger.load_discussions", [[discussionId]]);
170
- if (response && response[discussionId]) {
171
- const discussion = response[discussionId];
172
- const participants = discussion.participants || [];
173
- // 1:1 = exactly 2 participants: sender and bot
174
- if (participants.length === 2) {
175
- return participants.includes(this.botUserId) &&
176
- participants.includes(senderId);
177
- }
178
- }
179
- }
180
- catch {
181
- // Ignore errors
182
- }
183
- return false;
184
- }
185
- }
186
- exports.MessageClassifier = MessageClassifier;
187
- //# sourceMappingURL=message-classifier.js.map
@@ -1,89 +0,0 @@
1
- /**
2
- * Message Formatter Service
3
- *
4
- * Handles formatting of messages for Hailer:
5
- * - Converting @mentions and #activity tags to Hailer tags
6
- * - Resolving user/activity IDs via API
7
- * - Extracting tag links for messenger.send
8
- */
9
- import { BotClient } from "../../bot-manager";
10
- import { Logger } from "../../../lib/logger";
11
- import { McpToolCallback } from "../../shared/types";
12
- export declare class MessageFormatterService {
13
- private botClient;
14
- private logger;
15
- private callMcpTool;
16
- constructor(botClient: BotClient, logger: Logger, callMcpTool: McpToolCallback);
17
- /**
18
- * Sanitize display name to prevent tag injection attacks
19
- * Removes/escapes characters that could break the tag format
20
- */
21
- private sanitizeDisplayName;
22
- /**
23
- * Validate that targetId is a valid MongoDB ObjectId format
24
- */
25
- private isValidTargetId;
26
- /**
27
- * Format a Hailer tag for mentioning a user or activity
28
- * Hailer requires ZWNBSP (U+FEFF) around the tag
29
- */
30
- private formatHailerTag;
31
- /**
32
- * Look up user by ID and create a Hailer tag
33
- */
34
- private createUserTagById;
35
- /**
36
- * Look up user by name and create a Hailer tag
37
- */
38
- private createUserTagByName;
39
- /**
40
- * Convert @mentions and #activity tags in response to Hailer tags
41
- * Supports:
42
- * - @userId (24-char hex MongoDB ID) → user tag
43
- * - @"Full Name" (quoted name lookup) → user tag
44
- * - @FirstName (single word name lookup) → user tag
45
- * - #activityId (24-char hex) → activity tag
46
- * - #"Activity Name" (quoted) → activity tag (requires lookup)
47
- */
48
- convertMentionsToTags(content: string): string;
49
- /**
50
- * Resolve user tags - look up names for IDs via API when not in cache
51
- * Handles @userId (24-char hex) format
52
- */
53
- resolveUserTags(content: string): Promise<string>;
54
- /**
55
- * Resolve activity tags - look up names for IDs and IDs for names
56
- * Handles both #activityId and #"Activity Name" formats
57
- */
58
- resolveActivityTags(content: string): Promise<string>;
59
- /**
60
- * Convert Hailer URLs to Hailer tags
61
- * Handles:
62
- * - https://app.hailer.com/#/activities/{activityId}
63
- * - https://app.hailer.com/#/discussions/{discussionId}
64
- */
65
- resolveHailerUrls(content: string): Promise<string>;
66
- /**
67
- * Extract link metadata from hailerTag formatted content
68
- * Returns array of links for the messenger.send API
69
- */
70
- extractTagLinks(content: string): Array<{
71
- target: string;
72
- targetType: string;
73
- type: string;
74
- }>;
75
- /**
76
- * Format incoming message for LLM consumption
77
- */
78
- formatIncomingMessage(message: {
79
- discussionId: string;
80
- linkedActivityId?: string;
81
- senderName: string;
82
- senderId: string;
83
- timestamp: number;
84
- priority: string;
85
- priorityReason: string;
86
- content: string;
87
- }): string;
88
- }
89
- //# sourceMappingURL=message-formatter.d.ts.map