@hailer/mcp 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/tool-builder.md +37 -0
- package/.claude/commands/ws-pull.md +44 -0
- package/.claude/settings.json +8 -0
- package/.claude/settings.local.json +49 -0
- package/.claude/skills/activity-api/SKILL.md +96 -0
- package/.claude/skills/activity-api/references/activity-endpoints.md +845 -0
- package/.claude/skills/add-app-member-skill/SKILL.md +977 -0
- package/.claude/skills/agent-building/SKILL.md +243 -0
- package/.claude/skills/agent-building/references/architecture-patterns.md +446 -0
- package/.claude/skills/agent-building/references/code-examples.md +587 -0
- package/.claude/skills/agent-building/references/implementation-guide.md +619 -0
- package/.claude/skills/app-api/SKILL.md +219 -0
- package/.claude/skills/app-api/references/app-endpoints.md +759 -0
- package/.claude/skills/building-hailer-apps-skill/SKILL.md +548 -0
- package/.claude/skills/create-app-skill/SKILL.md +1101 -0
- package/.claude/skills/create-insight-skill/SKILL.md +1317 -0
- package/.claude/skills/get-insight-data-skill/SKILL.md +1053 -0
- package/.claude/skills/hailer-api/SKILL.md +283 -0
- package/.claude/skills/hailer-api/references/activities.md +620 -0
- package/.claude/skills/hailer-api/references/authentication.md +216 -0
- package/.claude/skills/hailer-api/references/datasets.md +437 -0
- package/.claude/skills/hailer-api/references/files.md +301 -0
- package/.claude/skills/hailer-api/references/insights.md +469 -0
- package/.claude/skills/hailer-api/references/workflows.md +720 -0
- package/.claude/skills/hailer-api/references/workspaces-users.md +445 -0
- package/.claude/skills/insight-api/SKILL.md +185 -0
- package/.claude/skills/insight-api/references/insight-endpoints.md +514 -0
- package/.claude/skills/install-workflow-skill/SKILL.md +1056 -0
- package/.claude/skills/list-apps-skill/SKILL.md +1010 -0
- package/.claude/skills/list-workflows-minimal-skill/SKILL.md +992 -0
- package/.claude/skills/local-first-skill/SKILL.md +570 -0
- package/.claude/skills/mcp-tools/SKILL.md +419 -0
- package/.claude/skills/mcp-tools/references/api-endpoints.md +499 -0
- package/.claude/skills/mcp-tools/references/data-structures.md +554 -0
- package/.claude/skills/mcp-tools/references/implementation-patterns.md +717 -0
- package/.claude/skills/preview-insight-skill/SKILL.md +1290 -0
- package/.claude/skills/publish-hailer-app-skill/SKILL.md +453 -0
- package/.claude/skills/remove-app-member-skill/SKILL.md +671 -0
- package/.claude/skills/remove-app-skill/SKILL.md +985 -0
- package/.claude/skills/remove-insight-skill/SKILL.md +1011 -0
- package/.claude/skills/remove-workflow-skill/SKILL.md +920 -0
- package/.claude/skills/scaffold-hailer-app-skill/SKILL.md +1034 -0
- package/.claude/skills/skill-testing/README.md +137 -0
- package/.claude/skills/skill-testing/SKILL.md +348 -0
- package/.claude/skills/skill-testing/references/test-patterns.md +705 -0
- package/.claude/skills/skill-testing/references/testing-guide.md +603 -0
- package/.claude/skills/skill-testing/references/validation-checklist.md +537 -0
- package/.claude/skills/tool-builder/SKILL.md +328 -0
- package/.claude/skills/update-app-skill/SKILL.md +970 -0
- package/.claude/skills/update-workflow-field-skill/SKILL.md +1098 -0
- package/.env.example +81 -0
- package/.mcp.json +13 -0
- package/README.md +297 -0
- package/dist/app.d.ts +4 -0
- package/dist/app.js +74 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +5 -0
- package/dist/client/adaptive-documentation-bot.d.ts +108 -0
- package/dist/client/adaptive-documentation-bot.js +475 -0
- package/dist/client/adaptive-documentation-types.d.ts +66 -0
- package/dist/client/adaptive-documentation-types.js +9 -0
- package/dist/client/agent-activity-bot.d.ts +51 -0
- package/dist/client/agent-activity-bot.js +166 -0
- package/dist/client/agent-tracker.d.ts +499 -0
- package/dist/client/agent-tracker.js +659 -0
- package/dist/client/description-updater.d.ts +56 -0
- package/dist/client/description-updater.js +259 -0
- package/dist/client/log-parser.d.ts +72 -0
- package/dist/client/log-parser.js +387 -0
- package/dist/client/mcp-client.d.ts +50 -0
- package/dist/client/mcp-client.js +532 -0
- package/dist/client/message-processor.d.ts +35 -0
- package/dist/client/message-processor.js +352 -0
- package/dist/client/multi-bot-manager.d.ts +24 -0
- package/dist/client/multi-bot-manager.js +74 -0
- package/dist/client/providers/anthropic-provider.d.ts +19 -0
- package/dist/client/providers/anthropic-provider.js +631 -0
- package/dist/client/providers/llm-provider.d.ts +47 -0
- package/dist/client/providers/llm-provider.js +367 -0
- package/dist/client/providers/openai-provider.d.ts +23 -0
- package/dist/client/providers/openai-provider.js +621 -0
- package/dist/client/simple-llm-caller.d.ts +19 -0
- package/dist/client/simple-llm-caller.js +100 -0
- package/dist/client/skill-generator.d.ts +81 -0
- package/dist/client/skill-generator.js +386 -0
- package/dist/client/test-adaptive-bot.d.ts +9 -0
- package/dist/client/test-adaptive-bot.js +82 -0
- package/dist/client/token-pricing.d.ts +38 -0
- package/dist/client/token-pricing.js +127 -0
- package/dist/client/token-tracker.d.ts +232 -0
- package/dist/client/token-tracker.js +457 -0
- package/dist/client/token-usage-bot.d.ts +53 -0
- package/dist/client/token-usage-bot.js +153 -0
- package/dist/client/tool-executor.d.ts +69 -0
- package/dist/client/tool-executor.js +159 -0
- package/dist/client/tool-schema-loader.d.ts +60 -0
- package/dist/client/tool-schema-loader.js +178 -0
- package/dist/client/types.d.ts +69 -0
- package/dist/client/types.js +7 -0
- package/dist/config.d.ts +162 -0
- package/dist/config.js +296 -0
- package/dist/core.d.ts +26 -0
- package/dist/core.js +147 -0
- package/dist/lib/context-manager.d.ts +111 -0
- package/dist/lib/context-manager.js +431 -0
- package/dist/lib/logger.d.ts +74 -0
- package/dist/lib/logger.js +277 -0
- package/dist/lib/materialize.d.ts +3 -0
- package/dist/lib/materialize.js +101 -0
- package/dist/lib/normalizedName.d.ts +7 -0
- package/dist/lib/normalizedName.js +48 -0
- package/dist/lib/prompt-length-manager.d.ts +81 -0
- package/dist/lib/prompt-length-manager.js +457 -0
- package/dist/lib/terminal-prompt.d.ts +9 -0
- package/dist/lib/terminal-prompt.js +108 -0
- package/dist/mcp/UserContextCache.d.ts +56 -0
- package/dist/mcp/UserContextCache.js +163 -0
- package/dist/mcp/auth.d.ts +2 -0
- package/dist/mcp/auth.js +29 -0
- package/dist/mcp/hailer-clients.d.ts +42 -0
- package/dist/mcp/hailer-clients.js +246 -0
- package/dist/mcp/signal-handler.d.ts +45 -0
- package/dist/mcp/signal-handler.js +317 -0
- package/dist/mcp/tool-registry.d.ts +100 -0
- package/dist/mcp/tool-registry.js +306 -0
- package/dist/mcp/tools/activity.d.ts +15 -0
- package/dist/mcp/tools/activity.js +955 -0
- package/dist/mcp/tools/app.d.ts +20 -0
- package/dist/mcp/tools/app.js +1488 -0
- package/dist/mcp/tools/discussion.d.ts +19 -0
- package/dist/mcp/tools/discussion.js +950 -0
- package/dist/mcp/tools/file.d.ts +15 -0
- package/dist/mcp/tools/file.js +119 -0
- package/dist/mcp/tools/insight.d.ts +17 -0
- package/dist/mcp/tools/insight.js +806 -0
- package/dist/mcp/tools/skill.d.ts +10 -0
- package/dist/mcp/tools/skill.js +279 -0
- package/dist/mcp/tools/user.d.ts +10 -0
- package/dist/mcp/tools/user.js +108 -0
- package/dist/mcp/tools/workflow-template.d.ts +19 -0
- package/dist/mcp/tools/workflow-template.js +822 -0
- package/dist/mcp/tools/workflow.d.ts +18 -0
- package/dist/mcp/tools/workflow.js +1362 -0
- package/dist/mcp/utils/api-errors.d.ts +45 -0
- package/dist/mcp/utils/api-errors.js +160 -0
- package/dist/mcp/utils/data-transformers.d.ts +102 -0
- package/dist/mcp/utils/data-transformers.js +194 -0
- package/dist/mcp/utils/file-upload.d.ts +33 -0
- package/dist/mcp/utils/file-upload.js +148 -0
- package/dist/mcp/utils/hailer-api-client.d.ts +120 -0
- package/dist/mcp/utils/hailer-api-client.js +323 -0
- package/dist/mcp/utils/index.d.ts +13 -0
- package/dist/mcp/utils/index.js +39 -0
- package/dist/mcp/utils/logger.d.ts +42 -0
- package/dist/mcp/utils/logger.js +103 -0
- package/dist/mcp/utils/types.d.ts +286 -0
- package/dist/mcp/utils/types.js +7 -0
- package/dist/mcp/workspace-cache.d.ts +42 -0
- package/dist/mcp/workspace-cache.js +97 -0
- package/dist/mcp-server.d.ts +42 -0
- package/dist/mcp-server.js +280 -0
- package/package.json +56 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Agent Activity Tracker
|
|
4
|
+
*
|
|
5
|
+
* Provides comprehensive tracking and analytics for AI agent interactions within
|
|
6
|
+
* the Hailer MCP ecosystem. This module captures conversation flows, performance
|
|
7
|
+
* metrics, and usage patterns to enable business intelligence and system optimization.
|
|
8
|
+
*
|
|
9
|
+
* Key Features:
|
|
10
|
+
* - End-to-end conversation flow tracking (trigger → completion correlation)
|
|
11
|
+
* - Detailed tool usage analytics with request/response data
|
|
12
|
+
* - Performance metrics (response times, success rates)
|
|
13
|
+
* - Agent usage statistics and behavioral insights
|
|
14
|
+
* - Persistent JSON-based storage with automatic rotation
|
|
15
|
+
*
|
|
16
|
+
* Environment Behavior:
|
|
17
|
+
* - Development (NODE_ENV !== 'production'): JSON file tracking enabled by default
|
|
18
|
+
* - Production (NODE_ENV === 'production'): JSON file tracking disabled by default
|
|
19
|
+
* - Override: Set AGENT_TRACKING_ENABLED=true to force enable in production
|
|
20
|
+
*
|
|
21
|
+
* In production, all tracking events are still logged via the unified logger
|
|
22
|
+
* (OTLP) but no JSON files are created to avoid disk I/O and storage costs.
|
|
23
|
+
*/
|
|
24
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
27
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
28
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
29
|
+
}
|
|
30
|
+
Object.defineProperty(o, k2, desc);
|
|
31
|
+
}) : (function(o, m, k, k2) {
|
|
32
|
+
if (k2 === undefined) k2 = k;
|
|
33
|
+
o[k2] = m[k];
|
|
34
|
+
}));
|
|
35
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
36
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
37
|
+
}) : function(o, v) {
|
|
38
|
+
o["default"] = v;
|
|
39
|
+
});
|
|
40
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
41
|
+
var ownKeys = function(o) {
|
|
42
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
43
|
+
var ar = [];
|
|
44
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
45
|
+
return ar;
|
|
46
|
+
};
|
|
47
|
+
return ownKeys(o);
|
|
48
|
+
};
|
|
49
|
+
return function (mod) {
|
|
50
|
+
if (mod && mod.__esModule) return mod;
|
|
51
|
+
var result = {};
|
|
52
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
53
|
+
__setModuleDefault(result, mod);
|
|
54
|
+
return result;
|
|
55
|
+
};
|
|
56
|
+
})();
|
|
57
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
58
|
+
exports.AgentTracker = void 0;
|
|
59
|
+
exports.createAgentTracker = createAgentTracker;
|
|
60
|
+
const logger_1 = require("../lib/logger");
|
|
61
|
+
const fs = __importStar(require("fs"));
|
|
62
|
+
const path = __importStar(require("path"));
|
|
63
|
+
/**
|
|
64
|
+
* Agent Activity Tracker
|
|
65
|
+
*
|
|
66
|
+
* Main class for tracking AI agent interactions, performance, and usage patterns.
|
|
67
|
+
* Provides both real-time logging capabilities and historical analytics.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const logger = createLogger({ component: 'my-component' });
|
|
72
|
+
* const tracker = new AgentTracker(logger);
|
|
73
|
+
*
|
|
74
|
+
* // Track a conversation flow
|
|
75
|
+
* const requestId = tracker.logTrigger({
|
|
76
|
+
* triggerType: 'mention',
|
|
77
|
+
* discussionId: 'disc_123',
|
|
78
|
+
* userId: 'user_456',
|
|
79
|
+
* userName: 'John Doe',
|
|
80
|
+
* botId: 'bot_789',
|
|
81
|
+
* messageContent: '@bot help me with this task'
|
|
82
|
+
* });
|
|
83
|
+
*
|
|
84
|
+
* // Later, track completion
|
|
85
|
+
* tracker.logCompletion({
|
|
86
|
+
* requestId,
|
|
87
|
+
* success: true,
|
|
88
|
+
* provider: 'anthropic',
|
|
89
|
+
* toolsCalled: ['list_activities', 'create_activity'],
|
|
90
|
+
* duration: 2500
|
|
91
|
+
* });
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
class AgentTracker {
|
|
95
|
+
logger;
|
|
96
|
+
logFilePath;
|
|
97
|
+
maxEntries;
|
|
98
|
+
isProduction;
|
|
99
|
+
isTrackingEnabled;
|
|
100
|
+
/**
|
|
101
|
+
* Creates a new Agent Activity Tracker instance
|
|
102
|
+
*
|
|
103
|
+
* @param logger - Optional logger instance for operational logging. If not provided, creates a new logger
|
|
104
|
+
* @param logDir - Directory where agent activity logs will be stored (default: 'logs')
|
|
105
|
+
* @param maxEntries - Maximum number of log entries before rotation (default: 1000)
|
|
106
|
+
*/
|
|
107
|
+
constructor(logger, logDir = 'logs', maxEntries = 1000) {
|
|
108
|
+
this.logger = logger || (0, logger_1.createLogger)({ component: 'agent-tracker' });
|
|
109
|
+
this.maxEntries = maxEntries;
|
|
110
|
+
this.isProduction = process.env.NODE_ENV === 'production';
|
|
111
|
+
// Only enable JSON file tracking in development or when explicitly enabled
|
|
112
|
+
this.isTrackingEnabled = !this.isProduction || process.env.AGENT_TRACKING_ENABLED === 'true';
|
|
113
|
+
if (this.isTrackingEnabled) {
|
|
114
|
+
this.logFilePath = path.join(logDir, 'agent-activity.json');
|
|
115
|
+
this.initializeLogFile();
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
this.logger.info('Agent activity tracking disabled in production environment');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Initializes the agent activity log file if it doesn't exist
|
|
123
|
+
* Creates the necessary directory structure and empty log file
|
|
124
|
+
* Only runs in development mode or when explicitly enabled
|
|
125
|
+
*
|
|
126
|
+
* @private
|
|
127
|
+
*/
|
|
128
|
+
initializeLogFile() {
|
|
129
|
+
if (!this.isTrackingEnabled || !this.logFilePath) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
// Ensure log directory exists
|
|
134
|
+
const logDir = path.dirname(this.logFilePath);
|
|
135
|
+
if (!fs.existsSync(logDir)) {
|
|
136
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
137
|
+
}
|
|
138
|
+
if (!fs.existsSync(this.logFilePath)) {
|
|
139
|
+
const initialLog = { entries: [] };
|
|
140
|
+
fs.writeFileSync(this.logFilePath, JSON.stringify(initialLog, null, 2));
|
|
141
|
+
this.logger.info('Agent activity tracker initialized', {
|
|
142
|
+
logFile: this.logFilePath,
|
|
143
|
+
maxEntries: this.maxEntries
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
this.logger.error('Failed to initialize agent activity log file', error, {
|
|
149
|
+
logFilePath: this.logFilePath
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Reads the current agent activity log from disk
|
|
155
|
+
* Returns empty log in production mode or when tracking is disabled
|
|
156
|
+
*
|
|
157
|
+
* @private
|
|
158
|
+
* @returns The current log data, or empty log if file cannot be read or tracking is disabled
|
|
159
|
+
*/
|
|
160
|
+
readLogFile() {
|
|
161
|
+
if (!this.isTrackingEnabled || !this.logFilePath) {
|
|
162
|
+
return { entries: [] };
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
const data = fs.readFileSync(this.logFilePath, 'utf8');
|
|
166
|
+
return JSON.parse(data);
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
this.logger.error('Failed to read agent activity log file', error, {
|
|
170
|
+
logFilePath: this.logFilePath
|
|
171
|
+
});
|
|
172
|
+
return { entries: [] };
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Writes the agent activity log to disk with automatic rotation
|
|
177
|
+
* Skips file writing in production mode unless explicitly enabled
|
|
178
|
+
*
|
|
179
|
+
* @private
|
|
180
|
+
* @param log - The log data to write
|
|
181
|
+
*/
|
|
182
|
+
writeLogFile(log) {
|
|
183
|
+
if (!this.isTrackingEnabled || !this.logFilePath) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
try {
|
|
187
|
+
// Rotate entries if we exceed max limit
|
|
188
|
+
if (log.entries.length > this.maxEntries) {
|
|
189
|
+
const removedCount = log.entries.length - this.maxEntries;
|
|
190
|
+
log.entries = log.entries.slice(-this.maxEntries);
|
|
191
|
+
this.logger.debug('Agent activity log rotated', {
|
|
192
|
+
removedEntries: removedCount,
|
|
193
|
+
remainingEntries: log.entries.length
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
fs.writeFileSync(this.logFilePath, JSON.stringify(log, null, 2));
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
this.logger.error('Failed to write agent activity log file', error, {
|
|
200
|
+
logFilePath: this.logFilePath,
|
|
201
|
+
entriesCount: log.entries.length
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Generates a unique request identifier for correlation
|
|
207
|
+
*
|
|
208
|
+
* @private
|
|
209
|
+
* @returns A unique request ID string
|
|
210
|
+
*/
|
|
211
|
+
generateRequestId() {
|
|
212
|
+
return `req-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Truncates text to a specified maximum length for preview purposes
|
|
216
|
+
*
|
|
217
|
+
* @private
|
|
218
|
+
* @param text - The text to truncate
|
|
219
|
+
* @param maxLength - Maximum length before truncation (default: 50)
|
|
220
|
+
* @returns Truncated text with ellipsis if needed
|
|
221
|
+
*/
|
|
222
|
+
truncateText(text, maxLength = 50) {
|
|
223
|
+
if (text.length <= maxLength)
|
|
224
|
+
return text;
|
|
225
|
+
return text.substring(0, maxLength) + '...';
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Logs when an AI agent is triggered to respond to a user message
|
|
229
|
+
*
|
|
230
|
+
* Creates a correlation ID that links trigger events to completion events,
|
|
231
|
+
* enabling end-to-end conversation flow analysis and performance tracking.
|
|
232
|
+
*
|
|
233
|
+
* @param params - Trigger event details
|
|
234
|
+
* @param params.triggerType - How the agent was activated ('mention' | 'direct')
|
|
235
|
+
* @param params.discussionId - Unique identifier for the conversation thread
|
|
236
|
+
* @param params.userId - User who triggered the agent
|
|
237
|
+
* @param params.userName - Display name of the triggering user
|
|
238
|
+
* @param params.botId - Unique identifier of the responding agent
|
|
239
|
+
* @param params.messageContent - Original message content that triggered the agent
|
|
240
|
+
* @param params.workspaceId - Optional workspace context
|
|
241
|
+
*
|
|
242
|
+
* @returns {string} requestId - Unique correlation ID for linking with completion events
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```typescript
|
|
246
|
+
* const requestId = agentTracker.logTrigger({
|
|
247
|
+
* triggerType: 'mention',
|
|
248
|
+
* discussionId: 'disc_123',
|
|
249
|
+
* userId: 'user_456',
|
|
250
|
+
* userName: 'John Doe',
|
|
251
|
+
* botId: 'bot_789',
|
|
252
|
+
* messageContent: '@bot help me with this task'
|
|
253
|
+
* });
|
|
254
|
+
* ```
|
|
255
|
+
*/
|
|
256
|
+
logTrigger(params) {
|
|
257
|
+
const requestId = this.generateRequestId();
|
|
258
|
+
try {
|
|
259
|
+
const log = this.readLogFile();
|
|
260
|
+
const triggerEntry = {
|
|
261
|
+
type: 'trigger',
|
|
262
|
+
requestId,
|
|
263
|
+
timestamp: new Date().toISOString(),
|
|
264
|
+
trigger: {
|
|
265
|
+
type: params.triggerType,
|
|
266
|
+
discussionId: params.discussionId,
|
|
267
|
+
userId: params.userId,
|
|
268
|
+
userName: params.userName,
|
|
269
|
+
botId: params.botId,
|
|
270
|
+
messagePreview: this.truncateText(params.messageContent),
|
|
271
|
+
workspaceId: params.workspaceId,
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
log.entries.push(triggerEntry);
|
|
275
|
+
this.writeLogFile(log);
|
|
276
|
+
this.logger.info('Agent trigger logged', {
|
|
277
|
+
requestId,
|
|
278
|
+
triggerType: params.triggerType,
|
|
279
|
+
botId: params.botId,
|
|
280
|
+
userId: params.userId,
|
|
281
|
+
discussionId: params.discussionId
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
this.logger.error('Failed to log agent trigger event', error, {
|
|
286
|
+
requestId,
|
|
287
|
+
triggerType: params.triggerType,
|
|
288
|
+
botId: params.botId
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
return requestId;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Logs when an AI agent completes processing a user request
|
|
295
|
+
*
|
|
296
|
+
* Records the final outcome, performance metrics, and tools used during processing.
|
|
297
|
+
* Must be correlated with a trigger event using the same requestId for complete
|
|
298
|
+
* conversation flow analysis.
|
|
299
|
+
*
|
|
300
|
+
* @param params - Completion event details
|
|
301
|
+
* @param params.requestId - Correlation ID from the original trigger event
|
|
302
|
+
* @param params.success - Whether the agent completed successfully
|
|
303
|
+
* @param params.provider - LLM provider used (anthropic, openai, etc)
|
|
304
|
+
* @param params.toolsCalled - Array of tool names that were invoked
|
|
305
|
+
* @param params.responseContent - The agent's response content
|
|
306
|
+
* @param params.duration - Total processing time in milliseconds
|
|
307
|
+
* @param params.error - Error message if processing failed
|
|
308
|
+
*
|
|
309
|
+
* @example
|
|
310
|
+
* ```typescript
|
|
311
|
+
* agentTracker.logCompletion({
|
|
312
|
+
* requestId: 'req-123-abc',
|
|
313
|
+
* success: true,
|
|
314
|
+
* provider: 'anthropic',
|
|
315
|
+
* toolsCalled: ['list_activities', 'create_activity'],
|
|
316
|
+
* responseContent: 'I created the task for you',
|
|
317
|
+
* duration: 2500
|
|
318
|
+
* });
|
|
319
|
+
* ```
|
|
320
|
+
*/
|
|
321
|
+
logCompletion(params) {
|
|
322
|
+
try {
|
|
323
|
+
const log = this.readLogFile();
|
|
324
|
+
const completionEntry = {
|
|
325
|
+
type: 'completion',
|
|
326
|
+
requestId: params.requestId,
|
|
327
|
+
timestamp: new Date().toISOString(),
|
|
328
|
+
completion: {
|
|
329
|
+
success: params.success,
|
|
330
|
+
provider: params.provider,
|
|
331
|
+
toolsCalled: params.toolsCalled || [],
|
|
332
|
+
responsePreview: params.responseContent ? this.truncateText(params.responseContent) : undefined,
|
|
333
|
+
duration: params.duration,
|
|
334
|
+
error: params.error,
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
log.entries.push(completionEntry);
|
|
338
|
+
this.writeLogFile(log);
|
|
339
|
+
const status = params.success ? 'SUCCESS' : 'FAILED';
|
|
340
|
+
this.logger.info('Agent completion logged', {
|
|
341
|
+
requestId: params.requestId,
|
|
342
|
+
success: params.success,
|
|
343
|
+
provider: params.provider,
|
|
344
|
+
toolsCount: params.toolsCalled?.length || 0,
|
|
345
|
+
duration: params.duration,
|
|
346
|
+
status
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
catch (error) {
|
|
350
|
+
this.logger.error('Failed to log agent completion event', error, {
|
|
351
|
+
requestId: params.requestId,
|
|
352
|
+
success: params.success
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Logs individual tool calls made during agent processing
|
|
358
|
+
*
|
|
359
|
+
* Provides granular visibility into agent decision-making by recording each
|
|
360
|
+
* tool invocation with full request/response data. Essential for debugging
|
|
361
|
+
* agent behavior and optimizing tool usage patterns.
|
|
362
|
+
*
|
|
363
|
+
* @param params - Tool call event details
|
|
364
|
+
* @param params.requestId - Optional correlation ID (generates new one if not provided)
|
|
365
|
+
* @param params.toolName - Name of the tool/function that was called
|
|
366
|
+
* @param params.provider - Provider handling the tool execution
|
|
367
|
+
* @param params.request - Input data sent to the tool
|
|
368
|
+
* @param params.request.arguments - Arguments passed to the tool
|
|
369
|
+
* @param params.request.endpoint - API endpoint if applicable
|
|
370
|
+
* @param params.request.method - HTTP method if applicable
|
|
371
|
+
* @param params.response - Output data received from the tool
|
|
372
|
+
* @param params.response.success - Whether the tool call succeeded
|
|
373
|
+
* @param params.response.data - Response data if successful
|
|
374
|
+
* @param params.response.error - Error details if failed
|
|
375
|
+
* @param params.duration - Tool execution time in milliseconds
|
|
376
|
+
* @param params.botId - Agent that made the tool call
|
|
377
|
+
* @param params.discussionId - Conversation context
|
|
378
|
+
* @param params.workspaceId - Workspace context
|
|
379
|
+
*
|
|
380
|
+
* @returns {string} requestId - The correlation ID used for this tool call
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* ```typescript
|
|
384
|
+
* agentTracker.logToolCall({
|
|
385
|
+
* requestId: 'req-123-abc',
|
|
386
|
+
* toolName: 'list_activities',
|
|
387
|
+
* provider: 'hailer-mcp',
|
|
388
|
+
* request: {
|
|
389
|
+
* arguments: { workflowId: 'wf_456', limit: 10 }
|
|
390
|
+
* },
|
|
391
|
+
* response: {
|
|
392
|
+
* success: true,
|
|
393
|
+
* data: { activities: [...] }
|
|
394
|
+
* },
|
|
395
|
+
* duration: 850,
|
|
396
|
+
* botId: 'bot_789'
|
|
397
|
+
* });
|
|
398
|
+
* ```
|
|
399
|
+
*/
|
|
400
|
+
logToolCall(params) {
|
|
401
|
+
const requestId = params.requestId || this.generateRequestId();
|
|
402
|
+
try {
|
|
403
|
+
const log = this.readLogFile();
|
|
404
|
+
const toolCallEntry = {
|
|
405
|
+
type: 'tool_call',
|
|
406
|
+
requestId,
|
|
407
|
+
timestamp: new Date().toISOString(),
|
|
408
|
+
toolCall: {
|
|
409
|
+
toolName: params.toolName,
|
|
410
|
+
provider: params.provider,
|
|
411
|
+
request: params.request,
|
|
412
|
+
response: params.response,
|
|
413
|
+
duration: params.duration,
|
|
414
|
+
botId: params.botId,
|
|
415
|
+
discussionId: params.discussionId,
|
|
416
|
+
workspaceId: params.workspaceId,
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
log.entries.push(toolCallEntry);
|
|
420
|
+
this.writeLogFile(log);
|
|
421
|
+
const status = params.response.success ? 'SUCCESS' : 'FAILED';
|
|
422
|
+
this.logger.info('Agent tool call logged', {
|
|
423
|
+
requestId,
|
|
424
|
+
toolName: params.toolName,
|
|
425
|
+
provider: params.provider,
|
|
426
|
+
success: params.response.success,
|
|
427
|
+
duration: params.duration,
|
|
428
|
+
status
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
this.logger.error('Failed to log agent tool call', error, {
|
|
433
|
+
requestId,
|
|
434
|
+
toolName: params.toolName,
|
|
435
|
+
provider: params.provider
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
return requestId;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Logs system-level events related to agent operations
|
|
442
|
+
*
|
|
443
|
+
* Captures infrastructure events such as agent initialization, shutdown,
|
|
444
|
+
* configuration changes, and other system-level activities that affect
|
|
445
|
+
* agent behavior but aren't directly part of user conversations.
|
|
446
|
+
*
|
|
447
|
+
* @param params - System event details
|
|
448
|
+
* @param params.success - Whether the system operation succeeded
|
|
449
|
+
* @param params.message - Human-readable description of the event
|
|
450
|
+
* @param params.details - Additional technical details about the event
|
|
451
|
+
* @param params.error - Error information if the operation failed
|
|
452
|
+
*
|
|
453
|
+
* @example
|
|
454
|
+
* ```typescript
|
|
455
|
+
* agentTracker.logSystem({
|
|
456
|
+
* success: true,
|
|
457
|
+
* message: 'Agent client initialized',
|
|
458
|
+
* details: 'Connected to MCP server with 5 tools available'
|
|
459
|
+
* });
|
|
460
|
+
* ```
|
|
461
|
+
*/
|
|
462
|
+
logSystem(params) {
|
|
463
|
+
const requestId = this.generateRequestId();
|
|
464
|
+
try {
|
|
465
|
+
const log = this.readLogFile();
|
|
466
|
+
const systemEntry = {
|
|
467
|
+
type: 'system',
|
|
468
|
+
requestId,
|
|
469
|
+
timestamp: new Date().toISOString(),
|
|
470
|
+
system: {
|
|
471
|
+
success: params.success,
|
|
472
|
+
message: params.message,
|
|
473
|
+
details: params.details,
|
|
474
|
+
error: params.error,
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
log.entries.push(systemEntry);
|
|
478
|
+
this.writeLogFile(log);
|
|
479
|
+
const status = params.success ? 'SUCCESS' : 'FAILED';
|
|
480
|
+
this.logger.info('Agent system event logged', {
|
|
481
|
+
requestId,
|
|
482
|
+
success: params.success,
|
|
483
|
+
message: params.message,
|
|
484
|
+
status
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
catch (error) {
|
|
488
|
+
this.logger.error('Failed to log agent system event', error, {
|
|
489
|
+
requestId,
|
|
490
|
+
message: params.message
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Retrieves recent agent activity entries for monitoring and debugging
|
|
496
|
+
*
|
|
497
|
+
* Returns the most recent log entries in chronological order (newest last).
|
|
498
|
+
* Useful for real-time monitoring dashboards and recent activity analysis.
|
|
499
|
+
*
|
|
500
|
+
* @param limit - Maximum number of entries to return (default: 10)
|
|
501
|
+
* @returns Array of recent agent log entries
|
|
502
|
+
*
|
|
503
|
+
* @example
|
|
504
|
+
* ```typescript
|
|
505
|
+
* const recentActivity = agentTracker.getRecentActivity(20);
|
|
506
|
+
* console.log(`Found ${recentActivity.length} recent events`);
|
|
507
|
+
* ```
|
|
508
|
+
*/
|
|
509
|
+
getRecentActivity(limit = 10) {
|
|
510
|
+
try {
|
|
511
|
+
const log = this.readLogFile();
|
|
512
|
+
return log.entries.slice(-limit);
|
|
513
|
+
}
|
|
514
|
+
catch (error) {
|
|
515
|
+
this.logger.error('Failed to get recent agent activity', error, { limit });
|
|
516
|
+
return [];
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Retrieves recent tool call logs for analysis and debugging
|
|
521
|
+
*
|
|
522
|
+
* Filters the log entries to return only tool call events, providing
|
|
523
|
+
* focused visibility into agent decision-making and API usage patterns.
|
|
524
|
+
*
|
|
525
|
+
* @param limit - Maximum number of tool call entries to return (default: 50)
|
|
526
|
+
* @returns Array of recent tool call log entries
|
|
527
|
+
*
|
|
528
|
+
* @example
|
|
529
|
+
* ```typescript
|
|
530
|
+
* const recentToolCalls = agentTracker.getRecentToolCalls(100);
|
|
531
|
+
* const failedCalls = recentToolCalls.filter(call => !call.toolCall.response.success);
|
|
532
|
+
* ```
|
|
533
|
+
*/
|
|
534
|
+
getRecentToolCalls(limit = 50) {
|
|
535
|
+
try {
|
|
536
|
+
const log = this.readLogFile();
|
|
537
|
+
const toolCalls = log.entries.filter(e => e.type === 'tool_call');
|
|
538
|
+
return toolCalls.slice(-limit);
|
|
539
|
+
}
|
|
540
|
+
catch (error) {
|
|
541
|
+
this.logger.error('Failed to get recent agent tool calls', error, { limit });
|
|
542
|
+
return [];
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Generates comprehensive statistics about agent activity and performance
|
|
547
|
+
*
|
|
548
|
+
* Analyzes all logged events to provide business intelligence metrics including
|
|
549
|
+
* success rates, performance trends, usage patterns, and identifying top
|
|
550
|
+
* performers. Essential for monitoring agent effectiveness and optimization.
|
|
551
|
+
*
|
|
552
|
+
* @returns Comprehensive statistics object with performance and usage metrics
|
|
553
|
+
*
|
|
554
|
+
* @example
|
|
555
|
+
* ```typescript
|
|
556
|
+
* const stats = agentTracker.getStats();
|
|
557
|
+
* console.log(`Success rate: ${stats.successRate}%`);
|
|
558
|
+
* console.log(`Average response time: ${stats.averageResponseTime}ms`);
|
|
559
|
+
* console.log(`Most active agent: ${stats.mostActiveBot}`);
|
|
560
|
+
* console.log(`Most used tool: ${stats.mostUsedTool}`);
|
|
561
|
+
* ```
|
|
562
|
+
*/
|
|
563
|
+
getStats() {
|
|
564
|
+
try {
|
|
565
|
+
const log = this.readLogFile();
|
|
566
|
+
const triggers = log.entries.filter(e => e.type === 'trigger');
|
|
567
|
+
const completions = log.entries.filter(e => e.type === 'completion');
|
|
568
|
+
const toolCalls = log.entries.filter(e => e.type === 'tool_call');
|
|
569
|
+
const systemEvents = log.entries.filter(e => e.type === 'system');
|
|
570
|
+
const successfulCompletions = completions.filter(c => c.completion.success);
|
|
571
|
+
const successRate = completions.length > 0 ? (successfulCompletions.length / completions.length) * 100 : 0;
|
|
572
|
+
const averageResponseTime = completions.length > 0
|
|
573
|
+
? completions.reduce((sum, c) => sum + c.completion.duration, 0) / completions.length
|
|
574
|
+
: 0;
|
|
575
|
+
// Find most active bot
|
|
576
|
+
const botCounts = new Map();
|
|
577
|
+
triggers.forEach(t => {
|
|
578
|
+
const count = botCounts.get(t.trigger.botId) || 0;
|
|
579
|
+
botCounts.set(t.trigger.botId, count + 1);
|
|
580
|
+
});
|
|
581
|
+
let mostActiveBot = null;
|
|
582
|
+
let maxCount = 0;
|
|
583
|
+
for (const [botId, count] of botCounts) {
|
|
584
|
+
if (count > maxCount) {
|
|
585
|
+
maxCount = count;
|
|
586
|
+
mostActiveBot = botId;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
// Find most used tool
|
|
590
|
+
const toolCounts = new Map();
|
|
591
|
+
toolCalls.forEach(t => {
|
|
592
|
+
const count = toolCounts.get(t.toolCall.toolName) || 0;
|
|
593
|
+
toolCounts.set(t.toolCall.toolName, count + 1);
|
|
594
|
+
});
|
|
595
|
+
let mostUsedTool = null;
|
|
596
|
+
let maxToolCount = 0;
|
|
597
|
+
for (const [toolName, count] of toolCounts) {
|
|
598
|
+
if (count > maxToolCount) {
|
|
599
|
+
maxToolCount = count;
|
|
600
|
+
mostUsedTool = toolName;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
const stats = {
|
|
604
|
+
totalTriggers: triggers.length,
|
|
605
|
+
totalCompletions: completions.length,
|
|
606
|
+
totalToolCalls: toolCalls.length,
|
|
607
|
+
successRate: Math.round(successRate * 100) / 100,
|
|
608
|
+
averageResponseTime: Math.round(averageResponseTime),
|
|
609
|
+
mostActiveBot,
|
|
610
|
+
systemEvents: systemEvents.length,
|
|
611
|
+
mostUsedTool,
|
|
612
|
+
};
|
|
613
|
+
this.logger.debug('Agent statistics calculated', stats);
|
|
614
|
+
return stats;
|
|
615
|
+
}
|
|
616
|
+
catch (error) {
|
|
617
|
+
this.logger.error('Failed to calculate agent statistics', error);
|
|
618
|
+
return {
|
|
619
|
+
totalTriggers: 0,
|
|
620
|
+
totalCompletions: 0,
|
|
621
|
+
totalToolCalls: 0,
|
|
622
|
+
successRate: 0,
|
|
623
|
+
averageResponseTime: 0,
|
|
624
|
+
mostActiveBot: null,
|
|
625
|
+
systemEvents: 0,
|
|
626
|
+
mostUsedTool: null,
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
exports.AgentTracker = AgentTracker;
|
|
632
|
+
/**
|
|
633
|
+
* Factory function to create a new AgentTracker instance
|
|
634
|
+
*
|
|
635
|
+
* Provides a clean way to instantiate agent trackers with dependency injection.
|
|
636
|
+
* Follows modern patterns and makes testing easier by allowing logger mocking.
|
|
637
|
+
*
|
|
638
|
+
* @param logger - Optional logger instance for operational logging
|
|
639
|
+
* @param logDir - Directory where agent activity logs will be stored
|
|
640
|
+
* @param maxEntries - Maximum number of log entries before rotation
|
|
641
|
+
* @returns A new AgentTracker instance
|
|
642
|
+
*
|
|
643
|
+
* @example
|
|
644
|
+
* ```typescript
|
|
645
|
+
* // Basic usage
|
|
646
|
+
* const agentTracker = createAgentTracker();
|
|
647
|
+
*
|
|
648
|
+
* // With custom logger
|
|
649
|
+
* const logger = createLogger({ component: 'my-service' });
|
|
650
|
+
* const agentTracker = createAgentTracker(logger);
|
|
651
|
+
*
|
|
652
|
+
* // With custom configuration
|
|
653
|
+
* const agentTracker = createAgentTracker(logger, '/var/log/agents', 5000);
|
|
654
|
+
* ```
|
|
655
|
+
*/
|
|
656
|
+
function createAgentTracker(logger, logDir, maxEntries) {
|
|
657
|
+
return new AgentTracker(logger, logDir, maxEntries);
|
|
658
|
+
}
|
|
659
|
+
//# sourceMappingURL=agent-tracker.js.map
|