snow-flow 1.1.91 → 1.1.93
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/agents/base-agent.js +0 -1
- package/dist/agents/coordinator.js +0 -1
- package/dist/agents/flow-builder-agent.js +0 -1
- package/dist/agents/index.js +0 -1
- package/dist/agents/queen-403-handler.d.ts +47 -0
- package/dist/agents/queen-403-handler.d.ts.map +1 -0
- package/dist/agents/queen-403-handler.js +174 -0
- package/dist/agents/queen-403-handler.js.map +1 -0
- package/dist/agents/queen-agent-example.js +0 -1
- package/dist/agents/queen-agent.d.ts +78 -90
- package/dist/agents/queen-agent.d.ts.map +1 -1
- package/dist/agents/queen-agent.js +596 -519
- package/dist/agents/queen-agent.js.map +1 -1
- package/dist/agents/script-writer-agent.js +0 -1
- package/dist/agents/security-agent.js +0 -1
- package/dist/agents/test-agent.js +0 -1
- package/dist/agents/test-agents.js +0 -1
- package/dist/agents/widget-creator-agent.js +0 -1
- package/dist/api/error-handling.js +0 -1
- package/dist/api/flow-designer-api.js +0 -1
- package/dist/api/natural-language-mapper.js +0 -1
- package/dist/api/performance-optimizer.js +0 -1
- package/dist/api/transaction-manager.js +0 -1
- package/dist/cli/deploy-artifact.js +0 -1
- package/dist/cli/snow-flow-cli-integration.js +0 -1
- package/dist/cli.js +0 -1
- package/dist/config/snow-flow-config.js +0 -1
- package/dist/health/system-health.js +0 -1
- package/dist/index.js +0 -1
- package/dist/intelligence/acl-analyzer.d.ts +88 -0
- package/dist/intelligence/acl-analyzer.d.ts.map +1 -0
- package/dist/intelligence/acl-analyzer.js +275 -0
- package/dist/intelligence/acl-analyzer.js.map +1 -0
- package/dist/intelligence/auto-resolution-engine.js +0 -1
- package/dist/intelligence/gap-analysis-engine.d.ts.map +1 -1
- package/dist/intelligence/gap-analysis-engine.js +0 -1
- package/dist/intelligence/gap-analysis-engine.js.map +1 -1
- package/dist/intelligence/manual-instructions-generator.js +0 -1
- package/dist/intelligence/mcp-coverage-analyzer.js +0 -1
- package/dist/intelligence/requirements-analyzer.js +0 -1
- package/dist/intelligence/task-analyzer.js +0 -1
- package/dist/managers/scope-manager.js +0 -1
- package/dist/mcp/base-mcp-server.js +0 -1
- package/dist/mcp/example-refactored-server.js +0 -1
- package/dist/mcp/http-transport-wrapper.js +0 -1
- package/dist/mcp/service-discovery-client.js +0 -1
- package/dist/mcp/servicenow-automation-mcp-refactored.js +0 -1
- package/dist/mcp/servicenow-automation-mcp.js +0 -1
- package/dist/mcp/servicenow-deployment-mcp-refactored.d.ts.map +1 -1
- package/dist/mcp/servicenow-deployment-mcp-refactored.js +30 -3
- package/dist/mcp/servicenow-deployment-mcp-refactored.js.map +1 -1
- package/dist/mcp/servicenow-deployment-mcp.js +0 -1
- package/dist/mcp/servicenow-flow-composer-mcp-refactored.js +0 -1
- package/dist/mcp/servicenow-flow-composer-mcp.js +0 -1
- package/dist/mcp/servicenow-graph-memory-mcp-refactored.js +0 -1
- package/dist/mcp/servicenow-graph-memory-mcp.js +0 -1
- package/dist/mcp/servicenow-integration-mcp-refactored.js +0 -1
- package/dist/mcp/servicenow-integration-mcp.js +0 -1
- package/dist/mcp/servicenow-intelligent-mcp-refactored.js +0 -1
- package/dist/mcp/servicenow-intelligent-mcp.js +0 -1
- package/dist/mcp/servicenow-mcp-server.js +0 -1
- package/dist/mcp/servicenow-operations-mcp-refactored.js +0 -1
- package/dist/mcp/servicenow-operations-mcp.js +0 -1
- package/dist/mcp/servicenow-platform-development-mcp-refactored.js +0 -1
- package/dist/mcp/servicenow-platform-development-mcp.js +0 -1
- package/dist/mcp/servicenow-progressive-indexer.js +0 -1
- package/dist/mcp/servicenow-reporting-analytics-mcp-refactored.js +0 -1
- package/dist/mcp/servicenow-reporting-analytics-mcp.js +0 -1
- package/dist/mcp/servicenow-security-compliance-mcp-refactored.js +0 -1
- package/dist/mcp/servicenow-security-compliance-mcp.js +0 -1
- package/dist/mcp/servicenow-update-set-mcp-refactored.js +0 -1
- package/dist/mcp/servicenow-update-set-mcp.js +0 -1
- package/dist/mcp/shared/agent-context-provider.js +0 -1
- package/dist/mcp/shared/base-mcp-server.js +0 -1
- package/dist/mcp/shared/mcp-memory-manager.js +0 -1
- package/dist/mcp/start-all-mcp-servers.js +0 -1
- package/dist/mcp/start-servicenow-mcp.js +0 -1
- package/dist/mcp/test-simple-mcp.js +0 -1
- package/dist/memory/index.js +0 -1
- package/dist/memory/mcp-integration-example.js +0 -1
- package/dist/memory/memory-client.js +0 -1
- package/dist/memory/memory-operations.js +0 -1
- package/dist/memory/memory-system.js +0 -1
- package/dist/memory/memory-test.js +0 -1
- package/dist/memory/servicenow-artifact-indexer.js +0 -1
- package/dist/memory/swarm-memory.js +0 -1
- package/dist/monitoring/performance-tracker.js +0 -1
- package/dist/orchestrator/flow-composer.js +0 -1
- package/dist/queen/advanced-integration-test.js +0 -1
- package/dist/queen/agent-factory.js +0 -1
- package/dist/queen/index.js +0 -1
- package/dist/queen/integration-example.js +0 -1
- package/dist/queen/integration-test.js +0 -1
- package/dist/queen/mcp-execution-bridge.js +0 -1
- package/dist/queen/neural-learning.js +0 -1
- package/dist/queen/parallel-agent-engine.d.ts.map +1 -1
- package/dist/queen/parallel-agent-engine.js +92 -18
- package/dist/queen/parallel-agent-engine.js.map +1 -1
- package/dist/queen/queen-memory.js +0 -1
- package/dist/queen/run-integration-tests.js +0 -1
- package/dist/queen/servicenow-queen.js +0 -1
- package/dist/queen/types.js +0 -1
- package/dist/snow-flow-system.js +0 -1
- package/dist/sparc/sparc-help.js +0 -1
- package/dist/sparc/team-sparc.js +0 -1
- package/dist/strategies/global-scope-strategy.js +0 -1
- package/dist/types/index.js +0 -1
- package/dist/types/servicenow.types.js +0 -1
- package/dist/types/snow-flow.types.d.ts +1 -1
- package/dist/types/snow-flow.types.d.ts.map +1 -1
- package/dist/types/snow-flow.types.js +0 -1
- package/dist/types/todo.types.js +0 -1
- package/dist/utils/action-type-cache.js +0 -1
- package/dist/utils/agent-detector.js +49 -12
- package/dist/utils/artifact-tracker.js +0 -1
- package/dist/utils/dependency-detector.js +0 -1
- package/dist/utils/error-recovery.js +0 -1
- package/dist/utils/flow-api-discovery.js +0 -1
- package/dist/utils/logger.js +0 -1
- package/dist/utils/mcp-auth-middleware.js +0 -1
- package/dist/utils/mcp-config-manager.js +0 -1
- package/dist/utils/mcp-server-manager.js +0 -1
- package/dist/utils/scope-utils.js +0 -1
- package/dist/utils/servicenow-client.js +0 -1
- package/dist/utils/snow-oauth.js +0 -1
- package/dist/utils/template-engine.js +0 -1
- package/dist/utils/theme-manager.js +0 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -2
- package/package.json +2 -2
- package/test-parallel-agents.js +177 -0
- package/test-queen-workflow.js +184 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Queen Agent Core
|
|
3
|
+
* Queen Agent Core with Enhanced 403 Error Handling
|
|
4
4
|
* Master coordinator that analyzes objectives and spawns specialized agents
|
|
5
5
|
* Works through Claude Code interface using TodoWrite for task coordination
|
|
6
|
+
* Now with intelligent 403 error handling using Gap Analysis Engine
|
|
6
7
|
*/
|
|
7
8
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
9
|
if (k2 === undefined) k2 = k;
|
|
@@ -43,6 +44,8 @@ const eventemitter3_1 = require("eventemitter3");
|
|
|
43
44
|
const queen_memory_1 = require("../queen/queen-memory");
|
|
44
45
|
const coordinator_1 = require("./coordinator");
|
|
45
46
|
const parallel_agent_engine_1 = require("../queen/parallel-agent-engine");
|
|
47
|
+
const queen_403_handler_1 = require("./queen-403-handler");
|
|
48
|
+
const logger_1 = require("../utils/logger");
|
|
46
49
|
const crypto = __importStar(require("crypto"));
|
|
47
50
|
class QueenAgent extends eventemitter3_1.EventEmitter {
|
|
48
51
|
constructor(config = {}) {
|
|
@@ -52,20 +55,31 @@ class QueenAgent extends eventemitter3_1.EventEmitter {
|
|
|
52
55
|
maxConcurrentAgents: config.maxConcurrentAgents || 8,
|
|
53
56
|
debugMode: config.debugMode || false,
|
|
54
57
|
autoSpawn: config.autoSpawn !== false,
|
|
55
|
-
claudeCodeInterface: config.claudeCodeInterface !== false
|
|
58
|
+
claudeCodeInterface: config.claudeCodeInterface !== false,
|
|
59
|
+
mcpTools: config.mcpTools || {}
|
|
56
60
|
};
|
|
61
|
+
// Initialize logger first
|
|
62
|
+
this.logger = new logger_1.Logger('QueenAgent');
|
|
57
63
|
// Initialize core systems
|
|
58
64
|
this.memory = new queen_memory_1.QueenMemorySystem(this.config.memoryPath);
|
|
59
65
|
this.coordinator = new coordinator_1.AgentCoordinator(this.memory);
|
|
60
66
|
this.parallelEngine = new parallel_agent_engine_1.ParallelAgentEngine(this.memory);
|
|
67
|
+
this.handler403 = new queen_403_handler_1.Queen403Handler(this.logger, this.config.mcpTools);
|
|
61
68
|
this.activeObjectives = new Map();
|
|
62
69
|
this.todoCoordinations = new Map();
|
|
63
70
|
this.activeAgents = new Map();
|
|
64
71
|
this.setupEventHandlers();
|
|
65
72
|
if (this.config.debugMode) {
|
|
66
|
-
console.log('👑 Queen Agent initialized with Claude Code interface');
|
|
73
|
+
console.log('👑 Queen Agent initialized with Claude Code interface and 403 handling');
|
|
67
74
|
}
|
|
68
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Update MCP tools configuration (useful when tools become available later)
|
|
78
|
+
*/
|
|
79
|
+
updateMCPTools(mcpTools) {
|
|
80
|
+
this.config.mcpTools = mcpTools;
|
|
81
|
+
this.handler403 = new queen_403_handler_1.Queen403Handler(this.logger, mcpTools);
|
|
82
|
+
}
|
|
69
83
|
/**
|
|
70
84
|
* Analyze objective and create coordinated execution plan
|
|
71
85
|
*/
|
|
@@ -95,6 +109,94 @@ class QueenAgent extends eventemitter3_1.EventEmitter {
|
|
|
95
109
|
throw error;
|
|
96
110
|
}
|
|
97
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Handle deployment error with intelligent 403 detection and resolution
|
|
114
|
+
*/
|
|
115
|
+
async handleDeploymentError(error, context) {
|
|
116
|
+
// Check if it's a 403 permission error
|
|
117
|
+
if (this.is403Error(error)) {
|
|
118
|
+
console.log('🚨 Queen Agent: Detected 403 permission error - activating intelligent analysis');
|
|
119
|
+
const objective = this.activeObjectives.get(context.objectiveId);
|
|
120
|
+
if (!objective) {
|
|
121
|
+
console.error('No objective found for error context');
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
// Use 403 handler with Gap Analysis
|
|
125
|
+
const result = await this.handler403.handle403Error({
|
|
126
|
+
error,
|
|
127
|
+
operation: context.operation,
|
|
128
|
+
tableName: context.tableName,
|
|
129
|
+
artifactType: context.artifactType,
|
|
130
|
+
objective: objective.description
|
|
131
|
+
});
|
|
132
|
+
// Update todos based on analysis
|
|
133
|
+
if (result.nextSteps.length > 0) {
|
|
134
|
+
await this.updateTodosWithPermissionFixes(context.objectiveId, result);
|
|
135
|
+
}
|
|
136
|
+
// If automatic fixes were applied, return true to retry
|
|
137
|
+
if (result.resolved) {
|
|
138
|
+
console.log('✅ Queen Agent: Automatic fixes applied - suggesting retry');
|
|
139
|
+
this.emit('permission:auto-fixed', { context, result });
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
// Emit event for manual intervention needed
|
|
143
|
+
this.emit('permission:manual-required', { context, result });
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check if error is a 403 permission error
|
|
150
|
+
*/
|
|
151
|
+
is403Error(error) {
|
|
152
|
+
const errorStr = error?.toString() || '';
|
|
153
|
+
const errorMsg = error?.message || '';
|
|
154
|
+
const statusCode = error?.status || error?.statusCode || error?.response?.status;
|
|
155
|
+
return statusCode === 403 ||
|
|
156
|
+
errorStr.includes('403') ||
|
|
157
|
+
errorMsg.includes('403') ||
|
|
158
|
+
errorMsg.includes('permission') ||
|
|
159
|
+
errorMsg.includes('access denied') ||
|
|
160
|
+
errorMsg.includes('insufficient privileges');
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Update todos with permission fix steps
|
|
164
|
+
*/
|
|
165
|
+
async updateTodosWithPermissionFixes(objectiveId, permissionResult) {
|
|
166
|
+
const todoCoordination = this.todoCoordinations.get(objectiveId);
|
|
167
|
+
if (!todoCoordination)
|
|
168
|
+
return;
|
|
169
|
+
// Add new todos for permission fixes
|
|
170
|
+
const newTodos = [];
|
|
171
|
+
// Add retry todo if automatic fixes were applied
|
|
172
|
+
if (permissionResult.resolved) {
|
|
173
|
+
newTodos.push({
|
|
174
|
+
id: this.generateId('todo'),
|
|
175
|
+
content: '🔄 Retry deployment after automatic permission fixes',
|
|
176
|
+
status: 'pending',
|
|
177
|
+
priority: 'high'
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
// Add manual action todos
|
|
181
|
+
permissionResult.nextSteps.forEach((step) => {
|
|
182
|
+
newTodos.push({
|
|
183
|
+
id: this.generateId('todo'),
|
|
184
|
+
content: step,
|
|
185
|
+
status: 'pending',
|
|
186
|
+
priority: 'high'
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
// Insert new todos at the beginning of pending todos
|
|
190
|
+
const pendingIndex = todoCoordination.todos.findIndex(t => t.status === 'pending');
|
|
191
|
+
if (pendingIndex >= 0) {
|
|
192
|
+
todoCoordination.todos.splice(pendingIndex, 0, ...newTodos);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
todoCoordination.todos.push(...newTodos);
|
|
196
|
+
}
|
|
197
|
+
// Emit update event
|
|
198
|
+
this.emit('todos:updated', { objectiveId, todos: todoCoordination.todos });
|
|
199
|
+
}
|
|
98
200
|
/**
|
|
99
201
|
* Spawn agents based on objective requirements with intelligent parallelization
|
|
100
202
|
*/
|
|
@@ -123,45 +225,19 @@ class QueenAgent extends eventemitter3_1.EventEmitter {
|
|
|
123
225
|
* 🚀 NEW: Spawn parallel agents based on opportunities
|
|
124
226
|
*/
|
|
125
227
|
async spawnParallelAgents(objectiveId, todoCoordination, opportunities) {
|
|
228
|
+
console.log('🚀 Queen Agent: Spawning parallel agent teams...');
|
|
126
229
|
// Create execution plan
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const agent = await this.spawnSpecializedAgent(type, objectiveId, specialization);
|
|
132
|
-
this.activeAgents.set(agent.id, agent);
|
|
133
|
-
return agent;
|
|
134
|
-
});
|
|
135
|
-
// Assign todos to parallel agents based on their workloads
|
|
136
|
-
for (const workload of plan.agentTeam) {
|
|
137
|
-
const agent = result.spawnedAgents.find(a => a.id === workload.agentId);
|
|
138
|
-
if (agent) {
|
|
139
|
-
// Advanced todo assignment based on workload specializations
|
|
140
|
-
this.assignTodosToParallelAgent(agent, todoCoordination, workload.assignedTodos, workload.specializations);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
// Store parallel execution details
|
|
144
|
-
await this.memory.store(`parallel_agents_${objectiveId}`, {
|
|
145
|
-
planId: plan.planId,
|
|
146
|
-
agents: result.spawnedAgents.map(a => ({ id: a.id, type: a.type, capabilities: a.capabilities })),
|
|
147
|
-
executionDetails: result.executionDetails,
|
|
148
|
-
parallelizationOpportunities: opportunities.length,
|
|
149
|
-
estimatedSpeedup: result.executionDetails.estimatedSpeedup,
|
|
150
|
-
timestamp: new Date().toISOString()
|
|
230
|
+
const executionPlan = await this.parallelEngine.createExecutionPlan(opportunities, todoCoordination.todos, this.config.maxConcurrentAgents);
|
|
231
|
+
// Execute the plan and get spawned agents
|
|
232
|
+
const result = await this.parallelEngine.executeParallelPlan(executionPlan, async (type, specialization) => {
|
|
233
|
+
return await this.spawnSpecializedAgent(type, objectiveId, specialization);
|
|
151
234
|
});
|
|
152
|
-
console.log(`✅ Spawned ${result.spawnedAgents.length}
|
|
235
|
+
console.log(`✅ Spawned ${result.spawnedAgents.length} specialized agents in parallel`);
|
|
153
236
|
console.log(`⚡ Estimated speedup: ${result.executionDetails.estimatedSpeedup}`);
|
|
154
|
-
console.log(`🔀 Parallel workflows: ${result.executionDetails.parallelWorkflows}`);
|
|
155
|
-
this.emit('agents:spawned', {
|
|
156
|
-
objectiveId,
|
|
157
|
-
agents: result.spawnedAgents,
|
|
158
|
-
parallel: true,
|
|
159
|
-
speedup: result.executionDetails.estimatedSpeedup
|
|
160
|
-
});
|
|
161
237
|
return result.spawnedAgents;
|
|
162
238
|
}
|
|
163
239
|
/**
|
|
164
|
-
* Fallback
|
|
240
|
+
* Fallback to sequential agent spawning
|
|
165
241
|
*/
|
|
166
242
|
async spawnSequentialAgents(objectiveId, todoCoordination, analysis) {
|
|
167
243
|
const agents = [];
|
|
@@ -170,170 +246,228 @@ class QueenAgent extends eventemitter3_1.EventEmitter {
|
|
|
170
246
|
for (const agentType of requiredAgentTypes) {
|
|
171
247
|
const agent = await this.spawnSpecializedAgent(agentType, objectiveId);
|
|
172
248
|
agents.push(agent);
|
|
173
|
-
this.activeAgents.set(agent.id, agent);
|
|
174
|
-
// Assign todos to agent based on capabilities
|
|
175
|
-
this.assignTodosToAgent(agent, todoCoordination);
|
|
176
249
|
}
|
|
177
|
-
// Update memory with agent spawning information
|
|
178
|
-
await this.memory.store(`agents_${objectiveId}`, {
|
|
179
|
-
agents: agents.map(a => ({ id: a.id, type: a.type, capabilities: a.capabilities })),
|
|
180
|
-
timestamp: new Date().toISOString()
|
|
181
|
-
});
|
|
182
|
-
this.emit('agents:spawned', { objectiveId, agents, parallel: false });
|
|
183
250
|
return agents;
|
|
184
251
|
}
|
|
185
252
|
/**
|
|
186
|
-
*
|
|
187
|
-
*/
|
|
188
|
-
async monitorProgress(objectiveId) {
|
|
189
|
-
const todoCoordination = this.todoCoordinations.get(objectiveId);
|
|
190
|
-
if (!todoCoordination) {
|
|
191
|
-
throw new Error(`No todo coordination found for objective: ${objectiveId}`);
|
|
192
|
-
}
|
|
193
|
-
// Calculate progress from todos
|
|
194
|
-
const completedTodos = todoCoordination.todos.filter(t => t.status === 'completed').length;
|
|
195
|
-
const totalTodos = todoCoordination.todos.length;
|
|
196
|
-
const overallProgress = totalTodos > 0 ? (completedTodos / totalTodos) * 100 : 0;
|
|
197
|
-
// Calculate per-agent progress
|
|
198
|
-
const byAgent = new Map();
|
|
199
|
-
for (const [todoId, agentId] of todoCoordination.agentAssignments) {
|
|
200
|
-
const agentTodos = Array.from(todoCoordination.agentAssignments.entries())
|
|
201
|
-
.filter(([_, aid]) => aid === agentId);
|
|
202
|
-
const agentCompleted = agentTodos.filter(([tid, _]) => todoCoordination.todos.find(t => t.id === tid)?.status === 'completed').length;
|
|
203
|
-
const agentProgress = agentTodos.length > 0 ? (agentCompleted / agentTodos.length) * 100 : 0;
|
|
204
|
-
byAgent.set(agentId, agentProgress);
|
|
205
|
-
}
|
|
206
|
-
// Identify blocking issues
|
|
207
|
-
const blockingIssues = await this.identifyBlockingIssues(todoCoordination);
|
|
208
|
-
// Estimate completion based on current velocity
|
|
209
|
-
const estimatedCompletion = this.estimateCompletion(todoCoordination, overallProgress);
|
|
210
|
-
// Store progress in memory
|
|
211
|
-
await this.memory.store(`progress_${objectiveId}`, {
|
|
212
|
-
overall: overallProgress,
|
|
213
|
-
byAgent: Object.fromEntries(byAgent),
|
|
214
|
-
blockingIssues,
|
|
215
|
-
estimatedCompletion: estimatedCompletion.toISOString(),
|
|
216
|
-
timestamp: new Date().toISOString()
|
|
217
|
-
});
|
|
218
|
-
this.emit('progress:updated', { objectiveId, overall: overallProgress, byAgent, blockingIssues });
|
|
219
|
-
return {
|
|
220
|
-
overall: overallProgress,
|
|
221
|
-
byAgent,
|
|
222
|
-
blockingIssues,
|
|
223
|
-
estimatedCompletion
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Make memory-driven decisions based on past patterns
|
|
253
|
+
* Spawn a specialized agent with optional specialization
|
|
228
254
|
*/
|
|
229
|
-
async
|
|
230
|
-
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
// Select best option
|
|
239
|
-
const bestOption = Array.from(optionScores.entries())
|
|
240
|
-
.sort((a, b) => b[1] - a[1])[0];
|
|
241
|
-
const decision = {
|
|
242
|
-
decision: bestOption[0],
|
|
243
|
-
reasoning: this.generateDecisionReasoning(bestOption[0], similarPatterns, context),
|
|
244
|
-
confidence: bestOption[1] / 100
|
|
255
|
+
async spawnSpecializedAgent(type, objectiveId, specialization) {
|
|
256
|
+
const agentId = this.generateId('agent');
|
|
257
|
+
const agent = {
|
|
258
|
+
id: agentId,
|
|
259
|
+
type,
|
|
260
|
+
status: 'active',
|
|
261
|
+
objectiveId,
|
|
262
|
+
specialization,
|
|
263
|
+
startTime: Date.now()
|
|
245
264
|
};
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
265
|
+
this.activeAgents.set(agentId, agent);
|
|
266
|
+
// Store agent info in memory for coordination
|
|
267
|
+
await this.memory.store(`agent_${agentId}`, {
|
|
268
|
+
agent,
|
|
269
|
+
objective: this.activeObjectives.get(objectiveId),
|
|
270
|
+
assignedTodos: [],
|
|
271
|
+
status: 'initializing'
|
|
252
272
|
});
|
|
253
|
-
this.emit('
|
|
254
|
-
|
|
273
|
+
this.emit('agent:spawned', agent);
|
|
274
|
+
// Assign todos to agent based on capabilities
|
|
275
|
+
await this.assignTodosToAgent(agent, objectiveId);
|
|
276
|
+
return agent;
|
|
255
277
|
}
|
|
256
278
|
/**
|
|
257
|
-
*
|
|
279
|
+
* Analyze objective to determine requirements
|
|
258
280
|
*/
|
|
259
|
-
async
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
281
|
+
async performObjectiveAnalysis(objective) {
|
|
282
|
+
const description = objective.description.toLowerCase();
|
|
283
|
+
// Determine task type
|
|
284
|
+
let type = 'generic';
|
|
285
|
+
let requiredAgents = [];
|
|
286
|
+
let estimatedComplexity = 5;
|
|
287
|
+
let suggestedPattern = 'standard';
|
|
288
|
+
let dependencies = [];
|
|
289
|
+
// Widget development detection
|
|
290
|
+
if (description.includes('widget') || description.includes('portal') || description.includes('ui component')) {
|
|
291
|
+
type = 'widget';
|
|
292
|
+
requiredAgents = ['widget-creator', 'script-writer', 'tester'];
|
|
293
|
+
if (description.includes('complex') || description.includes('interactive')) {
|
|
294
|
+
estimatedComplexity = 8;
|
|
295
|
+
requiredAgents.push('ui-ux-specialist');
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Flow development detection
|
|
299
|
+
else if (description.includes('flow') || description.includes('workflow') || description.includes('automation')) {
|
|
300
|
+
type = 'flow';
|
|
301
|
+
requiredAgents = ['flow-builder', 'integration-specialist', 'tester'];
|
|
302
|
+
if (description.includes('approval')) {
|
|
303
|
+
requiredAgents.push('approval-specialist');
|
|
304
|
+
dependencies.push('user_management', 'notification_system');
|
|
305
|
+
}
|
|
265
306
|
}
|
|
266
|
-
|
|
267
|
-
|
|
307
|
+
// Application development
|
|
308
|
+
else if (description.includes('application') || description.includes('app') || description.includes('complete solution')) {
|
|
309
|
+
type = 'application';
|
|
310
|
+
requiredAgents = ['app-architect', 'widget-creator', 'flow-builder', 'script-writer', 'tester'];
|
|
311
|
+
estimatedComplexity = 10;
|
|
312
|
+
suggestedPattern = 'modular';
|
|
268
313
|
}
|
|
269
|
-
|
|
270
|
-
|
|
314
|
+
// Script development
|
|
315
|
+
else if (description.includes('script') || description.includes('business rule') || description.includes('api')) {
|
|
316
|
+
type = 'script';
|
|
317
|
+
requiredAgents = ['script-writer', 'tester'];
|
|
318
|
+
if (description.includes('integration')) {
|
|
319
|
+
requiredAgents.push('integration-specialist');
|
|
320
|
+
}
|
|
271
321
|
}
|
|
272
|
-
|
|
273
|
-
|
|
322
|
+
// Integration development
|
|
323
|
+
else if (description.includes('integration') || description.includes('connect') || description.includes('external')) {
|
|
324
|
+
type = 'integration';
|
|
325
|
+
requiredAgents = ['integration-specialist', 'script-writer', 'tester'];
|
|
326
|
+
dependencies.push('authentication', 'data_transformation');
|
|
274
327
|
}
|
|
275
|
-
|
|
276
|
-
|
|
328
|
+
// Add security agent if mentioned
|
|
329
|
+
if (description.includes('secure') || description.includes('security') || description.includes('permission')) {
|
|
330
|
+
requiredAgents.push('security-specialist');
|
|
277
331
|
}
|
|
278
|
-
// Set up dependencies based on logical flow
|
|
279
|
-
this.setupTodoDependencies(todos, dependencies);
|
|
280
332
|
return {
|
|
281
|
-
|
|
333
|
+
type,
|
|
334
|
+
complexity: estimatedComplexity,
|
|
335
|
+
requiredAgents: [...new Set(requiredAgents)], // Remove duplicates
|
|
336
|
+
estimatedComplexity: Math.min(10, Math.max(1, estimatedComplexity)),
|
|
337
|
+
suggestedPattern,
|
|
338
|
+
dependencies
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Create todo coordination structure for Claude Code interface
|
|
343
|
+
*/
|
|
344
|
+
async createTodoCoordination(objective, analysis) {
|
|
345
|
+
const todos = this.generateTodosForObjective(objective, analysis);
|
|
346
|
+
const coordination = {
|
|
347
|
+
objectiveId: objective.id,
|
|
282
348
|
todos,
|
|
283
349
|
agentAssignments: new Map(),
|
|
284
|
-
dependencies
|
|
350
|
+
dependencies: this.analyzeTodoDependencies(todos)
|
|
285
351
|
};
|
|
352
|
+
// Store coordination info in memory
|
|
353
|
+
await this.memory.store(`coordination_${objective.id}`, coordination);
|
|
354
|
+
return coordination;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Generate todos based on objective type
|
|
358
|
+
*/
|
|
359
|
+
generateTodosForObjective(objective, analysis) {
|
|
360
|
+
const baseTodos = [
|
|
361
|
+
{
|
|
362
|
+
id: this.generateId('todo'),
|
|
363
|
+
content: `Initialize swarm memory session for: ${objective.description}`,
|
|
364
|
+
status: 'pending',
|
|
365
|
+
priority: 'high'
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
id: this.generateId('todo'),
|
|
369
|
+
content: 'Validate ServiceNow authentication and permissions',
|
|
370
|
+
status: 'pending',
|
|
371
|
+
priority: 'high'
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
id: this.generateId('todo'),
|
|
375
|
+
content: 'Check for existing similar artifacts',
|
|
376
|
+
status: 'pending',
|
|
377
|
+
priority: 'medium'
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
id: this.generateId('todo'),
|
|
381
|
+
content: 'Create Update Set for tracking changes',
|
|
382
|
+
status: 'pending',
|
|
383
|
+
priority: 'high'
|
|
384
|
+
}
|
|
385
|
+
];
|
|
386
|
+
// Add type-specific todos
|
|
387
|
+
switch (analysis.type) {
|
|
388
|
+
case 'widget':
|
|
389
|
+
baseTodos.push(...this.createWidgetTodos(objective, analysis));
|
|
390
|
+
break;
|
|
391
|
+
case 'flow':
|
|
392
|
+
baseTodos.push(...this.createFlowTodos(objective, analysis));
|
|
393
|
+
break;
|
|
394
|
+
case 'application':
|
|
395
|
+
baseTodos.push(...this.createApplicationTodos(objective, analysis));
|
|
396
|
+
break;
|
|
397
|
+
case 'script':
|
|
398
|
+
baseTodos.push(...this.createScriptTodos(objective, analysis));
|
|
399
|
+
break;
|
|
400
|
+
case 'integration':
|
|
401
|
+
baseTodos.push(...this.createIntegrationTodos(objective, analysis));
|
|
402
|
+
break;
|
|
403
|
+
default:
|
|
404
|
+
baseTodos.push(...this.createGenericTodos(objective, analysis));
|
|
405
|
+
}
|
|
406
|
+
// Add final todos
|
|
407
|
+
baseTodos.push({
|
|
408
|
+
id: this.generateId('todo'),
|
|
409
|
+
content: 'Validate solution completeness',
|
|
410
|
+
status: 'pending',
|
|
411
|
+
priority: 'high'
|
|
412
|
+
}, {
|
|
413
|
+
id: this.generateId('todo'),
|
|
414
|
+
content: 'Generate documentation and handoff materials',
|
|
415
|
+
status: 'pending',
|
|
416
|
+
priority: 'medium'
|
|
417
|
+
});
|
|
418
|
+
return baseTodos;
|
|
286
419
|
}
|
|
287
420
|
/**
|
|
288
421
|
* Create widget-specific todos
|
|
289
422
|
*/
|
|
290
423
|
createWidgetTodos(objective, analysis) {
|
|
424
|
+
// 🚀 ENHANCED: More specific todos to trigger parallel agent specialization
|
|
291
425
|
const todos = [
|
|
292
426
|
{
|
|
293
427
|
id: this.generateId('todo'),
|
|
294
|
-
content: `Analyze
|
|
428
|
+
content: `Analyze portal requirements and user experience design: ${objective.description}`,
|
|
295
429
|
status: 'pending',
|
|
296
430
|
priority: 'high'
|
|
297
431
|
},
|
|
298
432
|
{
|
|
299
433
|
id: this.generateId('todo'),
|
|
300
|
-
content: '
|
|
434
|
+
content: 'Create widget HTML structure with responsive design and accessibility features',
|
|
301
435
|
status: 'pending',
|
|
302
436
|
priority: 'high'
|
|
303
437
|
},
|
|
304
438
|
{
|
|
305
439
|
id: this.generateId('todo'),
|
|
306
|
-
content: '
|
|
440
|
+
content: 'Develop server-side script for backend data processing and API integration',
|
|
307
441
|
status: 'pending',
|
|
308
442
|
priority: 'high'
|
|
309
443
|
},
|
|
310
444
|
{
|
|
311
445
|
id: this.generateId('todo'),
|
|
312
|
-
content: '
|
|
446
|
+
content: 'Build client-side controller with interactive features and event handling',
|
|
313
447
|
status: 'pending',
|
|
314
|
-
priority: '
|
|
448
|
+
priority: 'high'
|
|
315
449
|
},
|
|
316
450
|
{
|
|
317
451
|
id: this.generateId('todo'),
|
|
318
|
-
content: 'Style widget with responsive
|
|
452
|
+
content: 'Style widget with CSS including responsive design and theme compliance',
|
|
319
453
|
status: 'pending',
|
|
320
|
-
priority: '
|
|
454
|
+
priority: 'high'
|
|
321
455
|
},
|
|
322
456
|
{
|
|
323
457
|
id: this.generateId('todo'),
|
|
324
|
-
content: '
|
|
458
|
+
content: 'Implement performance optimization and caching strategies',
|
|
325
459
|
status: 'pending',
|
|
326
460
|
priority: 'medium'
|
|
327
461
|
},
|
|
328
462
|
{
|
|
329
463
|
id: this.generateId('todo'),
|
|
330
|
-
content: '
|
|
464
|
+
content: 'Test widget functionality including cross-browser and mobile testing',
|
|
331
465
|
status: 'pending',
|
|
332
466
|
priority: 'high'
|
|
333
467
|
},
|
|
334
468
|
{
|
|
335
469
|
id: this.generateId('todo'),
|
|
336
|
-
content: '
|
|
470
|
+
content: 'Ensure security best practices and vulnerability scanning',
|
|
337
471
|
status: 'pending',
|
|
338
472
|
priority: 'high'
|
|
339
473
|
}
|
|
@@ -383,13 +517,63 @@ class QueenAgent extends eventemitter3_1.EventEmitter {
|
|
|
383
517
|
},
|
|
384
518
|
{
|
|
385
519
|
id: this.generateId('todo'),
|
|
386
|
-
content: 'Test flow with mock scenarios',
|
|
520
|
+
content: 'Test flow with mock data scenarios',
|
|
521
|
+
status: 'pending',
|
|
522
|
+
priority: 'high'
|
|
523
|
+
}
|
|
524
|
+
];
|
|
525
|
+
return todos;
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Create application-specific todos
|
|
529
|
+
*/
|
|
530
|
+
createApplicationTodos(objective, analysis) {
|
|
531
|
+
const todos = [
|
|
532
|
+
{
|
|
533
|
+
id: this.generateId('todo'),
|
|
534
|
+
content: `Design application architecture: ${objective.description}`,
|
|
535
|
+
status: 'pending',
|
|
536
|
+
priority: 'high'
|
|
537
|
+
},
|
|
538
|
+
{
|
|
539
|
+
id: this.generateId('todo'),
|
|
540
|
+
content: 'Create application scope and structure',
|
|
541
|
+
status: 'pending',
|
|
542
|
+
priority: 'high'
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
id: this.generateId('todo'),
|
|
546
|
+
content: 'Design data model and tables',
|
|
387
547
|
status: 'pending',
|
|
388
548
|
priority: 'high'
|
|
389
549
|
},
|
|
390
550
|
{
|
|
391
551
|
id: this.generateId('todo'),
|
|
392
|
-
content: '
|
|
552
|
+
content: 'Create UI components and widgets',
|
|
553
|
+
status: 'pending',
|
|
554
|
+
priority: 'high'
|
|
555
|
+
},
|
|
556
|
+
{
|
|
557
|
+
id: this.generateId('todo'),
|
|
558
|
+
content: 'Implement business logic and workflows',
|
|
559
|
+
status: 'pending',
|
|
560
|
+
priority: 'high'
|
|
561
|
+
},
|
|
562
|
+
{
|
|
563
|
+
id: this.generateId('todo'),
|
|
564
|
+
content: 'Configure security and access controls',
|
|
565
|
+
status: 'pending',
|
|
566
|
+
priority: 'high'
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
id: this.generateId('todo'),
|
|
570
|
+
content: 'Create integration points',
|
|
571
|
+
status: 'pending',
|
|
572
|
+
priority: 'medium'
|
|
573
|
+
},
|
|
574
|
+
{
|
|
575
|
+
id: this.generateId('todo'),
|
|
576
|
+
content: 'Test application end-to-end',
|
|
393
577
|
status: 'pending',
|
|
394
578
|
priority: 'high'
|
|
395
579
|
}
|
|
@@ -407,12 +591,6 @@ class QueenAgent extends eventemitter3_1.EventEmitter {
|
|
|
407
591
|
status: 'pending',
|
|
408
592
|
priority: 'high'
|
|
409
593
|
},
|
|
410
|
-
{
|
|
411
|
-
id: this.generateId('todo'),
|
|
412
|
-
content: 'Determine script type (Business Rule, Script Include, etc.)',
|
|
413
|
-
status: 'pending',
|
|
414
|
-
priority: 'high'
|
|
415
|
-
},
|
|
416
594
|
{
|
|
417
595
|
id: this.generateId('todo'),
|
|
418
596
|
content: 'Design script logic and error handling',
|
|
@@ -421,7 +599,7 @@ class QueenAgent extends eventemitter3_1.EventEmitter {
|
|
|
421
599
|
},
|
|
422
600
|
{
|
|
423
601
|
id: this.generateId('todo'),
|
|
424
|
-
content: 'Implement core
|
|
602
|
+
content: 'Implement core functionality',
|
|
425
603
|
status: 'pending',
|
|
426
604
|
priority: 'high'
|
|
427
605
|
},
|
|
@@ -433,19 +611,19 @@ class QueenAgent extends eventemitter3_1.EventEmitter {
|
|
|
433
611
|
},
|
|
434
612
|
{
|
|
435
613
|
id: this.generateId('todo'),
|
|
436
|
-
content: '
|
|
614
|
+
content: 'Optimize performance',
|
|
437
615
|
status: 'pending',
|
|
438
616
|
priority: 'medium'
|
|
439
617
|
},
|
|
440
618
|
{
|
|
441
619
|
id: this.generateId('todo'),
|
|
442
|
-
content: '
|
|
620
|
+
content: 'Create unit tests',
|
|
443
621
|
status: 'pending',
|
|
444
622
|
priority: 'high'
|
|
445
623
|
},
|
|
446
624
|
{
|
|
447
625
|
id: this.generateId('todo'),
|
|
448
|
-
content: '
|
|
626
|
+
content: 'Deploy and validate in ServiceNow',
|
|
449
627
|
status: 'pending',
|
|
450
628
|
priority: 'high'
|
|
451
629
|
}
|
|
@@ -557,7 +735,7 @@ class QueenAgent extends eventemitter3_1.EventEmitter {
|
|
|
557
735
|
},
|
|
558
736
|
{
|
|
559
737
|
id: this.generateId('todo'),
|
|
560
|
-
content: '
|
|
738
|
+
content: 'Monitor and validate deployment',
|
|
561
739
|
status: 'pending',
|
|
562
740
|
priority: 'medium'
|
|
563
741
|
}
|
|
@@ -565,432 +743,331 @@ class QueenAgent extends eventemitter3_1.EventEmitter {
|
|
|
565
743
|
return todos;
|
|
566
744
|
}
|
|
567
745
|
/**
|
|
568
|
-
*
|
|
746
|
+
* Analyze todo dependencies
|
|
569
747
|
*/
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
if (templateTodo && stylingTodo && clientTodo) {
|
|
581
|
-
// Both styling and client script depend only on template, not on each other
|
|
582
|
-
dependencies.set(stylingTodo.id, [templateTodo.id]);
|
|
583
|
-
dependencies.set(clientTodo.id, [templateTodo.id]);
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
/**
|
|
587
|
-
* 🚀 NEW: Assign todos to parallel agent with specializations
|
|
588
|
-
*/
|
|
589
|
-
assignTodosToParallelAgent(agent, todoCoordination, assignedTodoIds, specializations) {
|
|
590
|
-
// Assign specific todos based on parallel workload planning
|
|
591
|
-
for (const todoId of assignedTodoIds) {
|
|
592
|
-
todoCoordination.agentAssignments.set(todoId, agent.id);
|
|
593
|
-
// Update agent task with first assigned todo
|
|
594
|
-
if (!agent.task) {
|
|
595
|
-
agent.task = todoId;
|
|
748
|
+
analyzeTodoDependencies(todos) {
|
|
749
|
+
const dependencies = new Map();
|
|
750
|
+
// Simple dependency analysis - each todo depends on all previous high priority todos
|
|
751
|
+
const highPriorityTodos = todos.filter(t => t.priority === 'high');
|
|
752
|
+
highPriorityTodos.forEach((todo, index) => {
|
|
753
|
+
if (index > 0) {
|
|
754
|
+
const prevHighPriorityIds = highPriorityTodos
|
|
755
|
+
.slice(0, index)
|
|
756
|
+
.map(t => t.id);
|
|
757
|
+
dependencies.set(todo.id, prevHighPriorityIds);
|
|
596
758
|
}
|
|
597
|
-
}
|
|
598
|
-
// Store specialization context in memory for agent coordination
|
|
599
|
-
this.memory.store(`agent_specializations_${agent.id}`, {
|
|
600
|
-
agentId: agent.id,
|
|
601
|
-
specializations,
|
|
602
|
-
assignedTodos: assignedTodoIds,
|
|
603
|
-
parallelMode: true,
|
|
604
|
-
timestamp: new Date().toISOString()
|
|
605
759
|
});
|
|
606
|
-
|
|
607
|
-
console.log(`📝 Assigned ${assignedTodoIds.length} todos for parallel execution`);
|
|
760
|
+
return dependencies;
|
|
608
761
|
}
|
|
609
762
|
/**
|
|
610
763
|
* Assign todos to agent based on capabilities
|
|
611
764
|
*/
|
|
612
|
-
assignTodosToAgent(agent,
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
const todoLower = todo.content.toLowerCase();
|
|
628
|
-
const matches = agentKeywords.some(keyword => todoLower.includes(keyword.toLowerCase()));
|
|
629
|
-
if (matches) {
|
|
630
|
-
todoCoordination.agentAssignments.set(todo.id, agent.id);
|
|
631
|
-
// Update agent task list
|
|
632
|
-
if (!agent.task) {
|
|
633
|
-
agent.task = todo.id;
|
|
634
|
-
}
|
|
635
|
-
}
|
|
765
|
+
async assignTodosToAgent(agent, objectiveId) {
|
|
766
|
+
const todoCoordination = this.todoCoordinations.get(objectiveId);
|
|
767
|
+
if (!todoCoordination)
|
|
768
|
+
return;
|
|
769
|
+
const unassignedTodos = todoCoordination.todos.filter(todo => !Array.from(todoCoordination.agentAssignments.values()).includes(todo.id) &&
|
|
770
|
+
todo.status === 'pending');
|
|
771
|
+
// Assign todos based on agent type and specialization
|
|
772
|
+
const assignableTodos = unassignedTodos.filter(todo => this.canAgentHandleTodo(agent, todo));
|
|
773
|
+
for (const todo of assignableTodos) {
|
|
774
|
+
todoCoordination.agentAssignments.set(todo.id, agent.id);
|
|
775
|
+
// Update agent's assigned todos in memory
|
|
776
|
+
const agentData = await this.memory.get(`agent_${agent.id}`);
|
|
777
|
+
if (agentData) {
|
|
778
|
+
agentData.assignedTodos.push(todo.id);
|
|
779
|
+
await this.memory.store(`agent_${agent.id}`, agentData);
|
|
636
780
|
}
|
|
637
781
|
}
|
|
782
|
+
this.emit('todos:assigned', { agent, todos: assignableTodos });
|
|
638
783
|
}
|
|
639
784
|
/**
|
|
640
|
-
*
|
|
785
|
+
* Check if agent can handle specific todo
|
|
641
786
|
*/
|
|
642
|
-
|
|
643
|
-
const
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
case '
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
case '
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
case '
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
787
|
+
canAgentHandleTodo(agent, todo) {
|
|
788
|
+
const todoContent = todo.content.toLowerCase();
|
|
789
|
+
switch (agent.type) {
|
|
790
|
+
case 'widget-creator':
|
|
791
|
+
return todoContent.includes('widget') ||
|
|
792
|
+
todoContent.includes('html') ||
|
|
793
|
+
todoContent.includes('portal') ||
|
|
794
|
+
todoContent.includes('ui');
|
|
795
|
+
case 'css-specialist':
|
|
796
|
+
return todoContent.includes('style') ||
|
|
797
|
+
todoContent.includes('css') ||
|
|
798
|
+
todoContent.includes('responsive') ||
|
|
799
|
+
todoContent.includes('theme');
|
|
800
|
+
case 'backend-specialist':
|
|
801
|
+
return todoContent.includes('server') ||
|
|
802
|
+
todoContent.includes('backend') ||
|
|
803
|
+
todoContent.includes('data') ||
|
|
804
|
+
todoContent.includes('api');
|
|
805
|
+
case 'frontend-specialist':
|
|
806
|
+
return todoContent.includes('client') ||
|
|
807
|
+
todoContent.includes('controller') ||
|
|
808
|
+
todoContent.includes('interactive') ||
|
|
809
|
+
todoContent.includes('event');
|
|
810
|
+
case 'flow-builder':
|
|
811
|
+
return todoContent.includes('flow') ||
|
|
812
|
+
todoContent.includes('workflow') ||
|
|
813
|
+
todoContent.includes('trigger') ||
|
|
814
|
+
todoContent.includes('action');
|
|
815
|
+
case 'script-writer':
|
|
816
|
+
return todoContent.includes('script') ||
|
|
817
|
+
todoContent.includes('logic') ||
|
|
818
|
+
todoContent.includes('function');
|
|
819
|
+
case 'integration-specialist':
|
|
820
|
+
return todoContent.includes('integration') ||
|
|
821
|
+
todoContent.includes('external') ||
|
|
822
|
+
todoContent.includes('api') ||
|
|
823
|
+
todoContent.includes('rest');
|
|
824
|
+
case 'tester':
|
|
825
|
+
return todoContent.includes('test') ||
|
|
826
|
+
todoContent.includes('validate') ||
|
|
827
|
+
todoContent.includes('verify');
|
|
828
|
+
case 'security-specialist':
|
|
829
|
+
return todoContent.includes('security') ||
|
|
830
|
+
todoContent.includes('permission') ||
|
|
831
|
+
todoContent.includes('access') ||
|
|
832
|
+
todoContent.includes('vulnerability');
|
|
833
|
+
case 'performance-specialist':
|
|
834
|
+
return todoContent.includes('performance') ||
|
|
835
|
+
todoContent.includes('optimization') ||
|
|
836
|
+
todoContent.includes('caching');
|
|
837
|
+
case 'ui-ux-specialist':
|
|
838
|
+
return todoContent.includes('user experience') ||
|
|
839
|
+
todoContent.includes('design') ||
|
|
840
|
+
todoContent.includes('ux');
|
|
689
841
|
default:
|
|
690
|
-
//
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
842
|
+
// Generic agents can handle setup and coordination tasks
|
|
843
|
+
return todoContent.includes('initialize') ||
|
|
844
|
+
todoContent.includes('validate') ||
|
|
845
|
+
todoContent.includes('create update set') ||
|
|
846
|
+
todoContent.includes('documentation');
|
|
694
847
|
}
|
|
695
|
-
// Estimate complexity based on description
|
|
696
|
-
const complexityFactors = {
|
|
697
|
-
words: description.split(' ').length,
|
|
698
|
-
hasIntegration: description.includes('integration') || description.includes('api'),
|
|
699
|
-
hasMultipleComponents: description.includes('and') || description.includes('with'),
|
|
700
|
-
hasComplexLogic: description.includes('complex') || description.includes('advanced'),
|
|
701
|
-
hasPerformanceReqs: description.includes('performance') || description.includes('optimize')
|
|
702
|
-
};
|
|
703
|
-
const estimatedComplexity = complexityFactors.words / 10 +
|
|
704
|
-
(complexityFactors.hasIntegration ? 2 : 0) +
|
|
705
|
-
(complexityFactors.hasMultipleComponents ? 1 : 0) +
|
|
706
|
-
(complexityFactors.hasComplexLogic ? 2 : 0) +
|
|
707
|
-
(complexityFactors.hasPerformanceReqs ? 1 : 0);
|
|
708
|
-
// Look for successful patterns in memory
|
|
709
|
-
const suggestedPattern = await this.memory.findBestPattern(type);
|
|
710
|
-
// Extract dependencies
|
|
711
|
-
const dependencies = [];
|
|
712
|
-
if (description.includes('table'))
|
|
713
|
-
dependencies.push('table_creation');
|
|
714
|
-
if (description.includes('user'))
|
|
715
|
-
dependencies.push('user_management');
|
|
716
|
-
if (description.includes('approval'))
|
|
717
|
-
dependencies.push('approval_framework');
|
|
718
|
-
if (description.includes('notification'))
|
|
719
|
-
dependencies.push('notification_system');
|
|
720
|
-
return {
|
|
721
|
-
type,
|
|
722
|
-
requiredAgents: [...new Set(requiredAgents)], // Remove duplicates
|
|
723
|
-
estimatedComplexity: Math.min(10, Math.max(1, estimatedComplexity)),
|
|
724
|
-
suggestedPattern,
|
|
725
|
-
dependencies
|
|
726
|
-
};
|
|
727
848
|
}
|
|
728
849
|
/**
|
|
729
|
-
*
|
|
850
|
+
* Monitor agent progress through todo updates
|
|
730
851
|
*/
|
|
731
|
-
async
|
|
732
|
-
const
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
type,
|
|
736
|
-
status: 'idle',
|
|
737
|
-
capabilities: this.getAgentCapabilities(type),
|
|
738
|
-
mcpTools: this.getAgentMcpTools(type)
|
|
739
|
-
};
|
|
740
|
-
// Store agent in memory for coordination
|
|
741
|
-
await this.memory.store(`agent_${agentId}`, {
|
|
742
|
-
agent,
|
|
743
|
-
objectiveId,
|
|
744
|
-
specialization: specialization || 'general',
|
|
745
|
-
parallelMode: !!specialization,
|
|
746
|
-
spawnedAt: new Date().toISOString()
|
|
747
|
-
});
|
|
748
|
-
if (specialization) {
|
|
749
|
-
console.log(`👤 Spawned specialized ${type} agent: ${specialization}`);
|
|
750
|
-
}
|
|
751
|
-
// Notify coordinator of new agent
|
|
752
|
-
await this.coordinator.registerAgent(agent);
|
|
753
|
-
this.emit('agent:spawned', agent);
|
|
754
|
-
return agent;
|
|
755
|
-
}
|
|
756
|
-
/**
|
|
757
|
-
* Get agent capabilities based on type
|
|
758
|
-
*/
|
|
759
|
-
getAgentCapabilities(type) {
|
|
760
|
-
const capabilityMap = {
|
|
761
|
-
'widget-creator': ['html_generation', 'css_styling', 'javascript_development', 'servicenow_api', 'widget_deployment'],
|
|
762
|
-
'flow-builder': ['flow_design', 'trigger_configuration', 'action_creation', 'decision_logic', 'flow_testing'],
|
|
763
|
-
'script-writer': ['glide_scripting', 'business_logic', 'error_handling', 'performance_optimization', 'script_deployment'],
|
|
764
|
-
'app-architect': ['system_design', 'architecture_planning', 'component_integration', 'best_practices', 'documentation'],
|
|
765
|
-
'integration-specialist': ['rest_api', 'soap_services', 'data_transformation', 'authentication', 'error_recovery'],
|
|
766
|
-
'catalog-manager': ['catalog_creation', 'variable_management', 'workflow_linking', 'approval_setup', 'ui_design'],
|
|
767
|
-
'researcher': ['requirement_analysis', 'feasibility_study', 'solution_research', 'best_practice_identification'],
|
|
768
|
-
'tester': ['test_planning', 'test_execution', 'mock_data_creation', 'integration_testing', 'performance_testing']
|
|
769
|
-
};
|
|
770
|
-
return capabilityMap[type] || ['general_servicenow_development'];
|
|
771
|
-
}
|
|
772
|
-
/**
|
|
773
|
-
* Get MCP tools available to agent type
|
|
774
|
-
*/
|
|
775
|
-
getAgentMcpTools(type) {
|
|
776
|
-
const toolMap = {
|
|
777
|
-
'widget-creator': ['snow_deploy', 'snow_preview_widget', 'snow_widget_test'],
|
|
778
|
-
'flow-builder': ['snow_create_flow', 'snow_test_flow_with_mock', 'snow_validate_flow_definition'],
|
|
779
|
-
'script-writer': ['snow_create_script_include', 'snow_create_business_rule', 'snow_create_client_script'],
|
|
780
|
-
'app-architect': ['snow_analyze_requirements', 'snow_create_application', 'snow_intelligent_flow_analysis'],
|
|
781
|
-
'integration-specialist': ['snow_create_rest_message', 'snow_create_transform_map', 'snow_test_integration'],
|
|
782
|
-
'catalog-manager': ['snow_catalog_item_search', 'snow_catalog_item_manager', 'snow_link_catalog_to_flow'],
|
|
783
|
-
'researcher': ['snow_find_artifact', 'snow_comprehensive_search', 'snow_discover_existing_flows'],
|
|
784
|
-
'tester': ['snow_test_flow_with_mock', 'snow_widget_test', 'snow_comprehensive_flow_test']
|
|
785
|
-
};
|
|
786
|
-
return toolMap[type] || ['snow_find_artifact'];
|
|
787
|
-
}
|
|
788
|
-
/**
|
|
789
|
-
* Identify blocking issues in todo coordination
|
|
790
|
-
*/
|
|
791
|
-
async identifyBlockingIssues(todoCoordination) {
|
|
792
|
-
const issues = [];
|
|
793
|
-
// Check for todos with unmet dependencies
|
|
794
|
-
for (const [todoId, deps] of todoCoordination.dependencies) {
|
|
795
|
-
const todo = todoCoordination.todos.find(t => t.id === todoId);
|
|
796
|
-
if (todo && todo.status === 'pending') {
|
|
797
|
-
const unmetDeps = deps.filter(depId => {
|
|
798
|
-
const depTodo = todoCoordination.todos.find(t => t.id === depId);
|
|
799
|
-
return depTodo && depTodo.status !== 'completed';
|
|
800
|
-
});
|
|
801
|
-
if (unmetDeps.length > 0) {
|
|
802
|
-
issues.push(`Todo "${todo.content}" blocked by ${unmetDeps.length} dependencies`);
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
// Check for todos with no assigned agent
|
|
807
|
-
const unassignedTodos = todoCoordination.todos.filter(todo => !todoCoordination.agentAssignments.has(todo.id) && todo.status === 'pending');
|
|
808
|
-
if (unassignedTodos.length > 0) {
|
|
809
|
-
issues.push(`${unassignedTodos.length} todos have no assigned agent`);
|
|
852
|
+
async monitorProgress(objectiveId) {
|
|
853
|
+
const todoCoordination = this.todoCoordinations.get(objectiveId);
|
|
854
|
+
if (!todoCoordination) {
|
|
855
|
+
throw new Error(`No todo coordination found for objective: ${objectiveId}`);
|
|
810
856
|
}
|
|
811
|
-
//
|
|
812
|
-
const
|
|
813
|
-
|
|
814
|
-
|
|
857
|
+
// Calculate progress from todos
|
|
858
|
+
const completedTodos = todoCoordination.todos.filter(t => t.status === 'completed').length;
|
|
859
|
+
const totalTodos = todoCoordination.todos.length;
|
|
860
|
+
const overallProgress = totalTodos > 0 ? (completedTodos / totalTodos) * 100 : 0;
|
|
861
|
+
// Calculate per-agent progress
|
|
862
|
+
const byAgent = new Map();
|
|
863
|
+
for (const [todoId, agentId] of todoCoordination.agentAssignments) {
|
|
864
|
+
const agentTodos = Array.from(todoCoordination.agentAssignments.entries())
|
|
865
|
+
.filter(([_, aid]) => aid === agentId);
|
|
866
|
+
const agentCompleted = agentTodos.filter(([tid, _]) => todoCoordination.todos.find(t => t.id === tid)?.status === 'completed').length;
|
|
867
|
+
const agentProgress = agentTodos.length > 0 ? (agentCompleted / agentTodos.length) * 100 : 0;
|
|
868
|
+
byAgent.set(agentId, agentProgress);
|
|
815
869
|
}
|
|
816
|
-
|
|
870
|
+
// Identify blocking issues
|
|
871
|
+
const blockingIssues = await this.identifyBlockingIssues(todoCoordination);
|
|
872
|
+
// Estimate completion based on current velocity
|
|
873
|
+
const estimatedCompletion = this.estimateCompletion(todoCoordination, overallProgress);
|
|
874
|
+
// Store progress in memory
|
|
875
|
+
await this.memory.store(`progress_${objectiveId}`, {
|
|
876
|
+
overall: overallProgress,
|
|
877
|
+
byAgent: Object.fromEntries(byAgent),
|
|
878
|
+
blockingIssues,
|
|
879
|
+
estimatedCompletion: estimatedCompletion.toISOString(),
|
|
880
|
+
timestamp: new Date().toISOString()
|
|
881
|
+
});
|
|
882
|
+
this.emit('progress:updated', { objectiveId, overall: overallProgress, byAgent, blockingIssues });
|
|
883
|
+
return {
|
|
884
|
+
overall: overallProgress,
|
|
885
|
+
byAgent,
|
|
886
|
+
blockingIssues,
|
|
887
|
+
estimatedCompletion
|
|
888
|
+
};
|
|
817
889
|
}
|
|
818
890
|
/**
|
|
819
|
-
*
|
|
891
|
+
* Make memory-driven decisions based on past patterns
|
|
820
892
|
*/
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
const
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
893
|
+
async makeDecision(context) {
|
|
894
|
+
// Query memory for similar past decisions
|
|
895
|
+
const similarPatterns = await this.memory.findSimilarPatterns(context.objective);
|
|
896
|
+
// Analyze success rates of past decisions
|
|
897
|
+
const successRates = new Map();
|
|
898
|
+
for (const option of context.options) {
|
|
899
|
+
const pastOutcomes = similarPatterns.filter(p => p.decision === option);
|
|
900
|
+
const successRate = pastOutcomes.length > 0
|
|
901
|
+
? pastOutcomes.filter(p => p.outcome === 'success').length / pastOutcomes.length
|
|
902
|
+
: 0.5; // Default to 50% if no history
|
|
903
|
+
successRates.set(option, successRate);
|
|
827
904
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
calculateOptionScore(option, patterns, context) {
|
|
836
|
-
let score = 50; // Base score
|
|
837
|
-
// Adjust based on historical success with similar patterns
|
|
838
|
-
for (const pattern of patterns) {
|
|
839
|
-
if (pattern.agentSequence.some(agent => option.toLowerCase().includes(agent))) {
|
|
840
|
-
score += pattern.successRate * 20;
|
|
905
|
+
// Choose option with highest success rate
|
|
906
|
+
let bestOption = context.options[0];
|
|
907
|
+
let highestRate = 0;
|
|
908
|
+
for (const [option, rate] of successRates) {
|
|
909
|
+
if (rate > highestRate) {
|
|
910
|
+
highestRate = rate;
|
|
911
|
+
bestOption = option;
|
|
841
912
|
}
|
|
842
913
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
const reasons = [];
|
|
859
|
-
// Check historical patterns
|
|
860
|
-
const relevantPatterns = patterns.filter(p => p.agentSequence.some(agent => decision.toLowerCase().includes(agent)));
|
|
861
|
-
if (relevantPatterns.length > 0) {
|
|
862
|
-
const avgSuccess = relevantPatterns.reduce((sum, p) => sum + p.successRate, 0) / relevantPatterns.length;
|
|
863
|
-
reasons.push(`Historical success rate: ${Math.round(avgSuccess)}%`);
|
|
864
|
-
}
|
|
865
|
-
// Check objective alignment
|
|
866
|
-
const objectiveWords = context.objective.toLowerCase().split(' ');
|
|
867
|
-
const decisionWords = decision.toLowerCase().split(' ');
|
|
868
|
-
const alignment = objectiveWords.filter(word => decisionWords.includes(word)).length;
|
|
869
|
-
if (alignment > 0) {
|
|
870
|
-
reasons.push(`Strong alignment with objective (${alignment} matching concepts)`);
|
|
871
|
-
}
|
|
872
|
-
// Default reasoning if no specific reasons
|
|
873
|
-
if (reasons.length === 0) {
|
|
874
|
-
reasons.push('Best option based on current context and available capabilities');
|
|
875
|
-
}
|
|
876
|
-
return reasons.join('; ');
|
|
914
|
+
const confidence = highestRate > 0.7 ? 0.9 : highestRate > 0.5 ? 0.7 : 0.5;
|
|
915
|
+
const decision = {
|
|
916
|
+
decision: bestOption,
|
|
917
|
+
confidence,
|
|
918
|
+
reasoning: `Based on ${similarPatterns.length} similar past scenarios, "${bestOption}" has a ${(highestRate * 100).toFixed(0)}% success rate.`
|
|
919
|
+
};
|
|
920
|
+
// Store decision for future learning
|
|
921
|
+
await this.memory.storeDecision({
|
|
922
|
+
context,
|
|
923
|
+
decision: decision.decision,
|
|
924
|
+
confidence: decision.confidence,
|
|
925
|
+
timestamp: new Date().toISOString()
|
|
926
|
+
});
|
|
927
|
+
this.emit('decision:made', decision);
|
|
928
|
+
return decision;
|
|
877
929
|
}
|
|
878
930
|
/**
|
|
879
|
-
*
|
|
931
|
+
* Setup event handlers for coordination
|
|
880
932
|
*/
|
|
881
933
|
setupEventHandlers() {
|
|
882
|
-
//
|
|
883
|
-
this.coordinator.on('agent:
|
|
884
|
-
|
|
934
|
+
// Handle agent lifecycle events
|
|
935
|
+
this.coordinator.on('agent:ready', async (data) => {
|
|
936
|
+
console.log(`✅ Agent ${data.agentId} ready for tasks`);
|
|
937
|
+
await this.assignTodosToAgent(this.activeAgents.get(data.agentId), data.objectiveId);
|
|
885
938
|
});
|
|
886
|
-
this.coordinator.on('agent:
|
|
887
|
-
|
|
939
|
+
this.coordinator.on('agent:completed', async (data) => {
|
|
940
|
+
console.log(`✅ Agent ${data.agentId} completed all tasks`);
|
|
941
|
+
this.activeAgents.delete(data.agentId);
|
|
942
|
+
// Check if we need to spawn more agents
|
|
943
|
+
if (this.config.autoSpawn) {
|
|
944
|
+
await this.checkAndSpawnAgents(data.objectiveId);
|
|
945
|
+
}
|
|
888
946
|
});
|
|
889
|
-
this.coordinator.on('
|
|
890
|
-
|
|
947
|
+
this.coordinator.on('agent:error', async (data) => {
|
|
948
|
+
console.error(`❌ Agent ${data.agentId} encountered error:`, data.error);
|
|
949
|
+
// Handle 403 errors specifically
|
|
950
|
+
if (this.is403Error(data.error)) {
|
|
951
|
+
const handled = await this.handleDeploymentError(data.error, {
|
|
952
|
+
objectiveId: data.objectiveId,
|
|
953
|
+
agentId: data.agentId,
|
|
954
|
+
operation: 'deployment',
|
|
955
|
+
artifactType: data.artifactType
|
|
956
|
+
});
|
|
957
|
+
if (handled) {
|
|
958
|
+
// Retry the agent's task
|
|
959
|
+
this.emit('agent:retry', data);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
891
962
|
});
|
|
892
963
|
}
|
|
893
964
|
/**
|
|
894
|
-
*
|
|
965
|
+
* Check if more agents need to be spawned
|
|
895
966
|
*/
|
|
896
|
-
async
|
|
897
|
-
this.
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
967
|
+
async checkAndSpawnAgents(objectiveId) {
|
|
968
|
+
const todoCoordination = this.todoCoordinations.get(objectiveId);
|
|
969
|
+
if (!todoCoordination)
|
|
970
|
+
return;
|
|
971
|
+
const unassignedTodos = todoCoordination.todos.filter(todo => !Array.from(todoCoordination.agentAssignments.values()).includes(todo.id) &&
|
|
972
|
+
todo.status === 'pending');
|
|
973
|
+
if (unassignedTodos.length > 0 && this.activeAgents.size < this.config.maxConcurrentAgents) {
|
|
974
|
+
// Spawn additional agents if needed
|
|
975
|
+
await this.spawnAgents(objectiveId);
|
|
901
976
|
}
|
|
902
977
|
}
|
|
903
978
|
/**
|
|
904
|
-
* Handle
|
|
979
|
+
* Handle coordination errors
|
|
905
980
|
*/
|
|
906
|
-
async
|
|
907
|
-
|
|
908
|
-
//
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
981
|
+
async handleCoordinationError(error, context) {
|
|
982
|
+
console.error('❌ Coordination error:', error);
|
|
983
|
+
// Store error in memory for learning
|
|
984
|
+
await this.memory.storeError({
|
|
985
|
+
error: error.message || error,
|
|
986
|
+
context,
|
|
987
|
+
timestamp: new Date().toISOString(),
|
|
988
|
+
recovery: null
|
|
913
989
|
});
|
|
914
|
-
|
|
915
|
-
// Spawn additional agent to help
|
|
916
|
-
await this.spawnAgents(data.objectiveId);
|
|
917
|
-
}
|
|
990
|
+
this.emit('coordination:error', { error, context });
|
|
918
991
|
}
|
|
919
992
|
/**
|
|
920
|
-
*
|
|
993
|
+
* Identify blocking issues from todos
|
|
921
994
|
*/
|
|
922
|
-
async
|
|
923
|
-
|
|
924
|
-
//
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
995
|
+
async identifyBlockingIssues(todoCoordination) {
|
|
996
|
+
const issues = [];
|
|
997
|
+
// Check for failed todos
|
|
998
|
+
const failedTodos = todoCoordination.todos.filter(t => t.status === 'failed');
|
|
999
|
+
if (failedTodos.length > 0) {
|
|
1000
|
+
issues.push(`${failedTodos.length} failed tasks blocking progress`);
|
|
1001
|
+
}
|
|
1002
|
+
// Check for stuck in-progress todos (older than 10 minutes)
|
|
1003
|
+
const stuckTodos = todoCoordination.todos.filter(t => {
|
|
1004
|
+
if (t.status !== 'in_progress')
|
|
1005
|
+
return false;
|
|
1006
|
+
const todoData = this.memory.get(`todo_${t.id}`);
|
|
1007
|
+
if (!todoData || !todoData.startTime)
|
|
1008
|
+
return false;
|
|
1009
|
+
return Date.now() - todoData.startTime > 10 * 60 * 1000; // 10 minutes
|
|
930
1010
|
});
|
|
1011
|
+
if (stuckTodos.length > 0) {
|
|
1012
|
+
issues.push(`${stuckTodos.length} tasks stuck in progress`);
|
|
1013
|
+
}
|
|
1014
|
+
// Check for dependency bottlenecks
|
|
1015
|
+
const pendingWithDeps = todoCoordination.todos.filter(t => t.status === 'pending' &&
|
|
1016
|
+
todoCoordination.dependencies.has(t.id));
|
|
1017
|
+
for (const todo of pendingWithDeps) {
|
|
1018
|
+
const deps = todoCoordination.dependencies.get(todo.id) || [];
|
|
1019
|
+
const incompleteDeps = deps.filter(depId => {
|
|
1020
|
+
const depTodo = todoCoordination.todos.find(t => t.id === depId);
|
|
1021
|
+
return depTodo && depTodo.status !== 'completed';
|
|
1022
|
+
});
|
|
1023
|
+
if (incompleteDeps.length === deps.length) {
|
|
1024
|
+
issues.push(`Task "${todo.content}" blocked by dependencies`);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
return issues;
|
|
931
1028
|
}
|
|
932
1029
|
/**
|
|
933
|
-
*
|
|
1030
|
+
* Estimate completion time based on current progress
|
|
934
1031
|
*/
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
return;
|
|
939
|
-
const todo = todoCoordination.todos.find(t => t.id === todoId);
|
|
940
|
-
if (todo) {
|
|
941
|
-
todo.status = status;
|
|
942
|
-
// Store update in memory
|
|
943
|
-
await this.memory.store(`todo_update_${todoId}`, {
|
|
944
|
-
todoId,
|
|
945
|
-
newStatus: status,
|
|
946
|
-
timestamp: new Date().toISOString()
|
|
947
|
-
});
|
|
948
|
-
this.emit('todo:updated', { objectiveId, todoId, status });
|
|
1032
|
+
estimateCompletion(todoCoordination, currentProgress) {
|
|
1033
|
+
if (currentProgress === 0) {
|
|
1034
|
+
return new Date(Date.now() + 24 * 60 * 60 * 1000); // 24 hours if no progress
|
|
949
1035
|
}
|
|
1036
|
+
const completedTodos = todoCoordination.todos.filter(t => t.status === 'completed').length;
|
|
1037
|
+
const startTime = this.activeObjectives.get(todoCoordination.objectiveId)?.metadata?.startTime || Date.now();
|
|
1038
|
+
const elapsedTime = Date.now() - startTime;
|
|
1039
|
+
const averageTimePerTodo = elapsedTime / completedTodos;
|
|
1040
|
+
const remainingTodos = todoCoordination.todos.filter(t => t.status !== 'completed').length;
|
|
1041
|
+
const estimatedRemainingTime = averageTimePerTodo * remainingTodos;
|
|
1042
|
+
return new Date(Date.now() + estimatedRemainingTime);
|
|
950
1043
|
}
|
|
951
1044
|
/**
|
|
952
|
-
* Generate unique ID
|
|
1045
|
+
* Generate unique ID for entities
|
|
953
1046
|
*/
|
|
954
1047
|
generateId(prefix) {
|
|
955
1048
|
return `${prefix}_${Date.now()}_${crypto.randomBytes(4).toString('hex')}`;
|
|
956
1049
|
}
|
|
957
1050
|
/**
|
|
958
|
-
*
|
|
959
|
-
*/
|
|
960
|
-
async getStatus() {
|
|
961
|
-
let totalTodos = 0;
|
|
962
|
-
let completedTodos = 0;
|
|
963
|
-
for (const coordination of this.todoCoordinations.values()) {
|
|
964
|
-
totalTodos += coordination.todos.length;
|
|
965
|
-
completedTodos += coordination.todos.filter(t => t.status === 'completed').length;
|
|
966
|
-
}
|
|
967
|
-
return {
|
|
968
|
-
activeObjectives: this.activeObjectives.size,
|
|
969
|
-
activeAgents: this.activeAgents.size,
|
|
970
|
-
totalTodos,
|
|
971
|
-
completedTodos,
|
|
972
|
-
memoryStats: await this.memory.getStats()
|
|
973
|
-
};
|
|
974
|
-
}
|
|
975
|
-
/**
|
|
976
|
-
* Shutdown queen agent
|
|
1051
|
+
* Shutdown queen agent gracefully
|
|
977
1052
|
*/
|
|
978
1053
|
async shutdown() {
|
|
979
|
-
|
|
980
|
-
|
|
1054
|
+
console.log('👑 Queen Agent shutting down...');
|
|
1055
|
+
// Save current state
|
|
1056
|
+
for (const [objectiveId, objective] of this.activeObjectives) {
|
|
1057
|
+
await this.memory.store(`objective_state_${objectiveId}`, {
|
|
1058
|
+
objective,
|
|
1059
|
+
todoCoordination: this.todoCoordinations.get(objectiveId),
|
|
1060
|
+
activeAgents: Array.from(this.activeAgents.values()).filter(a => a.objectiveId === objectiveId),
|
|
1061
|
+
timestamp: new Date().toISOString()
|
|
1062
|
+
});
|
|
981
1063
|
}
|
|
982
|
-
//
|
|
1064
|
+
// Notify all active agents
|
|
983
1065
|
for (const agent of this.activeAgents.values()) {
|
|
984
|
-
|
|
1066
|
+
this.emit('agent:shutdown', agent);
|
|
985
1067
|
}
|
|
986
|
-
|
|
987
|
-
this.
|
|
988
|
-
|
|
989
|
-
this.activeObjectives.clear();
|
|
990
|
-
this.todoCoordinations.clear();
|
|
991
|
-
this.activeAgents.clear();
|
|
992
|
-
this.emit('shutdown');
|
|
1068
|
+
await this.memory.close();
|
|
1069
|
+
this.removeAllListeners();
|
|
1070
|
+
console.log('✅ Queen Agent shutdown complete');
|
|
993
1071
|
}
|
|
994
1072
|
}
|
|
995
1073
|
exports.QueenAgent = QueenAgent;
|
|
996
|
-
//# sourceMappingURL=queen-agent.js.map
|