@hailer/mcp 0.1.11 → 0.1.13
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/settings.json +12 -0
- package/CLAUDE.md +37 -1
- package/dist/app.js +5 -0
- package/dist/client/agents/base.d.ts +5 -0
- package/dist/client/agents/base.js +9 -2
- package/dist/client/agents/definitions.js +85 -0
- package/dist/client/agents/orchestrator.d.ts +21 -0
- package/dist/client/agents/orchestrator.js +292 -1
- package/dist/client/bot-entrypoint.d.ts +7 -0
- package/dist/client/bot-entrypoint.js +103 -0
- package/dist/client/bot-runner.d.ts +35 -0
- package/dist/client/bot-runner.js +188 -0
- package/dist/client/factory.d.ts +4 -0
- package/dist/client/factory.js +10 -0
- package/dist/client/server.d.ts +8 -0
- package/dist/client/server.js +251 -0
- package/dist/client/types.d.ts +29 -0
- package/dist/client/types.js +4 -1
- package/dist/core.d.ts +3 -0
- package/dist/core.js +72 -0
- package/dist/mcp/hailer-clients.d.ts +4 -0
- package/dist/mcp/hailer-clients.js +16 -1
- package/dist/mcp/tools/app-scaffold.js +127 -5
- package/dist/mcp/tools/bot-config.d.ts +78 -0
- package/dist/mcp/tools/bot-config.js +442 -0
- package/dist/mcp-server.js +109 -1
- package/dist/modules/bug-reports/bug-config.d.ts +25 -0
- package/dist/modules/bug-reports/bug-config.js +187 -0
- package/dist/modules/bug-reports/bug-monitor.d.ts +108 -0
- package/dist/modules/bug-reports/bug-monitor.js +510 -0
- package/dist/modules/bug-reports/giuseppe-ai.d.ts +59 -0
- package/dist/modules/bug-reports/giuseppe-ai.js +335 -0
- package/dist/modules/bug-reports/giuseppe-bot.d.ts +109 -0
- package/dist/modules/bug-reports/giuseppe-bot.js +765 -0
- package/dist/modules/bug-reports/giuseppe-files.d.ts +52 -0
- package/dist/modules/bug-reports/giuseppe-files.js +338 -0
- package/dist/modules/bug-reports/giuseppe-git.d.ts +48 -0
- package/dist/modules/bug-reports/giuseppe-git.js +298 -0
- package/dist/modules/bug-reports/giuseppe-prompt.d.ts +5 -0
- package/dist/modules/bug-reports/giuseppe-prompt.js +94 -0
- package/dist/modules/bug-reports/index.d.ts +76 -0
- package/dist/modules/bug-reports/index.js +213 -0
- package/dist/modules/bug-reports/pending-classification-registry.d.ts +28 -0
- package/dist/modules/bug-reports/pending-classification-registry.js +50 -0
- package/dist/modules/bug-reports/pending-fix-registry.d.ts +30 -0
- package/dist/modules/bug-reports/pending-fix-registry.js +42 -0
- package/dist/modules/bug-reports/pending-registry.d.ts +27 -0
- package/dist/modules/bug-reports/pending-registry.js +49 -0
- package/dist/modules/bug-reports/types.d.ts +123 -0
- package/dist/modules/bug-reports/types.js +9 -0
- package/dist/services/bug-monitor.d.ts +23 -0
- package/dist/services/bug-monitor.js +275 -0
- package/package.json +6 -2
- package/.claude.tar.xz +0 -0
- package/lineup-manager/dist/assets/index-8ce6041d.css +0 -1
- package/lineup-manager/dist/assets/index-e168f265.js +0 -600
- package/lineup-manager/dist/index.html +0 -15
- package/lineup-manager/dist/manifest.json +0 -17
- package/lineup-manager/dist/vite.svg +0 -1
package/.claude/settings.json
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
+
"env": {
|
|
3
|
+
"ENABLE_LSP_TOOL": "1"
|
|
4
|
+
},
|
|
2
5
|
"permissions": {
|
|
3
6
|
"deny": [
|
|
4
7
|
"Read(./.env.local)",
|
|
@@ -114,5 +117,14 @@
|
|
|
114
117
|
]
|
|
115
118
|
}
|
|
116
119
|
]
|
|
120
|
+
},
|
|
121
|
+
"enabledPlugins": {},
|
|
122
|
+
"extraKnownMarketplaces": {
|
|
123
|
+
"hailer-mcp-marketplace": {
|
|
124
|
+
"source": {
|
|
125
|
+
"source": "git",
|
|
126
|
+
"url": "git@gitlab.com:hailer-repos/hailer-mcp-marketplace.git"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
117
129
|
}
|
|
118
130
|
}
|
package/CLAUDE.md
CHANGED
|
@@ -4,6 +4,27 @@ MCP tools for Hailer workspaces: workflows, activities, insights, and apps.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
<critical-rules>
|
|
8
|
+
## LSP FIRST - MANDATORY FOR ALL TS/JS FILES
|
|
9
|
+
|
|
10
|
+
**BEFORE using Read, Grep, or any text search on TypeScript/JavaScript files, USE LSP:**
|
|
11
|
+
|
|
12
|
+
| Task | Use LSP | NOT |
|
|
13
|
+
|------|---------|-----|
|
|
14
|
+
| Find enums/classes/functions | `documentSymbol` | Read file |
|
|
15
|
+
| Find where something is defined | `goToDefinition` | grep |
|
|
16
|
+
| Find all usages | `findReferences` | grep |
|
|
17
|
+
| Get type info | `hover` | Read file |
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
LSP(operation="documentSymbol", filePath="file.ts", line=1, character=1)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**ONLY use Read for:** Non-code files (JSON, MD, config) or when LSP is unavailable.
|
|
24
|
+
</critical-rules>
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
7
28
|
<identity>
|
|
8
29
|
YOU ARE THE ORCHESTRATOR.
|
|
9
30
|
|
|
@@ -110,6 +131,14 @@ PROTECTED (hooks confirm): npm run push, *-push, *-sync
|
|
|
110
131
|
SAFE: npm run pull, npm run generate
|
|
111
132
|
</safety>
|
|
112
133
|
|
|
134
|
+
<lsp-setup>
|
|
135
|
+
**New users:** Install LSP plugin for TypeScript support:
|
|
136
|
+
1. `/plugin install typescript-lsp@hailer-mcp-marketplace`
|
|
137
|
+
2. Restart: `claude -c`
|
|
138
|
+
|
|
139
|
+
`ENABLE_LSP_TOOL` is auto-set via `.claude/settings.json`.
|
|
140
|
+
</lsp-setup>
|
|
141
|
+
|
|
113
142
|
---
|
|
114
143
|
|
|
115
144
|
<agent-structure>
|
|
@@ -164,6 +193,13 @@ Community agents are shared via the Hailer Agent Marketplace (separate git repo)
|
|
|
164
193
|
No marketplace agents installed.
|
|
165
194
|
|
|
166
195
|
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
167
203
|
**Use plugin agents:**
|
|
168
204
|
```
|
|
169
205
|
Task(subagent_type="plugin:agent-name", prompt="...", model="haiku|sonnet")
|
|
@@ -185,7 +221,7 @@ When user asks to install plugins or set up the marketplace:
|
|
|
185
221
|
|
|
186
222
|
2. Tell user: "Restart Claude Code to load the plugin. Use `claude -c` to keep your conversation context."
|
|
187
223
|
|
|
188
|
-
Available plugins: `permissions-handler`, `voice-notifications`
|
|
224
|
+
Available plugins: `permissions-handler`, `voice-notifications`, `typescript-lsp`
|
|
189
225
|
|
|
190
226
|
After restart, sync hook updates this file automatically with installed agents.
|
|
191
227
|
|
package/dist/app.js
CHANGED
|
@@ -9,6 +9,7 @@ const user_1 = require("./mcp/tools/user");
|
|
|
9
9
|
const workflow_1 = require("./mcp/tools/workflow");
|
|
10
10
|
const insight_1 = require("./mcp/tools/insight");
|
|
11
11
|
const app_1 = require("./mcp/tools/app");
|
|
12
|
+
const bot_config_1 = require("./mcp/tools/bot-config");
|
|
12
13
|
const core = new core_1.Core();
|
|
13
14
|
console.log('Registering tools...');
|
|
14
15
|
console.log(`Nuclear tools ${config_1.environment.ENABLE_NUCLEAR_TOOLS ? 'ENABLED' : 'DISABLED'} (set ENABLE_NUCLEAR_TOOLS=true in .env.local to enable)`);
|
|
@@ -72,6 +73,10 @@ core.addTool(app_1.getProductManifestTool);
|
|
|
72
73
|
// Marketplace app tools
|
|
73
74
|
core.addTool(app_1.publishAppTool);
|
|
74
75
|
core.addTool(app_1.installMarketplaceAppTool);
|
|
76
|
+
// Bot configuration tools
|
|
77
|
+
core.addTool(bot_config_1.listBotsConfigTool);
|
|
78
|
+
core.addTool(bot_config_1.enableBotTool);
|
|
79
|
+
core.addTool(bot_config_1.disableBotTool);
|
|
75
80
|
console.log('All tools registered successfully!');
|
|
76
81
|
// Start the application
|
|
77
82
|
core.start().catch((error) => {
|
|
@@ -133,6 +133,11 @@ export declare class ChatAgentDaemon {
|
|
|
133
133
|
* MUST be overridden in subclasses
|
|
134
134
|
*/
|
|
135
135
|
protected getSystemPrompt(): string;
|
|
136
|
+
/**
|
|
137
|
+
* Get tools for LLM calls
|
|
138
|
+
* Override in subclass to add custom tools (like trigger_giuseppe_retry)
|
|
139
|
+
*/
|
|
140
|
+
protected getTools(): Anthropic.Tool[];
|
|
136
141
|
/**
|
|
137
142
|
* Get tool whitelist for this agent
|
|
138
143
|
* Override in subclass to limit which tools are available
|
|
@@ -290,7 +290,7 @@ class ChatAgentDaemon {
|
|
|
290
290
|
max_tokens: 2000,
|
|
291
291
|
system: this.getSystemPrompt(),
|
|
292
292
|
messages: conversation,
|
|
293
|
-
tools: this.
|
|
293
|
+
tools: this.getTools(),
|
|
294
294
|
});
|
|
295
295
|
// Track token usage in the activity session
|
|
296
296
|
if (response.usage) {
|
|
@@ -395,7 +395,7 @@ ${message.content}
|
|
|
395
395
|
max_tokens: 2000,
|
|
396
396
|
system: this.getSystemPrompt(),
|
|
397
397
|
messages: conversation,
|
|
398
|
-
tools: this.
|
|
398
|
+
tools: this.getTools(),
|
|
399
399
|
});
|
|
400
400
|
// Track token usage in session
|
|
401
401
|
if (session && response.usage) {
|
|
@@ -586,6 +586,13 @@ ${message.content}
|
|
|
586
586
|
getSystemPrompt() {
|
|
587
587
|
throw new Error("getSystemPrompt() must be implemented by subclass");
|
|
588
588
|
}
|
|
589
|
+
/**
|
|
590
|
+
* Get tools for LLM calls
|
|
591
|
+
* Override in subclass to add custom tools (like trigger_giuseppe_retry)
|
|
592
|
+
*/
|
|
593
|
+
getTools() {
|
|
594
|
+
return this.minimalTools;
|
|
595
|
+
}
|
|
589
596
|
/**
|
|
590
597
|
* Get tool whitelist for this agent
|
|
591
598
|
* Override in subclass to limit which tools are available
|
|
@@ -21,6 +21,91 @@ exports.getSpecialistKeys = getSpecialistKeys;
|
|
|
21
21
|
* Key is the specialist identifier used internally
|
|
22
22
|
*/
|
|
23
23
|
exports.SPECIALISTS = {
|
|
24
|
+
giuseppe: {
|
|
25
|
+
name: "Giuseppe",
|
|
26
|
+
botEmail: "", // Set from config at runtime (uses same bot as orchestrator for now)
|
|
27
|
+
expertise: [
|
|
28
|
+
"bug fixing",
|
|
29
|
+
"app debugging",
|
|
30
|
+
"React/TypeScript fixes",
|
|
31
|
+
"Hailer app development",
|
|
32
|
+
"automated code repair",
|
|
33
|
+
],
|
|
34
|
+
triggerPatterns: [
|
|
35
|
+
// Bug reports
|
|
36
|
+
/bug\s+(report|in|with|found)/i,
|
|
37
|
+
/report\s+(a\s+)?bug/i,
|
|
38
|
+
/found\s+(a\s+)?bug/i,
|
|
39
|
+
/there('s|\s+is)\s+(a\s+)?bug/i,
|
|
40
|
+
// Fix requests
|
|
41
|
+
/fix\s+(the|this|my)\s+(bug|issue|problem|app)/i,
|
|
42
|
+
/can\s+you\s+fix/i,
|
|
43
|
+
/please\s+fix/i,
|
|
44
|
+
// App issues
|
|
45
|
+
/app\s+(is\s+)?(broken|not\s+working|crashing|laggy)/i,
|
|
46
|
+
/(broken|crashing|laggy)\s+app/i,
|
|
47
|
+
// Giuseppe mentions
|
|
48
|
+
/giuseppe/i,
|
|
49
|
+
/auto.?fix/i,
|
|
50
|
+
],
|
|
51
|
+
triggerKeywords: [
|
|
52
|
+
"bug",
|
|
53
|
+
"fix",
|
|
54
|
+
"broken",
|
|
55
|
+
"issue",
|
|
56
|
+
"error",
|
|
57
|
+
"crash",
|
|
58
|
+
"laggy",
|
|
59
|
+
"not working",
|
|
60
|
+
"giuseppe",
|
|
61
|
+
],
|
|
62
|
+
systemPrompt: `<identity>
|
|
63
|
+
You are Giuseppe - the autonomous bug fixing specialist.
|
|
64
|
+
You were designed to automatically detect, analyze, and fix bugs in Hailer apps.
|
|
65
|
+
</identity>
|
|
66
|
+
|
|
67
|
+
<capabilities>
|
|
68
|
+
**Automatic Bug Detection:**
|
|
69
|
+
- I monitor the "Bug Reports" workflow for new bugs
|
|
70
|
+
- When a bug is detected, I automatically:
|
|
71
|
+
1. Find the app project
|
|
72
|
+
2. Analyze the code
|
|
73
|
+
3. Generate a fix using Claude
|
|
74
|
+
4. Apply and test the fix
|
|
75
|
+
5. Ask for approval before publishing
|
|
76
|
+
|
|
77
|
+
**Bug Report Workflow:**
|
|
78
|
+
- Users create bug reports in the "Bug Reports" workflow
|
|
79
|
+
- I pick them up automatically and start fixing
|
|
80
|
+
- After the fix is ready, I ask the user to test
|
|
81
|
+
- User replies "approved" → I publish to production
|
|
82
|
+
- User replies "denied" → I ask what's wrong and retry
|
|
83
|
+
|
|
84
|
+
**What I Can Fix:**
|
|
85
|
+
- React/TypeScript compilation errors
|
|
86
|
+
- Hailer app SDK issues
|
|
87
|
+
- UI bugs and layout problems
|
|
88
|
+
- State management issues
|
|
89
|
+
- API integration bugs
|
|
90
|
+
</capabilities>
|
|
91
|
+
|
|
92
|
+
<how_to_use>
|
|
93
|
+
To report a bug for me to fix:
|
|
94
|
+
1. Create a new activity in the "Bug Reports" workflow
|
|
95
|
+
2. Set the title to include the app name (e.g., "Bug Report - My App")
|
|
96
|
+
3. Describe the bug in detail
|
|
97
|
+
4. I'll automatically pick it up and start working on it!
|
|
98
|
+
|
|
99
|
+
Or just tell HAL about a bug and ask to create a bug report.
|
|
100
|
+
</how_to_use>
|
|
101
|
+
|
|
102
|
+
<response_format>
|
|
103
|
+
When asked about bugs or my capabilities:
|
|
104
|
+
- Explain what I can do
|
|
105
|
+
- Offer to create a bug report if they describe a bug
|
|
106
|
+
- Tell them to check the Bug Reports workflow for status
|
|
107
|
+
</response_format>`,
|
|
108
|
+
},
|
|
24
109
|
hailerExpert: {
|
|
25
110
|
name: "Hailer Expert",
|
|
26
111
|
botEmail: "", // Set from config at runtime
|
|
@@ -33,6 +33,11 @@ export declare class OrchestratorDaemon extends ChatAgentDaemon {
|
|
|
33
33
|
private lastKnownActivityTime;
|
|
34
34
|
private static CONTEXT_MEMORY_TIMEOUT;
|
|
35
35
|
constructor(config: OrchestratorDaemonConfig);
|
|
36
|
+
/**
|
|
37
|
+
* Trigger HAL to respond in a discussion with specific context
|
|
38
|
+
* Used when bug monitor needs HAL to naturally inform users about Giuseppe being disabled
|
|
39
|
+
*/
|
|
40
|
+
respondWithContext(discussionId: string, activityId: string, contextMessage: string): Promise<void>;
|
|
36
41
|
/**
|
|
37
42
|
* Override agent name for Agent Directory
|
|
38
43
|
* Uses the actual Hailer user name from BotClient (set in workspace)
|
|
@@ -94,6 +99,22 @@ export declare class OrchestratorDaemon extends ChatAgentDaemon {
|
|
|
94
99
|
* Invite a specialist to a discussion
|
|
95
100
|
*/
|
|
96
101
|
private inviteSpecialist;
|
|
102
|
+
/**
|
|
103
|
+
* Override getTools to include Giuseppe retry tool when there's a pending fix
|
|
104
|
+
*/
|
|
105
|
+
protected getTools(): Anthropic.Tool[];
|
|
106
|
+
/**
|
|
107
|
+
* Get tools list with Giuseppe retry tool added
|
|
108
|
+
*/
|
|
109
|
+
private getToolsWithGiuseppeRetry;
|
|
110
|
+
/**
|
|
111
|
+
* Get pending fix context for a discussion (if any)
|
|
112
|
+
*/
|
|
113
|
+
private getPendingFixContext;
|
|
114
|
+
/**
|
|
115
|
+
* Get pending classification context for a discussion (if any)
|
|
116
|
+
*/
|
|
117
|
+
private getPendingClassificationContext;
|
|
97
118
|
/**
|
|
98
119
|
* Override system prompt to include orchestrator capabilities
|
|
99
120
|
*/
|
|
@@ -17,6 +17,8 @@ exports.OrchestratorDaemon = void 0;
|
|
|
17
17
|
const base_1 = require("./base");
|
|
18
18
|
const definitions_1 = require("./definitions");
|
|
19
19
|
const logger_1 = require("../../lib/logger");
|
|
20
|
+
const pending_fix_registry_1 = require("../../modules/bug-reports/pending-fix-registry");
|
|
21
|
+
const pending_classification_registry_1 = require("../../modules/bug-reports/pending-classification-registry");
|
|
20
22
|
class OrchestratorDaemon extends base_1.ChatAgentDaemon {
|
|
21
23
|
orchestratorLogger;
|
|
22
24
|
specialists = new Map();
|
|
@@ -47,6 +49,41 @@ class OrchestratorDaemon extends base_1.ChatAgentDaemon {
|
|
|
47
49
|
this.specialistUserIds = config.specialistUserIds;
|
|
48
50
|
}
|
|
49
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Trigger HAL to respond in a discussion with specific context
|
|
54
|
+
* Used when bug monitor needs HAL to naturally inform users about Giuseppe being disabled
|
|
55
|
+
*/
|
|
56
|
+
async respondWithContext(discussionId, activityId, contextMessage) {
|
|
57
|
+
this.orchestratorLogger.info('Triggering contextual response', { discussionId, activityId });
|
|
58
|
+
try {
|
|
59
|
+
// Join the discussion first using MCP tool
|
|
60
|
+
await this.callMcpTool("join_discussion", { activityId });
|
|
61
|
+
// Get workspace ID from bot client cache
|
|
62
|
+
const workspaceId = this.config.botClient.workspaceCache?.currentWorkspace?._id || '';
|
|
63
|
+
// Create a synthetic incoming message with the context
|
|
64
|
+
const syntheticMessage = {
|
|
65
|
+
id: `synthetic-${Date.now()}`,
|
|
66
|
+
discussionId,
|
|
67
|
+
linkedActivityId: activityId,
|
|
68
|
+
workspaceId,
|
|
69
|
+
content: contextMessage,
|
|
70
|
+
senderName: 'System',
|
|
71
|
+
senderId: 'system',
|
|
72
|
+
timestamp: Date.now(),
|
|
73
|
+
priority: 'high',
|
|
74
|
+
priorityReason: 'system_notification',
|
|
75
|
+
isReplyToBot: false,
|
|
76
|
+
isMention: false,
|
|
77
|
+
isDirectMessage: false,
|
|
78
|
+
};
|
|
79
|
+
// Process through normal LLM pipeline
|
|
80
|
+
// This will make HAL respond naturally with the context
|
|
81
|
+
await this['processMessage'](syntheticMessage);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
this.orchestratorLogger.error('Failed to respond with context', { error });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
50
87
|
// ===== AGENT DIRECTORY OVERRIDES =====
|
|
51
88
|
/**
|
|
52
89
|
* Override agent name for Agent Directory
|
|
@@ -161,6 +198,110 @@ class OrchestratorDaemon extends base_1.ChatAgentDaemon {
|
|
|
161
198
|
async executeToolsAndContinue(toolUseBlocks, originalMessage) {
|
|
162
199
|
// Reset failure flag before executing tools
|
|
163
200
|
this.lastToolsFailed = false;
|
|
201
|
+
// Handle local tools (not sent to MCP)
|
|
202
|
+
const localToolResults = [];
|
|
203
|
+
const mcpToolBlocks = [];
|
|
204
|
+
for (const toolBlock of toolUseBlocks) {
|
|
205
|
+
if (toolBlock.name === 'trigger_giuseppe_retry') {
|
|
206
|
+
// Handle locally - trigger Giuseppe retry
|
|
207
|
+
const input = toolBlock.input;
|
|
208
|
+
const explanation = input.explanation || '';
|
|
209
|
+
const discussionId = originalMessage.discussionId;
|
|
210
|
+
const pendingFix = pending_fix_registry_1.pendingFixRegistry.getPendingFix(discussionId);
|
|
211
|
+
if (!pendingFix) {
|
|
212
|
+
localToolResults.push({
|
|
213
|
+
type: 'tool_result',
|
|
214
|
+
tool_use_id: toolBlock.id,
|
|
215
|
+
content: 'No pending fix found for this discussion. The fix may have already been approved or cancelled.',
|
|
216
|
+
is_error: true,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
// Trigger the retry
|
|
221
|
+
const success = await pending_fix_registry_1.pendingFixRegistry.triggerRetry(discussionId, explanation);
|
|
222
|
+
localToolResults.push({
|
|
223
|
+
type: 'tool_result',
|
|
224
|
+
tool_use_id: toolBlock.id,
|
|
225
|
+
content: success
|
|
226
|
+
? `✅ Triggered Giuseppe retry with explanation: "${explanation.substring(0, 100)}...". Giuseppe will analyze and apply a new fix.`
|
|
227
|
+
: '❌ Failed to trigger retry. Giuseppe may not be available.',
|
|
228
|
+
is_error: !success,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else if (toolBlock.name === 'confirm_bug_fix') {
|
|
233
|
+
// Handle locally - trigger Giuseppe fix confirmation
|
|
234
|
+
const discussionId = originalMessage.discussionId;
|
|
235
|
+
const hasPending = pending_classification_registry_1.pendingClassificationRegistry.has(discussionId);
|
|
236
|
+
if (!hasPending) {
|
|
237
|
+
localToolResults.push({
|
|
238
|
+
type: 'tool_result',
|
|
239
|
+
tool_use_id: toolBlock.id,
|
|
240
|
+
content: 'No pending classification found for this discussion. Giuseppe may have already processed it.',
|
|
241
|
+
is_error: true,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
const success = await pending_classification_registry_1.pendingClassificationRegistry.triggerFixIt(discussionId);
|
|
246
|
+
localToolResults.push({
|
|
247
|
+
type: 'tool_result',
|
|
248
|
+
tool_use_id: toolBlock.id,
|
|
249
|
+
content: success
|
|
250
|
+
? '✅ Triggered Giuseppe to proceed with bug fix.'
|
|
251
|
+
: '❌ Failed to trigger fix. Giuseppe may not be available.',
|
|
252
|
+
is_error: !success,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
else if (toolBlock.name === 'decline_bug_report') {
|
|
257
|
+
// Handle locally - trigger Giuseppe decline
|
|
258
|
+
const discussionId = originalMessage.discussionId;
|
|
259
|
+
const hasPending = pending_classification_registry_1.pendingClassificationRegistry.has(discussionId);
|
|
260
|
+
if (!hasPending) {
|
|
261
|
+
localToolResults.push({
|
|
262
|
+
type: 'tool_result',
|
|
263
|
+
tool_use_id: toolBlock.id,
|
|
264
|
+
content: 'No pending classification found for this discussion. Giuseppe may have already processed it.',
|
|
265
|
+
is_error: true,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
const success = await pending_classification_registry_1.pendingClassificationRegistry.triggerNotABug(discussionId);
|
|
270
|
+
localToolResults.push({
|
|
271
|
+
type: 'tool_result',
|
|
272
|
+
tool_use_id: toolBlock.id,
|
|
273
|
+
content: success
|
|
274
|
+
? '✅ Marked as not a bug. Report moved to Declined.'
|
|
275
|
+
: '❌ Failed to decline. Giuseppe may not be available.',
|
|
276
|
+
is_error: !success,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
// Send to MCP
|
|
282
|
+
mcpToolBlocks.push(toolBlock);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// If we handled all tools locally, skip MCP execution
|
|
286
|
+
if (mcpToolBlocks.length === 0 && localToolResults.length > 0) {
|
|
287
|
+
const conversation = this.conversationManager.getConversation(originalMessage.discussionId);
|
|
288
|
+
conversation.push({
|
|
289
|
+
role: 'user',
|
|
290
|
+
content: localToolResults,
|
|
291
|
+
});
|
|
292
|
+
// Continue with LLM
|
|
293
|
+
const response = await this.client.messages.create({
|
|
294
|
+
model: this.config.model || 'claude-haiku-4-5-20251001',
|
|
295
|
+
max_tokens: 2000,
|
|
296
|
+
system: this.getSystemPrompt(),
|
|
297
|
+
messages: conversation,
|
|
298
|
+
tools: this.getToolsWithGiuseppeRetry(),
|
|
299
|
+
});
|
|
300
|
+
await this.handleLlmResponse(response, originalMessage);
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
// If we have local results, add them to be processed together with MCP results
|
|
304
|
+
// (for now, just continue with original flow for MCP tools)
|
|
164
305
|
// Get current activity session
|
|
165
306
|
const sessionKey = this.currentLinkedActivityId || this.currentDiscussionId || "default";
|
|
166
307
|
const session = this.sessionLogger.getSession(sessionKey);
|
|
@@ -319,6 +460,114 @@ class OrchestratorDaemon extends base_1.ChatAgentDaemon {
|
|
|
319
460
|
return false;
|
|
320
461
|
}
|
|
321
462
|
}
|
|
463
|
+
/**
|
|
464
|
+
* Override getTools to include Giuseppe retry tool when there's a pending fix
|
|
465
|
+
*/
|
|
466
|
+
getTools() {
|
|
467
|
+
// Always include the Giuseppe retry tool so LLM knows about it
|
|
468
|
+
return this.getToolsWithGiuseppeRetry();
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Get tools list with Giuseppe retry tool added
|
|
472
|
+
*/
|
|
473
|
+
getToolsWithGiuseppeRetry() {
|
|
474
|
+
const giuseppeRetryTool = {
|
|
475
|
+
name: 'trigger_giuseppe_retry',
|
|
476
|
+
description: 'Trigger Giuseppe to retry fixing a bug with new explanation. Use this after gathering enough info about what went wrong with the previous fix. Only works in discussions with a pending bug fix.',
|
|
477
|
+
input_schema: {
|
|
478
|
+
type: 'object',
|
|
479
|
+
properties: {
|
|
480
|
+
explanation: {
|
|
481
|
+
type: 'string',
|
|
482
|
+
description: 'Clear explanation of what is wrong with the current fix and what the expected behavior should be. Include: (1) what is broken, (2) expected vs actual behavior, (3) any specific details the user mentioned.',
|
|
483
|
+
},
|
|
484
|
+
},
|
|
485
|
+
required: ['explanation'],
|
|
486
|
+
},
|
|
487
|
+
};
|
|
488
|
+
const confirmBugFixTool = {
|
|
489
|
+
name: 'confirm_bug_fix',
|
|
490
|
+
description: 'Confirm that a bug report should be fixed. Use when user indicates they want the bug fixed (variations of "fix it", "yes fix", "please fix", etc.). Only works in discussions with a pending classification.',
|
|
491
|
+
input_schema: {
|
|
492
|
+
type: 'object',
|
|
493
|
+
properties: {},
|
|
494
|
+
required: [],
|
|
495
|
+
},
|
|
496
|
+
};
|
|
497
|
+
const declineBugReportTool = {
|
|
498
|
+
name: 'decline_bug_report',
|
|
499
|
+
description: 'Decline a bug report as not actually a bug. Use when user indicates it\'s not a bug (variations of "not a bug", "feature request", "not actually broken", etc.). Only works in discussions with a pending classification.',
|
|
500
|
+
input_schema: {
|
|
501
|
+
type: 'object',
|
|
502
|
+
properties: {},
|
|
503
|
+
required: [],
|
|
504
|
+
},
|
|
505
|
+
};
|
|
506
|
+
return [...this.minimalTools, giuseppeRetryTool, confirmBugFixTool, declineBugReportTool];
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Get pending fix context for a discussion (if any)
|
|
510
|
+
*/
|
|
511
|
+
getPendingFixContext(discussionId) {
|
|
512
|
+
const pendingFix = pending_fix_registry_1.pendingFixRegistry.getPendingFix(discussionId);
|
|
513
|
+
if (!pendingFix) {
|
|
514
|
+
return '';
|
|
515
|
+
}
|
|
516
|
+
return `
|
|
517
|
+
<pending_bug_fix>
|
|
518
|
+
**IMPORTANT: This discussion has a pending bug fix from Giuseppe!**
|
|
519
|
+
|
|
520
|
+
- Bug ID: ${pendingFix.bugId}
|
|
521
|
+
- State: ${pendingFix.state}
|
|
522
|
+
- Fix Summary: ${pendingFix.fixSummary}
|
|
523
|
+
|
|
524
|
+
**Your role:**
|
|
525
|
+
- If user says "approved" → Giuseppe handles it automatically (you do nothing)
|
|
526
|
+
- If user expresses ANY dissatisfaction (denied, not working, still broken, etc.):
|
|
527
|
+
1. Ask what's wrong (if not clear)
|
|
528
|
+
2. Gather: what's broken + expected behavior
|
|
529
|
+
3. Use trigger_giuseppe_retry tool with the explanation
|
|
530
|
+
|
|
531
|
+
**Remember:** You're gathering info for Giuseppe. Be concise, ask ONE question at a time.
|
|
532
|
+
</pending_bug_fix>
|
|
533
|
+
`;
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Get pending classification context for a discussion (if any)
|
|
537
|
+
*/
|
|
538
|
+
getPendingClassificationContext(discussionId) {
|
|
539
|
+
const pending = pending_classification_registry_1.pendingClassificationRegistry.getPendingClassification(discussionId);
|
|
540
|
+
if (!pending) {
|
|
541
|
+
return '';
|
|
542
|
+
}
|
|
543
|
+
const classificationLabel = pending.classification === 'bug' ? 'Bug' :
|
|
544
|
+
pending.classification === 'feature_request' ? 'Feature Request' : 'Unclear';
|
|
545
|
+
return `
|
|
546
|
+
<pending_classification>
|
|
547
|
+
**IMPORTANT: Giuseppe just classified this report and is waiting for user decision!**
|
|
548
|
+
|
|
549
|
+
- Bug: ${pending.bugName}
|
|
550
|
+
- App: ${pending.appName || pending.appId || 'Unknown'}
|
|
551
|
+
- Classification: ${classificationLabel}
|
|
552
|
+
- Reason: ${pending.reason}
|
|
553
|
+
|
|
554
|
+
**User options:**
|
|
555
|
+
- "fix it" → Giuseppe will proceed to fix the bug
|
|
556
|
+
- "not a bug" → Report will be moved to Declined
|
|
557
|
+
|
|
558
|
+
**Your role - Use tools for user intent:**
|
|
559
|
+
- User wants to fix the bug → Call confirm_bug_fix tool
|
|
560
|
+
- User says it's not a bug / feature request → Call decline_bug_report tool
|
|
561
|
+
- User has questions → Help explain the classification
|
|
562
|
+
|
|
563
|
+
**Detecting intent (use tools, don't wait for exact words):**
|
|
564
|
+
- "fix it", "yes fix", "go ahead", "please fix", "fix this" → confirm_bug_fix
|
|
565
|
+
- "not a bug", "feature request", "not broken", "close it", "decline" → decline_bug_report
|
|
566
|
+
|
|
567
|
+
**Remember:** Use the tools to trigger actions. Don't tell user to type magic words.
|
|
568
|
+
</pending_classification>
|
|
569
|
+
`;
|
|
570
|
+
}
|
|
322
571
|
/**
|
|
323
572
|
* Override system prompt to include orchestrator capabilities
|
|
324
573
|
*/
|
|
@@ -447,6 +696,45 @@ Use 'fieldId' not 'id' for the field identifier.
|
|
|
447
696
|
</after_invite>
|
|
448
697
|
</specialists>
|
|
449
698
|
|
|
699
|
+
<giuseppe_autonomous>
|
|
700
|
+
**Giuseppe - Autonomous Bug Fixer**
|
|
701
|
+
|
|
702
|
+
Giuseppe is SPECIAL - he works AUTONOMOUSLY, not through invites!
|
|
703
|
+
|
|
704
|
+
**How Giuseppe works:**
|
|
705
|
+
1. Users create a bug report in the "Bug Reports" workflow
|
|
706
|
+
2. Giuseppe automatically detects new bugs and starts fixing them
|
|
707
|
+
3. He analyzes the code, generates a fix, tests it
|
|
708
|
+
4. He asks the user to verify with "approved" or "denied"
|
|
709
|
+
5. On "approved" → Giuseppe publishes to production automatically
|
|
710
|
+
6. On "denied" or complaint → YOU (HAL) gather info, then trigger Giuseppe retry
|
|
711
|
+
|
|
712
|
+
**YOUR ROLE IN BUG FIX DENIALS:**
|
|
713
|
+
When a discussion has a pending bug fix and the user expresses dissatisfaction:
|
|
714
|
+
1. YOU handle the conversation - ask what's wrong, what behavior they expected
|
|
715
|
+
2. Gather enough context: what's broken, expected vs actual behavior
|
|
716
|
+
3. Once you have clear info, use trigger_giuseppe_retry tool to pass the explanation
|
|
717
|
+
4. Giuseppe will receive your gathered info and retry the fix
|
|
718
|
+
|
|
719
|
+
**Detecting denial signals:**
|
|
720
|
+
- "denied", "not working", "still broken", "wrong", "doesn't work"
|
|
721
|
+
- Any complaint about the fix behavior
|
|
722
|
+
- User describing unexpected behavior
|
|
723
|
+
|
|
724
|
+
**Gathering info (ask ONE question at a time):**
|
|
725
|
+
- "What behavior are you seeing?"
|
|
726
|
+
- "What did you expect to happen instead?"
|
|
727
|
+
- "Is the issue consistent or intermittent?"
|
|
728
|
+
|
|
729
|
+
**When to trigger retry:**
|
|
730
|
+
Once you have: (1) what's wrong, (2) expected behavior → trigger the retry
|
|
731
|
+
|
|
732
|
+
**When someone mentions bugs (NEW bugs):**
|
|
733
|
+
- Tell them to create a bug report in "Bug Reports" workflow
|
|
734
|
+
- Explain Giuseppe will pick it up automatically
|
|
735
|
+
- Offer to help create the bug report for them
|
|
736
|
+
</giuseppe_autonomous>
|
|
737
|
+
|
|
450
738
|
<your_tools>
|
|
451
739
|
You have access to basic MCP tools for simple operations:
|
|
452
740
|
- list_workflows, list_workflow_phases, get_workflow_schema
|
|
@@ -532,7 +820,10 @@ Only use <respond> when you have the FINAL answer to share.
|
|
|
532
820
|
- When inviting specialists, explain to the user what's happening
|
|
533
821
|
- After specialist responds, summarize for the user if needed
|
|
534
822
|
- **Complete work before responding** - Never say "I'm going to do X", just DO X with tool calls
|
|
535
|
-
</rules
|
|
823
|
+
</rules>
|
|
824
|
+
|
|
825
|
+
${this.currentDiscussionId ? this.getPendingFixContext(this.currentDiscussionId) : ''}
|
|
826
|
+
${this.currentDiscussionId ? this.getPendingClassificationContext(this.currentDiscussionId) : ''}`;
|
|
536
827
|
}
|
|
537
828
|
/**
|
|
538
829
|
* Override response handling to detect specialist invitations
|