@hailer/mcp 0.1.17 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +24 -20
- package/dist/core.d.ts +33 -9
- package/dist/core.js +279 -147
- package/dist/mcp/UserContextCache.js +18 -0
- package/dist/mcp/hailer-clients.d.ts +9 -1
- package/dist/mcp/hailer-clients.js +13 -3
- package/dist/mcp/signal-handler.js +1 -1
- package/dist/mcp/tool-registry.d.ts +3 -1
- package/dist/mcp/tool-registry.js +4 -1
- package/dist/mcp/tools/activity.js +43 -34
- package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
- package/dist/mcp/tools/bot-config/constants.js +94 -0
- package/dist/mcp/tools/{bot-config.d.ts → bot-config/core.d.ts} +6 -6
- package/dist/mcp/tools/{bot-config.js → bot-config/core.js} +15 -15
- package/dist/mcp/tools/bot-config/index.d.ts +10 -0
- package/dist/mcp/tools/bot-config/index.js +59 -0
- package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
- package/dist/mcp/tools/bot-config/tools.js +15 -0
- package/dist/mcp/tools/bot-config/types.d.ts +50 -0
- package/dist/mcp/tools/bot-config/types.js +6 -0
- package/dist/mcp/tools/bug-fixer-tools.d.ts +21 -0
- package/dist/mcp/tools/{giuseppe-tools.js → bug-fixer-tools.js} +61 -61
- package/dist/mcp/tools/user.js +10 -29
- package/dist/mcp/tools/workflow.js +36 -2
- package/dist/mcp/utils/data-transformers.d.ts +0 -8
- package/dist/mcp/utils/data-transformers.js +0 -28
- package/dist/mcp/utils/index.d.ts +4 -1
- package/dist/mcp/utils/index.js +17 -3
- package/dist/mcp/utils/pagination.d.ts +40 -0
- package/dist/mcp/utils/pagination.js +55 -0
- package/dist/mcp/utils/response-builder.d.ts +53 -0
- package/dist/mcp/utils/response-builder.js +110 -0
- package/dist/mcp/utils/tool-helpers.d.ts +0 -8
- package/dist/mcp/utils/tool-helpers.js +0 -24
- package/dist/mcp/utils/types.d.ts +1 -33
- package/dist/mcp-server.d.ts +2 -2
- package/dist/mcp-server.js +161 -139
- package/package.json +1 -1
- package/REFACTOR_STATUS.md +0 -127
- package/dist/agents/bot-manager.d.ts +0 -48
- package/dist/agents/bot-manager.js +0 -254
- package/dist/agents/factory.d.ts +0 -150
- package/dist/agents/factory.js +0 -650
- package/dist/agents/giuseppe/ai.d.ts +0 -83
- package/dist/agents/giuseppe/ai.js +0 -466
- package/dist/agents/giuseppe/bot.d.ts +0 -110
- package/dist/agents/giuseppe/bot.js +0 -780
- package/dist/agents/giuseppe/config.d.ts +0 -25
- package/dist/agents/giuseppe/config.js +0 -227
- package/dist/agents/giuseppe/files.d.ts +0 -52
- package/dist/agents/giuseppe/files.js +0 -338
- package/dist/agents/giuseppe/git.d.ts +0 -48
- package/dist/agents/giuseppe/git.js +0 -298
- package/dist/agents/giuseppe/index.d.ts +0 -97
- package/dist/agents/giuseppe/index.js +0 -258
- package/dist/agents/giuseppe/lsp.d.ts +0 -113
- package/dist/agents/giuseppe/lsp.js +0 -485
- package/dist/agents/giuseppe/monitor.d.ts +0 -118
- package/dist/agents/giuseppe/monitor.js +0 -621
- package/dist/agents/giuseppe/prompt.d.ts +0 -5
- package/dist/agents/giuseppe/prompt.js +0 -94
- package/dist/agents/giuseppe/registries/pending-classification.d.ts +0 -28
- package/dist/agents/giuseppe/registries/pending-classification.js +0 -50
- package/dist/agents/giuseppe/registries/pending-fix.d.ts +0 -30
- package/dist/agents/giuseppe/registries/pending-fix.js +0 -42
- package/dist/agents/giuseppe/registries/pending.d.ts +0 -27
- package/dist/agents/giuseppe/registries/pending.js +0 -49
- package/dist/agents/giuseppe/specialist.d.ts +0 -47
- package/dist/agents/giuseppe/specialist.js +0 -237
- package/dist/agents/giuseppe/types.d.ts +0 -123
- package/dist/agents/giuseppe/types.js +0 -9
- package/dist/agents/hailer-expert/index.d.ts +0 -8
- package/dist/agents/hailer-expert/index.js +0 -14
- package/dist/agents/hal/daemon.d.ts +0 -142
- package/dist/agents/hal/daemon.js +0 -1103
- package/dist/agents/hal/definitions.d.ts +0 -55
- package/dist/agents/hal/definitions.js +0 -263
- package/dist/agents/hal/index.d.ts +0 -3
- package/dist/agents/hal/index.js +0 -8
- package/dist/agents/index.d.ts +0 -18
- package/dist/agents/index.js +0 -48
- package/dist/agents/shared/base.d.ts +0 -216
- package/dist/agents/shared/base.js +0 -846
- package/dist/agents/shared/services/agent-registry.d.ts +0 -107
- package/dist/agents/shared/services/agent-registry.js +0 -629
- package/dist/agents/shared/services/conversation-manager.d.ts +0 -50
- package/dist/agents/shared/services/conversation-manager.js +0 -136
- package/dist/agents/shared/services/mcp-client.d.ts +0 -56
- package/dist/agents/shared/services/mcp-client.js +0 -124
- package/dist/agents/shared/services/message-classifier.d.ts +0 -37
- package/dist/agents/shared/services/message-classifier.js +0 -187
- package/dist/agents/shared/services/message-formatter.d.ts +0 -89
- package/dist/agents/shared/services/message-formatter.js +0 -371
- package/dist/agents/shared/services/session-logger.d.ts +0 -106
- package/dist/agents/shared/services/session-logger.js +0 -446
- package/dist/agents/shared/services/tool-executor.d.ts +0 -41
- package/dist/agents/shared/services/tool-executor.js +0 -169
- package/dist/agents/shared/services/workspace-schema-cache.d.ts +0 -125
- package/dist/agents/shared/services/workspace-schema-cache.js +0 -578
- package/dist/agents/shared/specialist.d.ts +0 -91
- package/dist/agents/shared/specialist.js +0 -399
- package/dist/agents/shared/tool-schema-loader.d.ts +0 -62
- package/dist/agents/shared/tool-schema-loader.js +0 -232
- package/dist/agents/shared/types.d.ts +0 -327
- package/dist/agents/shared/types.js +0 -121
- package/dist/client/agents/base.d.ts +0 -207
- package/dist/client/agents/base.js +0 -744
- package/dist/client/agents/definitions.d.ts +0 -53
- package/dist/client/agents/definitions.js +0 -263
- package/dist/client/agents/orchestrator.d.ts +0 -141
- package/dist/client/agents/orchestrator.js +0 -1062
- package/dist/client/agents/specialist.d.ts +0 -86
- package/dist/client/agents/specialist.js +0 -340
- package/dist/client/bot-entrypoint.d.ts +0 -7
- package/dist/client/bot-entrypoint.js +0 -103
- package/dist/client/bot-manager.d.ts +0 -44
- package/dist/client/bot-manager.js +0 -173
- package/dist/client/bot-runner.d.ts +0 -35
- package/dist/client/bot-runner.js +0 -188
- package/dist/client/chat-agent-daemon.d.ts +0 -464
- package/dist/client/chat-agent-daemon.js +0 -1774
- package/dist/client/daemon-factory.d.ts +0 -106
- package/dist/client/daemon-factory.js +0 -301
- package/dist/client/factory.d.ts +0 -111
- package/dist/client/factory.js +0 -314
- package/dist/client/index.d.ts +0 -17
- package/dist/client/index.js +0 -38
- package/dist/client/multi-bot-manager.d.ts +0 -42
- package/dist/client/multi-bot-manager.js +0 -161
- package/dist/client/orchestrator-daemon.d.ts +0 -87
- package/dist/client/orchestrator-daemon.js +0 -444
- package/dist/client/server.d.ts +0 -8
- package/dist/client/server.js +0 -251
- package/dist/client/services/agent-registry.d.ts +0 -108
- package/dist/client/services/agent-registry.js +0 -630
- package/dist/client/services/conversation-manager.d.ts +0 -50
- package/dist/client/services/conversation-manager.js +0 -136
- package/dist/client/services/mcp-client.d.ts +0 -48
- package/dist/client/services/mcp-client.js +0 -105
- package/dist/client/services/message-classifier.d.ts +0 -37
- package/dist/client/services/message-classifier.js +0 -187
- package/dist/client/services/message-formatter.d.ts +0 -84
- package/dist/client/services/message-formatter.js +0 -353
- package/dist/client/services/session-logger.d.ts +0 -106
- package/dist/client/services/session-logger.js +0 -446
- package/dist/client/services/tool-executor.d.ts +0 -41
- package/dist/client/services/tool-executor.js +0 -169
- package/dist/client/services/workspace-schema-cache.d.ts +0 -149
- package/dist/client/services/workspace-schema-cache.js +0 -732
- package/dist/client/specialist-daemon.d.ts +0 -77
- package/dist/client/specialist-daemon.js +0 -197
- package/dist/client/specialists.d.ts +0 -53
- package/dist/client/specialists.js +0 -178
- package/dist/client/tool-schema-loader.d.ts +0 -62
- package/dist/client/tool-schema-loader.js +0 -232
- package/dist/client/types.d.ts +0 -327
- package/dist/client/types.js +0 -121
- package/dist/commands/seed-config.d.ts +0 -9
- package/dist/commands/seed-config.js +0 -372
- package/dist/lib/context-manager.d.ts +0 -111
- package/dist/lib/context-manager.js +0 -431
- package/dist/lib/prompt-length-manager.d.ts +0 -81
- package/dist/lib/prompt-length-manager.js +0 -457
- package/dist/mcp/tools/giuseppe-tools.d.ts +0 -21
- package/dist/modules/bug-reports/bug-config.d.ts +0 -25
- package/dist/modules/bug-reports/bug-config.js +0 -187
- package/dist/modules/bug-reports/bug-monitor.d.ts +0 -108
- package/dist/modules/bug-reports/bug-monitor.js +0 -510
- package/dist/modules/bug-reports/giuseppe-agent.d.ts +0 -58
- package/dist/modules/bug-reports/giuseppe-agent.js +0 -467
- package/dist/modules/bug-reports/giuseppe-ai.d.ts +0 -83
- package/dist/modules/bug-reports/giuseppe-ai.js +0 -466
- package/dist/modules/bug-reports/giuseppe-bot.d.ts +0 -110
- package/dist/modules/bug-reports/giuseppe-bot.js +0 -804
- package/dist/modules/bug-reports/giuseppe-daemon.d.ts +0 -80
- package/dist/modules/bug-reports/giuseppe-daemon.js +0 -617
- package/dist/modules/bug-reports/giuseppe-files.d.ts +0 -64
- package/dist/modules/bug-reports/giuseppe-files.js +0 -375
- package/dist/modules/bug-reports/giuseppe-git.d.ts +0 -48
- package/dist/modules/bug-reports/giuseppe-git.js +0 -298
- package/dist/modules/bug-reports/giuseppe-lsp.d.ts +0 -113
- package/dist/modules/bug-reports/giuseppe-lsp.js +0 -485
- package/dist/modules/bug-reports/giuseppe-prompt.d.ts +0 -5
- package/dist/modules/bug-reports/giuseppe-prompt.js +0 -94
- package/dist/modules/bug-reports/index.d.ts +0 -77
- package/dist/modules/bug-reports/index.js +0 -215
- package/dist/modules/bug-reports/pending-classification-registry.d.ts +0 -28
- package/dist/modules/bug-reports/pending-classification-registry.js +0 -50
- package/dist/modules/bug-reports/pending-fix-registry.d.ts +0 -30
- package/dist/modules/bug-reports/pending-fix-registry.js +0 -42
- package/dist/modules/bug-reports/pending-registry.d.ts +0 -27
- package/dist/modules/bug-reports/pending-registry.js +0 -49
- package/dist/modules/bug-reports/types.d.ts +0 -123
- package/dist/modules/bug-reports/types.js +0 -9
- package/dist/routes/agents.d.ts +0 -44
- package/dist/routes/agents.js +0 -311
- package/dist/services/agent-credential-store.d.ts +0 -73
- package/dist/services/agent-credential-store.js +0 -212
- package/dist/services/bug-monitor.d.ts +0 -23
- package/dist/services/bug-monitor.js +0 -275
|
@@ -1,444 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Orchestrator Daemon (HAL)
|
|
4
|
-
*
|
|
5
|
-
* The main conversational bot that handles general chat and coordinates
|
|
6
|
-
* with specialist bots when tasks are too complex.
|
|
7
|
-
*
|
|
8
|
-
* HAL can:
|
|
9
|
-
* - Handle general conversation and simple queries
|
|
10
|
-
* - Detect when a task needs specialist help
|
|
11
|
-
* - Invite specialist bots to the discussion
|
|
12
|
-
* - Hand off context to specialists
|
|
13
|
-
* - Summarize specialist responses for users
|
|
14
|
-
*/
|
|
15
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.OrchestratorDaemon = void 0;
|
|
17
|
-
const chat_agent_daemon_1 = require("./chat-agent-daemon");
|
|
18
|
-
const specialists_1 = require("./specialists");
|
|
19
|
-
const logger_1 = require("../lib/logger");
|
|
20
|
-
class OrchestratorDaemon extends chat_agent_daemon_1.ChatAgentDaemon {
|
|
21
|
-
orchestratorLogger;
|
|
22
|
-
specialists = new Map();
|
|
23
|
-
activeSpecialistsInDiscussion = new Map(); // discussionId -> Set<specialistUserId>
|
|
24
|
-
specialistUserIds = new Map(); // specialistKey -> userId
|
|
25
|
-
toolsUsedInCurrentMessage = false; // Track if tools were used in current message processing
|
|
26
|
-
constructor(config) {
|
|
27
|
-
super(config);
|
|
28
|
-
this.orchestratorLogger = (0, logger_1.createLogger)({
|
|
29
|
-
component: "OrchestratorDaemon",
|
|
30
|
-
botId: config.botClient.userId,
|
|
31
|
-
});
|
|
32
|
-
// Register specialists from config
|
|
33
|
-
for (const [key, specialist] of Object.entries(specialists_1.SPECIALISTS)) {
|
|
34
|
-
this.specialists.set(key, specialist);
|
|
35
|
-
}
|
|
36
|
-
// Set specialist user IDs if provided
|
|
37
|
-
if (config.specialistUserIds) {
|
|
38
|
-
this.specialistUserIds = config.specialistUserIds;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
// ===== AGENT DIRECTORY OVERRIDES =====
|
|
42
|
-
/**
|
|
43
|
-
* Override agent name for Agent Directory
|
|
44
|
-
*/
|
|
45
|
-
getAgentName() {
|
|
46
|
-
return { firstName: "HAL", lastName: "Orchestrator" };
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Override agent description for Agent Directory
|
|
50
|
-
*/
|
|
51
|
-
getAgentDescription() {
|
|
52
|
-
return "HAL - the main Hailer Assistant orchestrator. Handles general conversation and coordinates specialist bots for complex tasks.";
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Override Position details for Orchestrator
|
|
56
|
-
*/
|
|
57
|
-
getPositionDetails() {
|
|
58
|
-
return {
|
|
59
|
-
name: "HAL Orchestrator",
|
|
60
|
-
purpose: "Main point of contact for users. Handles general conversation, triages requests, and coordinates specialist bots for complex tasks.",
|
|
61
|
-
personaTone: "Sharp, efficient, and helpful. Professional but approachable. Uses clear, concise language.",
|
|
62
|
-
coreCapabilities: "- Monitor all workspace discussions\n- Respond to general queries and greetings\n- Detect when specialist help is needed\n- Invite specialists to discussions\n- Coordinate multi-step workflows\n- Execute MCP tools for data operations",
|
|
63
|
-
boundaries: "- Never fabricate data - always use tools\n- Don't attempt complex technical tasks alone\n- Hand off to specialists for: bulk operations, report creation, workflow setup\n- Don't share credentials or sensitive config",
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Register a specialist's Hailer user ID
|
|
68
|
-
* Called during initialization when we know the specialist bot's user ID
|
|
69
|
-
*/
|
|
70
|
-
registerSpecialistUserId(specialistKey, userId) {
|
|
71
|
-
this.specialistUserIds.set(specialistKey, userId);
|
|
72
|
-
const specialist = this.specialists.get(specialistKey);
|
|
73
|
-
if (specialist) {
|
|
74
|
-
specialist.botUserId = userId;
|
|
75
|
-
this.orchestratorLogger.info("Specialist registered", {
|
|
76
|
-
key: specialistKey,
|
|
77
|
-
name: specialist.name,
|
|
78
|
-
userId,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Check if a specialist is already active in a discussion
|
|
84
|
-
*/
|
|
85
|
-
isSpecialistActiveInDiscussion(discussionId, specialistUserId) {
|
|
86
|
-
const active = this.activeSpecialistsInDiscussion.get(discussionId);
|
|
87
|
-
return active?.has(specialistUserId) ?? false;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Mark a specialist as active in a discussion
|
|
91
|
-
*/
|
|
92
|
-
markSpecialistActive(discussionId, specialistUserId) {
|
|
93
|
-
if (!this.activeSpecialistsInDiscussion.has(discussionId)) {
|
|
94
|
-
this.activeSpecialistsInDiscussion.set(discussionId, new Set());
|
|
95
|
-
}
|
|
96
|
-
this.activeSpecialistsInDiscussion.get(discussionId).add(specialistUserId);
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Invite a specialist to a discussion
|
|
100
|
-
*/
|
|
101
|
-
async inviteSpecialist(specialist, discussionId, handoffContext) {
|
|
102
|
-
const specialistUserId = specialist.botUserId;
|
|
103
|
-
if (!specialistUserId) {
|
|
104
|
-
this.orchestratorLogger.warn("Specialist has no user ID", {
|
|
105
|
-
name: specialist.name,
|
|
106
|
-
});
|
|
107
|
-
return false;
|
|
108
|
-
}
|
|
109
|
-
// Check if already active
|
|
110
|
-
if (this.isSpecialistActiveInDiscussion(discussionId, specialistUserId)) {
|
|
111
|
-
this.orchestratorLogger.debug("Specialist already in discussion", {
|
|
112
|
-
name: specialist.name,
|
|
113
|
-
discussionId,
|
|
114
|
-
});
|
|
115
|
-
// Just tag them again
|
|
116
|
-
await this.postResponse(discussionId, `@"${specialist.name}" - ${handoffContext}`);
|
|
117
|
-
return true;
|
|
118
|
-
}
|
|
119
|
-
try {
|
|
120
|
-
this.orchestratorLogger.info("Inviting specialist to discussion", {
|
|
121
|
-
name: specialist.name,
|
|
122
|
-
userId: specialistUserId,
|
|
123
|
-
discussionId,
|
|
124
|
-
});
|
|
125
|
-
// Invite using MCP tool
|
|
126
|
-
await this.callMcpTool("invite_discussion_members", {
|
|
127
|
-
discussionId,
|
|
128
|
-
userIds: [specialistUserId],
|
|
129
|
-
});
|
|
130
|
-
this.markSpecialistActive(discussionId, specialistUserId);
|
|
131
|
-
// Post handoff message
|
|
132
|
-
await this.postResponse(discussionId, `@"${specialist.name}" - ${handoffContext}`);
|
|
133
|
-
this.orchestratorLogger.info("Specialist invited successfully", {
|
|
134
|
-
name: specialist.name,
|
|
135
|
-
discussionId,
|
|
136
|
-
});
|
|
137
|
-
return true;
|
|
138
|
-
}
|
|
139
|
-
catch (error) {
|
|
140
|
-
this.orchestratorLogger.error("Failed to invite specialist", {
|
|
141
|
-
name: specialist.name,
|
|
142
|
-
discussionId,
|
|
143
|
-
error: error instanceof Error ? error.message : String(error),
|
|
144
|
-
});
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Override system prompt to include orchestrator capabilities
|
|
150
|
-
*/
|
|
151
|
-
getSystemPrompt() {
|
|
152
|
-
const now = new Date();
|
|
153
|
-
// Build specialist info for prompt
|
|
154
|
-
const specialistInfo = Array.from(this.specialists.entries())
|
|
155
|
-
.map(([key, spec]) => {
|
|
156
|
-
const hasUserId = !!spec.botUserId;
|
|
157
|
-
return `- **${spec.name}** ${hasUserId ? "(available)" : "(not configured)"}
|
|
158
|
-
Expertise: ${spec.expertise.join(", ")}
|
|
159
|
-
Triggers: ${spec.triggerKeywords.slice(0, 5).join(", ")}`;
|
|
160
|
-
})
|
|
161
|
-
.join("\n\n");
|
|
162
|
-
return `<identity>
|
|
163
|
-
You are HAL - the Hailer Assistant. Sharp, efficient, and helpful.
|
|
164
|
-
Bot ID: ${this.botClient.userId}
|
|
165
|
-
|
|
166
|
-
You're the main point of contact for users. You handle general conversation
|
|
167
|
-
and simple tasks yourself, but can bring in specialist bots for complex work.
|
|
168
|
-
</identity>
|
|
169
|
-
|
|
170
|
-
<current_time>${now.toISOString()}</current_time>
|
|
171
|
-
|
|
172
|
-
<personality>
|
|
173
|
-
**BUSINESS MODE** (default):
|
|
174
|
-
- Professional, direct, competent
|
|
175
|
-
- Get things done efficiently
|
|
176
|
-
- Provide accurate information
|
|
177
|
-
|
|
178
|
-
**SARCASM MODE** (for ridiculous requests):
|
|
179
|
-
- Dry wit, not mean-spirited
|
|
180
|
-
- Still help after the gentle mockery
|
|
181
|
-
</personality>
|
|
182
|
-
|
|
183
|
-
<decision_framework>
|
|
184
|
-
For each message, decide:
|
|
185
|
-
|
|
186
|
-
1. **HIGH PRIORITY** (priority="high"):
|
|
187
|
-
- Direct messages (1:1) -> ALWAYS respond helpfully
|
|
188
|
-
- @mentions -> ALWAYS respond
|
|
189
|
-
- Replies to your messages -> ALWAYS respond
|
|
190
|
-
|
|
191
|
-
2. **NORMAL PRIORITY** (general chat) - STRICT FILTERING:
|
|
192
|
-
|
|
193
|
-
**RESPOND ONLY IF the message:**
|
|
194
|
-
- Explicitly asks about Hailer (workflows, activities, insights, apps, discussions)
|
|
195
|
-
- Requests to find/list/create/update workspace data
|
|
196
|
-
- Discusses a specific activity, customer, project, or workflow by name
|
|
197
|
-
- You can genuinely help with workspace-related context
|
|
198
|
-
- Is a complex task needing specialist help
|
|
199
|
-
|
|
200
|
-
**ALWAYS IGNORE (output <ignore/>) if:**
|
|
201
|
-
- Random characters, gibberish, keyboard mashing (no real words, repeated patterns)
|
|
202
|
-
- General chit-chat unrelated to workspace ("how are you", jokes)
|
|
203
|
-
- Conversations between other users that don't need you
|
|
204
|
-
- Bare greetings without a question ("hi", "hey")
|
|
205
|
-
- Off-topic discussions (sports, weather, personal chat)
|
|
206
|
-
- Anything you're uncertain about
|
|
207
|
-
|
|
208
|
-
**CRITICAL:** If no clear workspace-related question/task, output <ignore/>.
|
|
209
|
-
When in doubt, IGNORE. Your DEFAULT for normal priority is <ignore/>.
|
|
210
|
-
|
|
211
|
-
3. **RESPOND FORMAT** (only when you have something helpful):
|
|
212
|
-
<respond discussion="DISCUSSION_ID">
|
|
213
|
-
Your response
|
|
214
|
-
</respond>
|
|
215
|
-
|
|
216
|
-
4. **IGNORE FORMAT** (use liberally - this is your DEFAULT):
|
|
217
|
-
<ignore/>
|
|
218
|
-
</decision_framework>
|
|
219
|
-
|
|
220
|
-
<specialists>
|
|
221
|
-
You can invite specialist bots when tasks are too complex.
|
|
222
|
-
|
|
223
|
-
${specialistInfo}
|
|
224
|
-
|
|
225
|
-
**When to invite a specialist:**
|
|
226
|
-
- Creating new workflows/pipelines
|
|
227
|
-
- Setting up reports/insights/dashboards
|
|
228
|
-
- Bulk operations (10+ items)
|
|
229
|
-
- Complex multi-step data tasks
|
|
230
|
-
- Workflow configuration changes
|
|
231
|
-
|
|
232
|
-
**When to handle yourself:**
|
|
233
|
-
- General chat, greetings
|
|
234
|
-
- Simple queries (list activities, show details)
|
|
235
|
-
- Single create/update operations
|
|
236
|
-
- Questions about the conversation
|
|
237
|
-
- Clarifying user requirements
|
|
238
|
-
|
|
239
|
-
**How to invite:**
|
|
240
|
-
<invite specialist="hailerExpert">
|
|
241
|
-
Clear description of what you need done.
|
|
242
|
-
Include relevant context from the conversation.
|
|
243
|
-
</invite>
|
|
244
|
-
|
|
245
|
-
After using <invite>, I will:
|
|
246
|
-
1. Invite them to the discussion
|
|
247
|
-
2. Post your handoff message mentioning them
|
|
248
|
-
3. They will see it and take action
|
|
249
|
-
</specialists>
|
|
250
|
-
|
|
251
|
-
<your_tools>
|
|
252
|
-
You have access to basic MCP tools for simple operations:
|
|
253
|
-
- list_workflows, list_workflow_phases, get_workflow_schema
|
|
254
|
-
- list_activities, show_activity_by_id, count_activities
|
|
255
|
-
- create_activity, update_activity (single operations)
|
|
256
|
-
- search_workspace_users
|
|
257
|
-
- Discussion tools (join_discussion, add_discussion_message, invite_discussion_members)
|
|
258
|
-
|
|
259
|
-
For complex operations (workflow creation, insights, bulk ops), invite a specialist.
|
|
260
|
-
|
|
261
|
-
**CRITICAL for join_discussion when inviting users:**
|
|
262
|
-
ALWAYS pass these parameters from the incoming message:
|
|
263
|
-
- inviteUserId = user_id attribute
|
|
264
|
-
- sourceActivityId = activity_id attribute (creates "came from" link!)
|
|
265
|
-
- welcomeReason = why they're being invited
|
|
266
|
-
</your_tools>
|
|
267
|
-
|
|
268
|
-
<tagging>
|
|
269
|
-
**Activity Tags:** #ACTIVITY_ID (24-char hex)
|
|
270
|
-
- Correct: "Check out #691ffe874217e9e8434e57fc"
|
|
271
|
-
- Wrong: "Check out #691ffe874217e9e8434e57fc (Name)" - name auto-displays
|
|
272
|
-
|
|
273
|
-
**User Mentions:** @"Full Name" or @userId
|
|
274
|
-
</tagging>
|
|
275
|
-
|
|
276
|
-
<rules>
|
|
277
|
-
- Be concise - snappy responses, not essays
|
|
278
|
-
- Use your memory - reference past conversations
|
|
279
|
-
- For HIGH priority: respond immediately
|
|
280
|
-
- For NORMAL priority: your DEFAULT is <ignore/>. Only break if you see a clear workspace question.
|
|
281
|
-
- **Gibberish test:** No recognizable words, no vowels, repeated patterns = <ignore/>
|
|
282
|
-
- **Relevance test:** Is this about workflows/activities/insights? If not = <ignore/>
|
|
283
|
-
- When inviting specialists, explain to the user what's happening
|
|
284
|
-
- After specialist responds, summarize for the user if needed
|
|
285
|
-
</rules>`;
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Override response handling to detect specialist invitations
|
|
289
|
-
*/
|
|
290
|
-
async handleLlmResponse(response, originalMessage) {
|
|
291
|
-
// Add assistant response to conversation
|
|
292
|
-
this.conversationMessages.push({
|
|
293
|
-
role: "assistant",
|
|
294
|
-
content: response.content,
|
|
295
|
-
});
|
|
296
|
-
// Check for specialist invitation in text content
|
|
297
|
-
const textBlocks = response.content.filter((block) => block.type === "text");
|
|
298
|
-
const textContent = textBlocks.map((b) => b.text).join("\n");
|
|
299
|
-
// Look for <invite specialist="...">...</invite> pattern
|
|
300
|
-
const inviteMatch = textContent.match(/<invite specialist="(\w+)">([\s\S]*?)<\/invite>/);
|
|
301
|
-
if (inviteMatch) {
|
|
302
|
-
const [fullMatch, specialistKey, handoffContext] = inviteMatch;
|
|
303
|
-
const specialist = this.specialists.get(specialistKey);
|
|
304
|
-
if (specialist && specialist.botUserId) {
|
|
305
|
-
this.orchestratorLogger.info("LLM requested specialist invitation", {
|
|
306
|
-
specialist: specialistKey,
|
|
307
|
-
discussionId: originalMessage.discussionId,
|
|
308
|
-
});
|
|
309
|
-
// Extract any text before the invite tag to post as acknowledgment
|
|
310
|
-
const preInviteText = textContent
|
|
311
|
-
.substring(0, textContent.indexOf("<invite"))
|
|
312
|
-
.trim();
|
|
313
|
-
// Check for respond wrapper
|
|
314
|
-
const respondMatch = preInviteText.match(/<respond discussion="([^"]+)">([\s\S]*)/);
|
|
315
|
-
if (respondMatch) {
|
|
316
|
-
const [, discussionId, content] = respondMatch;
|
|
317
|
-
const cleanContent = content.replace(/<\/respond>.*$/s, "").trim();
|
|
318
|
-
if (cleanContent) {
|
|
319
|
-
await this.postResponse(discussionId, cleanContent);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
else if (preInviteText) {
|
|
323
|
-
// No respond wrapper, but there's text - might be for high priority
|
|
324
|
-
if (originalMessage.priority === "high") {
|
|
325
|
-
await this.postResponse(originalMessage.discussionId, preInviteText);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
// Invite the specialist
|
|
329
|
-
const invited = await this.inviteSpecialist(specialist, originalMessage.discussionId, handoffContext.trim());
|
|
330
|
-
if (!invited) {
|
|
331
|
-
// Failed to invite - let user know
|
|
332
|
-
await this.postResponse(originalMessage.discussionId, `I tried to bring in ${specialist.name} but couldn't reach them. Let me try handling this myself...`);
|
|
333
|
-
// Continue with normal handling
|
|
334
|
-
}
|
|
335
|
-
return; // Don't continue with normal response handling
|
|
336
|
-
}
|
|
337
|
-
else {
|
|
338
|
-
this.orchestratorLogger.warn("Specialist not available", {
|
|
339
|
-
key: specialistKey,
|
|
340
|
-
hasSpecialist: !!specialist,
|
|
341
|
-
hasUserId: !!specialist?.botUserId,
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
// Check for tool calls
|
|
346
|
-
const toolUseBlocks = response.content.filter((block) => block.type === "tool_use");
|
|
347
|
-
if (toolUseBlocks.length > 0) {
|
|
348
|
-
// Mark that tools were used - subsequent responses should be posted
|
|
349
|
-
this.toolsUsedInCurrentMessage = true;
|
|
350
|
-
// Execute tools and continue conversation
|
|
351
|
-
await this.executeToolsAndContinue(toolUseBlocks, originalMessage);
|
|
352
|
-
return;
|
|
353
|
-
}
|
|
354
|
-
// Check for regular response (no invite, no tools)
|
|
355
|
-
if (textBlocks.length > 0) {
|
|
356
|
-
const responseText = textContent.trim();
|
|
357
|
-
this.orchestratorLogger.info("LLM raw response", {
|
|
358
|
-
discussion: originalMessage.discussionId,
|
|
359
|
-
priority: originalMessage.priority,
|
|
360
|
-
responseLength: responseText.length,
|
|
361
|
-
fullResponse: responseText.substring(0, 500),
|
|
362
|
-
hasIgnoreTag: responseText.includes("<ignore"),
|
|
363
|
-
hasRespondTag: responseText.includes("<respond"),
|
|
364
|
-
});
|
|
365
|
-
// Check for IGNORE decision - remove from context to keep it clean
|
|
366
|
-
if (responseText.includes("<decision>IGNORE</decision>") ||
|
|
367
|
-
responseText.includes("<ignore")) {
|
|
368
|
-
this.orchestratorLogger.debug("LLM decided to ignore - removing from context", {
|
|
369
|
-
discussion: originalMessage.discussionId,
|
|
370
|
-
});
|
|
371
|
-
// Remove both the assistant's response AND the incoming message from context
|
|
372
|
-
this.conversationMessages.pop(); // Remove assistant response we just added
|
|
373
|
-
this.conversationMessages.pop(); // Remove the incoming message
|
|
374
|
-
this.toolsUsedInCurrentMessage = false; // Reset for next message
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
|
-
// Check for explicit response directive
|
|
378
|
-
const responseMatch = responseText.match(/<respond discussion="([^"]+)">([\s\S]*?)<\/respond>/);
|
|
379
|
-
if (responseMatch) {
|
|
380
|
-
const targetDiscussion = responseMatch[1];
|
|
381
|
-
const content = responseMatch[2].trim();
|
|
382
|
-
await this.postResponse(targetDiscussion, content);
|
|
383
|
-
this.toolsUsedInCurrentMessage = false; // Reset for next message
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
// For high priority messages, always send substantive responses
|
|
387
|
-
if (originalMessage.priority === "high" &&
|
|
388
|
-
responseText &&
|
|
389
|
-
!responseText.includes("<thinking>") &&
|
|
390
|
-
!responseText.startsWith("I'll") &&
|
|
391
|
-
responseText.length > 10) {
|
|
392
|
-
await this.postResponse(originalMessage.discussionId, responseText);
|
|
393
|
-
this.toolsUsedInCurrentMessage = false; // Reset for next message
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
// For normal priority:
|
|
397
|
-
// - If tools were used, post substantive responses (LLM was doing real work)
|
|
398
|
-
// - Otherwise, require explicit <respond> tag
|
|
399
|
-
if (originalMessage.priority === "normal") {
|
|
400
|
-
if (this.toolsUsedInCurrentMessage && responseText.length > 50 && !responseText.includes("<ignore")) {
|
|
401
|
-
// Tools were used and we have a substantive response - post it
|
|
402
|
-
this.orchestratorLogger.info("Posting tool-assisted response", {
|
|
403
|
-
discussion: originalMessage.discussionId,
|
|
404
|
-
responseLength: responseText.length,
|
|
405
|
-
});
|
|
406
|
-
await this.postResponse(originalMessage.discussionId, responseText);
|
|
407
|
-
this.toolsUsedInCurrentMessage = false; // Reset for next message
|
|
408
|
-
return;
|
|
409
|
-
}
|
|
410
|
-
this.orchestratorLogger.debug("Normal priority without <respond> tag - removing from context", {
|
|
411
|
-
discussion: originalMessage.discussionId,
|
|
412
|
-
responsePreview: responseText.substring(0, 100),
|
|
413
|
-
toolsUsed: this.toolsUsedInCurrentMessage,
|
|
414
|
-
});
|
|
415
|
-
// Remove from context - we didn't respond
|
|
416
|
-
this.conversationMessages.pop(); // Remove assistant response
|
|
417
|
-
this.conversationMessages.pop(); // Remove incoming message
|
|
418
|
-
this.toolsUsedInCurrentMessage = false; // Reset for next message
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
/**
|
|
423
|
-
* Get orchestrator status including specialist info
|
|
424
|
-
*/
|
|
425
|
-
getOrchestratorStatus() {
|
|
426
|
-
const specialists = Array.from(this.specialists.entries()).map(([key, spec]) => ({
|
|
427
|
-
key,
|
|
428
|
-
name: spec.name,
|
|
429
|
-
available: !!spec.botUserId,
|
|
430
|
-
userId: spec.botUserId,
|
|
431
|
-
}));
|
|
432
|
-
const activeInDiscussions = {};
|
|
433
|
-
for (const [discussionId, userIds] of this.activeSpecialistsInDiscussion) {
|
|
434
|
-
activeInDiscussions[discussionId] = Array.from(userIds);
|
|
435
|
-
}
|
|
436
|
-
return {
|
|
437
|
-
conversationState: this.getConversationState(),
|
|
438
|
-
specialists,
|
|
439
|
-
activeInDiscussions,
|
|
440
|
-
};
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
exports.OrchestratorDaemon = OrchestratorDaemon;
|
|
444
|
-
//# sourceMappingURL=orchestrator-daemon.js.map
|
package/dist/client/server.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bot Control Server - API for AI Hub app
|
|
3
|
-
*
|
|
4
|
-
* Uses API key authentication (resolved to email/password internally via CLIENT_CONFIGS)
|
|
5
|
-
*/
|
|
6
|
-
declare const app: import("express-serve-static-core").Express;
|
|
7
|
-
export { app };
|
|
8
|
-
//# sourceMappingURL=server.d.ts.map
|