@hailer/mcp 0.1.17 → 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 (200) 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-server.d.ts +2 -2
  37. package/dist/mcp-server.js +161 -139
  38. package/package.json +1 -1
  39. package/REFACTOR_STATUS.md +0 -127
  40. package/dist/agents/bot-manager.d.ts +0 -48
  41. package/dist/agents/bot-manager.js +0 -254
  42. package/dist/agents/factory.d.ts +0 -150
  43. package/dist/agents/factory.js +0 -650
  44. package/dist/agents/giuseppe/ai.d.ts +0 -83
  45. package/dist/agents/giuseppe/ai.js +0 -466
  46. package/dist/agents/giuseppe/bot.d.ts +0 -110
  47. package/dist/agents/giuseppe/bot.js +0 -780
  48. package/dist/agents/giuseppe/config.d.ts +0 -25
  49. package/dist/agents/giuseppe/config.js +0 -227
  50. package/dist/agents/giuseppe/files.d.ts +0 -52
  51. package/dist/agents/giuseppe/files.js +0 -338
  52. package/dist/agents/giuseppe/git.d.ts +0 -48
  53. package/dist/agents/giuseppe/git.js +0 -298
  54. package/dist/agents/giuseppe/index.d.ts +0 -97
  55. package/dist/agents/giuseppe/index.js +0 -258
  56. package/dist/agents/giuseppe/lsp.d.ts +0 -113
  57. package/dist/agents/giuseppe/lsp.js +0 -485
  58. package/dist/agents/giuseppe/monitor.d.ts +0 -118
  59. package/dist/agents/giuseppe/monitor.js +0 -621
  60. package/dist/agents/giuseppe/prompt.d.ts +0 -5
  61. package/dist/agents/giuseppe/prompt.js +0 -94
  62. package/dist/agents/giuseppe/registries/pending-classification.d.ts +0 -28
  63. package/dist/agents/giuseppe/registries/pending-classification.js +0 -50
  64. package/dist/agents/giuseppe/registries/pending-fix.d.ts +0 -30
  65. package/dist/agents/giuseppe/registries/pending-fix.js +0 -42
  66. package/dist/agents/giuseppe/registries/pending.d.ts +0 -27
  67. package/dist/agents/giuseppe/registries/pending.js +0 -49
  68. package/dist/agents/giuseppe/specialist.d.ts +0 -47
  69. package/dist/agents/giuseppe/specialist.js +0 -237
  70. package/dist/agents/giuseppe/types.d.ts +0 -123
  71. package/dist/agents/giuseppe/types.js +0 -9
  72. package/dist/agents/hailer-expert/index.d.ts +0 -8
  73. package/dist/agents/hailer-expert/index.js +0 -14
  74. package/dist/agents/hal/daemon.d.ts +0 -142
  75. package/dist/agents/hal/daemon.js +0 -1103
  76. package/dist/agents/hal/definitions.d.ts +0 -55
  77. package/dist/agents/hal/definitions.js +0 -263
  78. package/dist/agents/hal/index.d.ts +0 -3
  79. package/dist/agents/hal/index.js +0 -8
  80. package/dist/agents/index.d.ts +0 -18
  81. package/dist/agents/index.js +0 -48
  82. package/dist/agents/shared/base.d.ts +0 -216
  83. package/dist/agents/shared/base.js +0 -846
  84. package/dist/agents/shared/services/agent-registry.d.ts +0 -107
  85. package/dist/agents/shared/services/agent-registry.js +0 -629
  86. package/dist/agents/shared/services/conversation-manager.d.ts +0 -50
  87. package/dist/agents/shared/services/conversation-manager.js +0 -136
  88. package/dist/agents/shared/services/mcp-client.d.ts +0 -56
  89. package/dist/agents/shared/services/mcp-client.js +0 -124
  90. package/dist/agents/shared/services/message-classifier.d.ts +0 -37
  91. package/dist/agents/shared/services/message-classifier.js +0 -187
  92. package/dist/agents/shared/services/message-formatter.d.ts +0 -89
  93. package/dist/agents/shared/services/message-formatter.js +0 -371
  94. package/dist/agents/shared/services/session-logger.d.ts +0 -106
  95. package/dist/agents/shared/services/session-logger.js +0 -446
  96. package/dist/agents/shared/services/tool-executor.d.ts +0 -41
  97. package/dist/agents/shared/services/tool-executor.js +0 -169
  98. package/dist/agents/shared/services/workspace-schema-cache.d.ts +0 -125
  99. package/dist/agents/shared/services/workspace-schema-cache.js +0 -578
  100. package/dist/agents/shared/specialist.d.ts +0 -91
  101. package/dist/agents/shared/specialist.js +0 -399
  102. package/dist/agents/shared/tool-schema-loader.d.ts +0 -62
  103. package/dist/agents/shared/tool-schema-loader.js +0 -232
  104. package/dist/agents/shared/types.d.ts +0 -327
  105. package/dist/agents/shared/types.js +0 -121
  106. package/dist/client/agents/base.d.ts +0 -207
  107. package/dist/client/agents/base.js +0 -744
  108. package/dist/client/agents/definitions.d.ts +0 -53
  109. package/dist/client/agents/definitions.js +0 -263
  110. package/dist/client/agents/orchestrator.d.ts +0 -141
  111. package/dist/client/agents/orchestrator.js +0 -1062
  112. package/dist/client/agents/specialist.d.ts +0 -86
  113. package/dist/client/agents/specialist.js +0 -340
  114. package/dist/client/bot-entrypoint.d.ts +0 -7
  115. package/dist/client/bot-entrypoint.js +0 -103
  116. package/dist/client/bot-manager.d.ts +0 -44
  117. package/dist/client/bot-manager.js +0 -173
  118. package/dist/client/bot-runner.d.ts +0 -35
  119. package/dist/client/bot-runner.js +0 -188
  120. package/dist/client/chat-agent-daemon.d.ts +0 -464
  121. package/dist/client/chat-agent-daemon.js +0 -1774
  122. package/dist/client/daemon-factory.d.ts +0 -106
  123. package/dist/client/daemon-factory.js +0 -301
  124. package/dist/client/factory.d.ts +0 -111
  125. package/dist/client/factory.js +0 -314
  126. package/dist/client/index.d.ts +0 -17
  127. package/dist/client/index.js +0 -38
  128. package/dist/client/multi-bot-manager.d.ts +0 -42
  129. package/dist/client/multi-bot-manager.js +0 -161
  130. package/dist/client/orchestrator-daemon.d.ts +0 -87
  131. package/dist/client/orchestrator-daemon.js +0 -444
  132. package/dist/client/server.d.ts +0 -8
  133. package/dist/client/server.js +0 -251
  134. package/dist/client/services/agent-registry.d.ts +0 -108
  135. package/dist/client/services/agent-registry.js +0 -630
  136. package/dist/client/services/conversation-manager.d.ts +0 -50
  137. package/dist/client/services/conversation-manager.js +0 -136
  138. package/dist/client/services/mcp-client.d.ts +0 -48
  139. package/dist/client/services/mcp-client.js +0 -105
  140. package/dist/client/services/message-classifier.d.ts +0 -37
  141. package/dist/client/services/message-classifier.js +0 -187
  142. package/dist/client/services/message-formatter.d.ts +0 -84
  143. package/dist/client/services/message-formatter.js +0 -353
  144. package/dist/client/services/session-logger.d.ts +0 -106
  145. package/dist/client/services/session-logger.js +0 -446
  146. package/dist/client/services/tool-executor.d.ts +0 -41
  147. package/dist/client/services/tool-executor.js +0 -169
  148. package/dist/client/services/workspace-schema-cache.d.ts +0 -149
  149. package/dist/client/services/workspace-schema-cache.js +0 -732
  150. package/dist/client/specialist-daemon.d.ts +0 -77
  151. package/dist/client/specialist-daemon.js +0 -197
  152. package/dist/client/specialists.d.ts +0 -53
  153. package/dist/client/specialists.js +0 -178
  154. package/dist/client/tool-schema-loader.d.ts +0 -62
  155. package/dist/client/tool-schema-loader.js +0 -232
  156. package/dist/client/types.d.ts +0 -327
  157. package/dist/client/types.js +0 -121
  158. package/dist/commands/seed-config.d.ts +0 -9
  159. package/dist/commands/seed-config.js +0 -372
  160. package/dist/lib/context-manager.d.ts +0 -111
  161. package/dist/lib/context-manager.js +0 -431
  162. package/dist/lib/prompt-length-manager.d.ts +0 -81
  163. package/dist/lib/prompt-length-manager.js +0 -457
  164. package/dist/mcp/tools/giuseppe-tools.d.ts +0 -21
  165. package/dist/modules/bug-reports/bug-config.d.ts +0 -25
  166. package/dist/modules/bug-reports/bug-config.js +0 -187
  167. package/dist/modules/bug-reports/bug-monitor.d.ts +0 -108
  168. package/dist/modules/bug-reports/bug-monitor.js +0 -510
  169. package/dist/modules/bug-reports/giuseppe-agent.d.ts +0 -58
  170. package/dist/modules/bug-reports/giuseppe-agent.js +0 -467
  171. package/dist/modules/bug-reports/giuseppe-ai.d.ts +0 -83
  172. package/dist/modules/bug-reports/giuseppe-ai.js +0 -466
  173. package/dist/modules/bug-reports/giuseppe-bot.d.ts +0 -110
  174. package/dist/modules/bug-reports/giuseppe-bot.js +0 -804
  175. package/dist/modules/bug-reports/giuseppe-daemon.d.ts +0 -80
  176. package/dist/modules/bug-reports/giuseppe-daemon.js +0 -617
  177. package/dist/modules/bug-reports/giuseppe-files.d.ts +0 -64
  178. package/dist/modules/bug-reports/giuseppe-files.js +0 -375
  179. package/dist/modules/bug-reports/giuseppe-git.d.ts +0 -48
  180. package/dist/modules/bug-reports/giuseppe-git.js +0 -298
  181. package/dist/modules/bug-reports/giuseppe-lsp.d.ts +0 -113
  182. package/dist/modules/bug-reports/giuseppe-lsp.js +0 -485
  183. package/dist/modules/bug-reports/giuseppe-prompt.d.ts +0 -5
  184. package/dist/modules/bug-reports/giuseppe-prompt.js +0 -94
  185. package/dist/modules/bug-reports/index.d.ts +0 -77
  186. package/dist/modules/bug-reports/index.js +0 -215
  187. package/dist/modules/bug-reports/pending-classification-registry.d.ts +0 -28
  188. package/dist/modules/bug-reports/pending-classification-registry.js +0 -50
  189. package/dist/modules/bug-reports/pending-fix-registry.d.ts +0 -30
  190. package/dist/modules/bug-reports/pending-fix-registry.js +0 -42
  191. package/dist/modules/bug-reports/pending-registry.d.ts +0 -27
  192. package/dist/modules/bug-reports/pending-registry.js +0 -49
  193. package/dist/modules/bug-reports/types.d.ts +0 -123
  194. package/dist/modules/bug-reports/types.js +0 -9
  195. package/dist/routes/agents.d.ts +0 -44
  196. package/dist/routes/agents.js +0 -311
  197. package/dist/services/agent-credential-store.d.ts +0 -73
  198. package/dist/services/agent-credential-store.js +0 -212
  199. package/dist/services/bug-monitor.d.ts +0 -23
  200. package/dist/services/bug-monitor.js +0 -275
@@ -1,353 +0,0 @@
1
- "use strict";
2
- /**
3
- * Message Formatter Service
4
- *
5
- * Handles formatting of messages for Hailer:
6
- * - Converting @mentions and #activity tags to Hailer tags
7
- * - Resolving user/activity IDs via API
8
- * - Extracting tag links for messenger.send
9
- */
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.MessageFormatterService = void 0;
12
- class MessageFormatterService {
13
- botClient;
14
- logger;
15
- callMcpTool;
16
- constructor(botClient, logger, callMcpTool) {
17
- this.botClient = botClient;
18
- this.logger = logger;
19
- this.callMcpTool = callMcpTool;
20
- }
21
- /**
22
- * Format a Hailer tag for mentioning a user or activity
23
- * Hailer requires ZWNBSP (U+FEFF) around the tag
24
- */
25
- formatHailerTag(targetId, displayName) {
26
- const ZWNBSP = '\uFEFF';
27
- return `${ZWNBSP}[hailerTag|${displayName}](${targetId})${ZWNBSP}`;
28
- }
29
- /**
30
- * Get user's display name from workspace cache
31
- */
32
- getUserDisplayName(userId) {
33
- const cache = this.botClient.workspaceCache;
34
- if (!cache)
35
- return null;
36
- const user = cache.usersById[userId];
37
- if (!user)
38
- return null;
39
- return user.fullName || `${user.firstname || ''} ${user.lastname || ''}`.trim() || null;
40
- }
41
- /**
42
- * Look up user by ID and create a Hailer tag
43
- */
44
- createUserTagById(userId) {
45
- const cache = this.botClient.workspaceCache;
46
- if (!cache)
47
- return null;
48
- const user = cache.usersById[userId];
49
- if (!user)
50
- return null;
51
- const displayName = user.fullName || `${user.firstname} ${user.lastname}`.trim();
52
- return this.formatHailerTag(userId, displayName);
53
- }
54
- /**
55
- * Look up user by name and create a Hailer tag
56
- */
57
- createUserTagByName(name) {
58
- const cache = this.botClient.workspaceCache;
59
- if (!cache)
60
- return null;
61
- const nameLower = name.toLowerCase();
62
- const user = cache.users.find(u => {
63
- const fullName = u.fullName || `${u.firstname} ${u.lastname}`.trim();
64
- return fullName.toLowerCase() === nameLower ||
65
- u.firstname?.toLowerCase() === nameLower ||
66
- u.lastname?.toLowerCase() === nameLower;
67
- });
68
- if (!user)
69
- return null;
70
- const displayName = user.fullName || `${user.firstname} ${user.lastname}`.trim();
71
- return this.formatHailerTag(user.id, displayName);
72
- }
73
- /**
74
- * Convert @mentions and #activity tags in response to Hailer tags
75
- * Supports:
76
- * - @userId (24-char hex MongoDB ID) → user tag
77
- * - @"Full Name" (quoted name lookup) → user tag
78
- * - @FirstName (single word name lookup) → user tag
79
- * - #activityId (24-char hex) → activity tag
80
- * - #"Activity Name" (quoted) → activity tag (requires lookup)
81
- */
82
- convertMentionsToTags(content) {
83
- // User mentions (from cache)
84
- const cache = this.botClient.workspaceCache;
85
- if (cache) {
86
- // Pattern 1: @userId (24-char hex)
87
- content = content.replace(/@([a-f0-9]{24})\b/gi, (match, userId) => {
88
- const tag = this.createUserTagById(userId);
89
- return tag || match;
90
- });
91
- // Pattern 2: @"Full Name" (quoted)
92
- content = content.replace(/@"([^"]+)"/g, (match, name) => {
93
- const tag = this.createUserTagByName(name);
94
- return tag || match;
95
- });
96
- // Pattern 3: @FirstName (single word, capitalized)
97
- content = content.replace(/@([A-Z][a-z]+)\b/g, (match, name) => {
98
- const tag = this.createUserTagByName(name);
99
- return tag || match;
100
- });
101
- }
102
- // Activity tags (#activityId and #"Name") are handled by
103
- // resolveActivityTags (async) which runs before this
104
- return content;
105
- }
106
- /**
107
- * Resolve user tags - look up names for IDs via API when not in cache
108
- * Handles @userId (24-char hex) format
109
- */
110
- async resolveUserTags(content) {
111
- const pattern = /@([a-f0-9]{24})\b/gi;
112
- const matches = [...content.matchAll(pattern)];
113
- for (const match of matches) {
114
- const userId = match[1];
115
- // Try cache first
116
- const cachedTag = this.createUserTagById(userId);
117
- if (cachedTag) {
118
- content = content.replace(match[0], cachedTag);
119
- this.logger.debug("User tag from cache", { userId });
120
- continue;
121
- }
122
- // Fallback to API
123
- try {
124
- this.logger.info("Resolving user tag via API", { userId });
125
- const result = await this.callMcpTool("search_workspace_users", { query: userId });
126
- const resultText = result?.content?.[0]?.text;
127
- if (resultText) {
128
- // Parse the JSON array from the response
129
- // Response format: "Found X users:\n\n```json\n[...]\n```"
130
- const jsonMatch = resultText.match(/```json\s*([\s\S]*?)\s*```/);
131
- if (jsonMatch) {
132
- const users = JSON.parse(jsonMatch[1]);
133
- const user = users.find((u) => u._id === userId);
134
- if (user) {
135
- const displayName = `${user.firstname || ''} ${user.lastname || ''}`.trim() || user.fullName || userId;
136
- const tag = this.formatHailerTag(userId, displayName);
137
- content = content.replace(match[0], tag);
138
- this.logger.info("Created user tag from API", { userId, displayName });
139
- }
140
- }
141
- }
142
- }
143
- catch (error) {
144
- this.logger.warn("Failed to resolve user tag", { userId, error });
145
- // Leave as @userId - won't be clickable but visible
146
- }
147
- }
148
- return content;
149
- }
150
- /**
151
- * Resolve activity tags - look up names for IDs and IDs for names
152
- * Handles both #activityId and #"Activity Name" formats
153
- */
154
- async resolveActivityTags(content) {
155
- // Pattern 1: #activityId (24-char hex) - need to look up the name
156
- const activityIdPattern = /#([a-f0-9]{24})\b/gi;
157
- const idMatches = [...content.matchAll(activityIdPattern)];
158
- for (const match of idMatches) {
159
- const activityId = match[1];
160
- try {
161
- this.logger.info("Resolving activity tag by ID", { activityId });
162
- // Fetch activity by ID to get its name
163
- const result = await this.callMcpTool("show_activity_by_id", {
164
- activityId: activityId,
165
- });
166
- const resultText = result?.content?.[0]?.text;
167
- this.logger.debug("show_activity_by_id response", {
168
- hasResult: !!resultText,
169
- preview: resultText?.substring(0, 200)
170
- });
171
- if (resultText) {
172
- // Response format: "✅ Loaded activity with ID "xxx":\n\n{ JSON }"
173
- // Extract the JSON part after the header
174
- const jsonMatch = resultText.match(/\{[\s\S]*\}/);
175
- if (jsonMatch) {
176
- const parsed = JSON.parse(jsonMatch[0]);
177
- const activityName = parsed.name;
178
- this.logger.info("Extracted activity name", { activityId, activityName });
179
- if (activityName) {
180
- const tag = this.formatHailerTag(activityId, activityName);
181
- content = content.replace(match[0], tag);
182
- this.logger.info("Created activity tag", { tag });
183
- }
184
- }
185
- else {
186
- this.logger.warn("Could not extract JSON from response", { preview: resultText.substring(0, 100) });
187
- }
188
- }
189
- }
190
- catch (error) {
191
- this.logger.warn("Failed to resolve activity ID tag", { activityId, error });
192
- // Leave as #id - won't be clickable but at least visible
193
- }
194
- }
195
- // Pattern 2: #"Activity Name" - need to look up the ID
196
- // This is harder because list_activities requires workflowId/phaseId
197
- // For now, search in each workflow until we find a match
198
- const activityNamePattern = /#"([^"]+)"/g;
199
- const nameMatches = [...content.matchAll(activityNamePattern)];
200
- for (const match of nameMatches) {
201
- const activityName = match[1];
202
- try {
203
- // Get list of workflows first
204
- const workflowsResult = await this.callMcpTool("list_workflows_minimal", {});
205
- const workflowsText = workflowsResult?.content?.[0]?.text;
206
- if (workflowsText) {
207
- // Extract workflow IDs from the response (format varies)
208
- const workflowIdMatches = workflowsText.matchAll(/"_id":\s*"([a-f0-9]{24})"/gi);
209
- const workflowIds = [...workflowIdMatches].map(m => m[1]);
210
- // Search each workflow for the activity
211
- for (const workflowId of workflowIds.slice(0, 5)) { // Limit to first 5 workflows
212
- try {
213
- const phasesResult = await this.callMcpTool("list_workflow_phases", { workflowId });
214
- const phasesText = phasesResult?.content?.[0]?.text;
215
- if (phasesText) {
216
- const phaseIdMatches = phasesText.matchAll(/"_id":\s*"([a-f0-9]{24})"/gi);
217
- const phaseIds = [...phaseIdMatches].map(m => m[1]);
218
- for (const phaseId of phaseIds.slice(0, 3)) { // Limit to first 3 phases
219
- const activitiesResult = await this.callMcpTool("list_activities", {
220
- workflowId,
221
- phaseId,
222
- search: activityName,
223
- limit: 1,
224
- });
225
- const activitiesText = activitiesResult?.content?.[0]?.text;
226
- if (activitiesText) {
227
- // Look for activity ID and name in the response
228
- const activityIdMatch = activitiesText.match(/"_id":\s*"([a-f0-9]{24})"/i);
229
- if (activityIdMatch) {
230
- const foundId = activityIdMatch[1];
231
- const tag = this.formatHailerTag(foundId, activityName);
232
- content = content.replace(match[0], tag);
233
- break; // Found it, stop searching
234
- }
235
- }
236
- }
237
- }
238
- }
239
- catch {
240
- // Continue to next workflow
241
- }
242
- }
243
- }
244
- }
245
- catch (error) {
246
- this.logger.warn("Failed to resolve activity name tag", { activityName, error });
247
- // Leave the original #"Name" in place
248
- }
249
- }
250
- return content;
251
- }
252
- /**
253
- * Convert Hailer URLs to Hailer tags
254
- * Handles:
255
- * - https://app.hailer.com/#/activities/{activityId}
256
- * - https://app.hailer.com/#/discussions/{discussionId}
257
- */
258
- async resolveHailerUrls(content) {
259
- // Pattern for activity URLs
260
- const activityUrlPattern = /https?:\/\/app\.hailer\.com\/#\/activities\/([a-f0-9]{24})/gi;
261
- const activityMatches = [...content.matchAll(activityUrlPattern)];
262
- for (const match of activityMatches) {
263
- const activityId = match[1];
264
- try {
265
- const result = await this.callMcpTool("show_activity_by_id", { activityId });
266
- const resultText = result?.content?.[0]?.text;
267
- if (resultText) {
268
- const jsonMatch = resultText.match(/\{[\s\S]*\}/);
269
- if (jsonMatch) {
270
- const parsed = JSON.parse(jsonMatch[0]);
271
- const activityName = parsed.name;
272
- if (activityName) {
273
- const tag = this.formatHailerTag(activityId, activityName);
274
- content = content.replace(match[0], tag);
275
- this.logger.debug("Converted activity URL to tag", { activityId, activityName });
276
- }
277
- }
278
- }
279
- }
280
- catch (error) {
281
- this.logger.debug("Failed to resolve activity URL", { activityId, error });
282
- // Leave URL as-is
283
- }
284
- }
285
- // Pattern for discussion URLs - need to look up the linked activity
286
- const discussionUrlPattern = /https?:\/\/app\.hailer\.com\/#\/discussions\/([a-f0-9]{24})/gi;
287
- const discussionMatches = [...content.matchAll(discussionUrlPattern)];
288
- for (const match of discussionMatches) {
289
- const discussionId = match[1];
290
- try {
291
- // Load discussion to get linked activity
292
- const discussionResponse = await this.botClient.client.socket.request("messenger.load_discussions", [[discussionId]]);
293
- if (discussionResponse && discussionResponse[discussionId]) {
294
- const discData = discussionResponse[discussionId];
295
- const linkedActivityId = discData.linked_activity;
296
- const discussionName = discData.name;
297
- if (linkedActivityId) {
298
- // It's an activity discussion - use the activity ID for the tag
299
- const tag = this.formatHailerTag(linkedActivityId, discussionName || "Activity");
300
- content = content.replace(match[0], tag);
301
- this.logger.debug("Converted discussion URL to activity tag", { discussionId, linkedActivityId, discussionName });
302
- }
303
- else if (discussionName) {
304
- // It's a standalone discussion - use discussion name but discussion ID
305
- const tag = this.formatHailerTag(discussionId, discussionName);
306
- content = content.replace(match[0], tag);
307
- this.logger.debug("Converted discussion URL to discussion tag", { discussionId, discussionName });
308
- }
309
- }
310
- }
311
- catch (error) {
312
- this.logger.debug("Failed to resolve discussion URL", { discussionId, error });
313
- // Leave URL as-is
314
- }
315
- }
316
- return content;
317
- }
318
- /**
319
- * Extract link metadata from hailerTag formatted content
320
- * Returns array of links for the messenger.send API
321
- */
322
- extractTagLinks(content) {
323
- const links = [];
324
- // Match all hailerTag patterns: [hailerTag|Name](id)
325
- const tagPattern = /\[hailerTag\|[^\]]+\]\(([a-f0-9]{24})\)/gi;
326
- const matches = content.matchAll(tagPattern);
327
- for (const match of matches) {
328
- const targetId = match[1];
329
- // Determine if it's a user or activity based on context
330
- // For now, check if it's in the user cache
331
- const isUser = this.botClient.workspaceCache?.usersById[targetId];
332
- links.push({
333
- target: targetId,
334
- targetType: isUser ? 'user' : 'activity',
335
- type: 'linked-to'
336
- });
337
- }
338
- return links;
339
- }
340
- /**
341
- * Format incoming message for LLM consumption
342
- */
343
- formatIncomingMessage(message) {
344
- const priorityTag = message.priority === "high" ? " priority=\"high\"" : "";
345
- const reasonAttr = message.priority === "high" ? ` reason="${message.priorityReason}"` : "";
346
- const activityAttr = message.linkedActivityId ? ` activity_id="${message.linkedActivityId}"` : "";
347
- return `<incoming discussion="${message.discussionId}"${activityAttr} from="${message.senderName}" user_id="${message.senderId}" timestamp="${new Date(message.timestamp).toISOString()}"${priorityTag}${reasonAttr}>
348
- ${message.content}
349
- </incoming>`;
350
- }
351
- }
352
- exports.MessageFormatterService = MessageFormatterService;
353
- //# sourceMappingURL=message-formatter.js.map
@@ -1,106 +0,0 @@
1
- /**
2
- * Session Logger Service
3
- *
4
- * Manages per-activity session tracking and logging to Hailer workflows:
5
- * - Tracks metrics (tokens, tool calls, messages)
6
- * - Logs completed sessions to SESSION_LOG workflow
7
- * - Manages idle session detection and flushing
8
- */
9
- import Anthropic from "@anthropic-ai/sdk";
10
- import { Logger } from "../../lib/logger";
11
- import { ActivitySession, McpToolCallback } from "../types";
12
- import { WorkspaceSchemaCacheService } from "./workspace-schema-cache";
13
- /** Memory entry loaded from SESSION_LOG */
14
- export interface MemoryEntry {
15
- sessionId: string;
16
- timestamp: number;
17
- summary: string;
18
- linkedActivityId?: string;
19
- }
20
- export declare class SessionLoggerService {
21
- private agentDirectoryId;
22
- private logger;
23
- private callMcpTool;
24
- private getDefaultTeamId;
25
- private activitySessions;
26
- private lastGlobalLogId;
27
- private idleCheckTimer;
28
- private anthropicClient;
29
- private schemaCache;
30
- private currentWorkspaceId;
31
- constructor(agentDirectoryId: string | null, logger: Logger, callMcpTool: McpToolCallback, getDefaultTeamId: () => string | undefined);
32
- /**
33
- * Set the workspace schema cache for dynamic ID lookup
34
- */
35
- setSchemaCache(cache: WorkspaceSchemaCacheService, workspaceId: string): void;
36
- /**
37
- * Get Session Log schema from cache for a specific workspace
38
- */
39
- private getSessionLogSchema;
40
- /**
41
- * Set Anthropic client for generating summaries
42
- */
43
- setAnthropicClient(client: Anthropic): void;
44
- /**
45
- * Get or create an activity session for tracking
46
- * Multi-tenant: workspaceId is required for proper schema lookup
47
- */
48
- getOrCreateActivitySession(message: {
49
- linkedActivityId?: string;
50
- linkedActivityName?: string;
51
- discussionId: string;
52
- workspaceId: string;
53
- }): ActivitySession;
54
- /**
55
- * Get session by key
56
- */
57
- getSession(key: string): ActivitySession | undefined;
58
- /**
59
- * Get all active sessions
60
- */
61
- getActiveSessions(): Map<string, ActivitySession>;
62
- /**
63
- * Check for idle sessions and flush them
64
- * Called periodically by timer
65
- */
66
- checkAndFlushIdleSessions(): Promise<void>;
67
- /**
68
- * Flush a single activity session to the session log
69
- */
70
- flushActivitySession(key: string, session: ActivitySession): Promise<void>;
71
- /**
72
- * Flush all active sessions (called on shutdown)
73
- */
74
- flushAllSessions(): Promise<void>;
75
- /**
76
- * Build summary for an activity session
77
- * Now includes conversation summary for memory recall
78
- */
79
- private buildActivitySessionSummary;
80
- /**
81
- * Start periodic idle session checking
82
- */
83
- startIdleCheckTimer(intervalMs?: number): void;
84
- /**
85
- * Stop idle check timer
86
- */
87
- stopIdleCheckTimer(): void;
88
- /**
89
- * Generate a conversation summary using LLM
90
- * Creates a condensed memory of what was discussed
91
- */
92
- private generateConversationSummary;
93
- /**
94
- * Load memory entries for an activity from SESSION_LOG
95
- * Returns past conversation summaries for context injection
96
- *
97
- * NOTE: ActivityLink fields store objects {_id, name}, so we fetch recent
98
- * session logs and filter client-side by checking the nested _id.
99
- */
100
- loadMemoryForActivity(activityId: string, workspaceId: string, limit?: number): Promise<MemoryEntry[]>;
101
- /**
102
- * Format memory entries for injection into conversation context
103
- */
104
- formatMemoryForContext(entries: MemoryEntry[]): string;
105
- }
106
- //# sourceMappingURL=session-logger.d.ts.map