@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
package/dist/config.js
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Universal Application Configuration
|
|
4
|
+
*
|
|
5
|
+
* Single source of truth that replaces all scattered config files:
|
|
6
|
+
* - lib/env.ts - Environment variable loading
|
|
7
|
+
* - mcp/config.ts - getClientConfig() function
|
|
8
|
+
* - client/config.ts - Client configuration creation
|
|
9
|
+
* - mcp/mcp-config.ts - MCP context optimization settings
|
|
10
|
+
*
|
|
11
|
+
* Key Features:
|
|
12
|
+
* - Map-based CLIENT_CONFIGS for O(1) API key lookups
|
|
13
|
+
* - Preserves existing excellent connection architecture
|
|
14
|
+
* - Comprehensive Zod validation with clear error messages
|
|
15
|
+
* - Development defaults for seamless local setup
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.ApplicationConfig = exports.environment = void 0;
|
|
19
|
+
exports.createApplicationConfig = createApplicationConfig;
|
|
20
|
+
const zod_1 = require("zod");
|
|
21
|
+
const dotenv_1 = require("dotenv");
|
|
22
|
+
// Load environment variables
|
|
23
|
+
(0, dotenv_1.config)({ path: '.env.local' });
|
|
24
|
+
// ================================================================================
|
|
25
|
+
// ENVIRONMENT VALIDATION
|
|
26
|
+
// ================================================================================
|
|
27
|
+
/**
|
|
28
|
+
* Hailer account configuration
|
|
29
|
+
*/
|
|
30
|
+
const hailerAccountSchema = zod_1.z.object({
|
|
31
|
+
email: zod_1.z.string().email(),
|
|
32
|
+
password: zod_1.z.string().min(1),
|
|
33
|
+
apiBaseUrl: zod_1.z.string().url().default('https://api.hailer.com'),
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* Transform CLIENT_CONFIGS to efficient Map format
|
|
37
|
+
* Supports both legacy array and new object formats
|
|
38
|
+
*/
|
|
39
|
+
const clientConfigsSchema = zod_1.z.string()
|
|
40
|
+
.transform((value, ctx) => {
|
|
41
|
+
try {
|
|
42
|
+
const parsed = JSON.parse(value);
|
|
43
|
+
// Convert legacy array format: [{ email, password, mcpServerApiKey, apiBaseUrl }]
|
|
44
|
+
// to new map format: { "api-key": { email, password, apiBaseUrl } }
|
|
45
|
+
if (Array.isArray(parsed)) {
|
|
46
|
+
const configMap = {};
|
|
47
|
+
for (const item of parsed) {
|
|
48
|
+
if (item.mcpServerApiKey) {
|
|
49
|
+
const { mcpServerApiKey, ...accountData } = item;
|
|
50
|
+
configMap[mcpServerApiKey] = accountData;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return configMap;
|
|
54
|
+
}
|
|
55
|
+
return parsed;
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
ctx.addIssue({
|
|
59
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
60
|
+
message: `Invalid CLIENT_CONFIGS JSON: ${error.message}`,
|
|
61
|
+
});
|
|
62
|
+
return zod_1.z.NEVER;
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
.pipe(zod_1.z.record(zod_1.z.string(), hailerAccountSchema));
|
|
66
|
+
/**
|
|
67
|
+
* JSON array helper
|
|
68
|
+
*/
|
|
69
|
+
const jsonArraySchema = (itemSchema) => zod_1.z.string()
|
|
70
|
+
.default('[]')
|
|
71
|
+
.transform((value, ctx) => {
|
|
72
|
+
try {
|
|
73
|
+
return zod_1.z.array(itemSchema).parse(JSON.parse(value));
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
ctx.addIssue({
|
|
77
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
78
|
+
message: `Invalid JSON array: ${error.message}`,
|
|
79
|
+
});
|
|
80
|
+
return zod_1.z.NEVER;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
/**
|
|
84
|
+
* Complete environment schema
|
|
85
|
+
*/
|
|
86
|
+
const environmentSchema = zod_1.z.object({
|
|
87
|
+
// Core
|
|
88
|
+
NODE_ENV: zod_1.z.enum(['development', 'production', 'test']).default('development'),
|
|
89
|
+
LOG_LEVEL: zod_1.z.enum(['debug', 'info', 'warn', 'error']).default('info'),
|
|
90
|
+
// Service control
|
|
91
|
+
DISABLE_MCP_SERVER: zod_1.z.string().transform(v => v === 'true').default('false'),
|
|
92
|
+
MCP_CLIENT_ENABLED: zod_1.z.string().transform(v => v === 'true').default('false'),
|
|
93
|
+
ENABLE_NUCLEAR_TOOLS: zod_1.z.string().transform(v => v === 'true').default('false'),
|
|
94
|
+
// Server
|
|
95
|
+
PORT: zod_1.z.string().transform(v => parseInt(v) || 3030).default('3030'),
|
|
96
|
+
CORS_ORIGINS: jsonArraySchema(zod_1.z.string().url()).default('[]'),
|
|
97
|
+
// Hailer integration - now as efficient Map
|
|
98
|
+
CLIENT_CONFIGS: clientConfigsSchema,
|
|
99
|
+
// Workspace configuration path (for reading workspace configs from external projects)
|
|
100
|
+
WORKSPACE_CONFIG_PATH: zod_1.z.string().optional(),
|
|
101
|
+
// Development apps path (for scaffolding Hailer apps outside the repo)
|
|
102
|
+
DEV_APPS_PATH: zod_1.z.string().optional(),
|
|
103
|
+
// LLM providers
|
|
104
|
+
OPENAI_API_KEY: zod_1.z.string().min(1).optional(),
|
|
105
|
+
ANTHROPIC_API_KEY: zod_1.z.string().min(1).optional(),
|
|
106
|
+
// MCP client settings
|
|
107
|
+
MCP_SERVER_URL: zod_1.z.string().url().default('http://localhost:3030/api/mcp'),
|
|
108
|
+
MCP_CLIENT_API_KEY: zod_1.z.string(),
|
|
109
|
+
MCP_CLIENT_AGENT_IDS: jsonArraySchema(zod_1.z.string()).default('[]'),
|
|
110
|
+
// Bot features
|
|
111
|
+
TOKEN_USAGE_BOT_ENABLED: zod_1.z.string().transform(v => v !== 'false').default('true'),
|
|
112
|
+
AGENT_ACTIVITY_BOT_ENABLED: zod_1.z.string().transform(v => v !== 'false').default('true'),
|
|
113
|
+
ADAPTIVE_DOCUMENTATION_BOT_ENABLED: zod_1.z.string().transform(v => v === 'true').default('false'),
|
|
114
|
+
ADAPTIVE_AUTO_UPDATE: zod_1.z.string().transform(v => v === 'true').default('false'),
|
|
115
|
+
ADAPTIVE_UPDATE_INTERVAL: zod_1.z.string().transform(v => parseInt(v) || 60000).default('60000'),
|
|
116
|
+
ADAPTIVE_MIN_ERROR_COUNT: zod_1.z.string().transform(v => parseInt(v) || 3).default('3'),
|
|
117
|
+
ADAPTIVE_SKILL_GENERATION: zod_1.z.string().transform(v => v === 'true').default('false'), // Chat bot can't use skills
|
|
118
|
+
// MCP context optimization (replaces mcp-config.ts)
|
|
119
|
+
MCP_EXCLUDE_TRANSLATIONS: zod_1.z.string().transform(v => v !== 'false').default('true'),
|
|
120
|
+
MCP_COMPACT_DATA: zod_1.z.string().transform(v => v !== 'false').default('true'),
|
|
121
|
+
MCP_INCLUDE_WORKSPACE_NAMES: zod_1.z.string().transform(v => v !== 'false').default('true'),
|
|
122
|
+
// Context management & token limits
|
|
123
|
+
CONTEXT_SAFETY_MARGIN_PERCENT: zod_1.z.string().transform(v => parseInt(v) || 25).default('25'),
|
|
124
|
+
CONTEXT_ENABLE_AUTO_SUMMARIZATION: zod_1.z.string().transform(v => v !== 'false').default('true'),
|
|
125
|
+
CONTEXT_MAX_SUMMARIZATION_CHUNKS: zod_1.z.string().transform(v => parseInt(v) || 10).default('10'),
|
|
126
|
+
});
|
|
127
|
+
/**
|
|
128
|
+
* Get process environment (no defaults - CLIENT_CONFIGS is required)
|
|
129
|
+
*/
|
|
130
|
+
function getProcessEnv() {
|
|
131
|
+
return { ...process.env };
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Validated environment - single source of truth
|
|
135
|
+
*/
|
|
136
|
+
exports.environment = environmentSchema.parse(getProcessEnv());
|
|
137
|
+
// ================================================================================
|
|
138
|
+
// UNIVERSAL APPLICATION CONFIG
|
|
139
|
+
// ================================================================================
|
|
140
|
+
/**
|
|
141
|
+
* Universal Application Configuration
|
|
142
|
+
*
|
|
143
|
+
* Single class that provides all configuration for the entire application.
|
|
144
|
+
* Replaces all scattered config files with one clean interface.
|
|
145
|
+
*/
|
|
146
|
+
class ApplicationConfig {
|
|
147
|
+
constructor() {
|
|
148
|
+
// Simple constructor - configuration is determined by environment variables
|
|
149
|
+
}
|
|
150
|
+
// ===== CORE CONFIGURATION =====
|
|
151
|
+
get server() {
|
|
152
|
+
return {
|
|
153
|
+
port: exports.environment.PORT,
|
|
154
|
+
corsOrigins: exports.environment.CORS_ORIGINS,
|
|
155
|
+
enableMcpServer: !exports.environment.DISABLE_MCP_SERVER,
|
|
156
|
+
enableClient: exports.environment.MCP_CLIENT_ENABLED,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Efficient Map-based Hailer accounts (replaces CLIENT_CONFIGS array)
|
|
161
|
+
*/
|
|
162
|
+
get hailerAccounts() {
|
|
163
|
+
return exports.environment.CLIENT_CONFIGS;
|
|
164
|
+
}
|
|
165
|
+
get llmProviders() {
|
|
166
|
+
const providers = [];
|
|
167
|
+
if (exports.environment.OPENAI_API_KEY) {
|
|
168
|
+
providers.push({
|
|
169
|
+
name: 'openai-gpt4o',
|
|
170
|
+
type: 'openai',
|
|
171
|
+
apiKey: exports.environment.OPENAI_API_KEY,
|
|
172
|
+
model: 'gpt-4o',
|
|
173
|
+
enabled: true,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
if (exports.environment.ANTHROPIC_API_KEY) {
|
|
177
|
+
providers.push({
|
|
178
|
+
name: 'anthropic-claude',
|
|
179
|
+
type: 'anthropic',
|
|
180
|
+
apiKey: exports.environment.ANTHROPIC_API_KEY,
|
|
181
|
+
model: 'claude-3-5-haiku-20241022', // Haiku - faster, testing instruction following
|
|
182
|
+
enabled: true,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
return providers;
|
|
186
|
+
}
|
|
187
|
+
// ===== MCP CONFIGURATION (replaces mcp-config.ts) =====
|
|
188
|
+
/**
|
|
189
|
+
* MCP context optimization settings
|
|
190
|
+
*/
|
|
191
|
+
get mcpConfig() {
|
|
192
|
+
return {
|
|
193
|
+
excludeTranslations: exports.environment.MCP_EXCLUDE_TRANSLATIONS,
|
|
194
|
+
excludeSystemMessages: true, // Always enabled for cleaner responses
|
|
195
|
+
excludeEmptyFields: true, // Always enabled to reduce context
|
|
196
|
+
compactUserData: exports.environment.MCP_COMPACT_DATA,
|
|
197
|
+
includeWorkspaceNamesInTools: exports.environment.MCP_INCLUDE_WORKSPACE_NAMES,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Context management settings for token limits and summarization
|
|
202
|
+
*/
|
|
203
|
+
get contextConfig() {
|
|
204
|
+
return {
|
|
205
|
+
safetyMarginPercent: exports.environment.CONTEXT_SAFETY_MARGIN_PERCENT,
|
|
206
|
+
enableAutoSummarization: exports.environment.CONTEXT_ENABLE_AUTO_SUMMARIZATION,
|
|
207
|
+
maxSummarizationChunks: exports.environment.CONTEXT_MAX_SUMMARIZATION_CHUNKS,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Adaptive Documentation Bot configuration
|
|
212
|
+
*/
|
|
213
|
+
get adaptiveDocumentation() {
|
|
214
|
+
return {
|
|
215
|
+
enabled: exports.environment.ADAPTIVE_DOCUMENTATION_BOT_ENABLED,
|
|
216
|
+
autoUpdate: exports.environment.ADAPTIVE_AUTO_UPDATE,
|
|
217
|
+
updateInterval: exports.environment.ADAPTIVE_UPDATE_INTERVAL,
|
|
218
|
+
minErrorCount: exports.environment.ADAPTIVE_MIN_ERROR_COUNT,
|
|
219
|
+
skillGeneration: exports.environment.ADAPTIVE_SKILL_GENERATION,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
// ===== CLIENT CONFIGURATION (replaces client/config.ts) =====
|
|
223
|
+
/**
|
|
224
|
+
* Create MCP Client configuration (replaces createMcpClientConfig())
|
|
225
|
+
*/
|
|
226
|
+
get mcpClient() {
|
|
227
|
+
const accounts = this.hailerAccounts;
|
|
228
|
+
const providers = this.llmProviders;
|
|
229
|
+
if (Object.keys(accounts).length === 0) {
|
|
230
|
+
console.warn('No Hailer accounts configured - MCP Client will be disabled');
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
if (providers.length === 0) {
|
|
234
|
+
console.warn('No LLM providers configured - MCP Client will be disabled');
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
// Convert Map format to BotClientConfig array for MultiBotManager compatibility
|
|
238
|
+
const botConfigs = Object.entries(accounts).map(([apiKey, account]) => ({
|
|
239
|
+
email: account.email,
|
|
240
|
+
password: account.password,
|
|
241
|
+
apiBaseUrl: account.apiBaseUrl,
|
|
242
|
+
mcpServerApiKey: apiKey,
|
|
243
|
+
}));
|
|
244
|
+
return {
|
|
245
|
+
enabled: exports.environment.MCP_CLIENT_ENABLED,
|
|
246
|
+
mcpServerUrl: exports.environment.MCP_SERVER_URL,
|
|
247
|
+
mcpServerApiKey: exports.environment.MCP_CLIENT_API_KEY,
|
|
248
|
+
providers,
|
|
249
|
+
mcpAgentIds: exports.environment.MCP_CLIENT_AGENT_IDS,
|
|
250
|
+
botConfigs,
|
|
251
|
+
enableDirectMessages: true,
|
|
252
|
+
tokenUsageBotEnabled: exports.environment.TOKEN_USAGE_BOT_ENABLED,
|
|
253
|
+
agentActivityBotEnabled: exports.environment.AGENT_ACTIVITY_BOT_ENABLED,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
// ===== UTILITY METHODS =====
|
|
257
|
+
/**
|
|
258
|
+
* Find account by API key - O(1) lookup (replaces getClientConfig())
|
|
259
|
+
* This is the key efficiency improvement that eliminates array filtering
|
|
260
|
+
*/
|
|
261
|
+
getClientConfig(apiKey) {
|
|
262
|
+
if (!apiKey) {
|
|
263
|
+
throw new Error('API key is required');
|
|
264
|
+
}
|
|
265
|
+
const account = this.hailerAccounts[apiKey];
|
|
266
|
+
if (!account) {
|
|
267
|
+
throw new Error(`No client configuration found for API key: ${apiKey}`);
|
|
268
|
+
}
|
|
269
|
+
return account;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Alternative method with null return (safer)
|
|
273
|
+
*/
|
|
274
|
+
findAccountByApiKey(apiKey) {
|
|
275
|
+
return this.hailerAccounts[apiKey] || null;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Get enabled LLM providers only
|
|
279
|
+
*/
|
|
280
|
+
getEnabledLlmProviders() {
|
|
281
|
+
return this.llmProviders.filter(provider => provider.enabled);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
exports.ApplicationConfig = ApplicationConfig;
|
|
285
|
+
// ================================================================================
|
|
286
|
+
// FACTORY FUNCTIONS
|
|
287
|
+
// ================================================================================
|
|
288
|
+
/**
|
|
289
|
+
* Create application configuration
|
|
290
|
+
* Configuration is determined by environment variables (DISABLE_MCP_SERVER, MCP_CLIENT_ENABLED)
|
|
291
|
+
*/
|
|
292
|
+
function createApplicationConfig() {
|
|
293
|
+
return new ApplicationConfig();
|
|
294
|
+
}
|
|
295
|
+
// All types are already exported above - no need for duplicate exports
|
|
296
|
+
//# sourceMappingURL=config.js.map
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core class for Hailer MCP Server
|
|
3
|
+
* Pure orchestrator - manages application lifecycle and service coordination
|
|
4
|
+
* Separated from Express server implementation for better architecture
|
|
5
|
+
*/
|
|
6
|
+
import { Tool } from './mcp/tool-registry';
|
|
7
|
+
export declare class Core {
|
|
8
|
+
private logger;
|
|
9
|
+
private appConfig;
|
|
10
|
+
private toolRegistry;
|
|
11
|
+
private mcpServer?;
|
|
12
|
+
private mcpClient;
|
|
13
|
+
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Public API for external tool registration
|
|
16
|
+
* Tools are registered explicitly from app.ts
|
|
17
|
+
*/
|
|
18
|
+
addTool(tool: Tool): void;
|
|
19
|
+
start(): Promise<void>;
|
|
20
|
+
private startMCPServer;
|
|
21
|
+
private startMCPClient;
|
|
22
|
+
private initializeMcpClient;
|
|
23
|
+
stop(): Promise<void>;
|
|
24
|
+
setupGracefulShutdown(): void;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=core.d.ts.map
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Core class for Hailer MCP Server
|
|
4
|
+
* Pure orchestrator - manages application lifecycle and service coordination
|
|
5
|
+
* Separated from Express server implementation for better architecture
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.Core = void 0;
|
|
9
|
+
const logger_1 = require("./lib/logger");
|
|
10
|
+
const config_1 = require("./config");
|
|
11
|
+
const mcp_client_1 = require("./client/mcp-client");
|
|
12
|
+
const mcp_server_1 = require("./mcp-server");
|
|
13
|
+
const tool_registry_1 = require("./mcp/tool-registry");
|
|
14
|
+
class Core {
|
|
15
|
+
logger;
|
|
16
|
+
appConfig;
|
|
17
|
+
toolRegistry;
|
|
18
|
+
mcpServer;
|
|
19
|
+
mcpClient = null;
|
|
20
|
+
constructor() {
|
|
21
|
+
// Initialize logger first
|
|
22
|
+
this.logger = (0, logger_1.createLogger)({
|
|
23
|
+
component: 'core',
|
|
24
|
+
service: 'hailer-mcp-server'
|
|
25
|
+
});
|
|
26
|
+
// Create tool registry with nuclear tools control
|
|
27
|
+
this.toolRegistry = new tool_registry_1.ToolRegistry({
|
|
28
|
+
enableNuclearTools: config_1.environment.ENABLE_NUCLEAR_TOOLS
|
|
29
|
+
});
|
|
30
|
+
// Use unified application configuration
|
|
31
|
+
this.appConfig = (0, config_1.createApplicationConfig)();
|
|
32
|
+
this.logger.info('Core orchestrator initialized', {
|
|
33
|
+
nodeEnv: process.env.NODE_ENV,
|
|
34
|
+
enableMcpServer: this.appConfig.server.enableMcpServer,
|
|
35
|
+
enableClient: this.appConfig.server.enableClient,
|
|
36
|
+
enableNuclearTools: config_1.environment.ENABLE_NUCLEAR_TOOLS
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Public API for external tool registration
|
|
41
|
+
* Tools are registered explicitly from app.ts
|
|
42
|
+
*/
|
|
43
|
+
addTool(tool) {
|
|
44
|
+
this.toolRegistry.addTool(tool);
|
|
45
|
+
}
|
|
46
|
+
async start() {
|
|
47
|
+
this.logger.info('Starting Hailer MCP application');
|
|
48
|
+
try {
|
|
49
|
+
// Start services based on configuration
|
|
50
|
+
if (this.appConfig.server.enableClient) {
|
|
51
|
+
await this.startMCPClient();
|
|
52
|
+
}
|
|
53
|
+
if (this.appConfig.server.enableMcpServer) {
|
|
54
|
+
// Check if accounts are configured
|
|
55
|
+
const hasAccounts = Object.keys(this.appConfig.hailerAccounts).length > 0;
|
|
56
|
+
if (!hasAccounts) {
|
|
57
|
+
this.logger.warn('MCP Server enabled but no accounts configured in CLIENT_CONFIGS. Server will not start.');
|
|
58
|
+
this.logger.warn('Add at least one account to CLIENT_CONFIGS in .env.local to use the MCP Server.');
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
await this.startMCPServer();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
this.setupGracefulShutdown();
|
|
65
|
+
this.logger.info('All configured services started successfully');
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
this.logger.error('Failed to start application', error);
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async startMCPServer() {
|
|
73
|
+
// Server configuration is provided by unified config
|
|
74
|
+
this.logger.info('Starting MCP Server service');
|
|
75
|
+
this.mcpServer = new mcp_server_1.MCPServerService({
|
|
76
|
+
port: this.appConfig.server.port,
|
|
77
|
+
corsOrigins: this.appConfig.server.corsOrigins,
|
|
78
|
+
toolRegistry: this.toolRegistry // ← Dependency injection
|
|
79
|
+
});
|
|
80
|
+
await this.mcpServer.start();
|
|
81
|
+
this.logger.info('MCP Server service started');
|
|
82
|
+
}
|
|
83
|
+
async startMCPClient() {
|
|
84
|
+
this.logger.info('Starting MCP Client service');
|
|
85
|
+
try {
|
|
86
|
+
await this.initializeMcpClient();
|
|
87
|
+
this.logger.info('MCP Client service started');
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
this.logger.warn('MCP Client service failed to start - server will continue without client capabilities', {
|
|
91
|
+
error: error instanceof Error ? error.message : String(error)
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async initializeMcpClient() {
|
|
96
|
+
this.logger.info('Initializing MCP Client');
|
|
97
|
+
const clientConfig = this.appConfig.mcpClient;
|
|
98
|
+
if (!clientConfig) {
|
|
99
|
+
throw new Error('MCP Client configuration not available');
|
|
100
|
+
}
|
|
101
|
+
this.mcpClient = new mcp_client_1.McpClient(clientConfig);
|
|
102
|
+
await this.mcpClient.initialize();
|
|
103
|
+
this.mcpClient.start();
|
|
104
|
+
const status = this.mcpClient.getStatus();
|
|
105
|
+
this.logger.info('MCP Client initialized and ready', {
|
|
106
|
+
enabledProviders: status.enabledProviders,
|
|
107
|
+
providersCount: status.providersCount
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
async stop() {
|
|
111
|
+
this.logger.info('Stopping Hailer MCP application');
|
|
112
|
+
try {
|
|
113
|
+
if (this.mcpClient) {
|
|
114
|
+
await this.mcpClient.shutdown();
|
|
115
|
+
this.logger.info('MCP Client stopped');
|
|
116
|
+
}
|
|
117
|
+
if (this.mcpServer) {
|
|
118
|
+
await this.mcpServer.stop();
|
|
119
|
+
this.logger.info('MCP Server stopped');
|
|
120
|
+
}
|
|
121
|
+
this.logger.info('Application stopped gracefully');
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
this.logger.error('Error during application shutdown', error);
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Graceful shutdown handling
|
|
129
|
+
setupGracefulShutdown() {
|
|
130
|
+
const shutdown = async (signal) => {
|
|
131
|
+
this.logger.info(`Received ${signal}, shutting down gracefully`);
|
|
132
|
+
try {
|
|
133
|
+
await this.stop();
|
|
134
|
+
process.exit(0);
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
this.logger.error('Error during shutdown', error);
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
142
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
143
|
+
this.logger.debug('Graceful shutdown handlers registered');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
exports.Core = Core;
|
|
147
|
+
//# sourceMappingURL=core.js.map
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Manager
|
|
3
|
+
*
|
|
4
|
+
* Handles token counting and automatic summarization to prevent "prompt too long" errors.
|
|
5
|
+
* Uses character-based token estimation and provider-specific limits with safety margins.
|
|
6
|
+
*/
|
|
7
|
+
export type ProviderType = 'anthropic' | 'openai';
|
|
8
|
+
export interface TokenLimits {
|
|
9
|
+
maxTokens: number;
|
|
10
|
+
safeTokens: number;
|
|
11
|
+
safetyMargin: number;
|
|
12
|
+
}
|
|
13
|
+
export interface TokenCountResult {
|
|
14
|
+
totalTokens: number;
|
|
15
|
+
systemPromptTokens: number;
|
|
16
|
+
messagesTokens: number;
|
|
17
|
+
toolsTokens: number;
|
|
18
|
+
exceedsLimit: boolean;
|
|
19
|
+
provider: ProviderType;
|
|
20
|
+
limit: TokenLimits;
|
|
21
|
+
}
|
|
22
|
+
export interface ToolResultGroup {
|
|
23
|
+
messages: any[];
|
|
24
|
+
tokens: number;
|
|
25
|
+
startIndex: number;
|
|
26
|
+
endIndex: number;
|
|
27
|
+
}
|
|
28
|
+
export interface SummarizationResult {
|
|
29
|
+
summarizedMessages: any[];
|
|
30
|
+
originalTokens: number;
|
|
31
|
+
summarizedTokens: number;
|
|
32
|
+
chunksProcessed: number;
|
|
33
|
+
reductionPercent: number;
|
|
34
|
+
}
|
|
35
|
+
export interface ContextManagerConfig {
|
|
36
|
+
safetyMarginPercent: number;
|
|
37
|
+
enableAutoSummarization: boolean;
|
|
38
|
+
maxSummarizationChunks: number;
|
|
39
|
+
anthropicApiKey?: string;
|
|
40
|
+
openaiApiKey?: string;
|
|
41
|
+
}
|
|
42
|
+
export declare class ContextManager {
|
|
43
|
+
private logger;
|
|
44
|
+
private config;
|
|
45
|
+
private readonly PROVIDER_LIMITS;
|
|
46
|
+
constructor(config?: Partial<ContextManagerConfig>);
|
|
47
|
+
/**
|
|
48
|
+
* Estimate tokens from text using character-based approximation
|
|
49
|
+
* Formula: 1 token ≈ 4 characters
|
|
50
|
+
*/
|
|
51
|
+
private estimateTokens;
|
|
52
|
+
/**
|
|
53
|
+
* Calculate token limits for a provider with safety margin
|
|
54
|
+
*/
|
|
55
|
+
private getTokenLimits;
|
|
56
|
+
/**
|
|
57
|
+
* Count tokens for system prompt
|
|
58
|
+
*/
|
|
59
|
+
private countSystemPromptTokens;
|
|
60
|
+
/**
|
|
61
|
+
* Count tokens for messages array
|
|
62
|
+
*/
|
|
63
|
+
private countMessagesTokens;
|
|
64
|
+
/**
|
|
65
|
+
* Count tokens for tools definitions
|
|
66
|
+
*/
|
|
67
|
+
private countToolsTokens;
|
|
68
|
+
/**
|
|
69
|
+
* Count total tokens for a complete prompt
|
|
70
|
+
*/
|
|
71
|
+
countTokens(systemPrompt: string | any, messages: any[], tools: any[], provider: ProviderType): TokenCountResult;
|
|
72
|
+
/**
|
|
73
|
+
* Split messages into logical groups based on tool call patterns
|
|
74
|
+
* Groups together: assistant message with tool_use -> tool results
|
|
75
|
+
*/
|
|
76
|
+
private splitIntoToolResultGroups;
|
|
77
|
+
/**
|
|
78
|
+
* Split tool result groups into chunks that fit within safe limits
|
|
79
|
+
*/
|
|
80
|
+
private splitIntoChunks;
|
|
81
|
+
/**
|
|
82
|
+
* Summarize a chunk of tool results using the LLM
|
|
83
|
+
*/
|
|
84
|
+
private summarizeChunk;
|
|
85
|
+
/**
|
|
86
|
+
* Summarize using Anthropic
|
|
87
|
+
*/
|
|
88
|
+
private summarizeWithAnthropic;
|
|
89
|
+
/**
|
|
90
|
+
* Summarize using OpenAI
|
|
91
|
+
*/
|
|
92
|
+
private summarizeWithOpenAI;
|
|
93
|
+
/**
|
|
94
|
+
* Main summarization orchestration
|
|
95
|
+
*/
|
|
96
|
+
summarizeContext(systemPrompt: string, messages: any[], provider: ProviderType, userQuery?: string): Promise<SummarizationResult>;
|
|
97
|
+
/**
|
|
98
|
+
* Check if token count exceeds safe limit
|
|
99
|
+
*/
|
|
100
|
+
exceedsLimit(tokenCount: number, provider: ProviderType): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Get warning threshold (80% of safe limit)
|
|
103
|
+
*/
|
|
104
|
+
approachingLimit(tokenCount: number, provider: ProviderType): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Get provider limits info
|
|
107
|
+
*/
|
|
108
|
+
getProviderLimits(provider: ProviderType): TokenLimits;
|
|
109
|
+
}
|
|
110
|
+
export declare function getContextManager(config?: Partial<ContextManagerConfig>): ContextManager;
|
|
111
|
+
//# sourceMappingURL=context-manager.d.ts.map
|