@hailer/mcp 0.2.7 → 1.0.20
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/skills/client-bot-architecture/skill.md +340 -0
- package/.claude/skills/publish-hailer-app/SKILL.md +11 -0
- package/dist/app.d.ts +1 -1
- package/dist/app.js +116 -84
- package/dist/bot/chat-bot.d.ts +31 -0
- package/dist/bot/chat-bot.js +356 -0
- package/dist/cli.js +0 -0
- package/dist/config.d.ts +15 -2
- package/dist/config.js +53 -3
- package/dist/lib/logger.js +11 -11
- package/dist/mcp/hailer-clients.js +12 -11
- package/dist/mcp/tool-registry.d.ts +4 -0
- package/dist/mcp/tool-registry.js +78 -1
- package/dist/mcp/tools/activity.js +47 -0
- package/dist/mcp/tools/discussion.js +44 -1
- package/dist/mcp/tools/metrics.d.ts +13 -0
- package/dist/mcp/tools/metrics.js +546 -0
- package/dist/mcp/tools/user.d.ts +1 -0
- package/dist/mcp/tools/user.js +94 -1
- package/dist/mcp/tools/workflow.js +109 -40
- package/dist/mcp/webhook-handler.js +7 -4
- package/dist/mcp-server.js +22 -6
- package/dist/stdio-server.d.ts +14 -0
- package/dist/stdio-server.js +101 -0
- package/package.json +6 -6
- package/scripts/test-hal-tools.ts +154 -0
- package/test-billing-server.js +136 -0
- package/dist/lib/discussion-lock.d.ts +0 -42
- package/dist/lib/discussion-lock.js +0 -110
- package/dist/mcp/tools/bot-config/constants.d.ts +0 -23
- package/dist/mcp/tools/bot-config/constants.js +0 -94
- package/dist/mcp/tools/bot-config/core.d.ts +0 -253
- package/dist/mcp/tools/bot-config/core.js +0 -2456
- package/dist/mcp/tools/bot-config/index.d.ts +0 -10
- package/dist/mcp/tools/bot-config/index.js +0 -59
- package/dist/mcp/tools/bot-config/tools.d.ts +0 -7
- package/dist/mcp/tools/bot-config/tools.js +0 -15
- package/dist/mcp/tools/bot-config/types.d.ts +0 -50
- package/dist/mcp/tools/bot-config/types.js +0 -6
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# Client Bot Architecture Reference
|
|
2
|
+
|
|
3
|
+
Load this skill when working on the client bot system (bot-manager, daemon, token billing, MCP tool execution).
|
|
4
|
+
|
|
5
|
+
**Full Documentation:** See `docs/client-bots/` for comprehensive guides:
|
|
6
|
+
- [index.md](../../../docs/client-bots/index.md) - Overview
|
|
7
|
+
- [architecture.md](../../../docs/client-bots/architecture.md) - Data flows, initialization
|
|
8
|
+
- [services.md](../../../docs/client-bots/services.md) - All 11 services
|
|
9
|
+
- [token-costs.md](../../../docs/client-bots/token-costs.md) - AI + Hailer costs
|
|
10
|
+
- [memory-context.md](../../../docs/client-bots/memory-context.md) - 3-layer context
|
|
11
|
+
- [configuration.md](../../../docs/client-bots/configuration.md) - Env vars, config files
|
|
12
|
+
- [edge-cases.md](../../../docs/client-bots/edge-cases.md) - Race conditions, gotchas
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Architecture Overview
|
|
17
|
+
|
|
18
|
+
The client bot system is a multi-bot orchestration platform for Hailer workspaces:
|
|
19
|
+
- **HAL Orchestrator** - Main bot that monitors chats, classifies messages, coordinates specialists
|
|
20
|
+
- **Specialist Bots** - Focused bots for specific tasks (invoked by HAL)
|
|
21
|
+
- **Bot Manager** - Manages multiple bot connections and credentials
|
|
22
|
+
- **Token Billing** - Real-time per-workspace cost tracking
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Key Files
|
|
27
|
+
|
|
28
|
+
| File | Purpose |
|
|
29
|
+
|------|---------|
|
|
30
|
+
| `src/agents/bot-manager.ts` | Multi-bot connection pool, credential management |
|
|
31
|
+
| `src/agents/hal/daemon.ts` | HAL orchestrator, message routing, specialist coordination |
|
|
32
|
+
| `src/agents/shared/base.ts` | ChatAgentDaemon base class, core processing loop |
|
|
33
|
+
| `src/agents/shared/services/token-billing.ts` | Per-workspace token burning |
|
|
34
|
+
| `src/bot-config/context.ts` | Per-workspace singleton, Agent Directory discovery |
|
|
35
|
+
| `src/mcp/hailer-clients.ts` | HailerClient pool, signal subscriptions |
|
|
36
|
+
| `src/mcp/tools/activity.ts` | list_activities, create_activity, update_activity |
|
|
37
|
+
| `src/mcp/tools/discussion.ts` | join_discussion, fetch_messages, add_message |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Message Processing Flow
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
User message in workspace
|
|
45
|
+
↓
|
|
46
|
+
[Signal: messenger.new] → HailerClientManager
|
|
47
|
+
↓
|
|
48
|
+
ChatAgentDaemon.handleSignal()
|
|
49
|
+
↓
|
|
50
|
+
MessageClassifier.extractIncomingMessage()
|
|
51
|
+
→ Priority: HIGH (DM, @mention, reply) or NORMAL
|
|
52
|
+
↓
|
|
53
|
+
processMessage(IncomingMessage)
|
|
54
|
+
→ Check token balance (first message)
|
|
55
|
+
→ Load memory from Session Log (cold start)
|
|
56
|
+
→ Build per-discussion conversation
|
|
57
|
+
↓
|
|
58
|
+
Call LLM with conversation + tools
|
|
59
|
+
↓
|
|
60
|
+
handleLlmResponse(response)
|
|
61
|
+
├─ Tool calls? → executeToolsAndContinue()
|
|
62
|
+
│ ├─ Execute via MCP
|
|
63
|
+
│ ├─ Add results to conversation
|
|
64
|
+
│ └─ Call LLM again (loop)
|
|
65
|
+
├─ Specialist invite? → inviteSpecialist()
|
|
66
|
+
├─ IGNORE? → Remove from context
|
|
67
|
+
└─ RESPOND? → postResponse()
|
|
68
|
+
└─ Resolve tags (@mentions, #activities)
|
|
69
|
+
└─ Send via messenger.send
|
|
70
|
+
└─ Burn tokens (fire-and-forget)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Tool Execution Pipeline
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// 1. LLM returns tool_use blocks
|
|
79
|
+
const toolUseBlocks = response.content.filter(b => b.type === "tool_use");
|
|
80
|
+
|
|
81
|
+
// 2. Preprocess each tool input (inject context)
|
|
82
|
+
preprocessToolInput(toolName, input) {
|
|
83
|
+
// Inject discussionId, sourceActivityId, etc.
|
|
84
|
+
return modified_input;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 3. Execute via MCP service
|
|
88
|
+
const toolResults = await toolExecutor.executeTools(toolUseBlocks, {
|
|
89
|
+
session,
|
|
90
|
+
preprocessToolInput
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// 4. Add results to conversation
|
|
94
|
+
conversation.push({ role: "user", content: toolResults });
|
|
95
|
+
|
|
96
|
+
// 5. Call LLM again with results
|
|
97
|
+
// 6. Track tokens per response
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Cost Concern:** Each tool response (workflow schemas, activity lists) adds input tokens at model rate.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Token Billing
|
|
105
|
+
|
|
106
|
+
**Pricing (Claude Haiku 4.5):**
|
|
107
|
+
```typescript
|
|
108
|
+
const HAIKU_PRICING = {
|
|
109
|
+
inputPerMillion: 1.00,
|
|
110
|
+
outputPerMillion: 5.00,
|
|
111
|
+
cacheWritePerMillion: 1.25, // 25% more than input
|
|
112
|
+
cacheReadPerMillion: 0.10, // 90% discount
|
|
113
|
+
};
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Normalized Token Formula:**
|
|
117
|
+
```
|
|
118
|
+
normalizedTokens =
|
|
119
|
+
inputTokens * 0.20 +
|
|
120
|
+
outputTokens * 1.0 +
|
|
121
|
+
cacheCreationTokens * 0.25 +
|
|
122
|
+
cacheReadTokens * 0.02
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**API Calls:**
|
|
126
|
+
- `v3.mcp.getTokenBalance(workspaceId)` - Balance check before session
|
|
127
|
+
- `v3.mcp.deductTokens({...})` - Fire-and-forget token burn
|
|
128
|
+
|
|
129
|
+
**Graceful Degradation:**
|
|
130
|
+
- Balance check returns "OK" if service unavailable
|
|
131
|
+
- Token burn is async, doesn't block response
|
|
132
|
+
|
|
133
|
+
**Cost Optimization:**
|
|
134
|
+
Set `DISABLE_SESSION_LOG=true` to save ~1620 tokens per conversation:
|
|
135
|
+
- Skips SESSION_LOG persistence (20 tokens)
|
|
136
|
+
- Uses truncation instead of LLM summarization (~1000 tokens)
|
|
137
|
+
- Skips metadata extraction (~600 tokens)
|
|
138
|
+
- Uses discussion messages for cold start (FREE)
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Specialist Coordination
|
|
143
|
+
|
|
144
|
+
**HAL can invoke specialists via XML pattern:**
|
|
145
|
+
```xml
|
|
146
|
+
<invite specialist="key">handoff context</invite>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Specialist Registry:**
|
|
150
|
+
```typescript
|
|
151
|
+
specialists: Map<string, Specialist>
|
|
152
|
+
activeSpecialistsInDiscussion: Map<string, Set<string>>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Handoff Flow:**
|
|
156
|
+
1. HAL detects task needs specialist
|
|
157
|
+
2. Calls `invite_discussion_members` with specialist userId
|
|
158
|
+
3. Posts handoff message with `[hailerTag|Name](userId)` mention
|
|
159
|
+
4. Specialist receives notification, joins discussion
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Per-Discussion Isolation
|
|
164
|
+
|
|
165
|
+
**Conversation Manager:**
|
|
166
|
+
- LRU cache of 100 most recent discussions
|
|
167
|
+
- Each discussion has independent conversation history
|
|
168
|
+
- Auto-truncates when >50 messages (keeps last 30)
|
|
169
|
+
- Prevents context pollution across chats
|
|
170
|
+
|
|
171
|
+
**Cost Optimization (`DISABLE_SESSION_LOG=true`):**
|
|
172
|
+
- Cold start: Fetches discussion messages (FREE) instead of SESSION_LOG
|
|
173
|
+
- Context overflow: Truncates (0 tokens) instead of LLM summarization (~1000 tokens)
|
|
174
|
+
- Session end: Skips persistence (saves 20 tokens + ~600 metadata extraction)
|
|
175
|
+
|
|
176
|
+
**Session Tracking:**
|
|
177
|
+
```typescript
|
|
178
|
+
interface ActivitySession {
|
|
179
|
+
discussionId: string;
|
|
180
|
+
activityId: string;
|
|
181
|
+
activityName: string;
|
|
182
|
+
metrics: { inputTokens, outputTokens, cacheTokens, apiCalls };
|
|
183
|
+
conversation: string[]; // ["SenderName: message preview"]
|
|
184
|
+
actions: string[]; // ["Responded", "Executed tool X"]
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Idle Cleanup:**
|
|
189
|
+
- Timer every 30 seconds
|
|
190
|
+
- Sessions inactive 1 hour auto-flushed
|
|
191
|
+
- Flush writes to Session Log workflow
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Cross-Discussion Memory
|
|
196
|
+
|
|
197
|
+
**Context Persistence (5 min TTL):**
|
|
198
|
+
```typescript
|
|
199
|
+
lastKnownActivityId: string | null;
|
|
200
|
+
lastKnownActivityTime: number;
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Used for:**
|
|
204
|
+
- Auto-inject `sourceActivityId` in `join_discussion`
|
|
205
|
+
- "Came from" wormhole links when inviting users
|
|
206
|
+
- Timeout-based expiration
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Bot Manager
|
|
211
|
+
|
|
212
|
+
**Connection Pool:**
|
|
213
|
+
```typescript
|
|
214
|
+
class MultiBotManager {
|
|
215
|
+
botClients: Map<string, BotClient>;
|
|
216
|
+
|
|
217
|
+
initializeBotClient(email, password, apiKey): Promise<string>
|
|
218
|
+
removeBotClient(userId): Promise<void>
|
|
219
|
+
getBotClient(userId): BotClient | undefined
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**BotClient Structure:**
|
|
224
|
+
```typescript
|
|
225
|
+
interface BotClient {
|
|
226
|
+
userId: string;
|
|
227
|
+
firstName: string;
|
|
228
|
+
lastName: string;
|
|
229
|
+
config: BotClientConfig;
|
|
230
|
+
client: HailerClient;
|
|
231
|
+
signalHandler: SignalHandler;
|
|
232
|
+
workspaceCache?: WorkspaceCache;
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
**Initialization:**
|
|
237
|
+
1. Load bot configs
|
|
238
|
+
2. Create HailerClient via API key
|
|
239
|
+
3. Fetch workspace cache (`v2.core.init`)
|
|
240
|
+
4. Check Agent Directory for custom display names
|
|
241
|
+
5. Register signal handlers
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Agent Directory Discovery
|
|
246
|
+
|
|
247
|
+
**Schema Discovery:**
|
|
248
|
+
1. List all workflows
|
|
249
|
+
2. Find "Agent Directory" workflow
|
|
250
|
+
3. Extract "Deployed"/"Retired" phases
|
|
251
|
+
4. Map field keys to field IDs
|
|
252
|
+
5. Cache for dynamic lookups
|
|
253
|
+
|
|
254
|
+
**BotContext Singleton (per workspace):**
|
|
255
|
+
```typescript
|
|
256
|
+
getBotContext(workspaceId) → {
|
|
257
|
+
agentDirectoryWorkflowId,
|
|
258
|
+
deployedPhaseId,
|
|
259
|
+
retiredPhaseId,
|
|
260
|
+
fields: { hailerProfile, email, password, botType }
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## System Prompt Caching (50% cost reduction)
|
|
267
|
+
|
|
268
|
+
**HAL uses Anthropic prompt caching:**
|
|
269
|
+
- Static content (identity, specialist list template) → `ephemeral` cache
|
|
270
|
+
- Dynamic content (current specialists, pending fixes) → appended fresh
|
|
271
|
+
- Format: `Anthropic.TextBlockParam[]`
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Error Handling
|
|
276
|
+
|
|
277
|
+
| Error Type | Handling |
|
|
278
|
+
|------------|----------|
|
|
279
|
+
| Tool execution | Return `is_error: true`, LLM sees and can retry |
|
|
280
|
+
| Message processing | Log, remove from context, silent fail |
|
|
281
|
+
| Billing errors | Graceful degradation, return "OK" |
|
|
282
|
+
| Signal errors | Early dedup, invalid messages cleaned |
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Structured Outputs Mode (Token Optimization)
|
|
287
|
+
|
|
288
|
+
**Problem:** Native tool definitions cost ~100K tokens per request (22 tool schemas sent every API call).
|
|
289
|
+
|
|
290
|
+
**Solution:** Use Anthropic's structured outputs beta to replace tool schemas with compact JSON action schema.
|
|
291
|
+
|
|
292
|
+
**Enable:**
|
|
293
|
+
```bash
|
|
294
|
+
USE_STRUCTURED_OUTPUTS=true npm run daemon
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
**Key Files:**
|
|
298
|
+
| File | Purpose |
|
|
299
|
+
|------|---------|
|
|
300
|
+
| `src/agents/shared/schemas/action-schema.ts` | Action type definitions, JSON schema |
|
|
301
|
+
| `src/agents/shared/services/structured-output-executor.ts` | Action parsing and execution |
|
|
302
|
+
|
|
303
|
+
**How It Works:**
|
|
304
|
+
1. Instead of `tools: [...]` array, uses `output_format: { type: "json_schema", schema: {...} }`
|
|
305
|
+
2. Claude outputs JSON with action type and params
|
|
306
|
+
3. `StructuredOutputExecutor` parses and executes via existing MCP tools
|
|
307
|
+
4. Multi-turn loops work the same way
|
|
308
|
+
|
|
309
|
+
**Action Schema:**
|
|
310
|
+
```typescript
|
|
311
|
+
interface ActionOutput {
|
|
312
|
+
thinking?: string; // Brief reasoning
|
|
313
|
+
action: BotAction; // "respond" | "list_activities" | etc.
|
|
314
|
+
params?: Record<string, unknown>; // Tool-specific params
|
|
315
|
+
response_text?: string; // For "respond" action
|
|
316
|
+
specialist_key?: string; // For "invite_specialist" action
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**Savings:**
|
|
321
|
+
- ~100K tokens saved per request
|
|
322
|
+
- At Haiku rates ($0.80/M): ~$0.08 saved per request
|
|
323
|
+
- 1000 requests/day = ~$80/day saved
|
|
324
|
+
|
|
325
|
+
**Trade-offs:**
|
|
326
|
+
- Beta feature (may have edge cases)
|
|
327
|
+
- Grammar compilation on first use (cached for 24h)
|
|
328
|
+
- Slightly different error handling
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## Key Design Patterns
|
|
333
|
+
|
|
334
|
+
1. **Per-Discussion Isolation** - Independent conversation per chat
|
|
335
|
+
2. **Multi-Tenant** - BotContext, schema cache, billing per workspace
|
|
336
|
+
3. **Signal-Driven** - Listen to `messenger.new`, early dedup
|
|
337
|
+
4. **Graceful Degradation** - Billing/memory failures don't block
|
|
338
|
+
5. **Fire-and-Forget Billing** - Async token burn, no blocking
|
|
339
|
+
6. **Tool Preprocessing** - Inject context before MCP execution
|
|
340
|
+
7. **Structured Outputs** - Optional token optimization via JSON action schema
|
|
@@ -82,12 +82,23 @@ Required structure:
|
|
|
82
82
|
|
|
83
83
|
### Step 4: Publish
|
|
84
84
|
|
|
85
|
+
**Option 1: Production Only**
|
|
85
86
|
```javascript
|
|
86
87
|
publish_hailer_app({
|
|
87
88
|
projectDirectory: "/path/to/app"
|
|
88
89
|
})
|
|
89
90
|
```
|
|
90
91
|
|
|
92
|
+
**Option 2: Production + Marketplace**
|
|
93
|
+
```javascript
|
|
94
|
+
publish_hailer_app({
|
|
95
|
+
projectDirectory: "/path/to/app",
|
|
96
|
+
publishToMarket: true
|
|
97
|
+
})
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**IMPORTANT:** The `publishToMarket: true` parameter is REQUIRED to publish the app to the Hailer Marketplace. Without it, the app is published only to your production environment.
|
|
101
|
+
|
|
91
102
|
### Step 5: Verify
|
|
92
103
|
|
|
93
104
|
```javascript
|
package/dist/app.d.ts
CHANGED
package/dist/app.js
CHANGED
|
@@ -3,7 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const core_1 = require("./core");
|
|
4
4
|
const config_1 = require("./config");
|
|
5
5
|
const logger_1 = require("./lib/logger");
|
|
6
|
+
const tool_registry_1 = require("./mcp/tool-registry");
|
|
7
|
+
const stdio_server_1 = require("./stdio-server");
|
|
6
8
|
const logger = (0, logger_1.createLogger)({ component: 'app' });
|
|
9
|
+
// Detect transport mode:
|
|
10
|
+
// - MCP_TRANSPORT=stdio - explicit stdio mode
|
|
11
|
+
// - MCP_TRANSPORT=http - explicit HTTP mode
|
|
12
|
+
// - No TTY on stdin - Claude Desktop spawned process, use stdio
|
|
13
|
+
// - TTY on stdin - manual terminal run, use HTTP
|
|
14
|
+
const transportMode = process.env.MCP_TRANSPORT || (process.stdin.isTTY ? 'http' : 'stdio');
|
|
15
|
+
const isStdioMode = transportMode === 'stdio';
|
|
16
|
+
logger.info('Transport mode detected', {
|
|
17
|
+
mode: transportMode,
|
|
18
|
+
isTTY: process.stdin.isTTY,
|
|
19
|
+
isStdioMode
|
|
20
|
+
});
|
|
7
21
|
const file_1 = require("./mcp/tools/file");
|
|
8
22
|
const activity_1 = require("./mcp/tools/activity");
|
|
9
23
|
const discussion_1 = require("./mcp/tools/discussion");
|
|
@@ -13,79 +27,87 @@ const insight_1 = require("./mcp/tools/insight");
|
|
|
13
27
|
const app_1 = require("./mcp/tools/app");
|
|
14
28
|
// Bot config and bug-fixer tools are dynamically imported only when MCP_CLIENT_ENABLED=true
|
|
15
29
|
// This allows the npm package to work without these modules
|
|
16
|
-
|
|
30
|
+
// For stdio mode, create standalone ToolRegistry
|
|
31
|
+
// For HTTP mode, use Core which has its own ToolRegistry
|
|
32
|
+
const toolRegistry = isStdioMode ? new tool_registry_1.ToolRegistry({ enableNuclearTools: config_1.environment.ENABLE_NUCLEAR_TOOLS }) : null;
|
|
33
|
+
const core = isStdioMode ? null : new core_1.Core();
|
|
34
|
+
// Helper to add tool to the appropriate registry
|
|
35
|
+
const addTool = (tool) => {
|
|
36
|
+
if (toolRegistry) {
|
|
37
|
+
toolRegistry.addTool(tool);
|
|
38
|
+
}
|
|
39
|
+
else if (core) {
|
|
40
|
+
core.addTool(tool);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
17
43
|
logger.info('Registering tools...');
|
|
18
44
|
logger.info('Nuclear tools status', { enabled: config_1.environment.ENABLE_NUCLEAR_TOOLS });
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
core.addTool(workflow_1.getWorkflowSchemaTool);
|
|
40
|
-
core.addTool(workflow_1.listWorkflowPhasesTool);
|
|
41
|
-
core.addTool(workflow_1.listWorkflowsTool);
|
|
42
|
-
core.addTool(workflow_1.installWorkflowTool);
|
|
45
|
+
addTool(file_1.uploadFilesTool);
|
|
46
|
+
addTool(file_1.downloadFileTool);
|
|
47
|
+
addTool(activity_1.listActivitiesTool);
|
|
48
|
+
addTool(activity_1.showActivityByIdTool);
|
|
49
|
+
addTool(activity_1.createActivityTool);
|
|
50
|
+
addTool(activity_1.updateActivityTool);
|
|
51
|
+
addTool(discussion_1.listMyDiscussionsTool);
|
|
52
|
+
addTool(discussion_1.fetchDiscussionMessagesTool);
|
|
53
|
+
addTool(discussion_1.fetchPreviousDiscussionMessagesTool);
|
|
54
|
+
addTool(discussion_1.joinDiscussionTool);
|
|
55
|
+
addTool(discussion_1.leaveDiscussionTool);
|
|
56
|
+
addTool(discussion_1.addDiscussionMessageTool);
|
|
57
|
+
addTool(discussion_1.inviteDiscussionMembersTool);
|
|
58
|
+
addTool(discussion_1.getActivityFromDiscussionTool);
|
|
59
|
+
addTool(user_1.searchWorkspaceUsersTool);
|
|
60
|
+
addTool(user_1.getWorkspaceBalanceTool);
|
|
61
|
+
addTool(workflow_1.getWorkflowSchemaTool);
|
|
62
|
+
addTool(workflow_1.listWorkflowPhasesTool);
|
|
63
|
+
addTool(workflow_1.listWorkflowsTool);
|
|
64
|
+
addTool(workflow_1.installWorkflowTool);
|
|
43
65
|
if (config_1.environment.ENABLE_NUCLEAR_TOOLS) {
|
|
44
|
-
|
|
66
|
+
addTool(workflow_1.removeWorkflowTool);
|
|
45
67
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
68
|
+
addTool(workflow_1.updateWorkflowFieldTool);
|
|
69
|
+
addTool(workflow_1.updateWorkflowPhaseTool);
|
|
70
|
+
addTool(workflow_1.testFunctionFieldTool);
|
|
71
|
+
addTool(workflow_1.listWorkflowsMinimalTool);
|
|
72
|
+
addTool(workflow_1.countActivitiesTool);
|
|
73
|
+
addTool(insight_1.createInsightTool);
|
|
74
|
+
addTool(insight_1.previewInsightTool);
|
|
75
|
+
addTool(insight_1.getInsightDataTool);
|
|
76
|
+
addTool(insight_1.updateInsightTool);
|
|
55
77
|
if (config_1.environment.ENABLE_NUCLEAR_TOOLS) {
|
|
56
|
-
|
|
78
|
+
addTool(insight_1.removeInsightTool);
|
|
57
79
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
80
|
+
addTool(insight_1.listInsightsTool);
|
|
81
|
+
addTool(app_1.createAppTool);
|
|
82
|
+
addTool(app_1.listAppsTool);
|
|
83
|
+
addTool(app_1.updateAppTool);
|
|
62
84
|
if (config_1.environment.ENABLE_NUCLEAR_TOOLS) {
|
|
63
|
-
|
|
85
|
+
addTool(app_1.removeAppTool);
|
|
64
86
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
87
|
+
addTool(app_1.addAppMemberTool);
|
|
88
|
+
addTool(app_1.removeAppMemberTool);
|
|
89
|
+
addTool(app_1.scaffoldHailerAppTool);
|
|
90
|
+
addTool(app_1.publishHailerAppTool);
|
|
69
91
|
// Marketplace template tools
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
92
|
+
addTool(app_1.listTemplatesTool);
|
|
93
|
+
addTool(app_1.createTemplateTool);
|
|
94
|
+
addTool(app_1.installTemplateTool);
|
|
95
|
+
addTool(app_1.getTemplateTool);
|
|
96
|
+
addTool(app_1.publishTemplateTool);
|
|
97
|
+
addTool(app_1.getProductTool);
|
|
98
|
+
addTool(app_1.getProductManifestTool);
|
|
77
99
|
// Marketplace app tools
|
|
78
|
-
|
|
79
|
-
|
|
100
|
+
addTool(app_1.publishAppTool);
|
|
101
|
+
addTool(app_1.installMarketplaceAppTool);
|
|
80
102
|
// Bot-internal tools - dynamically imported only when MCP_CLIENT_ENABLED=true
|
|
81
103
|
// This allows npm package to work without bot-config and bug-fixer modules
|
|
82
|
-
if (config_1.environment.MCP_CLIENT_ENABLED) {
|
|
104
|
+
if (config_1.environment.MCP_CLIENT_ENABLED && !isStdioMode) {
|
|
83
105
|
// Dynamic import bot-config tools
|
|
84
106
|
const { listBotsConfigTool, enableBotTool, disableBotTool, checkSpecialistStatusTool } = require('./bot-config');
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
107
|
+
addTool(listBotsConfigTool);
|
|
108
|
+
addTool(enableBotTool);
|
|
109
|
+
addTool(disableBotTool);
|
|
110
|
+
addTool(checkSpecialistStatusTool);
|
|
89
111
|
// Dynamic import bug-fixer tools
|
|
90
112
|
const {
|
|
91
113
|
// Low-level tools
|
|
@@ -93,34 +115,44 @@ if (config_1.environment.MCP_CLIENT_ENABLED) {
|
|
|
93
115
|
// High-level workflow tools (LLM-driven)
|
|
94
116
|
bugFixerAnalyzeBugTool, bugFixerStartFixTool, bugFixerMarkDeclinedTool, bugFixerPublishFixTool, bugFixerRetryFixTool, markBugDeclinedTool, markBugFixedTool } = require('./mcp/tools/bug-fixer-tools');
|
|
95
117
|
// Low-level tools
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
118
|
+
addTool(bugFixerFindAppTool);
|
|
119
|
+
addTool(bugFixerListFilesTool);
|
|
120
|
+
addTool(bugFixerReadFileTool);
|
|
121
|
+
addTool(bugFixerWriteFileTool);
|
|
122
|
+
addTool(bugFixerApplyFixTool);
|
|
123
|
+
addTool(bugFixerRunBuildTool);
|
|
124
|
+
addTool(bugFixerGitStatusTool);
|
|
125
|
+
addTool(bugFixerGitPullTool);
|
|
126
|
+
addTool(bugFixerGitCommitTool);
|
|
127
|
+
addTool(bugFixerGitPushTool);
|
|
128
|
+
addTool(bugFixerGitRevertTool);
|
|
129
|
+
addTool(bugFixerPublishAppTool);
|
|
108
130
|
// High-level workflow tools (LLM-driven)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
131
|
+
addTool(bugFixerAnalyzeBugTool);
|
|
132
|
+
addTool(bugFixerStartFixTool);
|
|
133
|
+
addTool(bugFixerMarkDeclinedTool);
|
|
134
|
+
addTool(bugFixerPublishFixTool);
|
|
135
|
+
addTool(bugFixerRetryFixTool);
|
|
136
|
+
addTool(markBugDeclinedTool);
|
|
137
|
+
addTool(markBugFixedTool);
|
|
116
138
|
logger.info('Bot-internal tools registered (MCP_CLIENT_ENABLED=true)');
|
|
117
139
|
}
|
|
118
140
|
logger.info('All tools registered successfully');
|
|
119
|
-
// Start the
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
141
|
+
// Start the appropriate server based on transport mode
|
|
142
|
+
if (isStdioMode && toolRegistry) {
|
|
143
|
+
// Stdio mode for Claude Desktop
|
|
144
|
+
(0, stdio_server_1.startStdioServer)(toolRegistry).catch((error) => {
|
|
145
|
+
logger.error('Failed to start stdio MCP server', error);
|
|
146
|
+
process.exit(1);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
else if (core) {
|
|
150
|
+
// HTTP mode for other clients
|
|
151
|
+
core.start().catch((error) => {
|
|
152
|
+
logger.error('Failed to start Hailer MCP application', error);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
// Export core for testing and external access (may be null in stdio mode)
|
|
125
157
|
exports.default = core;
|
|
126
158
|
//# sourceMappingURL=app.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple Hailer Chat Bot
|
|
3
|
+
*
|
|
4
|
+
* Listens to discussions via WebSocket, responds using Anthropic Claude API
|
|
5
|
+
* with access to ALL MCP tools via the ToolRegistry.
|
|
6
|
+
*/
|
|
7
|
+
interface BotConfig {
|
|
8
|
+
email: string;
|
|
9
|
+
password: string;
|
|
10
|
+
apiBaseUrl: string;
|
|
11
|
+
anthropicApiKey: string;
|
|
12
|
+
botName?: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class HailerChatBot {
|
|
16
|
+
private clientManager;
|
|
17
|
+
private hailerApi;
|
|
18
|
+
private anthropic;
|
|
19
|
+
private botUserId;
|
|
20
|
+
private apiKey;
|
|
21
|
+
private config;
|
|
22
|
+
private toolRegistry;
|
|
23
|
+
constructor(config: BotConfig);
|
|
24
|
+
private registerAllTools;
|
|
25
|
+
start(): Promise<void>;
|
|
26
|
+
private handleMessage;
|
|
27
|
+
private generateResponse;
|
|
28
|
+
stop(): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
export default HailerChatBot;
|
|
31
|
+
//# sourceMappingURL=chat-bot.d.ts.map
|