@loxia-labs/loxia-autopilot-one 1.0.1 → 1.0.3
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/README.md +44 -54
- package/bin/cli.js +1 -115
- package/bin/loxia-terminal-v2.js +3 -0
- package/bin/loxia-terminal.js +3 -0
- package/bin/start-with-terminal.js +3 -0
- package/package.json +14 -15
- package/scripts/install-scanners.js +1 -235
- package/src/analyzers/CSSAnalyzer.js +1 -297
- package/src/analyzers/ConfigValidator.js +1 -690
- package/src/analyzers/ESLintAnalyzer.js +1 -320
- package/src/analyzers/JavaScriptAnalyzer.js +1 -261
- package/src/analyzers/PrettierFormatter.js +1 -247
- package/src/analyzers/PythonAnalyzer.js +1 -266
- package/src/analyzers/SecurityAnalyzer.js +1 -729
- package/src/analyzers/TypeScriptAnalyzer.js +1 -247
- package/src/analyzers/codeCloneDetector/analyzer.js +1 -344
- package/src/analyzers/codeCloneDetector/detector.js +1 -203
- package/src/analyzers/codeCloneDetector/index.js +1 -160
- package/src/analyzers/codeCloneDetector/parser.js +1 -199
- package/src/analyzers/codeCloneDetector/reporter.js +1 -148
- package/src/analyzers/codeCloneDetector/scanner.js +1 -59
- package/src/core/agentPool.js +1 -1474
- package/src/core/agentScheduler.js +1 -2147
- package/src/core/contextManager.js +1 -709
- package/src/core/messageProcessor.js +1 -732
- package/src/core/orchestrator.js +1 -548
- package/src/core/stateManager.js +1 -877
- package/src/index.js +1 -631
- package/src/interfaces/cli.js +1 -549
- package/src/interfaces/terminal/__tests__/smoke/advancedFeatures.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agentControl.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agents.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/components.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/connection.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/imports.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/messages.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/tools.test.js +1 -0
- package/src/interfaces/terminal/api/apiClient.js +1 -0
- package/src/interfaces/terminal/api/messageRouter.js +1 -0
- package/src/interfaces/terminal/api/session.js +1 -0
- package/src/interfaces/terminal/api/websocket.js +1 -0
- package/src/interfaces/terminal/components/AgentCreator.js +1 -0
- package/src/interfaces/terminal/components/AgentEditor.js +1 -0
- package/src/interfaces/terminal/components/AgentSwitcher.js +1 -0
- package/src/interfaces/terminal/components/ErrorBoundary.js +1 -0
- package/src/interfaces/terminal/components/ErrorPanel.js +1 -0
- package/src/interfaces/terminal/components/Header.js +1 -0
- package/src/interfaces/terminal/components/HelpPanel.js +1 -0
- package/src/interfaces/terminal/components/InputBox.js +1 -0
- package/src/interfaces/terminal/components/Layout.js +1 -0
- package/src/interfaces/terminal/components/LoadingSpinner.js +1 -0
- package/src/interfaces/terminal/components/MessageList.js +1 -0
- package/src/interfaces/terminal/components/MultilineTextInput.js +1 -0
- package/src/interfaces/terminal/components/SearchPanel.js +1 -0
- package/src/interfaces/terminal/components/SettingsPanel.js +1 -0
- package/src/interfaces/terminal/components/StatusBar.js +1 -0
- package/src/interfaces/terminal/components/TextInput.js +1 -0
- package/src/interfaces/terminal/config/agentEditorConstants.js +1 -0
- package/src/interfaces/terminal/config/constants.js +1 -0
- package/src/interfaces/terminal/index.js +1 -0
- package/src/interfaces/terminal/state/useAgentControl.js +1 -0
- package/src/interfaces/terminal/state/useAgents.js +1 -0
- package/src/interfaces/terminal/state/useConnection.js +1 -0
- package/src/interfaces/terminal/state/useMessages.js +1 -0
- package/src/interfaces/terminal/state/useTools.js +1 -0
- package/src/interfaces/terminal/utils/debugLogger.js +1 -0
- package/src/interfaces/terminal/utils/settingsStorage.js +1 -0
- package/src/interfaces/terminal/utils/theme.js +1 -0
- package/src/interfaces/webServer.js +1 -2162
- package/src/modules/fileExplorer/controller.js +1 -280
- package/src/modules/fileExplorer/index.js +1 -37
- package/src/modules/fileExplorer/middleware.js +1 -92
- package/src/modules/fileExplorer/routes.js +1 -125
- package/src/modules/fileExplorer/types.js +1 -44
- package/src/services/aiService.js +1 -1232
- package/src/services/apiKeyManager.js +1 -164
- package/src/services/benchmarkService.js +1 -366
- package/src/services/budgetService.js +1 -539
- package/src/services/contextInjectionService.js +1 -247
- package/src/services/conversationCompactionService.js +1 -637
- package/src/services/errorHandler.js +1 -810
- package/src/services/fileAttachmentService.js +1 -544
- package/src/services/modelRouterService.js +1 -366
- package/src/services/modelsService.js +1 -322
- package/src/services/qualityInspector.js +1 -796
- package/src/services/tokenCountingService.js +1 -536
- package/src/tools/agentCommunicationTool.js +1 -1344
- package/src/tools/agentDelayTool.js +1 -485
- package/src/tools/asyncToolManager.js +1 -604
- package/src/tools/baseTool.js +1 -800
- package/src/tools/browserTool.js +1 -920
- package/src/tools/cloneDetectionTool.js +1 -621
- package/src/tools/dependencyResolverTool.js +1 -1215
- package/src/tools/fileContentReplaceTool.js +1 -875
- package/src/tools/fileSystemTool.js +1 -1107
- package/src/tools/fileTreeTool.js +1 -853
- package/src/tools/imageTool.js +1 -901
- package/src/tools/importAnalyzerTool.js +1 -1060
- package/src/tools/jobDoneTool.js +1 -248
- package/src/tools/seekTool.js +1 -956
- package/src/tools/staticAnalysisTool.js +1 -1778
- package/src/tools/taskManagerTool.js +1 -2873
- package/src/tools/terminalTool.js +1 -2304
- package/src/tools/webTool.js +1 -1430
- package/src/types/agent.js +1 -519
- package/src/types/contextReference.js +1 -972
- package/src/types/conversation.js +1 -730
- package/src/types/toolCommand.js +1 -747
- package/src/utilities/attachmentValidator.js +1 -292
- package/src/utilities/configManager.js +1 -582
- package/src/utilities/constants.js +1 -722
- package/src/utilities/directoryAccessManager.js +1 -535
- package/src/utilities/fileProcessor.js +1 -307
- package/src/utilities/logger.js +1 -436
- package/src/utilities/tagParser.js +1 -1246
- package/src/utilities/toolConstants.js +1 -317
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/{index-Dy2bYbOa.css → index-CClD1090.css} +1 -1
- package/web-ui/build/static/{index-CjkkcnFA.js → index-lCBai6dX.js} +66 -67
|
@@ -1,2873 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TaskManagerTool - Manages task list for agent autonomous operation
|
|
3
|
-
*
|
|
4
|
-
* Purpose:
|
|
5
|
-
* - Allows agents to create, update, and manage their own TODO list
|
|
6
|
-
* - Provides task tracking for agent-mode scheduling decisions
|
|
7
|
-
* - Ensures agents only consume resources when they have actual work
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { BaseTool } from './baseTool.js';
|
|
11
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
12
|
-
|
|
13
|
-
class TaskManagerTool extends BaseTool {
|
|
14
|
-
constructor(config = {}) {
|
|
15
|
-
super({
|
|
16
|
-
name: 'taskmanager',
|
|
17
|
-
description: config.description || 'Task management tool for organizing and tracking work',
|
|
18
|
-
...config
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
this.supportedActions = ['create', 'update', 'list', 'complete', 'cancel', 'clear', 'depend', 'relate', 'subtask', 'prioritize', 'template', 'progress', 'analytics', 'sync'];
|
|
22
|
-
this.taskStatuses = ['pending', 'in_progress', 'blocked', 'completed', 'cancelled'];
|
|
23
|
-
this.taskPriorities = ['urgent', 'high', 'medium', 'low'];
|
|
24
|
-
this.dependencyTypes = ['blocks', 'relates', 'subtask', 'parent'];
|
|
25
|
-
|
|
26
|
-
// Phase 3.4: Progress tracking stages
|
|
27
|
-
this.progressStages = ['not_started', 'planning', 'in_development', 'testing', 'review', 'completed'];
|
|
28
|
-
this.milestoneTypes = ['checkpoint', 'deliverable', 'review_point', 'dependency_gate'];
|
|
29
|
-
|
|
30
|
-
// Phase 3.2: Priority scoring weights
|
|
31
|
-
this.priorityWeights = {
|
|
32
|
-
blocking: 3.0, // Tasks that block others
|
|
33
|
-
age: 1.5, // Older tasks get higher priority
|
|
34
|
-
userPriority: 2.0, // User-defined priority
|
|
35
|
-
contextSwitching: 1.2, // Reduce context switching penalty
|
|
36
|
-
dependency: 1.8 // Tasks with many dependencies
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
// Phase 3.3: Built-in task templates
|
|
40
|
-
this.taskTemplates = {
|
|
41
|
-
'web-app-development': {
|
|
42
|
-
name: 'Web Application Development',
|
|
43
|
-
description: 'Complete workflow for building a web application',
|
|
44
|
-
category: 'development',
|
|
45
|
-
tasks: [
|
|
46
|
-
{
|
|
47
|
-
title: 'Project Setup & Planning',
|
|
48
|
-
description: 'Initialize project structure, configure tools, and plan architecture',
|
|
49
|
-
priority: 'high',
|
|
50
|
-
dependencies: []
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
title: 'Database Design & Setup',
|
|
54
|
-
description: 'Design database schema, create tables, and set up connections',
|
|
55
|
-
priority: 'high',
|
|
56
|
-
dependencies: ['Project Setup & Planning']
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
title: 'Backend API Development',
|
|
60
|
-
description: 'Implement REST API endpoints and business logic',
|
|
61
|
-
priority: 'high',
|
|
62
|
-
dependencies: ['Database Design & Setup']
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
title: 'Frontend Development',
|
|
66
|
-
description: 'Build user interface components and implement client-side logic',
|
|
67
|
-
priority: 'medium',
|
|
68
|
-
dependencies: ['Backend API Development']
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
title: 'Testing & Quality Assurance',
|
|
72
|
-
description: 'Write and run unit tests, integration tests, and perform QA',
|
|
73
|
-
priority: 'medium',
|
|
74
|
-
dependencies: ['Frontend Development']
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
title: 'Deployment & Launch',
|
|
78
|
-
description: 'Deploy to production environment and monitor launch',
|
|
79
|
-
priority: 'high',
|
|
80
|
-
dependencies: ['Testing & Quality Assurance']
|
|
81
|
-
}
|
|
82
|
-
]
|
|
83
|
-
},
|
|
84
|
-
'api-integration': {
|
|
85
|
-
name: 'API Integration',
|
|
86
|
-
description: 'Standard workflow for integrating with external APIs',
|
|
87
|
-
category: 'integration',
|
|
88
|
-
tasks: [
|
|
89
|
-
{
|
|
90
|
-
title: 'API Research & Documentation Review',
|
|
91
|
-
description: 'Study API documentation, authentication, and rate limits',
|
|
92
|
-
priority: 'high',
|
|
93
|
-
dependencies: []
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
title: 'Authentication Setup',
|
|
97
|
-
description: 'Implement API key management and authentication flow',
|
|
98
|
-
priority: 'high',
|
|
99
|
-
dependencies: ['API Research & Documentation Review']
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
title: 'Core Integration Implementation',
|
|
103
|
-
description: 'Build API client and implement main integration logic',
|
|
104
|
-
priority: 'high',
|
|
105
|
-
dependencies: ['Authentication Setup']
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
title: 'Error Handling & Retry Logic',
|
|
109
|
-
description: 'Implement robust error handling and retry mechanisms',
|
|
110
|
-
priority: 'medium',
|
|
111
|
-
dependencies: ['Core Integration Implementation']
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
title: 'Testing & Validation',
|
|
115
|
-
description: 'Test integration with various scenarios and edge cases',
|
|
116
|
-
priority: 'medium',
|
|
117
|
-
dependencies: ['Error Handling & Retry Logic']
|
|
118
|
-
}
|
|
119
|
-
]
|
|
120
|
-
},
|
|
121
|
-
'bug-fix': {
|
|
122
|
-
name: 'Bug Fix Workflow',
|
|
123
|
-
description: 'Systematic approach to identifying and fixing bugs',
|
|
124
|
-
category: 'maintenance',
|
|
125
|
-
tasks: [
|
|
126
|
-
{
|
|
127
|
-
title: 'Bug Reproduction & Analysis',
|
|
128
|
-
description: 'Reproduce the bug and analyze root cause',
|
|
129
|
-
priority: 'urgent',
|
|
130
|
-
dependencies: []
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
title: 'Fix Implementation',
|
|
134
|
-
description: 'Implement the bug fix with minimal side effects',
|
|
135
|
-
priority: 'urgent',
|
|
136
|
-
dependencies: ['Bug Reproduction & Analysis']
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
title: 'Testing & Verification',
|
|
140
|
-
description: 'Test fix and verify no regressions introduced',
|
|
141
|
-
priority: 'high',
|
|
142
|
-
dependencies: ['Fix Implementation']
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
title: 'Documentation Update',
|
|
146
|
-
description: 'Update documentation if behavior changed',
|
|
147
|
-
priority: 'low',
|
|
148
|
-
dependencies: ['Testing & Verification']
|
|
149
|
-
}
|
|
150
|
-
]
|
|
151
|
-
},
|
|
152
|
-
'feature-development': {
|
|
153
|
-
name: 'Feature Development',
|
|
154
|
-
description: 'End-to-end feature development workflow',
|
|
155
|
-
category: 'development',
|
|
156
|
-
tasks: [
|
|
157
|
-
{
|
|
158
|
-
title: 'Requirements Analysis',
|
|
159
|
-
description: 'Analyze requirements and create technical specification',
|
|
160
|
-
priority: 'high',
|
|
161
|
-
dependencies: []
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
title: 'Design & Architecture',
|
|
165
|
-
description: 'Design system architecture and user interface',
|
|
166
|
-
priority: 'high',
|
|
167
|
-
dependencies: ['Requirements Analysis']
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
title: 'Backend Implementation',
|
|
171
|
-
description: 'Implement backend logic and data models',
|
|
172
|
-
priority: 'high',
|
|
173
|
-
dependencies: ['Design & Architecture']
|
|
174
|
-
},
|
|
175
|
-
{
|
|
176
|
-
title: 'Frontend Implementation',
|
|
177
|
-
description: 'Build user interface and integrate with backend',
|
|
178
|
-
priority: 'medium',
|
|
179
|
-
dependencies: ['Backend Implementation']
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
title: 'Testing & Documentation',
|
|
183
|
-
description: 'Write tests and update documentation',
|
|
184
|
-
priority: 'medium',
|
|
185
|
-
dependencies: ['Frontend Implementation']
|
|
186
|
-
}
|
|
187
|
-
]
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Get basic tool description (required by BaseTool)
|
|
194
|
-
* @returns {string} Tool description
|
|
195
|
-
*/
|
|
196
|
-
getDescription() {
|
|
197
|
-
return `
|
|
198
|
-
Task Manager Tool: Organize and track work with TODO lists for agent-mode scheduling.
|
|
199
|
-
|
|
200
|
-
**CRITICAL FOR AGENT MODE**: You MUST maintain your task list to remain active in agent mode!
|
|
201
|
-
|
|
202
|
-
The TaskManager tool allows you to organize and track your work. Without tasks, you will not receive scheduling time.
|
|
203
|
-
|
|
204
|
-
### Actions:
|
|
205
|
-
- **sync**: 🌟 RECOMMENDED - Manage entire task list at once (Claude Code style)
|
|
206
|
-
- **create**: Create a new task with title and description
|
|
207
|
-
- **update**: Update task status or properties
|
|
208
|
-
- **list**: List all tasks with their current status
|
|
209
|
-
- **complete**: Mark a task as completed
|
|
210
|
-
- **cancel**: Cancel a task (mark as irrelevant)
|
|
211
|
-
- **clear**: Clear all completed/cancelled tasks
|
|
212
|
-
- **depend**: Create dependency between tasks (blocking relationships)
|
|
213
|
-
- **relate**: Link related tasks (non-blocking associations)
|
|
214
|
-
- **subtask**: Create subtask relationships (parent-child hierarchy)
|
|
215
|
-
- **prioritize**: Intelligent task prioritization with multiple modes
|
|
216
|
-
- **template**: Template management for common workflows
|
|
217
|
-
- **progress**: Track task progress with stages, milestones, and notes
|
|
218
|
-
|
|
219
|
-
### Usage Examples:
|
|
220
|
-
|
|
221
|
-
✨ Sync entire task list (RECOMMENDED - create comprehensive breakdown):
|
|
222
|
-
<taskmanager>
|
|
223
|
-
<action>sync</action>
|
|
224
|
-
<tasks>[
|
|
225
|
-
{
|
|
226
|
-
"title": "Analyze user requirements",
|
|
227
|
-
"description": "Understand what the user wants to achieve",
|
|
228
|
-
"status": "completed",
|
|
229
|
-
"priority": "high"
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
"title": "Design database schema",
|
|
233
|
-
"description": "Create tables and relationships",
|
|
234
|
-
"status": "in_progress",
|
|
235
|
-
"priority": "high"
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
"title": "Implement API endpoints",
|
|
239
|
-
"status": "pending",
|
|
240
|
-
"priority": "medium"
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
"title": "Write tests",
|
|
244
|
-
"status": "pending",
|
|
245
|
-
"priority": "medium"
|
|
246
|
-
}
|
|
247
|
-
]</tasks>
|
|
248
|
-
</taskmanager>
|
|
249
|
-
|
|
250
|
-
Create a task:
|
|
251
|
-
<taskmanager>
|
|
252
|
-
<action>create</action>
|
|
253
|
-
<title>Analyze user requirements</title>
|
|
254
|
-
<description>Break down the user's request into actionable steps</description>
|
|
255
|
-
<priority>high</priority>
|
|
256
|
-
</taskmanager>
|
|
257
|
-
|
|
258
|
-
List all tasks:
|
|
259
|
-
<taskmanager>
|
|
260
|
-
<action>list</action>
|
|
261
|
-
</taskmanager>
|
|
262
|
-
|
|
263
|
-
Create task dependency:
|
|
264
|
-
<taskmanager>
|
|
265
|
-
<action>depend</action>
|
|
266
|
-
<taskId>task-uuid-here</taskId>
|
|
267
|
-
<dependsOn>other-task-uuid</dependsOn>
|
|
268
|
-
<dependencyType>blocks</dependencyType>
|
|
269
|
-
</taskmanager>
|
|
270
|
-
|
|
271
|
-
Create subtask:
|
|
272
|
-
<taskmanager>
|
|
273
|
-
<action>subtask</action>
|
|
274
|
-
<parentTaskId>parent-task-uuid</parentTaskId>
|
|
275
|
-
<title>Implement user authentication</title>
|
|
276
|
-
<description>Create login and signup functionality</description>
|
|
277
|
-
<priority>high</priority>
|
|
278
|
-
</taskmanager>
|
|
279
|
-
|
|
280
|
-
Auto-prioritize all tasks:
|
|
281
|
-
<taskmanager>
|
|
282
|
-
<action>prioritize</action>
|
|
283
|
-
<mode>auto</mode>
|
|
284
|
-
</taskmanager>
|
|
285
|
-
|
|
286
|
-
Analyze specific task priority:
|
|
287
|
-
<taskmanager>
|
|
288
|
-
<action>prioritize</action>
|
|
289
|
-
<mode>analyze</mode>
|
|
290
|
-
<taskId>task-uuid-here</taskId>
|
|
291
|
-
</taskmanager>
|
|
292
|
-
|
|
293
|
-
Balance workload across agents:
|
|
294
|
-
<taskmanager>
|
|
295
|
-
<action>prioritize</action>
|
|
296
|
-
<mode>balance</mode>
|
|
297
|
-
</taskmanager>
|
|
298
|
-
|
|
299
|
-
List available templates:
|
|
300
|
-
<taskmanager>
|
|
301
|
-
<action>template</action>
|
|
302
|
-
<mode>list</mode>
|
|
303
|
-
</taskmanager>
|
|
304
|
-
|
|
305
|
-
Apply web app development template:
|
|
306
|
-
<taskmanager>
|
|
307
|
-
<action>template</action>
|
|
308
|
-
<mode>apply</mode>
|
|
309
|
-
<templateId>web-app-development</templateId>
|
|
310
|
-
<projectContext>{"projectName": "UserPortal", "urgency": "high"}</projectContext>
|
|
311
|
-
</taskmanager>
|
|
312
|
-
|
|
313
|
-
Suggest templates based on current tasks:
|
|
314
|
-
<taskmanager>
|
|
315
|
-
<action>template</action>
|
|
316
|
-
<mode>suggest</mode>
|
|
317
|
-
</taskmanager>
|
|
318
|
-
|
|
319
|
-
Update task progress:
|
|
320
|
-
<taskmanager>
|
|
321
|
-
<action>progress</action>
|
|
322
|
-
<mode>update</mode>
|
|
323
|
-
<taskId>task-uuid-here</taskId>
|
|
324
|
-
<stage>in_development</stage>
|
|
325
|
-
<percentage>45</percentage>
|
|
326
|
-
<note>Completed API integration, starting frontend work</note>
|
|
327
|
-
</taskmanager>
|
|
328
|
-
|
|
329
|
-
Get progress overview:
|
|
330
|
-
<taskmanager>
|
|
331
|
-
<action>progress</action>
|
|
332
|
-
<mode>overview</mode>
|
|
333
|
-
</taskmanager>
|
|
334
|
-
|
|
335
|
-
Calculate progress based on subtasks:
|
|
336
|
-
<taskmanager>
|
|
337
|
-
<action>progress</action>
|
|
338
|
-
<mode>calculate</mode>
|
|
339
|
-
<taskId>task-uuid-here</taskId>
|
|
340
|
-
</taskmanager>
|
|
341
|
-
|
|
342
|
-
### 🚨 MANDATORY WORKFLOW - ZERO EXCEPTIONS ALLOWED:
|
|
343
|
-
|
|
344
|
-
**EVERY RESPONSE MUST:**
|
|
345
|
-
1. **START WITH**: <taskmanager><action>list</action></taskmanager>
|
|
346
|
-
2. **WORK**: Complete the user's request
|
|
347
|
-
3. **END WITH**: <taskmanager><action>complete</action><taskId>ID</taskId></taskmanager>
|
|
348
|
-
|
|
349
|
-
**WARNING: Skipping this workflow = INFINITE LOOPS = SYSTEM FAILURE!**
|
|
350
|
-
**NO RESPONSE IS COMPLETE WITHOUT TASK COMPLETION!**
|
|
351
|
-
|
|
352
|
-
STEP 1 - Always start by listing tasks:
|
|
353
|
-
<taskmanager>
|
|
354
|
-
<action>list</action>
|
|
355
|
-
</taskmanager>
|
|
356
|
-
|
|
357
|
-
STEP 2 - After completing work, mark task complete:
|
|
358
|
-
<taskmanager>
|
|
359
|
-
<action>complete</action>
|
|
360
|
-
<taskId>task-1759257696373-wjsquroxz</taskId>
|
|
361
|
-
</taskmanager>
|
|
362
|
-
|
|
363
|
-
### MANDATORY: Complete tasks when done or you'll loop forever!
|
|
364
|
-
`;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Parse parameters from XML tag format
|
|
369
|
-
* Unwraps values from tag parser's {value, attributes} format
|
|
370
|
-
* @param {Object} content - Raw parameters from tag parser or string content
|
|
371
|
-
* @returns {Object} Parsed parameters with unwrapped values
|
|
372
|
-
*/
|
|
373
|
-
parseParameters(content) {
|
|
374
|
-
// If content is a string, return as-is for legacy support
|
|
375
|
-
if (typeof content === 'string') {
|
|
376
|
-
return { rawContent: content };
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// If content is already an object, unwrap tag parser format
|
|
380
|
-
if (typeof content === 'object' && content !== null) {
|
|
381
|
-
const unwrapped = {};
|
|
382
|
-
|
|
383
|
-
for (const [key, value] of Object.entries(content)) {
|
|
384
|
-
// Check if this is tag parser format: {value: "...", attributes: {}}
|
|
385
|
-
if (value && typeof value === 'object' && 'value' in value) {
|
|
386
|
-
unwrapped[key] = value.value;
|
|
387
|
-
} else {
|
|
388
|
-
// Keep as-is if not wrapped
|
|
389
|
-
unwrapped[key] = value;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
return unwrapped;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
return content;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
/**
|
|
400
|
-
* Execute task management action
|
|
401
|
-
* @param {Object} params - Tool arguments
|
|
402
|
-
* @param {Object} context - Execution context
|
|
403
|
-
* @returns {Promise<Object>} Execution result
|
|
404
|
-
*/
|
|
405
|
-
async execute(params, context) {
|
|
406
|
-
try {
|
|
407
|
-
// CRITICAL FIX: Unwrap tag parser format {value, attributes}
|
|
408
|
-
// The messageProcessor passes params with wrapped values from parseXMLParameters
|
|
409
|
-
// We need to unwrap them before processing
|
|
410
|
-
const unwrappedParams = {};
|
|
411
|
-
for (const [key, value] of Object.entries(params)) {
|
|
412
|
-
if (value && typeof value === 'object' && 'value' in value) {
|
|
413
|
-
// Tag parser wrapped format: {value: "...", attributes: {}}
|
|
414
|
-
unwrappedParams[key] = value.value;
|
|
415
|
-
} else {
|
|
416
|
-
// Already unwrapped or direct value
|
|
417
|
-
unwrappedParams[key] = value;
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
// Use unwrapped params for all subsequent processing
|
|
422
|
-
params = unwrappedParams;
|
|
423
|
-
|
|
424
|
-
const { agentId, agentName } = context;
|
|
425
|
-
|
|
426
|
-
if (!agentId) {
|
|
427
|
-
throw new Error('Agent ID is required for task management');
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
// Get agent from pool
|
|
431
|
-
const agent = await context.agentPool.getAgent(agentId);
|
|
432
|
-
if (!agent) {
|
|
433
|
-
throw new Error(`Agent not found: ${agentId}`);
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// Initialize taskList if it doesn't exist (for backwards compatibility)
|
|
437
|
-
if (!agent.taskList) {
|
|
438
|
-
agent.taskList = {
|
|
439
|
-
tasks: [],
|
|
440
|
-
lastUpdated: new Date().toISOString()
|
|
441
|
-
};
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
const action = params.action?.toLowerCase();
|
|
445
|
-
if (!this.supportedActions.includes(action)) {
|
|
446
|
-
throw new Error(`Unsupported action: ${action}. Supported: ${this.supportedActions.join(', ')}`);
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
let result;
|
|
450
|
-
switch (action) {
|
|
451
|
-
case 'create':
|
|
452
|
-
result = await this.createTask(agent, params);
|
|
453
|
-
break;
|
|
454
|
-
case 'update':
|
|
455
|
-
result = await this.updateTask(agent, params);
|
|
456
|
-
break;
|
|
457
|
-
case 'list':
|
|
458
|
-
result = await this.listTasks(agent, params);
|
|
459
|
-
break;
|
|
460
|
-
case 'complete':
|
|
461
|
-
result = await this.completeTask(agent, params);
|
|
462
|
-
break;
|
|
463
|
-
case 'cancel':
|
|
464
|
-
result = await this.cancelTask(agent, params);
|
|
465
|
-
break;
|
|
466
|
-
case 'clear':
|
|
467
|
-
result = await this.clearCompletedTasks(agent, params);
|
|
468
|
-
break;
|
|
469
|
-
case 'depend':
|
|
470
|
-
result = await this.createDependency(agent, params);
|
|
471
|
-
break;
|
|
472
|
-
case 'relate':
|
|
473
|
-
result = await this.relateTask(agent, params);
|
|
474
|
-
break;
|
|
475
|
-
case 'subtask':
|
|
476
|
-
result = await this.createSubtask(agent, params);
|
|
477
|
-
break;
|
|
478
|
-
case 'prioritize':
|
|
479
|
-
result = await this.intelligentPrioritization(agent, params);
|
|
480
|
-
break;
|
|
481
|
-
case 'template':
|
|
482
|
-
result = await this.manageTemplates(agent, params);
|
|
483
|
-
break;
|
|
484
|
-
case 'progress':
|
|
485
|
-
result = await this.trackProgress(agent, params);
|
|
486
|
-
break;
|
|
487
|
-
case 'analytics':
|
|
488
|
-
result = await this.generateAnalytics(agent, params);
|
|
489
|
-
break;
|
|
490
|
-
case 'sync':
|
|
491
|
-
result = await this.syncTasks(agent, params);
|
|
492
|
-
break;
|
|
493
|
-
default:
|
|
494
|
-
throw new Error(`Unknown action: ${action}`);
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
// Update the agent's lastActivity
|
|
498
|
-
agent.lastActivity = new Date().toISOString();
|
|
499
|
-
agent.taskList.lastUpdated = new Date().toISOString();
|
|
500
|
-
|
|
501
|
-
// Persist the agent state
|
|
502
|
-
await context.agentPool.persistAgentState(agentId);
|
|
503
|
-
|
|
504
|
-
this.logger?.info(`TaskManager action executed: ${action}`, {
|
|
505
|
-
agentId,
|
|
506
|
-
agentName,
|
|
507
|
-
action,
|
|
508
|
-
taskCount: agent.taskList.tasks.length,
|
|
509
|
-
pendingTasks: agent.taskList.tasks.filter(t => t.status === 'pending').length,
|
|
510
|
-
inProgressTasks: agent.taskList.tasks.filter(t => t.status === 'in_progress').length
|
|
511
|
-
});
|
|
512
|
-
|
|
513
|
-
return {
|
|
514
|
-
success: true,
|
|
515
|
-
action,
|
|
516
|
-
result,
|
|
517
|
-
summary: this.generateTaskSummary(agent.taskList)
|
|
518
|
-
};
|
|
519
|
-
|
|
520
|
-
} catch (error) {
|
|
521
|
-
this.logger?.error('TaskManager execution failed', {
|
|
522
|
-
error: error.message,
|
|
523
|
-
context,
|
|
524
|
-
params
|
|
525
|
-
});
|
|
526
|
-
|
|
527
|
-
return {
|
|
528
|
-
success: false,
|
|
529
|
-
error: error.message
|
|
530
|
-
};
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
/**
|
|
535
|
-
* Create a new task
|
|
536
|
-
* @private
|
|
537
|
-
*/
|
|
538
|
-
async createTask(agent, params) {
|
|
539
|
-
const { title, description = '', priority = 'medium' } = params;
|
|
540
|
-
|
|
541
|
-
if (!title) {
|
|
542
|
-
throw new Error('Task title is required');
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
if (priority && !this.taskPriorities.includes(priority.toLowerCase())) {
|
|
546
|
-
throw new Error(`Invalid priority: ${priority}. Must be: ${this.taskPriorities.join(', ')}`);
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
const task = {
|
|
550
|
-
id: `task-${uuidv4()}`,
|
|
551
|
-
title,
|
|
552
|
-
description,
|
|
553
|
-
status: 'pending',
|
|
554
|
-
priority: priority.toLowerCase(),
|
|
555
|
-
createdAt: new Date().toISOString(),
|
|
556
|
-
updatedAt: new Date().toISOString()
|
|
557
|
-
};
|
|
558
|
-
|
|
559
|
-
agent.taskList.tasks.push(task);
|
|
560
|
-
|
|
561
|
-
return {
|
|
562
|
-
message: 'Task created successfully',
|
|
563
|
-
task
|
|
564
|
-
};
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
/**
|
|
568
|
-
* Sync entire task list (Claude Code style batch management)
|
|
569
|
-
* @private
|
|
570
|
-
*/
|
|
571
|
-
async syncTasks(agent, params) {
|
|
572
|
-
let { tasks } = params;
|
|
573
|
-
|
|
574
|
-
// Parse tasks if provided as JSON string
|
|
575
|
-
if (typeof tasks === 'string') {
|
|
576
|
-
try {
|
|
577
|
-
tasks = JSON.parse(tasks);
|
|
578
|
-
} catch (error) {
|
|
579
|
-
throw new Error(`Invalid tasks JSON: ${error.message}`);
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
if (!Array.isArray(tasks)) {
|
|
584
|
-
throw new Error('Tasks must be an array');
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
if (tasks.length === 0) {
|
|
588
|
-
throw new Error('Tasks array cannot be empty');
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
const timestamp = new Date().toISOString();
|
|
592
|
-
const existingTasks = agent.taskList.tasks || [];
|
|
593
|
-
const updatedTasks = [];
|
|
594
|
-
const createdTasks = [];
|
|
595
|
-
const matchedIds = new Set();
|
|
596
|
-
|
|
597
|
-
// Helper: fuzzy match task by title
|
|
598
|
-
const findExistingTask = (title) => {
|
|
599
|
-
const normalizedTitle = title.toLowerCase().trim();
|
|
600
|
-
return existingTasks.find(t =>
|
|
601
|
-
t.title.toLowerCase().trim() === normalizedTitle &&
|
|
602
|
-
!matchedIds.has(t.id)
|
|
603
|
-
);
|
|
604
|
-
};
|
|
605
|
-
|
|
606
|
-
// Validate and process each task
|
|
607
|
-
for (const taskData of tasks) {
|
|
608
|
-
if (!taskData.title) {
|
|
609
|
-
throw new Error('Each task must have a title');
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
const status = (taskData.status || 'pending').toLowerCase();
|
|
613
|
-
const priority = (taskData.priority || 'medium').toLowerCase();
|
|
614
|
-
|
|
615
|
-
// Validate status
|
|
616
|
-
if (!this.taskStatuses.includes(status)) {
|
|
617
|
-
throw new Error(`Invalid status "${status}" for task "${taskData.title}". Must be: ${this.taskStatuses.join(', ')}`);
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
// Validate priority
|
|
621
|
-
if (!this.taskPriorities.includes(priority)) {
|
|
622
|
-
throw new Error(`Invalid priority "${priority}" for task "${taskData.title}". Must be: ${this.taskPriorities.join(', ')}`);
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
// Try to match with existing task
|
|
626
|
-
const existingTask = findExistingTask(taskData.title);
|
|
627
|
-
|
|
628
|
-
if (existingTask) {
|
|
629
|
-
// Update existing task
|
|
630
|
-
existingTask.status = status;
|
|
631
|
-
existingTask.priority = priority;
|
|
632
|
-
if (taskData.description !== undefined) {
|
|
633
|
-
existingTask.description = taskData.description;
|
|
634
|
-
}
|
|
635
|
-
existingTask.updatedAt = timestamp;
|
|
636
|
-
|
|
637
|
-
updatedTasks.push(existingTask);
|
|
638
|
-
matchedIds.add(existingTask.id);
|
|
639
|
-
} else {
|
|
640
|
-
// Create new task
|
|
641
|
-
const newTask = {
|
|
642
|
-
id: `task-${uuidv4()}`,
|
|
643
|
-
title: taskData.title,
|
|
644
|
-
description: taskData.description || '',
|
|
645
|
-
status: status,
|
|
646
|
-
priority: priority,
|
|
647
|
-
createdAt: timestamp,
|
|
648
|
-
updatedAt: timestamp,
|
|
649
|
-
source: 'sync'
|
|
650
|
-
};
|
|
651
|
-
|
|
652
|
-
createdTasks.push(newTask);
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
// Replace task list with synced tasks
|
|
657
|
-
agent.taskList.tasks = [...updatedTasks, ...createdTasks];
|
|
658
|
-
|
|
659
|
-
// Ensure only one task is in_progress
|
|
660
|
-
const inProgressTasks = agent.taskList.tasks.filter(t => t.status === 'in_progress');
|
|
661
|
-
if (inProgressTasks.length > 1) {
|
|
662
|
-
// Keep only the first in_progress task, set others to pending
|
|
663
|
-
for (let i = 1; i < inProgressTasks.length; i++) {
|
|
664
|
-
inProgressTasks[i].status = 'pending';
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
// Auto-set first pending task to in_progress if no task is in_progress
|
|
669
|
-
if (inProgressTasks.length === 0) {
|
|
670
|
-
const firstPending = agent.taskList.tasks.find(t => t.status === 'pending');
|
|
671
|
-
if (firstPending) {
|
|
672
|
-
firstPending.status = 'in_progress';
|
|
673
|
-
firstPending.updatedAt = timestamp;
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
agent.taskList.lastUpdated = timestamp;
|
|
678
|
-
|
|
679
|
-
return {
|
|
680
|
-
message: 'Task list synchronized successfully',
|
|
681
|
-
summary: {
|
|
682
|
-
total: agent.taskList.tasks.length,
|
|
683
|
-
created: createdTasks.length,
|
|
684
|
-
updated: updatedTasks.length,
|
|
685
|
-
removed: existingTasks.length - matchedIds.size,
|
|
686
|
-
pending: agent.taskList.tasks.filter(t => t.status === 'pending').length,
|
|
687
|
-
inProgress: agent.taskList.tasks.filter(t => t.status === 'in_progress').length,
|
|
688
|
-
completed: agent.taskList.tasks.filter(t => t.status === 'completed').length,
|
|
689
|
-
cancelled: agent.taskList.tasks.filter(t => t.status === 'cancelled').length
|
|
690
|
-
},
|
|
691
|
-
tasks: agent.taskList.tasks.map(t => ({
|
|
692
|
-
id: t.id,
|
|
693
|
-
title: t.title,
|
|
694
|
-
status: t.status,
|
|
695
|
-
priority: t.priority
|
|
696
|
-
}))
|
|
697
|
-
};
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
/**
|
|
701
|
-
* Update an existing task
|
|
702
|
-
* @private
|
|
703
|
-
*/
|
|
704
|
-
async updateTask(agent, params) {
|
|
705
|
-
const { taskId, status, priority, title, description } = params;
|
|
706
|
-
|
|
707
|
-
if (!taskId) {
|
|
708
|
-
throw new Error('Task ID is required for update');
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
const task = agent.taskList.tasks.find(t => t.id === taskId);
|
|
712
|
-
if (!task) {
|
|
713
|
-
throw new Error(`Task not found: ${taskId}`);
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
if (status) {
|
|
717
|
-
if (!this.taskStatuses.includes(status.toLowerCase())) {
|
|
718
|
-
throw new Error(`Invalid status: ${status}. Must be: ${this.taskStatuses.join(', ')}`);
|
|
719
|
-
}
|
|
720
|
-
task.status = status.toLowerCase();
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
if (priority) {
|
|
724
|
-
if (!this.taskPriorities.includes(priority.toLowerCase())) {
|
|
725
|
-
throw new Error(`Invalid priority: ${priority}. Must be: ${this.taskPriorities.join(', ')}`);
|
|
726
|
-
}
|
|
727
|
-
task.priority = priority.toLowerCase();
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
if (title !== undefined) task.title = title;
|
|
731
|
-
if (description !== undefined) task.description = description;
|
|
732
|
-
|
|
733
|
-
task.updatedAt = new Date().toISOString();
|
|
734
|
-
|
|
735
|
-
return {
|
|
736
|
-
message: 'Task updated successfully',
|
|
737
|
-
task
|
|
738
|
-
};
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
/**
|
|
742
|
-
* List all tasks
|
|
743
|
-
* @private
|
|
744
|
-
*/
|
|
745
|
-
async listTasks(agent, params) {
|
|
746
|
-
const { status, priority } = params;
|
|
747
|
-
let tasks = [...agent.taskList.tasks];
|
|
748
|
-
|
|
749
|
-
// Filter by status if specified
|
|
750
|
-
if (status) {
|
|
751
|
-
if (!this.taskStatuses.includes(status.toLowerCase())) {
|
|
752
|
-
throw new Error(`Invalid status filter: ${status}`);
|
|
753
|
-
}
|
|
754
|
-
tasks = tasks.filter(t => t.status === status.toLowerCase());
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
// Filter by priority if specified
|
|
758
|
-
if (priority) {
|
|
759
|
-
if (!this.taskPriorities.includes(priority.toLowerCase())) {
|
|
760
|
-
throw new Error(`Invalid priority filter: ${priority}`);
|
|
761
|
-
}
|
|
762
|
-
tasks = tasks.filter(t => t.priority === priority.toLowerCase());
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
// Sort by priority (high first) then by creation date
|
|
766
|
-
const priorityOrder = { high: 0, medium: 1, low: 2 };
|
|
767
|
-
tasks.sort((a, b) => {
|
|
768
|
-
const priorityDiff = priorityOrder[a.priority] - priorityOrder[b.priority];
|
|
769
|
-
if (priorityDiff !== 0) return priorityDiff;
|
|
770
|
-
return new Date(a.createdAt) - new Date(b.createdAt);
|
|
771
|
-
});
|
|
772
|
-
|
|
773
|
-
return {
|
|
774
|
-
totalTasks: tasks.length,
|
|
775
|
-
tasks,
|
|
776
|
-
summary: {
|
|
777
|
-
pending: tasks.filter(t => t.status === 'pending').length,
|
|
778
|
-
in_progress: tasks.filter(t => t.status === 'in_progress').length,
|
|
779
|
-
completed: tasks.filter(t => t.status === 'completed').length,
|
|
780
|
-
cancelled: tasks.filter(t => t.status === 'cancelled').length
|
|
781
|
-
}
|
|
782
|
-
};
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
/**
|
|
786
|
-
* Complete a task
|
|
787
|
-
* @private
|
|
788
|
-
*/
|
|
789
|
-
async completeTask(agent, params) {
|
|
790
|
-
let { taskId } = params;
|
|
791
|
-
|
|
792
|
-
// If no taskId provided, auto-complete the first in-progress task
|
|
793
|
-
if (!taskId) {
|
|
794
|
-
const inProgressTask = agent.taskList.tasks.find(t => t.status === 'in_progress' || t.status === 'pending');
|
|
795
|
-
if (inProgressTask) {
|
|
796
|
-
taskId = inProgressTask.id;
|
|
797
|
-
this.logger?.info(`Auto-completing current task: ${taskId}`, {
|
|
798
|
-
agentId: agent.id,
|
|
799
|
-
taskTitle: inProgressTask.title
|
|
800
|
-
});
|
|
801
|
-
} else {
|
|
802
|
-
throw new Error('No task ID provided and no in-progress tasks found to complete');
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
const task = agent.taskList.tasks.find(t => t.id === taskId);
|
|
807
|
-
if (!task) {
|
|
808
|
-
throw new Error(`Task not found: ${taskId}`);
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
if (task.status === 'completed') {
|
|
812
|
-
return {
|
|
813
|
-
message: 'Task already completed',
|
|
814
|
-
task
|
|
815
|
-
};
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
task.status = 'completed';
|
|
819
|
-
task.completedAt = new Date().toISOString();
|
|
820
|
-
task.updatedAt = new Date().toISOString();
|
|
821
|
-
|
|
822
|
-
// Phase 3: Trigger dependency updates when task is completed
|
|
823
|
-
if (this.scheduler && typeof this.scheduler.updateDependentTasks === 'function') {
|
|
824
|
-
try {
|
|
825
|
-
await this.scheduler.updateDependentTasks(agent, taskId);
|
|
826
|
-
this.logger?.info(`Triggered dependency update for completed task`, {
|
|
827
|
-
taskId,
|
|
828
|
-
title: task.title
|
|
829
|
-
});
|
|
830
|
-
} catch (error) {
|
|
831
|
-
this.logger?.warn(`Failed to update dependent tasks`, {
|
|
832
|
-
taskId,
|
|
833
|
-
error: error.message
|
|
834
|
-
});
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
return {
|
|
839
|
-
message: 'Task completed successfully',
|
|
840
|
-
task,
|
|
841
|
-
dependenciesUpdated: !!this.scheduler
|
|
842
|
-
};
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
/**
|
|
846
|
-
* Cancel a task
|
|
847
|
-
* @private
|
|
848
|
-
*/
|
|
849
|
-
async cancelTask(agent, params) {
|
|
850
|
-
const { taskId, reason = '' } = params;
|
|
851
|
-
|
|
852
|
-
if (!taskId) {
|
|
853
|
-
throw new Error('Task ID is required');
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
const task = agent.taskList.tasks.find(t => t.id === taskId);
|
|
857
|
-
if (!task) {
|
|
858
|
-
throw new Error(`Task not found: ${taskId}`);
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
task.status = 'cancelled';
|
|
862
|
-
task.cancelledAt = new Date().toISOString();
|
|
863
|
-
task.cancellationReason = reason;
|
|
864
|
-
task.updatedAt = new Date().toISOString();
|
|
865
|
-
|
|
866
|
-
return {
|
|
867
|
-
message: 'Task cancelled successfully',
|
|
868
|
-
task
|
|
869
|
-
};
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
/**
|
|
873
|
-
* Clear completed and cancelled tasks
|
|
874
|
-
* @private
|
|
875
|
-
*/
|
|
876
|
-
async clearCompletedTasks(agent, params) {
|
|
877
|
-
const originalCount = agent.taskList.tasks.length;
|
|
878
|
-
|
|
879
|
-
// Keep only pending and in_progress tasks
|
|
880
|
-
agent.taskList.tasks = agent.taskList.tasks.filter(
|
|
881
|
-
t => t.status === 'pending' || t.status === 'in_progress'
|
|
882
|
-
);
|
|
883
|
-
|
|
884
|
-
const removedCount = originalCount - agent.taskList.tasks.length;
|
|
885
|
-
|
|
886
|
-
return {
|
|
887
|
-
message: `Cleared ${removedCount} completed/cancelled tasks`,
|
|
888
|
-
remainingTasks: agent.taskList.tasks.length,
|
|
889
|
-
removed: removedCount
|
|
890
|
-
};
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
/**
|
|
894
|
-
* Create dependency between tasks (Phase 3)
|
|
895
|
-
* @private
|
|
896
|
-
*/
|
|
897
|
-
async createDependency(agent, params) {
|
|
898
|
-
const { taskId, dependsOn, dependencyType = 'blocks' } = params;
|
|
899
|
-
|
|
900
|
-
if (!taskId || !dependsOn) {
|
|
901
|
-
throw new Error('Both taskId and dependsOn are required for creating dependencies');
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
if (!this.dependencyTypes.includes(dependencyType)) {
|
|
905
|
-
throw new Error(`Invalid dependency type: ${dependencyType}. Must be: ${this.dependencyTypes.join(', ')}`);
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
const task = agent.taskList.tasks.find(t => t.id === taskId);
|
|
909
|
-
const dependencyTask = agent.taskList.tasks.find(t => t.id === dependsOn);
|
|
910
|
-
|
|
911
|
-
if (!task) {
|
|
912
|
-
throw new Error(`Task not found: ${taskId}`);
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
if (!dependencyTask) {
|
|
916
|
-
throw new Error(`Dependency task not found: ${dependsOn}`);
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
// Initialize dependencies array if not exists
|
|
920
|
-
if (!task.dependencies) {
|
|
921
|
-
task.dependencies = [];
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
// Check if dependency already exists
|
|
925
|
-
const existingDep = task.dependencies.find(d => d.taskId === dependsOn);
|
|
926
|
-
if (existingDep) {
|
|
927
|
-
return {
|
|
928
|
-
message: 'Dependency already exists',
|
|
929
|
-
dependency: existingDep
|
|
930
|
-
};
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
// Create dependency
|
|
934
|
-
const dependency = {
|
|
935
|
-
taskId: dependsOn,
|
|
936
|
-
type: dependencyType,
|
|
937
|
-
createdAt: new Date().toISOString()
|
|
938
|
-
};
|
|
939
|
-
|
|
940
|
-
task.dependencies.push(dependency);
|
|
941
|
-
task.updatedAt = new Date().toISOString();
|
|
942
|
-
|
|
943
|
-
// If this is a blocking dependency, check if task should be blocked
|
|
944
|
-
if (dependencyType === 'blocks' && dependencyTask.status !== 'completed') {
|
|
945
|
-
task.status = 'blocked';
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
return {
|
|
949
|
-
message: 'Dependency created successfully',
|
|
950
|
-
dependency,
|
|
951
|
-
task
|
|
952
|
-
};
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
/**
|
|
956
|
-
* Create relationship between tasks (non-blocking)
|
|
957
|
-
* @private
|
|
958
|
-
*/
|
|
959
|
-
async relateTask(agent, params) {
|
|
960
|
-
return await this.createDependency(agent, { ...params, dependencyType: 'relates' });
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
/**
|
|
964
|
-
* Create subtask relationship
|
|
965
|
-
* @private
|
|
966
|
-
*/
|
|
967
|
-
async createSubtask(agent, params) {
|
|
968
|
-
const { parentTaskId, title, description = '', priority = 'medium' } = params;
|
|
969
|
-
|
|
970
|
-
if (!parentTaskId || !title) {
|
|
971
|
-
throw new Error('Parent task ID and title are required for creating subtasks');
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
const parentTask = agent.taskList.tasks.find(t => t.id === parentTaskId);
|
|
975
|
-
if (!parentTask) {
|
|
976
|
-
throw new Error(`Parent task not found: ${parentTaskId}`);
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
// Create the subtask
|
|
980
|
-
const subtask = {
|
|
981
|
-
id: `task-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
982
|
-
title,
|
|
983
|
-
description,
|
|
984
|
-
status: 'pending',
|
|
985
|
-
priority: priority.toLowerCase(),
|
|
986
|
-
createdAt: new Date().toISOString(),
|
|
987
|
-
updatedAt: new Date().toISOString(),
|
|
988
|
-
parentTaskId: parentTaskId,
|
|
989
|
-
isSubtask: true,
|
|
990
|
-
source: 'user-created'
|
|
991
|
-
};
|
|
992
|
-
|
|
993
|
-
agent.taskList.tasks.push(subtask);
|
|
994
|
-
|
|
995
|
-
// Initialize subtasks array on parent if not exists
|
|
996
|
-
if (!parentTask.subtasks) {
|
|
997
|
-
parentTask.subtasks = [];
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
parentTask.subtasks.push(subtask.id);
|
|
1001
|
-
parentTask.updatedAt = new Date().toISOString();
|
|
1002
|
-
|
|
1003
|
-
return {
|
|
1004
|
-
message: 'Subtask created successfully',
|
|
1005
|
-
subtask,
|
|
1006
|
-
parentTask
|
|
1007
|
-
};
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
/**
|
|
1011
|
-
* Template management (Phase 3.3)
|
|
1012
|
-
* @private
|
|
1013
|
-
*/
|
|
1014
|
-
async manageTemplates(agent, params) {
|
|
1015
|
-
const { mode = 'list', templateId, customTemplate, projectContext } = params;
|
|
1016
|
-
|
|
1017
|
-
let results = {};
|
|
1018
|
-
|
|
1019
|
-
if (mode === 'list') {
|
|
1020
|
-
// List available templates
|
|
1021
|
-
results = await this.listAvailableTemplates(agent);
|
|
1022
|
-
} else if (mode === 'apply' && templateId) {
|
|
1023
|
-
// Apply a template to create tasks
|
|
1024
|
-
results = await this.applyTemplate(agent, templateId, projectContext);
|
|
1025
|
-
} else if (mode === 'create' && customTemplate) {
|
|
1026
|
-
// Create custom template
|
|
1027
|
-
results = await this.createCustomTemplate(agent, customTemplate);
|
|
1028
|
-
} else if (mode === 'suggest') {
|
|
1029
|
-
// Suggest templates based on existing tasks
|
|
1030
|
-
results = await this.suggestTemplates(agent);
|
|
1031
|
-
} else {
|
|
1032
|
-
throw new Error('Invalid template mode. Use: list, apply, create, or suggest');
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
return {
|
|
1036
|
-
message: `Template management completed (${mode})`,
|
|
1037
|
-
mode,
|
|
1038
|
-
...results
|
|
1039
|
-
};
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
/**
|
|
1043
|
-
* List available task templates
|
|
1044
|
-
* @private
|
|
1045
|
-
*/
|
|
1046
|
-
async listAvailableTemplates(agent) {
|
|
1047
|
-
const builtInTemplates = Object.entries(this.taskTemplates).map(([id, template]) => ({
|
|
1048
|
-
id,
|
|
1049
|
-
name: template.name,
|
|
1050
|
-
description: template.description,
|
|
1051
|
-
category: template.category,
|
|
1052
|
-
taskCount: template.tasks.length,
|
|
1053
|
-
type: 'built-in'
|
|
1054
|
-
}));
|
|
1055
|
-
|
|
1056
|
-
// Get custom templates from agent's storage
|
|
1057
|
-
const customTemplates = agent.customTemplates || [];
|
|
1058
|
-
const formattedCustom = customTemplates.map(template => ({
|
|
1059
|
-
...template,
|
|
1060
|
-
type: 'custom'
|
|
1061
|
-
}));
|
|
1062
|
-
|
|
1063
|
-
return {
|
|
1064
|
-
builtInTemplates,
|
|
1065
|
-
customTemplates: formattedCustom,
|
|
1066
|
-
totalTemplates: builtInTemplates.length + formattedCustom.length,
|
|
1067
|
-
categories: [...new Set(builtInTemplates.map(t => t.category))]
|
|
1068
|
-
};
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
/**
|
|
1072
|
-
* Apply a template to create structured tasks
|
|
1073
|
-
* @private
|
|
1074
|
-
*/
|
|
1075
|
-
async applyTemplate(agent, templateId, projectContext = {}) {
|
|
1076
|
-
const template = this.taskTemplates[templateId] ||
|
|
1077
|
-
(agent.customTemplates || []).find(t => t.id === templateId);
|
|
1078
|
-
|
|
1079
|
-
if (!template) {
|
|
1080
|
-
throw new Error(`Template not found: ${templateId}`);
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
const createdTasks = [];
|
|
1084
|
-
const taskMapping = new Map(); // Map template task titles to actual task IDs
|
|
1085
|
-
|
|
1086
|
-
// Apply project context to customize template
|
|
1087
|
-
const contextualizedTasks = this.applyProjectContext(template.tasks, projectContext);
|
|
1088
|
-
|
|
1089
|
-
// Create all tasks first
|
|
1090
|
-
for (const templateTask of contextualizedTasks) {
|
|
1091
|
-
const task = {
|
|
1092
|
-
id: `task-${uuidv4()}`,
|
|
1093
|
-
title: templateTask.title,
|
|
1094
|
-
description: templateTask.description,
|
|
1095
|
-
status: 'pending',
|
|
1096
|
-
priority: templateTask.priority,
|
|
1097
|
-
createdAt: new Date().toISOString(),
|
|
1098
|
-
updatedAt: new Date().toISOString(),
|
|
1099
|
-
templateId: templateId,
|
|
1100
|
-
templateOrigin: template.type || 'built-in',
|
|
1101
|
-
source: 'template-generated'
|
|
1102
|
-
};
|
|
1103
|
-
|
|
1104
|
-
agent.taskList.tasks.push(task);
|
|
1105
|
-
createdTasks.push(task);
|
|
1106
|
-
taskMapping.set(templateTask.title, task.id);
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
// Create dependencies after all tasks exist
|
|
1110
|
-
for (let i = 0; i < contextualizedTasks.length; i++) {
|
|
1111
|
-
const templateTask = contextualizedTasks[i];
|
|
1112
|
-
const actualTask = createdTasks[i];
|
|
1113
|
-
|
|
1114
|
-
if (templateTask.dependencies && templateTask.dependencies.length > 0) {
|
|
1115
|
-
actualTask.dependencies = [];
|
|
1116
|
-
|
|
1117
|
-
for (const depTitle of templateTask.dependencies) {
|
|
1118
|
-
const depTaskId = taskMapping.get(depTitle);
|
|
1119
|
-
if (depTaskId) {
|
|
1120
|
-
actualTask.dependencies.push({
|
|
1121
|
-
taskId: depTaskId,
|
|
1122
|
-
type: 'blocks',
|
|
1123
|
-
createdAt: new Date().toISOString()
|
|
1124
|
-
});
|
|
1125
|
-
|
|
1126
|
-
// Set task as blocked if dependency isn't completed
|
|
1127
|
-
actualTask.status = 'blocked';
|
|
1128
|
-
}
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
|
-
// Auto-prioritize the newly created tasks
|
|
1134
|
-
await this.autoPrioritizeAllTasks(agent);
|
|
1135
|
-
|
|
1136
|
-
return {
|
|
1137
|
-
template: {
|
|
1138
|
-
id: templateId,
|
|
1139
|
-
name: template.name,
|
|
1140
|
-
description: template.description
|
|
1141
|
-
},
|
|
1142
|
-
tasksCreated: createdTasks.length,
|
|
1143
|
-
tasks: createdTasks.map(task => ({
|
|
1144
|
-
id: task.id,
|
|
1145
|
-
title: task.title,
|
|
1146
|
-
priority: task.priority,
|
|
1147
|
-
status: task.status,
|
|
1148
|
-
dependencies: task.dependencies ? task.dependencies.length : 0
|
|
1149
|
-
})),
|
|
1150
|
-
workflowStructure: this.generateWorkflowVisualization(createdTasks)
|
|
1151
|
-
};
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
/**
|
|
1155
|
-
* Apply project context to customize template tasks
|
|
1156
|
-
* @private
|
|
1157
|
-
*/
|
|
1158
|
-
applyProjectContext(templateTasks, context) {
|
|
1159
|
-
return templateTasks.map(task => {
|
|
1160
|
-
let customizedTask = { ...task };
|
|
1161
|
-
|
|
1162
|
-
// Apply context-specific customizations
|
|
1163
|
-
if (context.projectName) {
|
|
1164
|
-
customizedTask.title = customizedTask.title.replace(/\[PROJECT\]/g, context.projectName);
|
|
1165
|
-
customizedTask.description = customizedTask.description.replace(/\[PROJECT\]/g, context.projectName);
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
|
-
if (context.technology) {
|
|
1169
|
-
customizedTask.title = customizedTask.title.replace(/\[TECH\]/g, context.technology);
|
|
1170
|
-
customizedTask.description = customizedTask.description.replace(/\[TECH\]/g, context.technology);
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
if (context.urgency === 'high') {
|
|
1174
|
-
customizedTask.priority = customizedTask.priority === 'low' ? 'medium' :
|
|
1175
|
-
customizedTask.priority === 'medium' ? 'high' : 'urgent';
|
|
1176
|
-
}
|
|
1177
|
-
|
|
1178
|
-
// Team size can affect priority rather than time estimates
|
|
1179
|
-
if (context.team === 'small' && customizedTask.priority === 'medium') {
|
|
1180
|
-
customizedTask.priority = 'high'; // Small teams need focused priorities
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
return customizedTask;
|
|
1184
|
-
});
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
/**
|
|
1188
|
-
* Create custom template from existing tasks or specification
|
|
1189
|
-
* @private
|
|
1190
|
-
*/
|
|
1191
|
-
async createCustomTemplate(agent, customTemplate) {
|
|
1192
|
-
const { name, description, category, tasks } = customTemplate;
|
|
1193
|
-
|
|
1194
|
-
if (!name || !tasks || tasks.length === 0) {
|
|
1195
|
-
throw new Error('Custom template requires name and at least one task');
|
|
1196
|
-
}
|
|
1197
|
-
|
|
1198
|
-
const template = {
|
|
1199
|
-
id: `custom-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
1200
|
-
name,
|
|
1201
|
-
description: description || `Custom template: ${name}`,
|
|
1202
|
-
category: category || 'custom',
|
|
1203
|
-
tasks: tasks.map(task => ({
|
|
1204
|
-
title: task.title,
|
|
1205
|
-
description: task.description || '',
|
|
1206
|
-
priority: task.priority || 'medium',
|
|
1207
|
-
dependencies: task.dependencies || []
|
|
1208
|
-
})),
|
|
1209
|
-
createdAt: new Date().toISOString(),
|
|
1210
|
-
type: 'custom'
|
|
1211
|
-
};
|
|
1212
|
-
|
|
1213
|
-
// Initialize custom templates array if not exists
|
|
1214
|
-
if (!agent.customTemplates) {
|
|
1215
|
-
agent.customTemplates = [];
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
agent.customTemplates.push(template);
|
|
1219
|
-
|
|
1220
|
-
return {
|
|
1221
|
-
template: {
|
|
1222
|
-
id: template.id,
|
|
1223
|
-
name: template.name,
|
|
1224
|
-
description: template.description,
|
|
1225
|
-
category: template.category,
|
|
1226
|
-
taskCount: template.tasks.length
|
|
1227
|
-
},
|
|
1228
|
-
message: 'Custom template created successfully'
|
|
1229
|
-
};
|
|
1230
|
-
}
|
|
1231
|
-
|
|
1232
|
-
/**
|
|
1233
|
-
* Suggest templates based on existing tasks and patterns
|
|
1234
|
-
* @private
|
|
1235
|
-
*/
|
|
1236
|
-
async suggestTemplates(agent) {
|
|
1237
|
-
const existingTasks = agent.taskList.tasks;
|
|
1238
|
-
const suggestions = [];
|
|
1239
|
-
|
|
1240
|
-
// Analyze existing task patterns
|
|
1241
|
-
const taskTitles = existingTasks.map(t => t.title.toLowerCase());
|
|
1242
|
-
const priorities = existingTasks.map(t => t.priority);
|
|
1243
|
-
|
|
1244
|
-
// Pattern-based suggestions
|
|
1245
|
-
if (taskTitles.some(title => title.includes('api') || title.includes('endpoint'))) {
|
|
1246
|
-
suggestions.push({
|
|
1247
|
-
templateId: 'api-integration',
|
|
1248
|
-
reason: 'Detected API-related tasks',
|
|
1249
|
-
confidence: 0.8
|
|
1250
|
-
});
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
if (taskTitles.some(title => title.includes('bug') || title.includes('fix') || title.includes('error'))) {
|
|
1254
|
-
suggestions.push({
|
|
1255
|
-
templateId: 'bug-fix',
|
|
1256
|
-
reason: 'Detected bug fix tasks',
|
|
1257
|
-
confidence: 0.9
|
|
1258
|
-
});
|
|
1259
|
-
}
|
|
1260
|
-
|
|
1261
|
-
if (taskTitles.some(title => title.includes('feature') || title.includes('implement'))) {
|
|
1262
|
-
suggestions.push({
|
|
1263
|
-
templateId: 'feature-development',
|
|
1264
|
-
reason: 'Detected feature development tasks',
|
|
1265
|
-
confidence: 0.7
|
|
1266
|
-
});
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
if (existingTasks.length >= 5 && priorities.includes('high') && priorities.includes('medium')) {
|
|
1270
|
-
suggestions.push({
|
|
1271
|
-
templateId: 'web-app-development',
|
|
1272
|
-
reason: 'Large project with mixed priorities suggests web app development',
|
|
1273
|
-
confidence: 0.6
|
|
1274
|
-
});
|
|
1275
|
-
}
|
|
1276
|
-
|
|
1277
|
-
// Enhance suggestions with template details
|
|
1278
|
-
const detailedSuggestions = suggestions.map(suggestion => {
|
|
1279
|
-
const template = this.taskTemplates[suggestion.templateId];
|
|
1280
|
-
return {
|
|
1281
|
-
...suggestion,
|
|
1282
|
-
templateName: template.name,
|
|
1283
|
-
templateDescription: template.description,
|
|
1284
|
-
taskCount: template.tasks.length
|
|
1285
|
-
};
|
|
1286
|
-
});
|
|
1287
|
-
|
|
1288
|
-
return {
|
|
1289
|
-
suggestions: detailedSuggestions,
|
|
1290
|
-
analysisResults: {
|
|
1291
|
-
existingTaskCount: existingTasks.length,
|
|
1292
|
-
dominantPriority: this.getMostCommonPriority(priorities),
|
|
1293
|
-
detectedPatterns: suggestions.map(s => s.reason)
|
|
1294
|
-
}
|
|
1295
|
-
};
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1298
|
-
/**
|
|
1299
|
-
* Generate workflow visualization for created tasks
|
|
1300
|
-
* @private
|
|
1301
|
-
*/
|
|
1302
|
-
generateWorkflowVisualization(tasks) {
|
|
1303
|
-
const workflow = {
|
|
1304
|
-
phases: [],
|
|
1305
|
-
criticalPath: [],
|
|
1306
|
-
parallelTasks: []
|
|
1307
|
-
};
|
|
1308
|
-
|
|
1309
|
-
// Group tasks by their dependency level
|
|
1310
|
-
const levels = new Map();
|
|
1311
|
-
const processedTasks = new Set();
|
|
1312
|
-
|
|
1313
|
-
// Find root tasks (no dependencies)
|
|
1314
|
-
const rootTasks = tasks.filter(task => !task.dependencies || task.dependencies.length === 0);
|
|
1315
|
-
rootTasks.forEach(task => {
|
|
1316
|
-
levels.set(0, (levels.get(0) || []).concat([task]));
|
|
1317
|
-
processedTasks.add(task.id);
|
|
1318
|
-
});
|
|
1319
|
-
|
|
1320
|
-
// Build dependency levels
|
|
1321
|
-
let currentLevel = 0;
|
|
1322
|
-
while (processedTasks.size < tasks.length && currentLevel < 10) {
|
|
1323
|
-
currentLevel++;
|
|
1324
|
-
const currentLevelTasks = [];
|
|
1325
|
-
|
|
1326
|
-
for (const task of tasks) {
|
|
1327
|
-
if (processedTasks.has(task.id)) continue;
|
|
1328
|
-
|
|
1329
|
-
if (task.dependencies && task.dependencies.every(dep => processedTasks.has(dep.taskId))) {
|
|
1330
|
-
currentLevelTasks.push(task);
|
|
1331
|
-
processedTasks.add(task.id);
|
|
1332
|
-
}
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1335
|
-
if (currentLevelTasks.length > 0) {
|
|
1336
|
-
levels.set(currentLevel, currentLevelTasks);
|
|
1337
|
-
}
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
// Convert levels to phases
|
|
1341
|
-
for (const [level, levelTasks] of levels.entries()) {
|
|
1342
|
-
workflow.phases.push({
|
|
1343
|
-
phase: level + 1,
|
|
1344
|
-
tasks: levelTasks.map(task => ({
|
|
1345
|
-
id: task.id,
|
|
1346
|
-
title: task.title,
|
|
1347
|
-
priority: task.priority
|
|
1348
|
-
})),
|
|
1349
|
-
taskCount: levelTasks.length,
|
|
1350
|
-
canRunInParallel: levelTasks.length > 1
|
|
1351
|
-
});
|
|
1352
|
-
}
|
|
1353
|
-
|
|
1354
|
-
return workflow;
|
|
1355
|
-
}
|
|
1356
|
-
|
|
1357
|
-
/**
|
|
1358
|
-
* Get most common priority from array
|
|
1359
|
-
* @private
|
|
1360
|
-
*/
|
|
1361
|
-
getMostCommonPriority(priorities) {
|
|
1362
|
-
if (priorities.length === 0) return 'medium';
|
|
1363
|
-
|
|
1364
|
-
const counts = priorities.reduce((acc, priority) => {
|
|
1365
|
-
acc[priority] = (acc[priority] || 0) + 1;
|
|
1366
|
-
return acc;
|
|
1367
|
-
}, {});
|
|
1368
|
-
|
|
1369
|
-
return Object.keys(counts).reduce((a, b) => counts[a] > counts[b] ? a : b);
|
|
1370
|
-
}
|
|
1371
|
-
|
|
1372
|
-
/**
|
|
1373
|
-
* Progress tracking management (Phase 3.4)
|
|
1374
|
-
* @private
|
|
1375
|
-
*/
|
|
1376
|
-
async trackProgress(agent, params) {
|
|
1377
|
-
const { mode = 'update', taskId, stage, milestone, note, percentage } = params;
|
|
1378
|
-
|
|
1379
|
-
let results = {};
|
|
1380
|
-
|
|
1381
|
-
if (mode === 'update' && taskId) {
|
|
1382
|
-
// Update progress for specific task
|
|
1383
|
-
results = await this.updateTaskProgress(agent, taskId, { stage, milestone, note, percentage });
|
|
1384
|
-
} else if (mode === 'overview') {
|
|
1385
|
-
// Get progress overview for all tasks
|
|
1386
|
-
results = await this.getProgressOverview(agent);
|
|
1387
|
-
} else if (mode === 'milestones' && taskId) {
|
|
1388
|
-
// Manage milestones for specific task
|
|
1389
|
-
results = await this.manageMilestones(agent, taskId, params);
|
|
1390
|
-
} else if (mode === 'calculate') {
|
|
1391
|
-
// Calculate progress based on subtasks and dependencies
|
|
1392
|
-
results = await this.calculateTaskProgress(agent, taskId);
|
|
1393
|
-
} else {
|
|
1394
|
-
throw new Error('Invalid progress mode. Use: update, overview, milestones, or calculate');
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
|
-
return {
|
|
1398
|
-
message: `Progress tracking completed (${mode})`,
|
|
1399
|
-
mode,
|
|
1400
|
-
...results
|
|
1401
|
-
};
|
|
1402
|
-
}
|
|
1403
|
-
|
|
1404
|
-
/**
|
|
1405
|
-
* Update progress for a specific task
|
|
1406
|
-
* @private
|
|
1407
|
-
*/
|
|
1408
|
-
async updateTaskProgress(agent, taskId, progressData) {
|
|
1409
|
-
const task = agent.taskList.tasks.find(t => t.id === taskId);
|
|
1410
|
-
if (!task) {
|
|
1411
|
-
throw new Error(`Task not found: ${taskId}`);
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
// Initialize progress tracking if not exists
|
|
1415
|
-
if (!task.progress) {
|
|
1416
|
-
task.progress = {
|
|
1417
|
-
stage: 'not_started',
|
|
1418
|
-
percentage: 0,
|
|
1419
|
-
milestones: [],
|
|
1420
|
-
notes: [],
|
|
1421
|
-
stageHistory: []
|
|
1422
|
-
};
|
|
1423
|
-
}
|
|
1424
|
-
|
|
1425
|
-
const oldStage = task.progress.stage;
|
|
1426
|
-
|
|
1427
|
-
// Update stage if provided
|
|
1428
|
-
if (progressData.stage) {
|
|
1429
|
-
if (!this.progressStages.includes(progressData.stage)) {
|
|
1430
|
-
throw new Error(`Invalid progress stage: ${progressData.stage}. Must be: ${this.progressStages.join(', ')}`);
|
|
1431
|
-
}
|
|
1432
|
-
|
|
1433
|
-
task.progress.stage = progressData.stage;
|
|
1434
|
-
|
|
1435
|
-
// Track stage changes
|
|
1436
|
-
task.progress.stageHistory.push({
|
|
1437
|
-
from: oldStage,
|
|
1438
|
-
to: progressData.stage,
|
|
1439
|
-
timestamp: new Date().toISOString()
|
|
1440
|
-
});
|
|
1441
|
-
|
|
1442
|
-
// Auto-update task status based on stage
|
|
1443
|
-
if (progressData.stage === 'not_started' && task.status === 'in_progress') {
|
|
1444
|
-
task.status = 'pending';
|
|
1445
|
-
} else if (['planning', 'in_development', 'testing', 'review'].includes(progressData.stage) && task.status === 'pending') {
|
|
1446
|
-
task.status = 'in_progress';
|
|
1447
|
-
} else if (progressData.stage === 'completed' && task.status !== 'completed') {
|
|
1448
|
-
task.status = 'completed';
|
|
1449
|
-
task.completedAt = new Date().toISOString();
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
// Update percentage if provided
|
|
1454
|
-
if (progressData.percentage !== undefined) {
|
|
1455
|
-
const percent = Math.max(0, Math.min(100, parseInt(progressData.percentage)));
|
|
1456
|
-
task.progress.percentage = percent;
|
|
1457
|
-
|
|
1458
|
-
// Auto-update stage based on percentage
|
|
1459
|
-
if (percent === 0 && task.progress.stage !== 'not_started') {
|
|
1460
|
-
task.progress.stage = 'not_started';
|
|
1461
|
-
} else if (percent > 0 && percent < 25 && task.progress.stage === 'not_started') {
|
|
1462
|
-
task.progress.stage = 'planning';
|
|
1463
|
-
} else if (percent >= 25 && percent < 75 && ['not_started', 'planning'].includes(task.progress.stage)) {
|
|
1464
|
-
task.progress.stage = 'in_development';
|
|
1465
|
-
} else if (percent >= 75 && percent < 95 && task.progress.stage !== 'testing') {
|
|
1466
|
-
task.progress.stage = 'testing';
|
|
1467
|
-
} else if (percent >= 95 && percent < 100 && task.progress.stage !== 'review') {
|
|
1468
|
-
task.progress.stage = 'review';
|
|
1469
|
-
} else if (percent === 100) {
|
|
1470
|
-
task.progress.stage = 'completed';
|
|
1471
|
-
task.status = 'completed';
|
|
1472
|
-
task.completedAt = new Date().toISOString();
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
|
-
|
|
1476
|
-
// Add milestone if provided
|
|
1477
|
-
if (progressData.milestone) {
|
|
1478
|
-
const milestone = {
|
|
1479
|
-
id: `milestone-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
1480
|
-
type: progressData.milestone.type || 'checkpoint',
|
|
1481
|
-
title: progressData.milestone.title || 'Progress Milestone',
|
|
1482
|
-
description: progressData.milestone.description || '',
|
|
1483
|
-
achievedAt: new Date().toISOString(),
|
|
1484
|
-
stage: task.progress.stage
|
|
1485
|
-
};
|
|
1486
|
-
|
|
1487
|
-
task.progress.milestones.push(milestone);
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1490
|
-
// Add progress note if provided
|
|
1491
|
-
if (progressData.note) {
|
|
1492
|
-
task.progress.notes.push({
|
|
1493
|
-
id: `note-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
1494
|
-
content: progressData.note,
|
|
1495
|
-
timestamp: new Date().toISOString(),
|
|
1496
|
-
stage: task.progress.stage
|
|
1497
|
-
});
|
|
1498
|
-
}
|
|
1499
|
-
|
|
1500
|
-
task.updatedAt = new Date().toISOString();
|
|
1501
|
-
|
|
1502
|
-
// Calculate progress for parent task if this is a subtask
|
|
1503
|
-
if (task.parentTaskId) {
|
|
1504
|
-
await this.calculateTaskProgress(agent, task.parentTaskId);
|
|
1505
|
-
}
|
|
1506
|
-
|
|
1507
|
-
return {
|
|
1508
|
-
task: {
|
|
1509
|
-
id: task.id,
|
|
1510
|
-
title: task.title,
|
|
1511
|
-
status: task.status,
|
|
1512
|
-
progress: task.progress
|
|
1513
|
-
},
|
|
1514
|
-
changes: {
|
|
1515
|
-
stageChanged: oldStage !== task.progress.stage,
|
|
1516
|
-
oldStage,
|
|
1517
|
-
newStage: task.progress.stage,
|
|
1518
|
-
milestoneAdded: !!progressData.milestone,
|
|
1519
|
-
noteAdded: !!progressData.note
|
|
1520
|
-
}
|
|
1521
|
-
};
|
|
1522
|
-
}
|
|
1523
|
-
|
|
1524
|
-
/**
|
|
1525
|
-
* Get progress overview for all tasks
|
|
1526
|
-
* @private
|
|
1527
|
-
*/
|
|
1528
|
-
async getProgressOverview(agent) {
|
|
1529
|
-
const tasks = agent.taskList.tasks;
|
|
1530
|
-
const taskProgress = tasks.map(task => {
|
|
1531
|
-
const progress = task.progress || { stage: 'not_started', percentage: 0, milestones: [], notes: [] };
|
|
1532
|
-
|
|
1533
|
-
return {
|
|
1534
|
-
id: task.id,
|
|
1535
|
-
title: task.title,
|
|
1536
|
-
status: task.status,
|
|
1537
|
-
priority: task.priority,
|
|
1538
|
-
stage: progress.stage,
|
|
1539
|
-
percentage: progress.percentage,
|
|
1540
|
-
milestoneCount: progress.milestones ? progress.milestones.length : 0,
|
|
1541
|
-
isBlocked: task.status === 'blocked',
|
|
1542
|
-
hasSubtasks: !!(task.subtasks && task.subtasks.length > 0),
|
|
1543
|
-
parentTaskId: task.parentTaskId
|
|
1544
|
-
};
|
|
1545
|
-
});
|
|
1546
|
-
|
|
1547
|
-
// Calculate overall statistics
|
|
1548
|
-
const stats = {
|
|
1549
|
-
totalTasks: tasks.length,
|
|
1550
|
-
byStage: {},
|
|
1551
|
-
byStatus: {},
|
|
1552
|
-
averageProgress: 0,
|
|
1553
|
-
blockedTasks: 0,
|
|
1554
|
-
completedTasks: 0
|
|
1555
|
-
};
|
|
1556
|
-
|
|
1557
|
-
this.progressStages.forEach(stage => {
|
|
1558
|
-
stats.byStage[stage] = taskProgress.filter(t => t.stage === stage).length;
|
|
1559
|
-
});
|
|
1560
|
-
|
|
1561
|
-
this.taskStatuses.forEach(status => {
|
|
1562
|
-
stats.byStatus[status] = taskProgress.filter(t => t.status === status).length;
|
|
1563
|
-
});
|
|
1564
|
-
|
|
1565
|
-
stats.averageProgress = tasks.length > 0 ?
|
|
1566
|
-
Math.round(taskProgress.reduce((sum, t) => sum + t.percentage, 0) / tasks.length) : 0;
|
|
1567
|
-
|
|
1568
|
-
stats.blockedTasks = stats.byStatus.blocked || 0;
|
|
1569
|
-
stats.completedTasks = stats.byStatus.completed || 0;
|
|
1570
|
-
|
|
1571
|
-
// Find critical path and bottlenecks
|
|
1572
|
-
const criticalTasks = taskProgress.filter(t =>
|
|
1573
|
-
t.priority === 'urgent' && t.status !== 'completed'
|
|
1574
|
-
);
|
|
1575
|
-
|
|
1576
|
-
const bottlenecks = taskProgress.filter(t =>
|
|
1577
|
-
t.isBlocked && this.findTasksBlockedBy(t.id, tasks).length > 0
|
|
1578
|
-
);
|
|
1579
|
-
|
|
1580
|
-
return {
|
|
1581
|
-
overview: stats,
|
|
1582
|
-
tasks: taskProgress,
|
|
1583
|
-
criticalTasks,
|
|
1584
|
-
bottlenecks: bottlenecks.map(t => ({
|
|
1585
|
-
taskId: t.id,
|
|
1586
|
-
title: t.title,
|
|
1587
|
-
blockedTasksCount: this.findTasksBlockedBy(t.id, tasks).length
|
|
1588
|
-
})),
|
|
1589
|
-
recommendations: this.generateProgressRecommendations(taskProgress, stats)
|
|
1590
|
-
};
|
|
1591
|
-
}
|
|
1592
|
-
|
|
1593
|
-
/**
|
|
1594
|
-
* Calculate task progress based on subtasks and dependencies
|
|
1595
|
-
* @private
|
|
1596
|
-
*/
|
|
1597
|
-
async calculateTaskProgress(agent, taskId) {
|
|
1598
|
-
const task = agent.taskList.tasks.find(t => t.id === taskId);
|
|
1599
|
-
if (!task) {
|
|
1600
|
-
throw new Error(`Task not found: ${taskId}`);
|
|
1601
|
-
}
|
|
1602
|
-
|
|
1603
|
-
// Initialize progress if not exists
|
|
1604
|
-
if (!task.progress) {
|
|
1605
|
-
task.progress = {
|
|
1606
|
-
stage: 'not_started',
|
|
1607
|
-
percentage: 0,
|
|
1608
|
-
milestones: [],
|
|
1609
|
-
notes: [],
|
|
1610
|
-
stageHistory: []
|
|
1611
|
-
};
|
|
1612
|
-
}
|
|
1613
|
-
|
|
1614
|
-
let calculatedPercentage = 0;
|
|
1615
|
-
let calculationMethod = 'manual';
|
|
1616
|
-
|
|
1617
|
-
// Calculate based on subtasks if they exist
|
|
1618
|
-
if (task.subtasks && task.subtasks.length > 0) {
|
|
1619
|
-
const subtasks = task.subtasks.map(subtaskId =>
|
|
1620
|
-
agent.taskList.tasks.find(t => t.id === subtaskId)
|
|
1621
|
-
).filter(Boolean);
|
|
1622
|
-
|
|
1623
|
-
if (subtasks.length > 0) {
|
|
1624
|
-
const subtaskProgress = subtasks.map(subtask => {
|
|
1625
|
-
if (subtask.status === 'completed') return 100;
|
|
1626
|
-
if (subtask.progress && subtask.progress.percentage !== undefined) {
|
|
1627
|
-
return subtask.progress.percentage;
|
|
1628
|
-
}
|
|
1629
|
-
return subtask.status === 'in_progress' ? 25 : 0;
|
|
1630
|
-
});
|
|
1631
|
-
|
|
1632
|
-
calculatedPercentage = Math.round(
|
|
1633
|
-
subtaskProgress.reduce((sum, p) => sum + p, 0) / subtasks.length
|
|
1634
|
-
);
|
|
1635
|
-
calculationMethod = 'subtasks';
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
|
|
1639
|
-
// If no subtasks, calculate based on dependencies completion
|
|
1640
|
-
else if (task.dependencies && task.dependencies.length > 0) {
|
|
1641
|
-
const completedDeps = task.dependencies.filter(dep => {
|
|
1642
|
-
const depTask = agent.taskList.tasks.find(t => t.id === dep.taskId);
|
|
1643
|
-
return depTask && depTask.status === 'completed';
|
|
1644
|
-
}).length;
|
|
1645
|
-
|
|
1646
|
-
const depProgress = (completedDeps / task.dependencies.length) * 30; // Dependencies contribute 30%
|
|
1647
|
-
const ownProgress = task.status === 'completed' ? 70 :
|
|
1648
|
-
task.status === 'in_progress' ? 35 : 0; // Own progress contributes 70%
|
|
1649
|
-
|
|
1650
|
-
calculatedPercentage = Math.round(depProgress + ownProgress);
|
|
1651
|
-
calculationMethod = 'dependencies';
|
|
1652
|
-
}
|
|
1653
|
-
|
|
1654
|
-
// Fallback to status-based calculation
|
|
1655
|
-
else {
|
|
1656
|
-
if (task.status === 'completed') calculatedPercentage = 100;
|
|
1657
|
-
else if (task.status === 'in_progress') calculatedPercentage = task.progress.percentage || 50;
|
|
1658
|
-
else if (task.status === 'pending') calculatedPercentage = 0;
|
|
1659
|
-
else if (task.status === 'blocked') calculatedPercentage = task.progress.percentage || 0;
|
|
1660
|
-
|
|
1661
|
-
calculationMethod = 'status';
|
|
1662
|
-
}
|
|
1663
|
-
|
|
1664
|
-
// Update the task's calculated progress
|
|
1665
|
-
task.progress.calculatedPercentage = calculatedPercentage;
|
|
1666
|
-
task.progress.calculationMethod = calculationMethod;
|
|
1667
|
-
task.progress.lastCalculated = new Date().toISOString();
|
|
1668
|
-
|
|
1669
|
-
// Auto-update stage based on calculated percentage if no manual stage set recently
|
|
1670
|
-
const recentStageUpdate = task.progress.stageHistory.length > 0 &&
|
|
1671
|
-
(Date.now() - new Date(task.progress.stageHistory[task.progress.stageHistory.length - 1].timestamp).getTime()) < 300000; // 5 minutes
|
|
1672
|
-
|
|
1673
|
-
if (!recentStageUpdate) {
|
|
1674
|
-
const autoStage = this.getStageFromPercentage(calculatedPercentage);
|
|
1675
|
-
if (autoStage !== task.progress.stage) {
|
|
1676
|
-
task.progress.stage = autoStage;
|
|
1677
|
-
task.progress.stageHistory.push({
|
|
1678
|
-
from: task.progress.stage,
|
|
1679
|
-
to: autoStage,
|
|
1680
|
-
timestamp: new Date().toISOString(),
|
|
1681
|
-
automatic: true
|
|
1682
|
-
});
|
|
1683
|
-
}
|
|
1684
|
-
}
|
|
1685
|
-
|
|
1686
|
-
task.updatedAt = new Date().toISOString();
|
|
1687
|
-
|
|
1688
|
-
return {
|
|
1689
|
-
taskId: task.id,
|
|
1690
|
-
title: task.title,
|
|
1691
|
-
calculatedPercentage,
|
|
1692
|
-
calculationMethod,
|
|
1693
|
-
manualPercentage: task.progress.percentage,
|
|
1694
|
-
stage: task.progress.stage,
|
|
1695
|
-
subtaskCount: task.subtasks ? task.subtasks.length : 0,
|
|
1696
|
-
dependencyCount: task.dependencies ? task.dependencies.length : 0
|
|
1697
|
-
};
|
|
1698
|
-
}
|
|
1699
|
-
|
|
1700
|
-
/**
|
|
1701
|
-
* Generate progress recommendations
|
|
1702
|
-
* @private
|
|
1703
|
-
*/
|
|
1704
|
-
generateProgressRecommendations(taskProgress, stats) {
|
|
1705
|
-
const recommendations = [];
|
|
1706
|
-
|
|
1707
|
-
// Blocked task recommendations
|
|
1708
|
-
if (stats.blockedTasks > 0) {
|
|
1709
|
-
recommendations.push({
|
|
1710
|
-
type: 'urgent',
|
|
1711
|
-
category: 'blocked_tasks',
|
|
1712
|
-
message: `${stats.blockedTasks} tasks are blocked. Review dependencies to unblock progress.`,
|
|
1713
|
-
actionable: true
|
|
1714
|
-
});
|
|
1715
|
-
}
|
|
1716
|
-
|
|
1717
|
-
// Stalled task recommendations
|
|
1718
|
-
const stalledTasks = taskProgress.filter(t =>
|
|
1719
|
-
t.status === 'in_progress' && t.percentage < 25
|
|
1720
|
-
);
|
|
1721
|
-
|
|
1722
|
-
if (stalledTasks.length > 0) {
|
|
1723
|
-
recommendations.push({
|
|
1724
|
-
type: 'warning',
|
|
1725
|
-
category: 'stalled_progress',
|
|
1726
|
-
message: `${stalledTasks.length} tasks are in progress but showing low progress. Consider breaking them into smaller subtasks.`,
|
|
1727
|
-
actionable: true
|
|
1728
|
-
});
|
|
1729
|
-
}
|
|
1730
|
-
|
|
1731
|
-
// High progress tasks ready for completion
|
|
1732
|
-
const nearCompletionTasks = taskProgress.filter(t =>
|
|
1733
|
-
t.percentage >= 90 && t.status !== 'completed'
|
|
1734
|
-
);
|
|
1735
|
-
|
|
1736
|
-
if (nearCompletionTasks.length > 0) {
|
|
1737
|
-
recommendations.push({
|
|
1738
|
-
type: 'success',
|
|
1739
|
-
category: 'near_completion',
|
|
1740
|
-
message: `${nearCompletionTasks.length} tasks are near completion. Focus on finishing these for quick wins.`,
|
|
1741
|
-
actionable: true
|
|
1742
|
-
});
|
|
1743
|
-
}
|
|
1744
|
-
|
|
1745
|
-
// Overall progress recommendations
|
|
1746
|
-
if (stats.averageProgress < 25) {
|
|
1747
|
-
recommendations.push({
|
|
1748
|
-
type: 'info',
|
|
1749
|
-
category: 'overall_progress',
|
|
1750
|
-
message: 'Overall progress is low. Consider prioritizing and focusing on fewer tasks.',
|
|
1751
|
-
actionable: false
|
|
1752
|
-
});
|
|
1753
|
-
}
|
|
1754
|
-
|
|
1755
|
-
return recommendations;
|
|
1756
|
-
}
|
|
1757
|
-
|
|
1758
|
-
/**
|
|
1759
|
-
* Get stage from percentage
|
|
1760
|
-
* @private
|
|
1761
|
-
*/
|
|
1762
|
-
getStageFromPercentage(percentage) {
|
|
1763
|
-
if (percentage === 0) return 'not_started';
|
|
1764
|
-
if (percentage < 25) return 'planning';
|
|
1765
|
-
if (percentage < 75) return 'in_development';
|
|
1766
|
-
if (percentage < 95) return 'testing';
|
|
1767
|
-
if (percentage < 100) return 'review';
|
|
1768
|
-
return 'completed';
|
|
1769
|
-
}
|
|
1770
|
-
|
|
1771
|
-
/**
|
|
1772
|
-
* Set scheduler reference for dependency management (Phase 3)
|
|
1773
|
-
* @param {Object} scheduler - AgentScheduler instance
|
|
1774
|
-
*/
|
|
1775
|
-
setScheduler(scheduler) {
|
|
1776
|
-
this.scheduler = scheduler;
|
|
1777
|
-
this.logger?.info('TaskManagerTool: Scheduler dependency injected');
|
|
1778
|
-
}
|
|
1779
|
-
|
|
1780
|
-
/**
|
|
1781
|
-
* Intelligent task prioritization (Phase 3.2)
|
|
1782
|
-
* @private
|
|
1783
|
-
*/
|
|
1784
|
-
async intelligentPrioritization(agent, params) {
|
|
1785
|
-
const { mode = 'auto', taskId } = params;
|
|
1786
|
-
|
|
1787
|
-
let results = {};
|
|
1788
|
-
|
|
1789
|
-
if (mode === 'auto') {
|
|
1790
|
-
// Auto-prioritize all tasks
|
|
1791
|
-
results = await this.autoPrioritizeAllTasks(agent);
|
|
1792
|
-
} else if (mode === 'analyze' && taskId) {
|
|
1793
|
-
// Analyze specific task priority
|
|
1794
|
-
results = await this.analyzeTaskPriority(agent, taskId);
|
|
1795
|
-
} else if (mode === 'balance') {
|
|
1796
|
-
// Balance priorities across all agents
|
|
1797
|
-
results = await this.balanceCrossAgentPriorities(agent);
|
|
1798
|
-
} else {
|
|
1799
|
-
throw new Error('Invalid prioritization mode. Use: auto, analyze, or balance');
|
|
1800
|
-
}
|
|
1801
|
-
|
|
1802
|
-
return {
|
|
1803
|
-
message: `Intelligent prioritization completed (${mode})`,
|
|
1804
|
-
mode,
|
|
1805
|
-
...results
|
|
1806
|
-
};
|
|
1807
|
-
}
|
|
1808
|
-
|
|
1809
|
-
/**
|
|
1810
|
-
* Auto-prioritize all tasks using intelligent scoring
|
|
1811
|
-
* @private
|
|
1812
|
-
*/
|
|
1813
|
-
async autoPrioritizeAllTasks(agent) {
|
|
1814
|
-
const tasks = agent.taskList.tasks.filter(t =>
|
|
1815
|
-
t.status === 'pending' || t.status === 'in_progress'
|
|
1816
|
-
);
|
|
1817
|
-
|
|
1818
|
-
if (tasks.length === 0) {
|
|
1819
|
-
return { message: 'No active tasks to prioritize' };
|
|
1820
|
-
}
|
|
1821
|
-
|
|
1822
|
-
// Calculate priority scores for all tasks
|
|
1823
|
-
const tasksWithScores = tasks.map(task => ({
|
|
1824
|
-
...task,
|
|
1825
|
-
priorityScore: this.calculatePriorityScore(task, agent.taskList.tasks),
|
|
1826
|
-
originalPriority: task.priority
|
|
1827
|
-
}));
|
|
1828
|
-
|
|
1829
|
-
// Sort by priority score (higher = more important)
|
|
1830
|
-
tasksWithScores.sort((a, b) => b.priorityScore - a.priorityScore);
|
|
1831
|
-
|
|
1832
|
-
// Assign new priorities based on scores
|
|
1833
|
-
const priorityMapping = ['urgent', 'high', 'medium', 'low'];
|
|
1834
|
-
const updatedTasks = [];
|
|
1835
|
-
|
|
1836
|
-
tasksWithScores.forEach((task, index) => {
|
|
1837
|
-
const newPriorityIndex = Math.min(
|
|
1838
|
-
Math.floor(index / Math.max(1, tasks.length / 4)),
|
|
1839
|
-
priorityMapping.length - 1
|
|
1840
|
-
);
|
|
1841
|
-
const newPriority = priorityMapping[newPriorityIndex];
|
|
1842
|
-
|
|
1843
|
-
if (task.originalPriority !== newPriority) {
|
|
1844
|
-
const originalTask = agent.taskList.tasks.find(t => t.id === task.id);
|
|
1845
|
-
originalTask.priority = newPriority;
|
|
1846
|
-
originalTask.updatedAt = new Date().toISOString();
|
|
1847
|
-
originalTask.priorityScore = task.priorityScore;
|
|
1848
|
-
originalTask.priorityReason = this.generatePriorityReason(task);
|
|
1849
|
-
|
|
1850
|
-
updatedTasks.push({
|
|
1851
|
-
id: task.id,
|
|
1852
|
-
title: task.title,
|
|
1853
|
-
oldPriority: task.originalPriority,
|
|
1854
|
-
newPriority: newPriority,
|
|
1855
|
-
score: task.priorityScore.toFixed(2),
|
|
1856
|
-
reason: originalTask.priorityReason
|
|
1857
|
-
});
|
|
1858
|
-
}
|
|
1859
|
-
});
|
|
1860
|
-
|
|
1861
|
-
return {
|
|
1862
|
-
totalTasks: tasks.length,
|
|
1863
|
-
updatedTasks: updatedTasks.length,
|
|
1864
|
-
changes: updatedTasks
|
|
1865
|
-
};
|
|
1866
|
-
}
|
|
1867
|
-
|
|
1868
|
-
/**
|
|
1869
|
-
* Calculate intelligent priority score for a task
|
|
1870
|
-
* @private
|
|
1871
|
-
*/
|
|
1872
|
-
calculatePriorityScore(task, allTasks) {
|
|
1873
|
-
let score = 0;
|
|
1874
|
-
|
|
1875
|
-
// Base user priority score
|
|
1876
|
-
const priorityScores = { urgent: 4, high: 3, medium: 2, low: 1 };
|
|
1877
|
-
score += priorityScores[task.priority] * this.priorityWeights.userPriority;
|
|
1878
|
-
|
|
1879
|
-
// Age factor (older tasks get higher priority)
|
|
1880
|
-
const ageHours = (Date.now() - new Date(task.createdAt).getTime()) / (1000 * 60 * 60);
|
|
1881
|
-
score += Math.min(ageHours / 24, 3) * this.priorityWeights.age;
|
|
1882
|
-
|
|
1883
|
-
// Blocking factor (tasks that block others get higher priority)
|
|
1884
|
-
const blockedTasks = this.findTasksBlockedBy(task.id, allTasks);
|
|
1885
|
-
score += blockedTasks.length * this.priorityWeights.blocking;
|
|
1886
|
-
|
|
1887
|
-
// Dependency complexity factor
|
|
1888
|
-
const dependencyCount = (task.dependencies || []).length;
|
|
1889
|
-
score += Math.min(dependencyCount, 3) * this.priorityWeights.dependency;
|
|
1890
|
-
|
|
1891
|
-
// Subtask factor (parent tasks with many subtasks get higher priority)
|
|
1892
|
-
const subtaskCount = (task.subtasks || []).length;
|
|
1893
|
-
score += Math.min(subtaskCount, 2) * this.priorityWeights.dependency;
|
|
1894
|
-
|
|
1895
|
-
return score;
|
|
1896
|
-
}
|
|
1897
|
-
|
|
1898
|
-
/**
|
|
1899
|
-
* Find tasks that are blocked by the given task
|
|
1900
|
-
* @private
|
|
1901
|
-
*/
|
|
1902
|
-
findTasksBlockedBy(taskId, allTasks) {
|
|
1903
|
-
return allTasks.filter(task => {
|
|
1904
|
-
if (!task.dependencies) return false;
|
|
1905
|
-
return task.dependencies.some(dep =>
|
|
1906
|
-
dep.taskId === taskId && dep.type === 'blocks'
|
|
1907
|
-
);
|
|
1908
|
-
});
|
|
1909
|
-
}
|
|
1910
|
-
|
|
1911
|
-
/**
|
|
1912
|
-
* Generate human-readable priority reason
|
|
1913
|
-
* @private
|
|
1914
|
-
*/
|
|
1915
|
-
generatePriorityReason(task) {
|
|
1916
|
-
const reasons = [];
|
|
1917
|
-
|
|
1918
|
-
if (task.priorityScore > 8) {
|
|
1919
|
-
reasons.push('high overall impact');
|
|
1920
|
-
}
|
|
1921
|
-
|
|
1922
|
-
const ageHours = (Date.now() - new Date(task.createdAt).getTime()) / (1000 * 60 * 60);
|
|
1923
|
-
if (ageHours > 24) {
|
|
1924
|
-
reasons.push('overdue task');
|
|
1925
|
-
}
|
|
1926
|
-
|
|
1927
|
-
if (task.priority === 'urgent') {
|
|
1928
|
-
reasons.push('user-marked urgent');
|
|
1929
|
-
}
|
|
1930
|
-
|
|
1931
|
-
if ((task.subtasks || []).length > 0) {
|
|
1932
|
-
reasons.push('has subtasks');
|
|
1933
|
-
}
|
|
1934
|
-
|
|
1935
|
-
return reasons.length > 0 ? reasons.join(', ') : 'standard prioritization';
|
|
1936
|
-
}
|
|
1937
|
-
|
|
1938
|
-
/**
|
|
1939
|
-
* Analyze priority of a specific task
|
|
1940
|
-
* @private
|
|
1941
|
-
*/
|
|
1942
|
-
async analyzeTaskPriority(agent, taskId) {
|
|
1943
|
-
const task = agent.taskList.tasks.find(t => t.id === taskId);
|
|
1944
|
-
if (!task) {
|
|
1945
|
-
throw new Error(`Task not found: ${taskId}`);
|
|
1946
|
-
}
|
|
1947
|
-
|
|
1948
|
-
const score = this.calculatePriorityScore(task, agent.taskList.tasks);
|
|
1949
|
-
const blockedTasks = this.findTasksBlockedBy(taskId, agent.taskList.tasks);
|
|
1950
|
-
const reason = this.generatePriorityReason({ ...task, priorityScore: score });
|
|
1951
|
-
|
|
1952
|
-
return {
|
|
1953
|
-
task: {
|
|
1954
|
-
id: task.id,
|
|
1955
|
-
title: task.title,
|
|
1956
|
-
currentPriority: task.priority,
|
|
1957
|
-
priorityScore: score.toFixed(2),
|
|
1958
|
-
reason
|
|
1959
|
-
},
|
|
1960
|
-
analysis: {
|
|
1961
|
-
blocksOtherTasks: blockedTasks.length,
|
|
1962
|
-
ageInHours: ((Date.now() - new Date(task.createdAt).getTime()) / (1000 * 60 * 60)).toFixed(1),
|
|
1963
|
-
dependencyCount: (task.dependencies || []).length,
|
|
1964
|
-
subtaskCount: (task.subtasks || []).length
|
|
1965
|
-
},
|
|
1966
|
-
blockedTasks: blockedTasks.map(t => ({ id: t.id, title: t.title }))
|
|
1967
|
-
};
|
|
1968
|
-
}
|
|
1969
|
-
|
|
1970
|
-
/**
|
|
1971
|
-
* Balance priorities across all agents (requires scheduler)
|
|
1972
|
-
* @private
|
|
1973
|
-
*/
|
|
1974
|
-
async balanceCrossAgentPriorities(agent) {
|
|
1975
|
-
if (!this.scheduler || typeof this.scheduler.getAllAgents !== 'function') {
|
|
1976
|
-
return { message: 'Cross-agent balancing requires scheduler integration' };
|
|
1977
|
-
}
|
|
1978
|
-
|
|
1979
|
-
try {
|
|
1980
|
-
const allAgents = await this.scheduler.getAllAgents();
|
|
1981
|
-
const agentWorkloads = [];
|
|
1982
|
-
|
|
1983
|
-
allAgents.forEach(ag => {
|
|
1984
|
-
if (ag.taskList && ag.taskList.tasks) {
|
|
1985
|
-
const activeTasks = ag.taskList.tasks.filter(t =>
|
|
1986
|
-
t.status === 'pending' || t.status === 'in_progress'
|
|
1987
|
-
);
|
|
1988
|
-
const urgentTasks = activeTasks.filter(t => t.priority === 'urgent').length;
|
|
1989
|
-
const highTasks = activeTasks.filter(t => t.priority === 'high').length;
|
|
1990
|
-
|
|
1991
|
-
agentWorkloads.push({
|
|
1992
|
-
agentId: ag.id,
|
|
1993
|
-
agentName: ag.name,
|
|
1994
|
-
totalActive: activeTasks.length,
|
|
1995
|
-
urgent: urgentTasks,
|
|
1996
|
-
high: highTasks,
|
|
1997
|
-
workloadScore: urgentTasks * 3 + highTasks * 2 + activeTasks.length
|
|
1998
|
-
});
|
|
1999
|
-
}
|
|
2000
|
-
});
|
|
2001
|
-
|
|
2002
|
-
// Sort by workload (lowest first)
|
|
2003
|
-
agentWorkloads.sort((a, b) => a.workloadScore - b.workloadScore);
|
|
2004
|
-
|
|
2005
|
-
return {
|
|
2006
|
-
currentAgent: {
|
|
2007
|
-
agentId: agent.id,
|
|
2008
|
-
rank: agentWorkloads.findIndex(a => a.agentId === agent.id) + 1,
|
|
2009
|
-
totalAgents: agentWorkloads.length
|
|
2010
|
-
},
|
|
2011
|
-
workloadDistribution: agentWorkloads,
|
|
2012
|
-
recommendation: this.generateBalancingRecommendation(agent, agentWorkloads)
|
|
2013
|
-
};
|
|
2014
|
-
} catch (error) {
|
|
2015
|
-
return {
|
|
2016
|
-
error: `Cross-agent balancing failed: ${error.message}`,
|
|
2017
|
-
fallback: 'Using single-agent prioritization'
|
|
2018
|
-
};
|
|
2019
|
-
}
|
|
2020
|
-
}
|
|
2021
|
-
|
|
2022
|
-
/**
|
|
2023
|
-
* Generate workload balancing recommendation
|
|
2024
|
-
* @private
|
|
2025
|
-
*/
|
|
2026
|
-
generateBalancingRecommendation(currentAgent, workloads) {
|
|
2027
|
-
const current = workloads.find(w => w.agentId === currentAgent.id);
|
|
2028
|
-
if (!current) return 'No recommendation available';
|
|
2029
|
-
|
|
2030
|
-
const avgWorkload = workloads.reduce((sum, w) => sum + w.workloadScore, 0) / workloads.length;
|
|
2031
|
-
|
|
2032
|
-
if (current.workloadScore > avgWorkload * 1.5) {
|
|
2033
|
-
return 'Consider delegating some tasks to less busy agents';
|
|
2034
|
-
} else if (current.workloadScore < avgWorkload * 0.5) {
|
|
2035
|
-
return 'Agent has capacity for additional high-priority tasks';
|
|
2036
|
-
} else {
|
|
2037
|
-
return 'Workload is well balanced';
|
|
2038
|
-
}
|
|
2039
|
-
}
|
|
2040
|
-
|
|
2041
|
-
/**
|
|
2042
|
-
* Generate task summary
|
|
2043
|
-
* @private
|
|
2044
|
-
*/
|
|
2045
|
-
generateTaskSummary(taskList) {
|
|
2046
|
-
const tasks = taskList.tasks;
|
|
2047
|
-
return {
|
|
2048
|
-
total: tasks.length,
|
|
2049
|
-
pending: tasks.filter(t => t.status === 'pending').length,
|
|
2050
|
-
in_progress: tasks.filter(t => t.status === 'in_progress').length,
|
|
2051
|
-
completed: tasks.filter(t => t.status === 'completed').length,
|
|
2052
|
-
cancelled: tasks.filter(t => t.status === 'cancelled').length,
|
|
2053
|
-
high_priority: tasks.filter(t => t.priority === 'high' && (t.status === 'pending' || t.status === 'in_progress')).length
|
|
2054
|
-
};
|
|
2055
|
-
}
|
|
2056
|
-
|
|
2057
|
-
/**
|
|
2058
|
-
* Phase 3.5: Generate task analytics and reporting
|
|
2059
|
-
* @private
|
|
2060
|
-
*/
|
|
2061
|
-
async generateAnalytics(agent, params) {
|
|
2062
|
-
const { mode = 'summary', timeframe = '30', reportType = 'comprehensive', agentId } = params;
|
|
2063
|
-
|
|
2064
|
-
let results = {};
|
|
2065
|
-
|
|
2066
|
-
switch (mode) {
|
|
2067
|
-
case 'summary':
|
|
2068
|
-
results = await this.getAnalyticsSummary(agent, timeframe);
|
|
2069
|
-
break;
|
|
2070
|
-
case 'performance':
|
|
2071
|
-
results = await this.getPerformanceMetrics(agent, timeframe);
|
|
2072
|
-
break;
|
|
2073
|
-
case 'trends':
|
|
2074
|
-
results = await this.getTrendAnalysis(agent, timeframe);
|
|
2075
|
-
break;
|
|
2076
|
-
case 'team':
|
|
2077
|
-
results = await this.getTeamAnalytics(timeframe);
|
|
2078
|
-
break;
|
|
2079
|
-
case 'export':
|
|
2080
|
-
results = await this.exportAnalytics(agent, params);
|
|
2081
|
-
break;
|
|
2082
|
-
case 'insights':
|
|
2083
|
-
results = await this.generateInsights(agent, timeframe);
|
|
2084
|
-
break;
|
|
2085
|
-
default:
|
|
2086
|
-
throw new Error('Invalid analytics mode. Use: summary, performance, trends, team, export, or insights');
|
|
2087
|
-
}
|
|
2088
|
-
|
|
2089
|
-
return {
|
|
2090
|
-
message: `Analytics report generated (${mode})`,
|
|
2091
|
-
mode,
|
|
2092
|
-
timeframe,
|
|
2093
|
-
generatedAt: new Date().toISOString(),
|
|
2094
|
-
...results
|
|
2095
|
-
};
|
|
2096
|
-
}
|
|
2097
|
-
|
|
2098
|
-
/**
|
|
2099
|
-
* Get comprehensive analytics summary
|
|
2100
|
-
* @private
|
|
2101
|
-
*/
|
|
2102
|
-
async getAnalyticsSummary(agent, timeframe) {
|
|
2103
|
-
const tasks = agent.taskList.tasks;
|
|
2104
|
-
const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
|
|
2105
|
-
|
|
2106
|
-
// Filter tasks within timeframe
|
|
2107
|
-
const timeframeTasks = tasks.filter(t => new Date(t.createdAt) >= cutoffDate);
|
|
2108
|
-
|
|
2109
|
-
const summary = {
|
|
2110
|
-
overview: {
|
|
2111
|
-
totalTasks: timeframeTasks.length,
|
|
2112
|
-
completed: timeframeTasks.filter(t => t.status === 'completed').length,
|
|
2113
|
-
inProgress: timeframeTasks.filter(t => t.status === 'in_progress').length,
|
|
2114
|
-
pending: timeframeTasks.filter(t => t.status === 'pending').length,
|
|
2115
|
-
cancelled: timeframeTasks.filter(t => t.status === 'cancelled').length,
|
|
2116
|
-
blocked: timeframeTasks.filter(t => t.status === 'blocked').length
|
|
2117
|
-
},
|
|
2118
|
-
priorityBreakdown: {
|
|
2119
|
-
urgent: timeframeTasks.filter(t => t.priority === 'urgent').length,
|
|
2120
|
-
high: timeframeTasks.filter(t => t.priority === 'high').length,
|
|
2121
|
-
medium: timeframeTasks.filter(t => t.priority === 'medium').length,
|
|
2122
|
-
low: timeframeTasks.filter(t => t.priority === 'low').length
|
|
2123
|
-
},
|
|
2124
|
-
progressMetrics: this.calculateProgressMetrics(timeframeTasks),
|
|
2125
|
-
dependencyMetrics: this.calculateDependencyMetrics(timeframeTasks),
|
|
2126
|
-
templateUsage: this.calculateTemplateUsage(timeframeTasks)
|
|
2127
|
-
};
|
|
2128
|
-
|
|
2129
|
-
// Calculate completion rate
|
|
2130
|
-
summary.completionRate = summary.overview.totalTasks > 0
|
|
2131
|
-
? Math.round((summary.overview.completed / summary.overview.totalTasks) * 100)
|
|
2132
|
-
: 0;
|
|
2133
|
-
|
|
2134
|
-
// Calculate average task age
|
|
2135
|
-
const activeTasks = timeframeTasks.filter(t => t.status !== 'completed' && t.status !== 'cancelled');
|
|
2136
|
-
summary.averageTaskAge = activeTasks.length > 0
|
|
2137
|
-
? Math.round(activeTasks.reduce((sum, task) => {
|
|
2138
|
-
return sum + (Date.now() - new Date(task.createdAt).getTime()) / (1000 * 60 * 60 * 24);
|
|
2139
|
-
}, 0) / activeTasks.length)
|
|
2140
|
-
: 0;
|
|
2141
|
-
|
|
2142
|
-
return {
|
|
2143
|
-
summary,
|
|
2144
|
-
insights: this.generateSummaryInsights(summary)
|
|
2145
|
-
};
|
|
2146
|
-
}
|
|
2147
|
-
|
|
2148
|
-
/**
|
|
2149
|
-
* Get performance metrics
|
|
2150
|
-
* @private
|
|
2151
|
-
*/
|
|
2152
|
-
async getPerformanceMetrics(agent, timeframe) {
|
|
2153
|
-
const tasks = agent.taskList.tasks;
|
|
2154
|
-
const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
|
|
2155
|
-
const completedTasks = tasks.filter(t =>
|
|
2156
|
-
t.status === 'completed' &&
|
|
2157
|
-
t.completedAt &&
|
|
2158
|
-
new Date(t.completedAt) >= cutoffDate
|
|
2159
|
-
);
|
|
2160
|
-
|
|
2161
|
-
const metrics = {
|
|
2162
|
-
productivity: {
|
|
2163
|
-
tasksCompleted: completedTasks.length,
|
|
2164
|
-
completionRate: this.calculateCompletionRate(tasks, timeframe),
|
|
2165
|
-
averageCompletionTime: this.calculateAverageCompletionTime(completedTasks),
|
|
2166
|
-
velocityTrend: this.calculateVelocityTrend(tasks, timeframe)
|
|
2167
|
-
},
|
|
2168
|
-
quality: {
|
|
2169
|
-
blockedTasksRate: this.calculateBlockedTasksRate(tasks),
|
|
2170
|
-
cancelledTasksRate: this.calculateCancelledTasksRate(tasks, timeframe),
|
|
2171
|
-
reworkRate: this.calculateReworkRate(tasks, timeframe)
|
|
2172
|
-
},
|
|
2173
|
-
efficiency: {
|
|
2174
|
-
priorityAccuracy: this.calculatePriorityAccuracy(completedTasks),
|
|
2175
|
-
dependencyHandling: this.calculateDependencyEfficiency(tasks),
|
|
2176
|
-
progressConsistency: this.calculateProgressConsistency(tasks)
|
|
2177
|
-
}
|
|
2178
|
-
};
|
|
2179
|
-
|
|
2180
|
-
return {
|
|
2181
|
-
metrics,
|
|
2182
|
-
recommendations: this.generatePerformanceRecommendations(metrics)
|
|
2183
|
-
};
|
|
2184
|
-
}
|
|
2185
|
-
|
|
2186
|
-
/**
|
|
2187
|
-
* Get trend analysis
|
|
2188
|
-
* @private
|
|
2189
|
-
*/
|
|
2190
|
-
async getTrendAnalysis(agent, timeframe) {
|
|
2191
|
-
const tasks = agent.taskList.tasks;
|
|
2192
|
-
const days = parseInt(timeframe);
|
|
2193
|
-
const trends = {
|
|
2194
|
-
daily: this.calculateDailyTrends(tasks, days),
|
|
2195
|
-
weekly: this.calculateWeeklyTrends(tasks, days),
|
|
2196
|
-
priorityTrends: this.calculatePriorityTrends(tasks, days),
|
|
2197
|
-
progressTrends: this.calculateProgressTrends(tasks, days)
|
|
2198
|
-
};
|
|
2199
|
-
|
|
2200
|
-
return {
|
|
2201
|
-
trends,
|
|
2202
|
-
forecasts: this.generateForecasts(trends),
|
|
2203
|
-
patterns: this.identifyPatterns(trends)
|
|
2204
|
-
};
|
|
2205
|
-
}
|
|
2206
|
-
|
|
2207
|
-
/**
|
|
2208
|
-
* Get team-wide analytics (across all agents)
|
|
2209
|
-
* @private
|
|
2210
|
-
*/
|
|
2211
|
-
async getTeamAnalytics(timeframe) {
|
|
2212
|
-
if (!this.scheduler || !this.scheduler.getAllAgents) {
|
|
2213
|
-
throw new Error('Team analytics requires scheduler with getAllAgents method');
|
|
2214
|
-
}
|
|
2215
|
-
|
|
2216
|
-
const allAgents = await this.scheduler.getAllAgents();
|
|
2217
|
-
const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
|
|
2218
|
-
|
|
2219
|
-
const teamData = {
|
|
2220
|
-
agents: [],
|
|
2221
|
-
aggregatedMetrics: {
|
|
2222
|
-
totalTasks: 0,
|
|
2223
|
-
totalCompleted: 0,
|
|
2224
|
-
averageWorkload: 0,
|
|
2225
|
-
topPerformers: [],
|
|
2226
|
-
bottlenecks: []
|
|
2227
|
-
}
|
|
2228
|
-
};
|
|
2229
|
-
|
|
2230
|
-
// Analyze each agent
|
|
2231
|
-
for (const agent of allAgents) {
|
|
2232
|
-
if (!agent.taskList || !agent.taskList.tasks) continue;
|
|
2233
|
-
|
|
2234
|
-
const tasks = agent.taskList.tasks;
|
|
2235
|
-
const timeframeTasks = tasks.filter(t => new Date(t.createdAt) >= cutoffDate);
|
|
2236
|
-
|
|
2237
|
-
const agentMetrics = {
|
|
2238
|
-
agentId: agent.id,
|
|
2239
|
-
agentName: agent.name,
|
|
2240
|
-
totalTasks: timeframeTasks.length,
|
|
2241
|
-
completed: timeframeTasks.filter(t => t.status === 'completed').length,
|
|
2242
|
-
pending: timeframeTasks.filter(t => t.status === 'pending').length,
|
|
2243
|
-
inProgress: timeframeTasks.filter(t => t.status === 'in_progress').length,
|
|
2244
|
-
workloadScore: this.calculateWorkloadScore(tasks),
|
|
2245
|
-
completionRate: timeframeTasks.length > 0
|
|
2246
|
-
? Math.round((timeframeTasks.filter(t => t.status === 'completed').length / timeframeTasks.length) * 100)
|
|
2247
|
-
: 0
|
|
2248
|
-
};
|
|
2249
|
-
|
|
2250
|
-
teamData.agents.push(agentMetrics);
|
|
2251
|
-
teamData.aggregatedMetrics.totalTasks += agentMetrics.totalTasks;
|
|
2252
|
-
teamData.aggregatedMetrics.totalCompleted += agentMetrics.completed;
|
|
2253
|
-
}
|
|
2254
|
-
|
|
2255
|
-
// Calculate team-level metrics
|
|
2256
|
-
teamData.aggregatedMetrics.teamCompletionRate = teamData.aggregatedMetrics.totalTasks > 0
|
|
2257
|
-
? Math.round((teamData.aggregatedMetrics.totalCompleted / teamData.aggregatedMetrics.totalTasks) * 100)
|
|
2258
|
-
: 0;
|
|
2259
|
-
|
|
2260
|
-
teamData.aggregatedMetrics.averageWorkload = teamData.agents.length > 0
|
|
2261
|
-
? Math.round(teamData.agents.reduce((sum, a) => sum + a.workloadScore, 0) / teamData.agents.length)
|
|
2262
|
-
: 0;
|
|
2263
|
-
|
|
2264
|
-
// Identify top performers and bottlenecks
|
|
2265
|
-
teamData.aggregatedMetrics.topPerformers = teamData.agents
|
|
2266
|
-
.filter(a => a.completionRate >= 80)
|
|
2267
|
-
.sort((a, b) => b.completionRate - a.completionRate)
|
|
2268
|
-
.slice(0, 3);
|
|
2269
|
-
|
|
2270
|
-
teamData.aggregatedMetrics.bottlenecks = teamData.agents
|
|
2271
|
-
.filter(a => a.workloadScore > teamData.aggregatedMetrics.averageWorkload * 1.5)
|
|
2272
|
-
.sort((a, b) => b.workloadScore - a.workloadScore);
|
|
2273
|
-
|
|
2274
|
-
return {
|
|
2275
|
-
teamAnalytics: teamData,
|
|
2276
|
-
workloadDistribution: this.analyzeWorkloadDistribution(teamData.agents),
|
|
2277
|
-
collaborationMetrics: this.analyzeCollaborationMetrics(allAgents)
|
|
2278
|
-
};
|
|
2279
|
-
}
|
|
2280
|
-
|
|
2281
|
-
/**
|
|
2282
|
-
* Export analytics data
|
|
2283
|
-
* @private
|
|
2284
|
-
*/
|
|
2285
|
-
async exportAnalytics(agent, params) {
|
|
2286
|
-
const { format = 'json', includeRawData = false, timeframe = '30' } = params;
|
|
2287
|
-
|
|
2288
|
-
const analyticsData = {
|
|
2289
|
-
metadata: {
|
|
2290
|
-
agentId: agent.id,
|
|
2291
|
-
agentName: agent.name,
|
|
2292
|
-
exportedAt: new Date().toISOString(),
|
|
2293
|
-
timeframe: `${timeframe} days`,
|
|
2294
|
-
format
|
|
2295
|
-
},
|
|
2296
|
-
summary: await this.getAnalyticsSummary(agent, timeframe),
|
|
2297
|
-
performance: await this.getPerformanceMetrics(agent, timeframe),
|
|
2298
|
-
trends: await this.getTrendAnalysis(agent, timeframe)
|
|
2299
|
-
};
|
|
2300
|
-
|
|
2301
|
-
if (includeRawData) {
|
|
2302
|
-
const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
|
|
2303
|
-
analyticsData.rawData = {
|
|
2304
|
-
tasks: agent.taskList.tasks.filter(t => new Date(t.createdAt) >= cutoffDate)
|
|
2305
|
-
};
|
|
2306
|
-
}
|
|
2307
|
-
|
|
2308
|
-
let exportedData;
|
|
2309
|
-
switch (format.toLowerCase()) {
|
|
2310
|
-
case 'json':
|
|
2311
|
-
exportedData = JSON.stringify(analyticsData, null, 2);
|
|
2312
|
-
break;
|
|
2313
|
-
case 'csv':
|
|
2314
|
-
exportedData = this.convertToCSV(analyticsData);
|
|
2315
|
-
break;
|
|
2316
|
-
case 'summary':
|
|
2317
|
-
exportedData = this.generateTextSummary(analyticsData);
|
|
2318
|
-
break;
|
|
2319
|
-
default:
|
|
2320
|
-
throw new Error('Invalid export format. Use: json, csv, or summary');
|
|
2321
|
-
}
|
|
2322
|
-
|
|
2323
|
-
return {
|
|
2324
|
-
exportData: exportedData,
|
|
2325
|
-
format,
|
|
2326
|
-
size: exportedData.length,
|
|
2327
|
-
records: analyticsData.rawData ? analyticsData.rawData.tasks.length : 0
|
|
2328
|
-
};
|
|
2329
|
-
}
|
|
2330
|
-
|
|
2331
|
-
/**
|
|
2332
|
-
* Generate actionable insights
|
|
2333
|
-
* @private
|
|
2334
|
-
*/
|
|
2335
|
-
async generateInsights(agent, timeframe) {
|
|
2336
|
-
const summary = await this.getAnalyticsSummary(agent, timeframe);
|
|
2337
|
-
const performance = await this.getPerformanceMetrics(agent, timeframe);
|
|
2338
|
-
const trends = await this.getTrendAnalysis(agent, timeframe);
|
|
2339
|
-
|
|
2340
|
-
const insights = {
|
|
2341
|
-
productivity: this.generateProductivityInsights(summary, performance, trends),
|
|
2342
|
-
workflow: this.generateWorkflowInsights(summary, performance, trends),
|
|
2343
|
-
optimization: this.generateOptimizationInsights(summary, performance, trends),
|
|
2344
|
-
predictions: this.generatePredictions(trends)
|
|
2345
|
-
};
|
|
2346
|
-
|
|
2347
|
-
return {
|
|
2348
|
-
insights,
|
|
2349
|
-
actionItems: this.generateActionItems(insights),
|
|
2350
|
-
priorities: this.generatePriorityRecommendations(insights)
|
|
2351
|
-
};
|
|
2352
|
-
}
|
|
2353
|
-
|
|
2354
|
-
// Helper methods for analytics calculations
|
|
2355
|
-
|
|
2356
|
-
calculateProgressMetrics(tasks) {
|
|
2357
|
-
const tasksWithProgress = tasks.filter(t => t.progress);
|
|
2358
|
-
if (tasksWithProgress.length === 0) return { averageProgress: 0, stageDistribution: {} };
|
|
2359
|
-
|
|
2360
|
-
const averageProgress = Math.round(
|
|
2361
|
-
tasksWithProgress.reduce((sum, t) => sum + (t.progress.percentage || 0), 0) / tasksWithProgress.length
|
|
2362
|
-
);
|
|
2363
|
-
|
|
2364
|
-
const stageDistribution = {};
|
|
2365
|
-
this.progressStages.forEach(stage => {
|
|
2366
|
-
stageDistribution[stage] = tasksWithProgress.filter(t => t.progress.stage === stage).length;
|
|
2367
|
-
});
|
|
2368
|
-
|
|
2369
|
-
return { averageProgress, stageDistribution };
|
|
2370
|
-
}
|
|
2371
|
-
|
|
2372
|
-
calculateDependencyMetrics(tasks) {
|
|
2373
|
-
const tasksWithDeps = tasks.filter(t => t.dependencies && t.dependencies.length > 0);
|
|
2374
|
-
const blockedTasks = tasks.filter(t => t.status === 'blocked').length;
|
|
2375
|
-
|
|
2376
|
-
return {
|
|
2377
|
-
tasksWithDependencies: tasksWithDeps.length,
|
|
2378
|
-
averageDependencies: tasksWithDeps.length > 0
|
|
2379
|
-
? Math.round(tasksWithDeps.reduce((sum, t) => sum + t.dependencies.length, 0) / tasksWithDeps.length)
|
|
2380
|
-
: 0,
|
|
2381
|
-
blockedTasks,
|
|
2382
|
-
dependencyChainLength: this.calculateMaxDependencyChain(tasks)
|
|
2383
|
-
};
|
|
2384
|
-
}
|
|
2385
|
-
|
|
2386
|
-
calculateTemplateUsage(tasks) {
|
|
2387
|
-
const templateTasks = tasks.filter(t => t.source === 'template-generated');
|
|
2388
|
-
const templateDistribution = {};
|
|
2389
|
-
|
|
2390
|
-
templateTasks.forEach(t => {
|
|
2391
|
-
const templateId = t.templateId || 'unknown';
|
|
2392
|
-
templateDistribution[templateId] = (templateDistribution[templateId] || 0) + 1;
|
|
2393
|
-
});
|
|
2394
|
-
|
|
2395
|
-
return {
|
|
2396
|
-
totalTemplateGenerated: templateTasks.length,
|
|
2397
|
-
templateDistribution,
|
|
2398
|
-
templateEfficiency: this.calculateTemplateEfficiency(templateTasks)
|
|
2399
|
-
};
|
|
2400
|
-
}
|
|
2401
|
-
|
|
2402
|
-
calculateCompletionRate(tasks, timeframe) {
|
|
2403
|
-
const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
|
|
2404
|
-
const timeframeTasks = tasks.filter(t => new Date(t.createdAt) >= cutoffDate);
|
|
2405
|
-
|
|
2406
|
-
return timeframeTasks.length > 0
|
|
2407
|
-
? Math.round((timeframeTasks.filter(t => t.status === 'completed').length / timeframeTasks.length) * 100)
|
|
2408
|
-
: 0;
|
|
2409
|
-
}
|
|
2410
|
-
|
|
2411
|
-
calculateAverageCompletionTime(completedTasks) {
|
|
2412
|
-
if (completedTasks.length === 0) return 0;
|
|
2413
|
-
|
|
2414
|
-
const completionTimes = completedTasks.map(task => {
|
|
2415
|
-
const created = new Date(task.createdAt);
|
|
2416
|
-
const completed = new Date(task.completedAt);
|
|
2417
|
-
return (completed - created) / (1000 * 60 * 60 * 24); // days
|
|
2418
|
-
});
|
|
2419
|
-
|
|
2420
|
-
return Math.round(completionTimes.reduce((sum, time) => sum + time, 0) / completionTimes.length * 10) / 10;
|
|
2421
|
-
}
|
|
2422
|
-
|
|
2423
|
-
generateSummaryInsights(summary) {
|
|
2424
|
-
const insights = [];
|
|
2425
|
-
|
|
2426
|
-
if (summary.completionRate < 50) {
|
|
2427
|
-
insights.push('Completion rate is below 50%. Consider reviewing task prioritization and blocking issues.');
|
|
2428
|
-
}
|
|
2429
|
-
|
|
2430
|
-
if (summary.averageTaskAge > 7) {
|
|
2431
|
-
insights.push(`Tasks are aging (avg: ${summary.averageTaskAge} days). Focus on completing older tasks.`);
|
|
2432
|
-
}
|
|
2433
|
-
|
|
2434
|
-
if (summary.priorityBreakdown.urgent > summary.overview.totalTasks * 0.3) {
|
|
2435
|
-
insights.push('High proportion of urgent tasks. Consider better planning and early issue identification.');
|
|
2436
|
-
}
|
|
2437
|
-
|
|
2438
|
-
return insights;
|
|
2439
|
-
}
|
|
2440
|
-
|
|
2441
|
-
generatePerformanceRecommendations(metrics) {
|
|
2442
|
-
const recommendations = [];
|
|
2443
|
-
|
|
2444
|
-
if (metrics.productivity.completionRate < 70) {
|
|
2445
|
-
recommendations.push('Focus on improving task completion rate through better time management');
|
|
2446
|
-
}
|
|
2447
|
-
|
|
2448
|
-
if (metrics.quality.blockedTasksRate > 20) {
|
|
2449
|
-
recommendations.push('High blocked task rate - review dependency management and resource allocation');
|
|
2450
|
-
}
|
|
2451
|
-
|
|
2452
|
-
if (metrics.efficiency.priorityAccuracy < 60) {
|
|
2453
|
-
recommendations.push('Improve priority setting accuracy by reviewing completed task outcomes');
|
|
2454
|
-
}
|
|
2455
|
-
|
|
2456
|
-
return recommendations;
|
|
2457
|
-
}
|
|
2458
|
-
|
|
2459
|
-
// Additional helper methods for complex calculations
|
|
2460
|
-
calculateWorkloadScore(tasks) {
|
|
2461
|
-
const activeTasks = tasks.filter(t => t.status === 'pending' || t.status === 'in_progress');
|
|
2462
|
-
const urgentCount = activeTasks.filter(t => t.priority === 'urgent').length;
|
|
2463
|
-
const highCount = activeTasks.filter(t => t.priority === 'high').length;
|
|
2464
|
-
|
|
2465
|
-
return urgentCount * 3 + highCount * 2 + activeTasks.length;
|
|
2466
|
-
}
|
|
2467
|
-
|
|
2468
|
-
calculateMaxDependencyChain(tasks) {
|
|
2469
|
-
// Simple implementation - returns the maximum number of dependencies for any task
|
|
2470
|
-
return Math.max(0, ...tasks.map(t => (t.dependencies ? t.dependencies.length : 0)));
|
|
2471
|
-
}
|
|
2472
|
-
|
|
2473
|
-
calculateTemplateEfficiency(templateTasks) {
|
|
2474
|
-
if (templateTasks.length === 0) return 100;
|
|
2475
|
-
const completedTemplateProps = templateTasks.filter(t => t.status === 'completed').length;
|
|
2476
|
-
return Math.round((completedTemplateProps / templateTasks.length) * 100);
|
|
2477
|
-
}
|
|
2478
|
-
|
|
2479
|
-
calculateVelocityTrend(tasks, timeframe) {
|
|
2480
|
-
// Simple velocity calculation based on completed tasks in timeframe
|
|
2481
|
-
const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
|
|
2482
|
-
const completedInTimeframe = tasks.filter(t =>
|
|
2483
|
-
t.status === 'completed' &&
|
|
2484
|
-
t.completedAt &&
|
|
2485
|
-
new Date(t.completedAt) >= cutoffDate
|
|
2486
|
-
).length;
|
|
2487
|
-
|
|
2488
|
-
return Math.round((completedInTimeframe / parseInt(timeframe)) * 7); // tasks per week
|
|
2489
|
-
}
|
|
2490
|
-
|
|
2491
|
-
calculateBlockedTasksRate(tasks) {
|
|
2492
|
-
const activeTasks = tasks.filter(t => t.status !== 'completed' && t.status !== 'cancelled');
|
|
2493
|
-
if (activeTasks.length === 0) return 0;
|
|
2494
|
-
const blockedTasks = tasks.filter(t => t.status === 'blocked').length;
|
|
2495
|
-
return Math.round((blockedTasks / activeTasks.length) * 100);
|
|
2496
|
-
}
|
|
2497
|
-
|
|
2498
|
-
calculateCancelledTasksRate(tasks, timeframe) {
|
|
2499
|
-
const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
|
|
2500
|
-
const timeframeTasks = tasks.filter(t => new Date(t.createdAt) >= cutoffDate);
|
|
2501
|
-
if (timeframeTasks.length === 0) return 0;
|
|
2502
|
-
const cancelledTasks = timeframeTasks.filter(t => t.status === 'cancelled').length;
|
|
2503
|
-
return Math.round((cancelledTasks / timeframeTasks.length) * 100);
|
|
2504
|
-
}
|
|
2505
|
-
|
|
2506
|
-
calculateReworkRate(tasks, timeframe) {
|
|
2507
|
-
// Simple implementation - tasks that moved back to earlier progress stages
|
|
2508
|
-
const cutoffDate = new Date(Date.now() - parseInt(timeframe) * 24 * 60 * 60 * 1000);
|
|
2509
|
-
const timeframeTasks = tasks.filter(t => new Date(t.createdAt) >= cutoffDate);
|
|
2510
|
-
const tasksWithRework = timeframeTasks.filter(t =>
|
|
2511
|
-
t.progress &&
|
|
2512
|
-
t.progress.stageHistory &&
|
|
2513
|
-
t.progress.stageHistory.some(h =>
|
|
2514
|
-
this.progressStages.indexOf(h.to) < this.progressStages.indexOf(h.from)
|
|
2515
|
-
)
|
|
2516
|
-
).length;
|
|
2517
|
-
|
|
2518
|
-
return timeframeTasks.length > 0 ? Math.round((tasksWithRework / timeframeTasks.length) * 100) : 0;
|
|
2519
|
-
}
|
|
2520
|
-
|
|
2521
|
-
calculatePriorityAccuracy(completedTasks) {
|
|
2522
|
-
if (completedTasks.length === 0) return 100;
|
|
2523
|
-
// Simple heuristic: assume urgent/high priority tasks completed faster were accurate
|
|
2524
|
-
const fastCompletedUrgentHigh = completedTasks.filter(t => {
|
|
2525
|
-
if (!['urgent', 'high'].includes(t.priority)) return false;
|
|
2526
|
-
const created = new Date(t.createdAt);
|
|
2527
|
-
const completed = new Date(t.completedAt);
|
|
2528
|
-
const daysToComplete = (completed - created) / (1000 * 60 * 60 * 24);
|
|
2529
|
-
return daysToComplete <= 3; // completed within 3 days
|
|
2530
|
-
}).length;
|
|
2531
|
-
|
|
2532
|
-
const totalUrgentHigh = completedTasks.filter(t => ['urgent', 'high'].includes(t.priority)).length;
|
|
2533
|
-
return totalUrgentHigh > 0 ? Math.round((fastCompletedUrgentHigh / totalUrgentHigh) * 100) : 100;
|
|
2534
|
-
}
|
|
2535
|
-
|
|
2536
|
-
calculateDependencyEfficiency(tasks) {
|
|
2537
|
-
const tasksWithDeps = tasks.filter(t => t.dependencies && t.dependencies.length > 0);
|
|
2538
|
-
if (tasksWithDeps.length === 0) return 100;
|
|
2539
|
-
|
|
2540
|
-
const efficientTasks = tasksWithDeps.filter(t => t.status !== 'blocked').length;
|
|
2541
|
-
return Math.round((efficientTasks / tasksWithDeps.length) * 100);
|
|
2542
|
-
}
|
|
2543
|
-
|
|
2544
|
-
calculateProgressConsistency(tasks) {
|
|
2545
|
-
const tasksWithProgress = tasks.filter(t => t.progress && t.progress.percentage !== undefined);
|
|
2546
|
-
if (tasksWithProgress.length === 0) return 100;
|
|
2547
|
-
|
|
2548
|
-
// Simple heuristic: tasks with progress matching their stage
|
|
2549
|
-
const consistentTasks = tasksWithProgress.filter(t => {
|
|
2550
|
-
const stage = t.progress.stage;
|
|
2551
|
-
const percentage = t.progress.percentage;
|
|
2552
|
-
|
|
2553
|
-
if (stage === 'not_started' && percentage === 0) return true;
|
|
2554
|
-
if (stage === 'planning' && percentage > 0 && percentage < 25) return true;
|
|
2555
|
-
if (stage === 'in_development' && percentage >= 25 && percentage < 75) return true;
|
|
2556
|
-
if (stage === 'testing' && percentage >= 75 && percentage < 95) return true;
|
|
2557
|
-
if (stage === 'review' && percentage >= 95 && percentage < 100) return true;
|
|
2558
|
-
if (stage === 'completed' && percentage === 100) return true;
|
|
2559
|
-
|
|
2560
|
-
return false;
|
|
2561
|
-
}).length;
|
|
2562
|
-
|
|
2563
|
-
return Math.round((consistentTasks / tasksWithProgress.length) * 100);
|
|
2564
|
-
}
|
|
2565
|
-
|
|
2566
|
-
calculateDailyTrends(tasks, days) {
|
|
2567
|
-
const trends = [];
|
|
2568
|
-
for (let i = 0; i < days; i++) {
|
|
2569
|
-
const date = new Date(Date.now() - i * 24 * 60 * 60 * 1000);
|
|
2570
|
-
const dayStart = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
2571
|
-
const dayEnd = new Date(dayStart.getTime() + 24 * 60 * 60 * 1000);
|
|
2572
|
-
|
|
2573
|
-
const dayTasks = tasks.filter(t => {
|
|
2574
|
-
const created = new Date(t.createdAt);
|
|
2575
|
-
return created >= dayStart && created < dayEnd;
|
|
2576
|
-
});
|
|
2577
|
-
|
|
2578
|
-
trends.unshift({
|
|
2579
|
-
date: dayStart.toISOString().split('T')[0],
|
|
2580
|
-
created: dayTasks.length,
|
|
2581
|
-
completed: dayTasks.filter(t => t.status === 'completed').length
|
|
2582
|
-
});
|
|
2583
|
-
}
|
|
2584
|
-
return trends;
|
|
2585
|
-
}
|
|
2586
|
-
|
|
2587
|
-
calculateWeeklyTrends(tasks, days) {
|
|
2588
|
-
const weeks = Math.ceil(days / 7);
|
|
2589
|
-
const trends = [];
|
|
2590
|
-
|
|
2591
|
-
for (let i = 0; i < weeks; i++) {
|
|
2592
|
-
const weekStart = new Date(Date.now() - (i + 1) * 7 * 24 * 60 * 60 * 1000);
|
|
2593
|
-
const weekEnd = new Date(Date.now() - i * 7 * 24 * 60 * 60 * 1000);
|
|
2594
|
-
|
|
2595
|
-
const weekTasks = tasks.filter(t => {
|
|
2596
|
-
const created = new Date(t.createdAt);
|
|
2597
|
-
return created >= weekStart && created < weekEnd;
|
|
2598
|
-
});
|
|
2599
|
-
|
|
2600
|
-
trends.unshift({
|
|
2601
|
-
week: `Week ${weeks - i}`,
|
|
2602
|
-
created: weekTasks.length,
|
|
2603
|
-
completed: weekTasks.filter(t => t.status === 'completed').length
|
|
2604
|
-
});
|
|
2605
|
-
}
|
|
2606
|
-
return trends;
|
|
2607
|
-
}
|
|
2608
|
-
|
|
2609
|
-
calculatePriorityTrends(tasks, days) {
|
|
2610
|
-
const cutoffDate = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
|
|
2611
|
-
const timeframeTasks = tasks.filter(t => new Date(t.createdAt) >= cutoffDate);
|
|
2612
|
-
|
|
2613
|
-
return {
|
|
2614
|
-
urgent: timeframeTasks.filter(t => t.priority === 'urgent').length,
|
|
2615
|
-
high: timeframeTasks.filter(t => t.priority === 'high').length,
|
|
2616
|
-
medium: timeframeTasks.filter(t => t.priority === 'medium').length,
|
|
2617
|
-
low: timeframeTasks.filter(t => t.priority === 'low').length
|
|
2618
|
-
};
|
|
2619
|
-
}
|
|
2620
|
-
|
|
2621
|
-
calculateProgressTrends(tasks, days) {
|
|
2622
|
-
const cutoffDate = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
|
|
2623
|
-
const timeframeTasks = tasks.filter(t => new Date(t.createdAt) >= cutoffDate);
|
|
2624
|
-
const tasksWithProgress = timeframeTasks.filter(t => t.progress);
|
|
2625
|
-
|
|
2626
|
-
const stageTrends = {};
|
|
2627
|
-
this.progressStages.forEach(stage => {
|
|
2628
|
-
stageTrends[stage] = tasksWithProgress.filter(t => t.progress.stage === stage).length;
|
|
2629
|
-
});
|
|
2630
|
-
|
|
2631
|
-
return stageTrends;
|
|
2632
|
-
}
|
|
2633
|
-
|
|
2634
|
-
generateForecasts(trends) {
|
|
2635
|
-
return {
|
|
2636
|
-
predictedCompletions: this.predictFutureCompletions(trends.daily),
|
|
2637
|
-
workloadForecast: this.predictWorkloadTrend(trends.weekly),
|
|
2638
|
-
priorityShift: this.predictPriorityShift(trends.priorityTrends)
|
|
2639
|
-
};
|
|
2640
|
-
}
|
|
2641
|
-
|
|
2642
|
-
identifyPatterns(trends) {
|
|
2643
|
-
return {
|
|
2644
|
-
peakDays: this.identifyPeakActivityDays(trends.daily),
|
|
2645
|
-
cyclicalPatterns: this.identifyCyclicalPatterns(trends.weekly),
|
|
2646
|
-
priorityPatterns: this.identifyPriorityPatterns(trends.priorityTrends)
|
|
2647
|
-
};
|
|
2648
|
-
}
|
|
2649
|
-
|
|
2650
|
-
// Simplified implementations for missing complex methods
|
|
2651
|
-
predictFutureCompletions(dailyTrends) {
|
|
2652
|
-
if (dailyTrends.length < 7) return 'Insufficient data';
|
|
2653
|
-
const recentAvg = dailyTrends.slice(-7).reduce((sum, day) => sum + day.completed, 0) / 7;
|
|
2654
|
-
return `${Math.round(recentAvg)} tasks/day predicted`;
|
|
2655
|
-
}
|
|
2656
|
-
|
|
2657
|
-
predictWorkloadTrend(weeklyTrends) {
|
|
2658
|
-
if (weeklyTrends.length < 2) return 'Stable';
|
|
2659
|
-
const recent = weeklyTrends[weeklyTrends.length - 1].created;
|
|
2660
|
-
const previous = weeklyTrends[weeklyTrends.length - 2].created;
|
|
2661
|
-
const change = ((recent - previous) / previous) * 100;
|
|
2662
|
-
|
|
2663
|
-
if (change > 20) return 'Increasing workload';
|
|
2664
|
-
if (change < -20) return 'Decreasing workload';
|
|
2665
|
-
return 'Stable workload';
|
|
2666
|
-
}
|
|
2667
|
-
|
|
2668
|
-
predictPriorityShift(priorityTrends) {
|
|
2669
|
-
const total = Object.values(priorityTrends).reduce((sum, count) => sum + count, 0);
|
|
2670
|
-
if (total === 0) return 'No priority data';
|
|
2671
|
-
|
|
2672
|
-
const urgentPercent = (priorityTrends.urgent / total) * 100;
|
|
2673
|
-
if (urgentPercent > 30) return 'High urgent task ratio - plan for capacity';
|
|
2674
|
-
return 'Balanced priority distribution';
|
|
2675
|
-
}
|
|
2676
|
-
|
|
2677
|
-
identifyPeakActivityDays(dailyTrends) {
|
|
2678
|
-
const maxCreated = Math.max(...dailyTrends.map(d => d.created));
|
|
2679
|
-
return dailyTrends.filter(d => d.created === maxCreated).map(d => d.date);
|
|
2680
|
-
}
|
|
2681
|
-
|
|
2682
|
-
identifyCyclicalPatterns(weeklyTrends) {
|
|
2683
|
-
if (weeklyTrends.length < 4) return 'Insufficient data for pattern analysis';
|
|
2684
|
-
return 'Weekly patterns detected - further analysis available';
|
|
2685
|
-
}
|
|
2686
|
-
|
|
2687
|
-
identifyPriorityPatterns(priorityTrends) {
|
|
2688
|
-
const total = Object.values(priorityTrends).reduce((sum, count) => sum + count, 0);
|
|
2689
|
-
if (total === 0) return 'No priority patterns';
|
|
2690
|
-
|
|
2691
|
-
const dominant = Object.entries(priorityTrends).reduce((max, [priority, count]) =>
|
|
2692
|
-
count > max.count ? { priority, count } : max, { priority: '', count: 0 }
|
|
2693
|
-
);
|
|
2694
|
-
|
|
2695
|
-
return `${dominant.priority} priority tasks dominate (${Math.round((dominant.count / total) * 100)}%)`;
|
|
2696
|
-
}
|
|
2697
|
-
|
|
2698
|
-
generateProductivityInsights(summary, performance, trends) {
|
|
2699
|
-
const insights = [];
|
|
2700
|
-
|
|
2701
|
-
if (performance.metrics.productivity.completionRate > 80) {
|
|
2702
|
-
insights.push('High productivity - excellent task completion rate');
|
|
2703
|
-
} else if (performance.metrics.productivity.completionRate < 50) {
|
|
2704
|
-
insights.push('Low productivity - focus on task completion strategies');
|
|
2705
|
-
}
|
|
2706
|
-
|
|
2707
|
-
if (summary.summary.averageTaskAge > 10) {
|
|
2708
|
-
insights.push('Tasks are aging significantly - prioritize older tasks');
|
|
2709
|
-
}
|
|
2710
|
-
|
|
2711
|
-
return insights;
|
|
2712
|
-
}
|
|
2713
|
-
|
|
2714
|
-
generateWorkflowInsights(summary, performance, trends) {
|
|
2715
|
-
const insights = [];
|
|
2716
|
-
|
|
2717
|
-
if (summary.summary.dependencyMetrics.blockedTasks > 3) {
|
|
2718
|
-
insights.push('Multiple blocked tasks - review dependency management');
|
|
2719
|
-
}
|
|
2720
|
-
|
|
2721
|
-
if (summary.summary.templateUsage.totalTemplateGenerated > summary.summary.overview.totalTasks * 0.5) {
|
|
2722
|
-
insights.push('Heavy template usage - consider workflow optimization');
|
|
2723
|
-
}
|
|
2724
|
-
|
|
2725
|
-
return insights;
|
|
2726
|
-
}
|
|
2727
|
-
|
|
2728
|
-
generateOptimizationInsights(summary, performance, trends) {
|
|
2729
|
-
const insights = [];
|
|
2730
|
-
|
|
2731
|
-
if (performance.metrics.efficiency.priorityAccuracy < 70) {
|
|
2732
|
-
insights.push('Priority setting needs improvement - review task urgency assessment');
|
|
2733
|
-
}
|
|
2734
|
-
|
|
2735
|
-
if (performance.metrics.quality.blockedTasksRate > 15) {
|
|
2736
|
-
insights.push('High blocked task rate - optimize dependency planning');
|
|
2737
|
-
}
|
|
2738
|
-
|
|
2739
|
-
return insights;
|
|
2740
|
-
}
|
|
2741
|
-
|
|
2742
|
-
generatePredictions(trends) {
|
|
2743
|
-
return [
|
|
2744
|
-
trends.forecasts.predictedCompletions,
|
|
2745
|
-
trends.forecasts.workloadForecast,
|
|
2746
|
-
trends.forecasts.priorityShift
|
|
2747
|
-
];
|
|
2748
|
-
}
|
|
2749
|
-
|
|
2750
|
-
generateActionItems(insights) {
|
|
2751
|
-
const allInsights = [
|
|
2752
|
-
...insights.productivity,
|
|
2753
|
-
...insights.workflow,
|
|
2754
|
-
...insights.optimization
|
|
2755
|
-
];
|
|
2756
|
-
|
|
2757
|
-
return allInsights.map((insight, index) => ({
|
|
2758
|
-
id: `action-${index + 1}`,
|
|
2759
|
-
description: insight,
|
|
2760
|
-
priority: insight.includes('urgent') || insight.includes('critical') ? 'high' : 'medium',
|
|
2761
|
-
category: insight.includes('productivity') ? 'productivity' :
|
|
2762
|
-
insight.includes('workflow') ? 'workflow' : 'optimization'
|
|
2763
|
-
}));
|
|
2764
|
-
}
|
|
2765
|
-
|
|
2766
|
-
generatePriorityRecommendations(insights) {
|
|
2767
|
-
const recommendations = [];
|
|
2768
|
-
|
|
2769
|
-
if (insights.productivity.some(i => i.includes('Low productivity'))) {
|
|
2770
|
-
recommendations.push({
|
|
2771
|
-
priority: 'urgent',
|
|
2772
|
-
action: 'Focus on task completion strategies',
|
|
2773
|
-
impact: 'high'
|
|
2774
|
-
});
|
|
2775
|
-
}
|
|
2776
|
-
|
|
2777
|
-
if (insights.workflow.some(i => i.includes('blocked tasks'))) {
|
|
2778
|
-
recommendations.push({
|
|
2779
|
-
priority: 'high',
|
|
2780
|
-
action: 'Review and resolve task dependencies',
|
|
2781
|
-
impact: 'medium'
|
|
2782
|
-
});
|
|
2783
|
-
}
|
|
2784
|
-
|
|
2785
|
-
return recommendations;
|
|
2786
|
-
}
|
|
2787
|
-
|
|
2788
|
-
analyzeWorkloadDistribution(agents) {
|
|
2789
|
-
if (agents.length === 0) return { balance: 'No agents', distribution: [] };
|
|
2790
|
-
|
|
2791
|
-
const workloads = agents.map(a => a.workloadScore);
|
|
2792
|
-
const avg = workloads.reduce((sum, w) => sum + w, 0) / workloads.length;
|
|
2793
|
-
const maxDeviation = Math.max(...workloads.map(w => Math.abs(w - avg)));
|
|
2794
|
-
|
|
2795
|
-
return {
|
|
2796
|
-
balance: maxDeviation > avg * 0.5 ? 'Unbalanced' : 'Balanced',
|
|
2797
|
-
distribution: agents.map(a => ({
|
|
2798
|
-
agent: a.agentName,
|
|
2799
|
-
workload: a.workloadScore,
|
|
2800
|
-
deviation: Math.round(((a.workloadScore - avg) / avg) * 100)
|
|
2801
|
-
}))
|
|
2802
|
-
};
|
|
2803
|
-
}
|
|
2804
|
-
|
|
2805
|
-
analyzeCollaborationMetrics(allAgents) {
|
|
2806
|
-
return {
|
|
2807
|
-
totalAgents: allAgents.length,
|
|
2808
|
-
activeAgents: allAgents.filter(a => a.taskList && a.taskList.tasks.length > 0).length,
|
|
2809
|
-
collaborationScore: Math.round(Math.random() * 100) // Simplified - would analyze shared dependencies
|
|
2810
|
-
};
|
|
2811
|
-
}
|
|
2812
|
-
|
|
2813
|
-
convertToCSV(analyticsData) {
|
|
2814
|
-
// Simplified CSV export
|
|
2815
|
-
const headers = ['Metric', 'Value'];
|
|
2816
|
-
const rows = [
|
|
2817
|
-
['Total Tasks', analyticsData.summary.summary.overview.totalTasks],
|
|
2818
|
-
['Completed Tasks', analyticsData.summary.summary.overview.completed],
|
|
2819
|
-
['Completion Rate', `${analyticsData.summary.summary.completionRate}%`],
|
|
2820
|
-
['Average Task Age', `${analyticsData.summary.summary.averageTaskAge} days`]
|
|
2821
|
-
];
|
|
2822
|
-
|
|
2823
|
-
return [headers, ...rows].map(row => row.join(',')).join('\n');
|
|
2824
|
-
}
|
|
2825
|
-
|
|
2826
|
-
generateTextSummary(analyticsData) {
|
|
2827
|
-
const summary = analyticsData.summary.summary;
|
|
2828
|
-
return `
|
|
2829
|
-
Analytics Summary
|
|
2830
|
-
================
|
|
2831
|
-
Total Tasks: ${summary.overview.totalTasks}
|
|
2832
|
-
Completed: ${summary.overview.completed} (${summary.completionRate}%)
|
|
2833
|
-
In Progress: ${summary.overview.inProgress}
|
|
2834
|
-
Pending: ${summary.overview.pending}
|
|
2835
|
-
Average Task Age: ${summary.averageTaskAge} days
|
|
2836
|
-
|
|
2837
|
-
Key Insights:
|
|
2838
|
-
${analyticsData.summary.insights.map(insight => `- ${insight}`).join('\n')}
|
|
2839
|
-
`.trim();
|
|
2840
|
-
}
|
|
2841
|
-
|
|
2842
|
-
/**
|
|
2843
|
-
* Format tool result for display
|
|
2844
|
-
* @param {Object} result - Tool execution result
|
|
2845
|
-
* @returns {string} Formatted result
|
|
2846
|
-
*/
|
|
2847
|
-
formatResult(result) {
|
|
2848
|
-
if (!result.success) {
|
|
2849
|
-
return `TaskManager Error: ${result.error}`;
|
|
2850
|
-
}
|
|
2851
|
-
|
|
2852
|
-
const lines = [`TaskManager: ${result.action} completed`];
|
|
2853
|
-
|
|
2854
|
-
if (result.result.task) {
|
|
2855
|
-
lines.push(`Task: [${result.result.task.status}] ${result.result.task.title} (${result.result.task.id})`);
|
|
2856
|
-
}
|
|
2857
|
-
|
|
2858
|
-
if (result.result.tasks) {
|
|
2859
|
-
lines.push(`Found ${result.result.tasks.length} tasks:`);
|
|
2860
|
-
result.result.tasks.forEach(task => {
|
|
2861
|
-
lines.push(` - [${task.status}] ${task.title} (Priority: ${task.priority})`);
|
|
2862
|
-
});
|
|
2863
|
-
}
|
|
2864
|
-
|
|
2865
|
-
if (result.summary) {
|
|
2866
|
-
lines.push(`Summary: ${result.summary.pending} pending, ${result.summary.in_progress} in progress, ${result.summary.completed} completed`);
|
|
2867
|
-
}
|
|
2868
|
-
|
|
2869
|
-
return lines.join('\n');
|
|
2870
|
-
}
|
|
2871
|
-
}
|
|
2872
|
-
|
|
2873
|
-
export default TaskManagerTool;
|
|
1
|
+
const a0_0x40f7e7=a0_0x2f3d;(function(_0x2eb84c,_0x375092){const _0x344ce2=a0_0x2f3d,_0x5de506=_0x2eb84c();while(!![]){try{const _0x1e6d18=parseInt(_0x344ce2(0x275))/0x1+parseInt(_0x344ce2(0x20b))/0x2*(parseInt(_0x344ce2(0x12d))/0x3)+parseInt(_0x344ce2(0x193))/0x4+-parseInt(_0x344ce2(0x258))/0x5*(-parseInt(_0x344ce2(0x265))/0x6)+-parseInt(_0x344ce2(0x260))/0x7+parseInt(_0x344ce2(0x21b))/0x8*(parseInt(_0x344ce2(0x221))/0x9)+-parseInt(_0x344ce2(0x15d))/0xa;if(_0x1e6d18===_0x375092)break;else _0x5de506['push'](_0x5de506['shift']());}catch(_0x42fd5d){_0x5de506['push'](_0x5de506['shift']());}}}(a0_0x996e,0x7f593));import{BaseTool}from'./baseTool.js';import{v4 as a0_0x592b6c}from'uuid';function a0_0x2f3d(_0x4faeec,_0x1b6e4e){_0x4faeec=_0x4faeec-0x127;const _0x996eb6=a0_0x996e();let _0x2f3d9c=_0x996eb6[_0x4faeec];if(a0_0x2f3d['GmpnCE']===undefined){var _0x193184=function(_0x2dd54b){const _0xa3c588='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x592b6c='',_0x404716='';for(let _0x484ed5=0x0,_0x173833,_0x263a35,_0x583eff=0x0;_0x263a35=_0x2dd54b['charAt'](_0x583eff++);~_0x263a35&&(_0x173833=_0x484ed5%0x4?_0x173833*0x40+_0x263a35:_0x263a35,_0x484ed5++%0x4)?_0x592b6c+=String['fromCharCode'](0xff&_0x173833>>(-0x2*_0x484ed5&0x6)):0x0){_0x263a35=_0xa3c588['indexOf'](_0x263a35);}for(let _0x598f6c=0x0,_0x19c5c9=_0x592b6c['length'];_0x598f6c<_0x19c5c9;_0x598f6c++){_0x404716+='%'+('00'+_0x592b6c['charCodeAt'](_0x598f6c)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x404716);};a0_0x2f3d['cqkRAb']=_0x193184,a0_0x2f3d['xyaaGM']={},a0_0x2f3d['GmpnCE']=!![];}const _0x57026a=_0x996eb6[0x0],_0x35a2aa=_0x4faeec+_0x57026a,_0x4fe108=a0_0x2f3d['xyaaGM'][_0x35a2aa];return!_0x4fe108?(_0x2f3d9c=a0_0x2f3d['cqkRAb'](_0x2f3d9c),a0_0x2f3d['xyaaGM'][_0x35a2aa]=_0x2f3d9c):_0x2f3d9c=_0x4fe108,_0x2f3d9c;}function a0_0x996e(){const _0x30fb4a=['Bwv0CMLJCW','ndu2nJa3mNjfAvLUuW','y2fSy3vSyxrLrgvWzw5Kzw5JEu1LDhjPy3m','ihrHC2TZigfYzsbIBg9JA2vKlIbszxzPzxCGzgvWzw5Kzw5JAwvZihrVihvUyMXVy2SGChjVz3jLC3mU','zw50CMLLCW','DhjPBq','mteYmdi2r3vOzvzk','C3rHBgXLzf9WCM9NCMvZCW','DxbKyxrLzef0','ChjLzgLJDfbYAw9YAxr5u2HPzNq','Dg9mB3DLCKnHC2u','BwLSzxn0B25Llq','Aw50zwXSAwDLBNrqCMLVCML0AxPHDgLVBG','ChjLzgLJDgvKq29TCgXLDgLVBNm','vgfZA3mGyxjLigfNAw5NicHHDMC6ia','vgfZAYbTyw5Hz2vTzw50ihrVB2WGzM9Yig9Yz2fUAxPPBMCGyw5KihrYywnRAw5NihDVCMS','ywDLBNrZ','rxjYB3iGsgfUzgXPBMCGjIbszxrYEsbmB2DPyW','y2fSy3vSyxrLzfbLCMnLBNrHz2u','D29YA2zSB3C','CxvHBgL0Eq','ChjPB3jPDhLszwfZB24','nJu0mdu5Ew1Rr1zy','BwLSzxn0B25L','Dg90ywXuyxnRCW','u3rHBMrHCMqGD29YA2zSB3CGzM9YigLUDgvNCMf0Aw5NihDPDgGGzxH0zxjUywWGqvbjCW','y291BNq','z2vUzxjHDgvby3rPB25jDgvTCW','AwrLBNrPzNLqCMLVCML0EvbHDhrLCM5Z','tgfYz2uGChjVAMvJDcb3AxrOig1PEgvKihbYAw9YAxrPzxmGC3vNz2vZDhmGD2vIigfWCcbKzxzLBg9WBwvUDa','y2fUy2vSvgfZAW','C3LUyW','tM8GDgfZAYbjrcbWCM92AwrLzcbHBMqGBM8GAw4TChjVz3jLC3mGDgfZA3mGzM91BMqGDg8Gy29TCgXLDgu','AgLNAa','B3jPz2LUywXqCMLVCML0Eq','DgfZA1bYAw9YAxrPzxm','y29TCgXLDgvK','CMvSyxrLvgfZAW','CMvWBgfJzq','vgfZAYbSAxn0ihn5BMnOCM9UAxPLzcbZDwnJzxnZzNvSBhK','vgfZA01HBMfNzxiGrxjYB3i6ia','CMv2Awv3x3bVAw50','uhjVz3jLC3mGDhjHy2TPBMCGy29TCgXLDgvKicG','z2vUzxjHDgvuzxH0u3vTBwfYEq','vgfZAYbjrcbPCYbYzxf1AxjLza','zNvUy3rPB24','zgv2zwXVCg1LBNq','vgfZAYbUB3qGzM91BMq6ia','CgfYC2u','mtvqywzTyNG','DgvZDgLUzW','D2vLA2X5','sw1WBgvTzw50ihrOzsbIDwCGzML4ihDPDgGGBwLUAw1HBcbZAwrLigvMzMvJDhm','D29YA2XVywrgB3jLy2fZDa','DxbKyxrLvgfZAW','ChjVz3jLC3ntDgfNzxm','tg93ihbYB2r1y3rPDML0EsaTigzVy3vZig9UihrHC2SGy29TCgXLDgLVBIbZDhjHDgvNAwvZ','BM90zq','iI4GtxvZDcbIztOG','u3vTBwfYEtOG','z2vUzxjHDgvxB3jRzMXVD0LUC2LNAhrZ','CMvSyxrLCW','z2v0qw5HBhL0AwnZu3vTBwfYEq','z2vUzxjHDgvgB3jLy2fZDhm','Dg90ywXdB21WBgv0zwq','CgvUzgLUzW','qNvPBgqGDxnLCIbPBNrLCMzHy2uGyw5KigLUDgvNCMf0zsb3AxrOigjHy2TLBMq','z2vUzxjHDgvjBNnPz2H0CW','igrHExm','yxbWBhLuzw1WBgf0zq','DgLTzxn0yw1W','z2vUzxjHDgvqzxjMB3jTyw5JzvjLy29TBwvUzgf0Aw9UCW','yNLtDgf0Dxm','y2f0zwDVCNK','zMLUza','zgvWzw5Kzw5JEvr5CgvZ','CMv2Awv3','DgfZA1rLBxbSyxrLCW','Dg9WugvYzM9YBwvYCW','y2fSy3vSyxrLvgfZA1bYB2DYzxnZ','sw52ywXPzcbWCM9NCMvZCYbTB2rLlIbvC2u6ihvWzgf0zsWGB3zLCNzPzxCSig1PBgvZDg9UzxmSig9YignHBgn1Bgf0zq','BwvZC2fNzq','ChjPB3jPDhLtAgLMDa','Bwf4','sw5ZDwzMAwnPzw50igrHDge','ywDNCMvNyxrLze1LDhjPy3m','Aw5JBhvKzxm','sw1WCM92zsbWCMLVCML0EsbZzxr0Aw5NigfJy3vYywn5igj5ihjLDMLLD2LUzYbJB21WBgv0zwqGDgfZAYbVDxrJB21LCW','y29TCgXLDgLVBLjHDgu','vgfZAZOGwW','z2v0tw9UDgG','vg90ywWGvgfZA3m','rM9JDxmGB24GDgfZAYbJB21WBgv0Aw9Uihn0CMf0zwDPzxm','y2XLyxjdB21WBgv0zwruyxnRCW','Dg9tDhjPBMC','ihrHC2TZoG','sw5JCMvHC2LUzYb3B3jRBg9Hza','mtm3ntmZnJbKD3DpBvi','DxnLCI1JCMvHDgvK','ChjPB3jPDhLxzwLNAhrZ','C3rHz2viAxn0B3j5','vgvZDgLUzYaMifzLCMLMAwnHDgLVBG','DgvTCgXHDguTz2vUzxjHDgvK','zxHWB3j0qw5HBhL0AwnZ','C3vIDgfZAW','C29Tzq','C3LUy1rHC2TZ','BwfW','C3vNz2vZDa','y3vZDg9TvgvTCgXHDgvZ','BM90zs0','yw5HBhL6zvrHC2TqCMLVCML0Eq','DMfSDwvZ','yMXVy2TLzcb0yxnRCW','vgfZA3mGyxjYyxKGy2fUBM90igjLigvTChr5','z2vUzxjHDgvuyxnRu3vTBwfYEq','sw52ywXPzcb0yxnRCYbku09ooIa','z2v0vgvHBufUywX5DgLJCW','vgvZDgLUzYaMiff1ywXPDhKGqxnZDxjHBMnL','yMXVy2TZ','y2fSy3vSyxrLuhjPB3jPDhLuCMvUzhm','yMfSyw5Jzq','yw5HBhL0AwnZ','z2vUzxjHDgvqCM9NCMvZC1jLy29TBwvUzgf0Aw9UCW','y2fUy2vSBgvK','ChjVz3jLC3m','vgvZDgLUzYaMifzHBgLKyxrPB24','C3vNz2vZDfrLBxbSyxrLCW','BM90x3n0yxj0zwq','vgfZAYb0AxrSzsbPCYbYzxf1AxjLza','ChjPB3jPDhLty29Yzq','ywDLBNrjza','C3vIC3rY','y2fSy3vSyxrL','C21HBgW','CMfUzg9T','vgfZAYbJB21WBgv0zwqGC3vJy2vZC2z1BgX5','z2vUzxjHDgvpChrPBwL6yxrPB25jBNnPz2H0CW','rgf0ywjHC2uGrgvZAwDUicyGu2v0Dxa','sw52ywXPzcbWCM9NCMvZCYbZDgfNztOG','rgvZAwDUicyGqxjJAgL0zwn0DxjL','B2jQzwn0','ihbLBMrPBMCSia','v3jPDguGyw5Kihj1BIb1BML0ihrLC3rZlcbPBNrLz3jHDgLVBIb0zxn0CYWGyw5KihbLCMzVCM0Guue','rNjVBNrLBMqGsw1WBgvTzw50yxrPB24','qxzLCMfNzsbuyxnRiefNzq','y2fSy3vSyxrLvgvTCgXHDgvvC2fNzq','z2v0qwXSqwDLBNrZ','rgvZAwDUihn5C3rLBsbHCMnOAxrLy3r1CMuGyw5KihvZzxiGAw50zxjMywnL','zMLSDgvY','zM9YzwnHC3rZ','otiWmti4vKPktgnI','AxnbCNjHEq','y2fSy3vSyxrLuhjVz3jLC3nnzxrYAwnZ','ChjPB3jPDhLcCMvHA2rVD24','BwfUywDLvgvTCgXHDgvZ','sw52ywXPzcbWCMLVCML0EtOG','C3vTBwfYEq','DMfSDwu','C3rHDhvZ','BwvKAxvT','y2fSy3vSyxrLq2fUy2vSBgvKvgfZA3nsyxrL','y2fSy3vSyxrLuhjPB3jPDhLty29Yzq','zwzMAwnPzw5JEq','ugfYzw50ihrHC2SGBM90igzVDw5KoIa','y2fSy3vSyxrLvgvTCgXHDgvfzMzPy2LLBMn5','C3vIDgfZA3m','y2vPBa','zNjVBq','CMf3rgf0yq','ChvZAa','D2fYBMLUzW','B3zLCMfSBf9WCM9NCMvZCW','y2fSy3vSyxrLv29YA2XVywrty29Yzq','C3rYAw5N','DgfZAW','sw1WBgvTzw50ifjfu1qGqvbjigvUzhbVAw50CYbHBMqGyNvZAw5LC3mGBg9NAwm','y29TCgXLDgvKqxq','y2fSy3vSyxrLuMv3B3jRuMf0zq','y3jLyxrL','ChjLzgLJDfDVCMTSB2fKvhjLBMq','CgvYy2vUDgfNzq','z2vUzxjHDgvqCMLVCML0EvjLyxnVBG','y2fSy3vSyxrLtwf4rgvWzw5Kzw5JEunOywLU','z2v0u3rHz2vgCM9TugvYy2vUDgfNzq','lIbtDxbWB3j0zwq6ia','D2fYBG','vgfZAYbJyw5JzwXSzwqGC3vJy2vZC2z1BgX5','yxbWBhK','cLrHC2SGtwfUywDLCIbuB29SoIbpCMDHBML6zsbHBMqGDhjHy2SGD29YAYb3AxrOifrpre8GBgLZDhmGzM9YigfNzw50lw1VzguGC2nOzwr1BgLUzY4kcIOQq1jjveLdquWGrK9siefhru5uie1preuQkJOGww91ie1vu1qGBwfPBNrHAw4GEw91CIb0yxnRigXPC3qGDg8GCMvTywLUigfJDgL2zsbPBIbHz2vUDcbTB2rLiqOkvgHLifrHC2Tnyw5Hz2vYihrVB2WGywXSB3DZihLVDsb0BYbVCMDHBML6zsbHBMqGDhjHy2SGEw91CIb3B3jRlIbxAxrOB3v0ihrHC2TZlcb5B3uGD2LSBcbUB3qGCMvJzwL2zsbZy2HLzhvSAw5NihrPBwuUcGOJiYmGqwn0Aw9UCZOklsaQkNn5BMmQkJOG8j+mNYbsrunptu1ftKrfrcaTie1HBMfNzsbLBNrPCMuGDgfZAYbSAxn0igf0ig9Uy2uGkenSyxvKzsbdB2rLihn0EwXLkqOTicOQy3jLyxrLkIO6ienYzwf0zsbHig5LDYb0yxnRihDPDgGGDgL0BguGyw5KigrLC2nYAxb0Aw9UcI0GkIP1CgrHDguQkJOGvxbKyxrLihrHC2SGC3rHDhvZig9YihbYB3bLCNrPzxmklsaQkMXPC3qQkJOGtgLZDcbHBgWGDgfZA3mGD2L0Acb0AgvPCIbJDxjYzw50ihn0yxr1CWOTicOQy29TCgXLDguQkJOGtwfYAYbHihrHC2SGyxmGy29TCgXLDgvKcI0GkIPJyw5JzwWQkJOGq2fUy2vSigeGDgfZAYaOBwfYAYbHCYbPCNjLBgv2yw50kqOTicOQy2XLyxiQkJOGq2XLyxiGywXSignVBxbSzxrLzc9Jyw5JzwXSzwqGDgfZA3mklsaQkMrLCgvUzcOQoIbdCMvHDguGzgvWzw5Kzw5JEsbIzxr3zwvUihrHC2TZicHIBg9JA2LUzYbYzwXHDgLVBNnOAxbZkqOTicOQCMvSyxrLkIO6ieXPBMSGCMvSyxrLzcb0yxnRCYaOBM9UlwjSB2nRAw5NigfZC29JAwf0Aw9UCYKklsaQkNn1yNrHC2SQkJOGq3jLyxrLihn1yNrHC2SGCMvSyxrPB25ZAgLWCYaOCgfYzw50lwnOAwXKigHPzxjHCMnOEsKklsaQkNbYAw9YAxrPEMuQkJOGsw50zwXSAwDLBNqGDgfZAYbWCMLVCML0AxPHDgLVBIb3AxrOig11BhrPCgXLig1VzgvZcI0GkIP0zw1WBgf0zsOQoIbuzw1WBgf0zsbTyw5Hz2vTzw50igzVCIbJB21TB24GD29YA2zSB3DZcI0GkIPWCM9NCMvZCYOQoIbuCMfJAYb0yxnRihbYB2DYzxnZihDPDgGGC3rHz2vZlcbTAwXLC3rVBMvZlcbHBMqGBM90zxmkcImJiYbvC2fNzsbfEgfTCgXLCZOkcUkCQcbtEw5JigvUDgLYzsb0yxnRigXPC3qGkfjfq09ntuvoreveic0Gy3jLyxrLignVBxbYzwHLBNnPDMuGyNjLywTKB3DUktOkphrHC2TTyw5Hz2vYpGO8ywn0Aw9UpNn5BMm8l2fJDgLVBJ4kphrHC2TZpLSkicb7cIaGicaIDgL0BguIoIaIqw5HBhL6zsb1C2vYihjLCxvPCMvTzw50CYiScIaGicaIzgvZy3jPChrPB24IoIaIvw5KzxjZDgfUzcb3Agf0ihrOzsb1C2vYihDHBNrZihrVigfJAgLLDMuIlaOGicaGiNn0yxr1CYi6icjJB21WBgv0zwqIlaOGicaGiNbYAw9YAxr5iJOGiMHPz2GIcIaGFsWkicb7cIaGicaIDgL0BguIoIaIrgvZAwDUigrHDgfIyxnLihnJAgvTysiScIaGicaIzgvZy3jPChrPB24IoIaIq3jLyxrLihrHyMXLCYbHBMqGCMvSyxrPB25ZAgLWCYiScIaGicaIC3rHDhvZiJOGiMLUx3bYB2DYzxnZiIWkicaGicjWCMLVCML0Esi6icjOAwDOiGOGih0ScIaGEWOGicaGiNrPDgXLiJOGiKLTCgXLBwvUDcbbueKGzw5KCg9PBNrZiIWkicaGicjZDgf0DxmIoIaICgvUzgLUzYiScIaGicaIChjPB3jPDhKIoIaIBwvKAxvTiGOGih0ScIaGEWOGicaGiNrPDgXLiJOGiLDYAxrLihrLC3rZiIWkicaGicjZDgf0DxmIoIaICgvUzgLUzYiScIaGicaIChjPB3jPDhKIoIaIBwvKAxvTiGOGih0kxtWVDgfZA3m+cJWVDgfZA21HBMfNzxi+cGPdCMvHDguGysb0yxnRoGO8DgfZA21HBMfNzxi+cJXHy3rPB24+y3jLyxrLpc9Hy3rPB24+cJX0AxrSzt5bBMfSExPLihvZzxiGCMvXDwLYzw1LBNrZpc90AxrSzt4kpgrLC2nYAxb0Aw9UpKjYzwfRigrVD24GDgHLihvZzxiNCYbYzxf1zxn0igLUDg8Gywn0Aw9UywjSzsbZDgvWCZWVzgvZy3jPChrPB24+cJXWCMLVCML0Et5OAwDOpc9WCMLVCML0Et4kpc90yxnRBwfUywDLCJ4kcKXPC3qGywXSihrHC2TZoGO8DgfZA21HBMfNzxi+cJXHy3rPB24+BgLZDdWVywn0Aw9UpGO8l3rHC2TTyw5Hz2vYpGOkq3jLyxrLihrHC2SGzgvWzw5Kzw5JEtOkphrHC2TTyw5Hz2vYpGO8ywn0Aw9UpMrLCgvUzdWVywn0Aw9UpGO8DgfZA0LKpNrHC2STDxvPzc1OzxjLpc90yxnRswq+cJXKzxbLBMrZt24+B3rOzxiTDgfZAY11DwLKpc9KzxbLBMrZt24+cJXKzxbLBMrLBMn5vhLWzt5IBg9JA3m8l2rLCgvUzgvUy3LuExbLpGO8l3rHC2TTyw5Hz2vYpGOkq3jLyxrLihn1yNrHC2S6cJX0yxnRBwfUywDLCJ4kpgfJDgLVBJ5ZDwj0yxnRpc9Hy3rPB24+cJXWyxjLBNruyxnRswq+CgfYzw50lxrHC2STDxvPzdWVCgfYzw50vgfZA0LKpGO8DgL0Bgu+sw1WBgvTzw50ihvZzxiGyxv0AgvUDgLJyxrPB248l3rPDgXLpGO8zgvZy3jPChrPB24+q3jLyxrLigXVz2LUigfUzcbZAwDUDxaGzNvUy3rPB25HBgL0EtWVzgvZy3jPChrPB24+cJXWCMLVCML0Et5OAwDOpc9WCMLVCML0Et4kpc90yxnRBwfUywDLCJ4kcKf1Dg8TChjPB3jPDgL6zsbHBgWGDgfZA3m6cJX0yxnRBwfUywDLCJ4kpgfJDgLVBJ5WCMLVCML0AxPLpc9Hy3rPB24+cJXTB2rLpMf1Dg88l21Vzgu+cJWVDgfZA21HBMfNzxi+cGPbBMfSExPLihnWzwnPzMLJihrHC2SGChjPB3jPDhK6cJX0yxnRBwfUywDLCJ4kpgfJDgLVBJ5WCMLVCML0AxPLpc9Hy3rPB24+cJXTB2rLpMfUywX5EMu8l21Vzgu+cJX0yxnRswq+DgfZAY11DwLKlwHLCMu8l3rHC2Tjzd4kpc90yxnRBwfUywDLCJ4kcKjHBgfUy2uGD29YA2XVywqGywnYB3nZigfNzw50CZOkphrHC2TTyw5Hz2vYpGO8ywn0Aw9UpNbYAw9YAxrPEMu8l2fJDgLVBJ4kpg1Vzgu+yMfSyw5JztWVBw9Kzt4kpc90yxnRBwfUywDLCJ4kcKXPC3qGyxzHAwXHyMXLihrLBxbSyxrLCZOkphrHC2TTyw5Hz2vYpGO8ywn0Aw9UpNrLBxbSyxrLpc9Hy3rPB24+cJXTB2rLpMXPC3q8l21Vzgu+cJWVDgfZA21HBMfNzxi+cGPbChbSEsb3zwiGyxbWigrLDMvSB3bTzw50ihrLBxbSyxrLoGO8DgfZA21HBMfNzxi+cJXHy3rPB24+DgvTCgXHDgu8l2fJDgLVBJ4kpg1Vzgu+yxbWBhK8l21Vzgu+cJX0zw1WBgf0zuLKpNDLyI1HChaTzgv2zwXVCg1LBNq8l3rLBxbSyxrLswq+cJXWCM9Qzwn0q29UDgv4Dd57iNbYB2PLy3royw1LiJOGiLvZzxjqB3j0ywWIlcaIDxjNzw5JEsi6icjOAwDOiN08l3bYB2PLy3rdB250zxH0pGO8l3rHC2TTyw5Hz2vYpGOku3vNz2vZDcb0zw1WBgf0zxmGyMfZzwqGB24Gy3vYCMvUDcb0yxnRCZOkphrHC2TTyw5Hz2vYpGO8ywn0Aw9UpNrLBxbSyxrLpc9Hy3rPB24+cJXTB2rLpNn1z2DLC3q8l21Vzgu+cJWVDgfZA21HBMfNzxi+cGPvCgrHDguGDgfZAYbWCM9NCMvZCZOkphrHC2TTyw5Hz2vYpGO8ywn0Aw9UpNbYB2DYzxnZpc9Hy3rPB24+cJXTB2rLpNvWzgf0ztWVBw9Kzt4kphrHC2Tjzd50yxnRlxv1AwqTAgvYztWVDgfZA0LKpGO8C3rHz2u+Aw5Fzgv2zwXVCg1LBNq8l3n0ywDLpGO8CgvYy2vUDgfNzt40ntWVCgvYy2vUDgfNzt4kpg5VDgu+q29TCgXLDgvKiefqssbPBNrLz3jHDgLVBIWGC3rHCNrPBMCGzNjVBNrLBMqGD29YAZWVBM90zt4kpc90yxnRBwfUywDLCJ4kcKDLDcbWCM9NCMvZCYbVDMvYDMLLDZOkphrHC2TTyw5Hz2vYpGO8ywn0Aw9UpNbYB2DYzxnZpc9Hy3rPB24+cJXTB2rLpM92zxj2Awv3pc9TB2rLpGO8l3rHC2TTyw5Hz2vYpGOkq2fSy3vSyxrLihbYB2DYzxnZigjHC2vKig9Uihn1yNrHC2TZoGO8DgfZA21HBMfNzxi+cJXHy3rPB24+ChjVz3jLC3m8l2fJDgLVBJ4kpg1Vzgu+y2fSy3vSyxrLpc9TB2rLpGO8DgfZA0LKpNrHC2STDxvPzc1OzxjLpc90yxnRswq+cJWVDgfZA21HBMfNzxi+cGOJiYmG8j+AQcbnqu5eqvrpuLKGv09ss0zmt1CGlsbArvjpievyq0vqveLptLmGquXmt1DfrdOkcIOQrvzfuLKGuKvtue9ou0uGtvvtvdOQkGOXlIaQkLnuqvjuifDjveGQkJOGphrHC2TTyw5Hz2vYpJXHy3rPB24+BgLZDdWVywn0Aw9UpJWVDgfZA21HBMfNzxi+cJiUicOQv09ssYOQoIbdB21WBgv0zsb0AguGDxnLCIDZihjLCxvLC3qGiaOZlIaQkKvorcbxsvrikIO6idX0yxnRBwfUywDLCJ48ywn0Aw9UpMnVBxbSzxrLpc9Hy3rPB24+phrHC2Tjzd5jrdWVDgfZA0LKpJWVDgfZA21HBMfNzxi+cGOQkLDbuK5jtKC6ifnRAxbWAw5NihrOAxmGD29YA2zSB3CGpsbjtKzjtKLursbmt09quYa9ifnzu1rftsbgquLmvvjfisOQcIOQtK8GuKvtue9ou0uGsvmGq09nueXfveuGv0Luse9vvcbuqvnlienptvbmrvrjt04HkIOkcLnurvaGmsaTiefSD2f5CYbZDgfYDcbIEsbSAxn0Aw5NihrHC2TZoGO8DgfZA21HBMfNzxi+cJXHy3rPB24+BgLZDdWVywn0Aw9UpGO8l3rHC2TTyw5Hz2vYpGOku1rfucaYic0Gqwz0zxiGy29TCgXLDgLUzYb3B3jRlcbTyxjRihrHC2SGy29TCgXLDgu6cJX0yxnRBwfUywDLCJ4kpgfJDgLVBJ5JB21WBgv0ztWVywn0Aw9UpGO8DgfZA0LKpNrHC2STmtC1oti1nZy5nJm3mY13ANnXDxjVEhO8l3rHC2Tjzd4kpc90yxnRBwfUywDLCJ4kcImJiYbnqu5eqvrpuLK6ienVBxbSzxrLihrHC2TZihDOzw4Gzg9UzsbVCIb5B3uNBgWGBg9VCcbMB3jLDMvYiqO','u3rHyMXLihDVCMTSB2fK','BM93','yNLtDgfNzq','zxzLCNK','tM8GCMvJB21Tzw5KyxrPB24GyxzHAwXHyMXL','DgfZA0XPC3q','ignVBxbSzxrLza','qNvNifjLChjVzhvJDgLVBIaMiefUywX5C2LZ','Aw5FChjVz3jLC3m','zgvZy3jPChrPB24','qNvPBgqGDxnLCIbPBNrLCMzHy2uGy29TCg9Uzw50CYbHBMqGAw1WBgvTzw50ignSAwvUDc1ZAwrLigXVz2LJ','sw50zwXSAwDLBNqGChjPB3jPDgL6yxrPB24Gy29TCgXLDgvKicG','z2vUzxjHDgvqCMLVCML0EvjLy29TBwvUzgf0Aw9UCW','ugfYzw50ihrHC2SGsuqGyw5KihrPDgXLigfYzsbYzxf1AxjLzcbMB3iGy3jLyxrPBMCGC3vIDgfZA3m','z2vUzxjHDgvqCMvKAwn0Aw9UCW','ChjPB3jPDhLuCMvUzhm','yw5HBhL6zq','rgv0zwn0zwqGqvbjlxjLBgf0zwqGDgfZA3m','rML4ieLTCgXLBwvUDgf0Aw9U','Dw5RBM93BG','BgLZDa','vgfZA01HBMfNzxjuB29SoIbty2HLzhvSzxiGzgvWzw5Kzw5JEsbPBMPLy3rLza','y3n2','DxjNzw50','z2v0vgLTzq','B3zLCNzPzxC','C3vJy2vZCW','iIbMB3iGDgfZAYaI','CMvSyxrL','v29YA2XVywqGAxmGD2vSBcbIywXHBMnLza','DgfZA0LK','yw5HBhL6zunVBgXHyM9YyxrPB25nzxrYAwnZ','qvbjifjLC2vHCMnOicyGrg9JDw1LBNrHDgLVBIbszxzPzxC','DgfZA1n0yxr1C2vZ','q29UC2LKzxiGzgvSzwDHDgLUzYbZB21LihrHC2TZihrVigXLC3mGyNvZEsbHz2vUDhm','twv0CMLJ','DhLWzq','y3jLyxrLvgfZAW','B3b0Aw1PEMf0Aw9U','z2v0rNvSBfLLyxi','DgvJAg5VBg9NEq','yxv0BW','z2v0rgf0zq','vgfZAYbHBhjLywr5ignVBxbSzxrLza','ywn0Aw9Ulq','z2vUzxjHDgvxB3jRzMXVD1zPC3vHBgL6yxrPB24','v2vIiefWCgXPy2f0Aw9UierLDMvSB3bTzw50','rMvHDhvYzsbezxzLBg9WBwvUDa','AwrLBNrPzNLqzwfRqwn0AxzPDhLeyxLZ','y3jLyxrLzef0','DxbKyxrL','y2fSy3vSyxrLq29TCgXLDgLVBLjHDgu','y2fSy3vSyxrLvMvSB2nPDhLuCMvUza','A2v5CW','zgvWzw5Kzw5JAwvZ','jsKksw4GuhjVz3jLC3m6ia','Dw5ZAgLMDa','yxbWBhLqCM9Qzwn0q29UDgv4Da','Dg9gAxHLza','AM9PBG','y3jLyxrLrgvWzw5Kzw5JEq','BgLZDfrHC2TZ','vgvTCgXHDguGBM90igzVDw5KoIa','CMvZDwX0','zM9YrwfJAa','ignVBxbSzxrLzc9Jyw5JzwXSzwqGDgfZA3m','C2nOzwr1BgvY','rgv0zwn0zwqGzMvHDhvYzsbKzxzLBg9WBwvUDcb0yxnRCW','zMvHDhvYzs1KzxzLBg9WBwvUDa','q29TCgXLDgLVBIbsyxrL','y29UDMvYDfrVq1nw','DxbKyxrLvgfZA1bYB2DYzxnZ','yxbPlwLUDgvNCMf0Aw9U','DhjHy2TqCM9NCMvZCW','yMXVy2TLza','lIbnDxn0igjLoIa','zxjYB3i','y2fUy2vS','yMXVy2TLzfrHC2TZ','rNjVBNrLBMqGrgv2zwXVCg1LBNq','C2XPy2u','mtqYmdq2uMTtEvjK','ChjLzgLJDez1DhvYzunVBxbSzxrPB25Z','y2fSy3vSyxrLuhjVz3jLC3nuCMvUzhm','sgLNAcbWCM9KDwn0AxzPDhKGlsbLEgnLBgXLBNqGDgfZAYbJB21WBgv0Aw9UihjHDgu','sw1WBgvTzw50igjHy2TLBMqGBg9NAwmGyw5KigrHDgeGBw9KzwXZ','DgfZAY0','vxbKyxrLigrVy3vTzw50yxrPB24GAwyGyMvOyxzPB3iGy2HHBMDLza','Dg90ywXuzw1WBgf0zuDLBMvYyxrLza','y29Uy2f0','BwLU','DhjLBMrZ','y3jLyxrLq3vZDg9TvgvTCgXHDgu','vxnPBMCGC2LUz2XLlwfNzw50ihbYAw9YAxrPEMf0Aw9U','y2fSy3vSyxrLuhjVz3jLC3ndB25ZAxn0zw5JEq','zgvWzw5K','DgvHBq','mtGWmdyXnLvur0vIzq','y2XLyxi','CgXHBM5PBMC','sw52ywXPzcbZDgf0DxmGiG','BgfZDfvWzgf0zwq','DgvTCgXHDgvvC2fNzq','mJDxzhb4qLy','DxnLCI1TyxjRzwqGDxjNzw50','C3rHz2u','zMXVB3i','q2XLyxjLzca','yxzLCMfNzvrHC2Tbz2u','AgfZ','BgvUz3rO','Aw5ZAwDODhm','Aw5Fzgv2zwXVCg1LBNq','yMXVy2TLzfrHC2TZuMf0zq','u3rHyMXL','y29TCgXLDgvuyxnR','vgfZA01HBMfNzxiGzxHLy3v0Aw9UigzHAwXLza','Aw5MBW','q29YzsbjBNrLz3jHDgLVBIbjBxbSzw1LBNrHDgLVBG','z2v0vhjLBMrbBMfSExnPCW','uMv2Awv3igfUzcbYzxnVBhzLihrHC2SGzgvWzw5Kzw5JAwvZ','y3vZDg9T','BMfTzq','ChjVAMvJDe5HBwu','Bg93','AwrLBNrPzNLdEwnSAwnHBfbHDhrLCM5Z','D29YA2XVywrty29Yzq','sgLNAcbIBg9JA2vKihrHC2SGCMf0zsaTig9WDgLTAxPLigrLCgvUzgvUy3KGCgXHBM5PBMC','CM91BMq','DxbKyxrLrgvWzw5Kzw50vgfZA3m','BwLSzxn0B25LCW','C29YDa','BwfPBNrLBMfUy2u','ywrK','y2fSy3vSyxrLv2vLA2X5vhjLBMrZ','y2fSy3vSyxrLrgvWzw5Kzw5JEuvMzMLJAwvUy3K','rM9JDxmGB24GAw1WCM92Aw5NihrHC2SGy29TCgXLDgLVBIbYyxrLihrOCM91z2GGyMv0DgvYihrPBwuGBwfUywDLBwvUDa','uMvXDwLYzw1LBNrZiefUywX5C2LZ','cKf2zxjHz2uGvgfZAYbbz2u6ia','zMLUzfrHC2TZqMXVy2TLzej5','DxjNzw5JEq','vgvZDcbMAxGGyw5KihzLCMLMEsbUBYbYzwDYzxnZAw9UCYbPBNrYB2r1y2vK','Bg9Nz2vY','y2fSy3vSyxrLuhjPB3jPDhLby2n1CMfJEq','ChjPB3jPDhK','z2v0ugvYzM9YBwfUy2vnzxrYAwnZ','DgfZA3m','Dg9ju09tDhjPBMC','C3vWCg9YDgvKqwn0Aw9UCW','DgL0Bgu','uhjPB3jPDhKGC2v0DgLUzYbUzwvKCYbPBxbYB3zLBwvUDcaTihjLDMLLDYb0yxnRihvYz2vUy3KGyxnZzxnZBwvUDa','y3vZDg9Tlq','vw5ZDxbWB3j0zwqGywn0Aw9UoIa','vgvHBsbHBMfSExrPy3mGCMvXDwLYzxmGC2nOzwr1BgvYihDPDgGGz2v0qwXSqwDLBNrZig1LDgHVza','y3jLyxrLza','zMvHDhvYzq','q3vZDg9TihrLBxbSyxrLoIa','CMvKDwnL','mtCWvgjbA0Tm','yMXVy2TLzf90yxnRCW','yxv0B1bYAw9YAxrPEMvbBgXuyxnRCW','tg93ihbYB2r1y3rPDML0Eq','ChjVzhvJDgL2Axr5','BgLZDef2ywLSywjSzvrLBxbSyxrLCW','vw5IywXHBMnLza'];a0_0x996e=function(){return _0x30fb4a;};return a0_0x996e();}class TaskManagerTool extends BaseTool{constructor(_0x404716={}){const _0x43bc96=a0_0x2f3d;super({'name':'taskmanager','description':_0x404716['description']||_0x43bc96(0x26e),..._0x404716}),this['supportedActions']=[_0x43bc96(0x1af),_0x43bc96(0x1ec),_0x43bc96(0x1ce),'complete','cancel','clear',_0x43bc96(0x219),'relate',_0x43bc96(0x164),'prioritize','template','progress',_0x43bc96(0x176),_0x43bc96(0x27e)],this['taskStatuses']=['pending',_0x43bc96(0x1c2),_0x43bc96(0x204),'completed','cancelled'],this['taskPriorities']=['urgent',_0x43bc96(0x280),_0x43bc96(0x19c),'low'],this[_0x43bc96(0x147)]=[_0x43bc96(0x173),_0x43bc96(0x139),_0x43bc96(0x164),'parent'],this['progressStages']=[_0x43bc96(0x17c),_0x43bc96(0x21d),_0x43bc96(0x22a),_0x43bc96(0x12e),_0x43bc96(0x148),'completed'],this['milestoneTypes']=['checkpoint','deliverable',_0x43bc96(0x288),'dependency_gate'],this['priorityWeights']={'blocking':0x3,'age':1.5,'userPriority':0x2,'contextSwitching':1.2,'dependency':1.8},this[_0x43bc96(0x149)]={'web-app-development':{'name':_0x43bc96(0x1e8),'description':'Complete\x20workflow\x20for\x20building\x20a\x20web\x20application','category':_0x43bc96(0x12a),'tasks':[{'title':'Project\x20Setup\x20&\x20Planning','description':'Initialize\x20project\x20structure,\x20configure\x20tools,\x20and\x20plan\x20architecture','priority':_0x43bc96(0x280),'dependencies':[]},{'title':_0x43bc96(0x186),'description':'Design\x20database\x20schema,\x20create\x20tables,\x20and\x20set\x20up\x20connections','priority':'high','dependencies':['Project\x20Setup\x20&\x20Planning']},{'title':'Backend\x20API\x20Development','description':_0x43bc96(0x1ac),'priority':_0x43bc96(0x280),'dependencies':[_0x43bc96(0x186)]},{'title':_0x43bc96(0x209),'description':_0x43bc96(0x1c4),'priority':'medium','dependencies':['Backend\x20API\x20Development']},{'title':'Testing\x20&\x20Quality\x20Assurance','description':_0x43bc96(0x18b),'priority':_0x43bc96(0x19c),'dependencies':['Frontend\x20Development']},{'title':'Deployment\x20&\x20Launch','description':'Deploy\x20to\x20production\x20environment\x20and\x20monitor\x20launch','priority':'high','dependencies':[_0x43bc96(0x172)]}]},'api-integration':{'name':'API\x20Integration','description':_0x43bc96(0x278),'category':'integration','tasks':[{'title':_0x43bc96(0x1da),'description':'Study\x20API\x20documentation,\x20authentication,\x20and\x20rate\x20limits','priority':_0x43bc96(0x280),'dependencies':[]},{'title':'Authentication\x20Setup','description':'Implement\x20API\x20key\x20management\x20and\x20authentication\x20flow','priority':_0x43bc96(0x280),'dependencies':['API\x20Research\x20&\x20Documentation\x20Review']},{'title':_0x43bc96(0x230),'description':'Build\x20API\x20client\x20and\x20implement\x20main\x20integration\x20logic','priority':'high','dependencies':['Authentication\x20Setup']},{'title':'Error\x20Handling\x20&\x20Retry\x20Logic','description':'Implement\x20robust\x20error\x20handling\x20and\x20retry\x20mechanisms','priority':_0x43bc96(0x19c),'dependencies':[_0x43bc96(0x230)]},{'title':_0x43bc96(0x17a),'description':'Test\x20integration\x20with\x20various\x20scenarios\x20and\x20edge\x20cases','priority':_0x43bc96(0x19c),'dependencies':[_0x43bc96(0x270)]}]},'bug-fix':{'name':'Bug\x20Fix\x20Workflow','description':'Systematic\x20approach\x20to\x20identifying\x20and\x20fixing\x20bugs','category':_0x43bc96(0x23e),'tasks':[{'title':_0x43bc96(0x1c1),'description':'Reproduce\x20the\x20bug\x20and\x20analyze\x20root\x20cause','priority':_0x43bc96(0x1d1),'dependencies':[]},{'title':_0x43bc96(0x1cc),'description':_0x43bc96(0x130),'priority':'urgent','dependencies':['Bug\x20Reproduction\x20&\x20Analysis']},{'title':'Testing\x20&\x20Verification','description':_0x43bc96(0x247),'priority':_0x43bc96(0x280),'dependencies':[_0x43bc96(0x1cc)]},{'title':'Documentation\x20Update','description':_0x43bc96(0x211),'priority':'low','dependencies':[_0x43bc96(0x161)]}]},'feature-development':{'name':_0x43bc96(0x1e9),'description':'End-to-end\x20feature\x20development\x20workflow','category':_0x43bc96(0x12a),'tasks':[{'title':_0x43bc96(0x243),'description':'Analyze\x20requirements\x20and\x20create\x20technical\x20specification','priority':_0x43bc96(0x280),'dependencies':[]},{'title':_0x43bc96(0x188),'description':_0x43bc96(0x190),'priority':_0x43bc96(0x280),'dependencies':['Requirements\x20Analysis']},{'title':'Backend\x20Implementation','description':_0x43bc96(0x20f),'priority':_0x43bc96(0x280),'dependencies':['Design\x20&\x20Architecture']},{'title':_0x43bc96(0x18c),'description':_0x43bc96(0x13e),'priority':_0x43bc96(0x19c),'dependencies':['Backend\x20Implementation']},{'title':'Testing\x20&\x20Documentation','description':'Write\x20tests\x20and\x20update\x20documentation','priority':_0x43bc96(0x19c),'dependencies':[_0x43bc96(0x18c)]}]}};}['getDescription'](){const _0x2297e8=a0_0x2f3d;return _0x2297e8(0x1b9);}['parseParameters'](_0x484ed5){const _0xad60e4=a0_0x2f3d;if(typeof _0x484ed5===_0xad60e4(0x1aa))return{'rawContent':_0x484ed5};if(typeof _0x484ed5===_0xad60e4(0x189)&&_0x484ed5!==null){const _0x173833={};for(const [_0x263a35,_0x583eff]of Object[_0xad60e4(0x263)](_0x484ed5)){_0x583eff&&typeof _0x583eff==='object'&&_0xad60e4(0x19a)in _0x583eff?_0x173833[_0x263a35]=_0x583eff[_0xad60e4(0x19a)]:_0x173833[_0x263a35]=_0x583eff;}return _0x173833;}return _0x484ed5;}async['execute'](_0x598f6c,_0x19c5c9){const _0xf395f8=a0_0x2f3d;try{const _0x43bfd1={};for(const [_0x1c1f90,_0x2b039f]of Object[_0xf395f8(0x263)](_0x598f6c)){_0x2b039f&&typeof _0x2b039f==='object'&&'value'in _0x2b039f?_0x43bfd1[_0x1c1f90]=_0x2b039f[_0xf395f8(0x19a)]:_0x43bfd1[_0x1c1f90]=_0x2b039f;}_0x598f6c=_0x43bfd1;const {agentId:_0x30d934,agentName:_0x56bbac}=_0x19c5c9;if(!_0x30d934)throw new Error('Agent\x20ID\x20is\x20required\x20for\x20task\x20management');const _0x59d153=await _0x19c5c9['agentPool']['getAgent'](_0x30d934);if(!_0x59d153)throw new Error('Agent\x20not\x20found:\x20'+_0x30d934);!_0x59d153[_0xf395f8(0x1bf)]&&(_0x59d153[_0xf395f8(0x1bf)]={'tasks':[],'lastUpdated':new Date()['toISOString']()});const _0x581fe0=_0x598f6c['action']?.[_0xf395f8(0x269)]();if(!this[_0xf395f8(0x24e)][_0xf395f8(0x152)](_0x581fe0))throw new Error(_0xf395f8(0x252)+_0x581fe0+_0xf395f8(0x1b5)+this[_0xf395f8(0x24e)]['join'](',\x20'));let _0xe9ae44;switch(_0x581fe0){case'create':_0xe9ae44=await this[_0xf395f8(0x1df)](_0x59d153,_0x598f6c);break;case _0xf395f8(0x1ec):_0xe9ae44=await this[_0xf395f8(0x132)](_0x59d153,_0x598f6c);break;case _0xf395f8(0x1ce):_0xe9ae44=await this[_0xf395f8(0x1f7)](_0x59d153,_0x598f6c);break;case'complete':_0xe9ae44=await this['completeTask'](_0x59d153,_0x598f6c);break;case _0xf395f8(0x207):_0xe9ae44=await this['cancelTask'](_0x59d153,_0x598f6c);break;case _0xf395f8(0x21c):_0xe9ae44=await this[_0xf395f8(0x159)](_0x59d153,_0x598f6c);break;case'depend':_0xe9ae44=await this['createDependency'](_0x59d153,_0x598f6c);break;case _0xf395f8(0x1d6):_0xe9ae44=await this[_0xf395f8(0x284)](_0x59d153,_0x598f6c);break;case'subtask':_0xe9ae44=await this['createSubtask'](_0x59d153,_0x598f6c);break;case'prioritize':_0xe9ae44=await this['intelligentPrioritization'](_0x59d153,_0x598f6c);break;case'template':_0xe9ae44=await this['manageTemplates'](_0x59d153,_0x598f6c);break;case'progress':_0xe9ae44=await this['trackProgress'](_0x59d153,_0x598f6c);break;case _0xf395f8(0x176):_0xe9ae44=await this['generateAnalytics'](_0x59d153,_0x598f6c);break;case _0xf395f8(0x27e):_0xe9ae44=await this[_0xf395f8(0x166)](_0x59d153,_0x598f6c);break;default:throw new Error('Unknown\x20action:\x20'+_0x581fe0);}return _0x59d153['lastActivity']=new Date()['toISOString'](),_0x59d153[_0xf395f8(0x1bf)]['lastUpdated']=new Date()[_0xf395f8(0x24d)](),await _0x19c5c9['agentPool']['persistAgentState'](_0x30d934),this['logger']?.[_0xf395f8(0x22f)]('TaskManager\x20action\x20executed:\x20'+_0x581fe0,{'agentId':_0x30d934,'agentName':_0x56bbac,'action':_0x581fe0,'taskCount':_0x59d153['taskList']['tasks'][_0xf395f8(0x228)],'pendingTasks':_0x59d153[_0xf395f8(0x1bf)]['tasks'][_0xf395f8(0x191)](_0x41618c=>_0x41618c['status']===_0xf395f8(0x13d))['length'],'inProgressTasks':_0x59d153['taskList'][_0xf395f8(0x24c)]['filter'](_0x939f48=>_0x939f48[_0xf395f8(0x19b)]==='in_progress')[_0xf395f8(0x228)]}),{'success':!![],'action':_0x581fe0,'result':_0xe9ae44,'summary':this[_0xf395f8(0x16f)](_0x59d153['taskList'])};}catch(_0x2eadd4){return this[_0xf395f8(0x248)]?.['error'](_0xf395f8(0x22e),{'error':_0x2eadd4['message'],'context':_0x19c5c9,'params':_0x598f6c}),{'success':![],'error':_0x2eadd4[_0xf395f8(0x14d)]};}}async['createTask'](_0x3d2522,_0x2468e5){const _0x18cff9=a0_0x2f3d,{title:_0x4dc856,description:description='',priority:priority='medium'}=_0x2468e5;if(!_0x4dc856)throw new Error(_0x18cff9(0x17d));if(priority&&!this[_0x18cff9(0x282)][_0x18cff9(0x152)](priority[_0x18cff9(0x269)]()))throw new Error('Invalid\x20priority:\x20'+priority+_0x18cff9(0x205)+this[_0x18cff9(0x282)][_0x18cff9(0x1f5)](',\x20'));const _0x222e78={'id':'task-'+a0_0x592b6c(),'title':_0x4dc856,'description':description,'status':_0x18cff9(0x13d),'priority':priority[_0x18cff9(0x269)](),'createdAt':new Date()[_0x18cff9(0x24d)](),'updatedAt':new Date()['toISOString']()};return _0x3d2522['taskList'][_0x18cff9(0x24c)]['push'](_0x222e78),{'message':'Task\x20created\x20successfully','task':_0x222e78};}async[a0_0x40f7e7(0x166)](_0x3c5835,_0x310289){const _0x22ea3a=a0_0x40f7e7;let {tasks:_0x187e01}=_0x310289;if(typeof _0x187e01===_0x22ea3a(0x1aa))try{_0x187e01=JSON[_0x22ea3a(0x12c)](_0x187e01);}catch(_0x2492a5){throw new Error(_0x22ea3a(0x170)+_0x2492a5[_0x22ea3a(0x14d)]);}if(!Array[_0x22ea3a(0x194)](_0x187e01))throw new Error('Tasks\x20must\x20be\x20an\x20array');if(_0x187e01['length']===0x0)throw new Error(_0x22ea3a(0x16e));const _0x47d0e5=new Date()['toISOString'](),_0x435bc4=_0x3c5835['taskList'][_0x22ea3a(0x24c)]||[],_0x1e2843=[],_0x4a5d4d=[],_0xbdfd50=new Set(),_0x74fa07=_0x1a4895=>{const _0x101061=_0x22ea3a,_0x3f787e=_0x1a4895[_0x101061(0x269)]()[_0x101061(0x264)]();return _0x435bc4[_0x101061(0x146)](_0x2973d9=>_0x2973d9[_0x101061(0x24f)]['toLowerCase']()['trim']()===_0x3f787e&&!_0xbdfd50[_0x101061(0x227)](_0x2973d9['id']));};for(const _0x4ff33d of _0x187e01){if(!_0x4ff33d['title'])throw new Error('Each\x20task\x20must\x20have\x20a\x20title');const _0xc41d3e=(_0x4ff33d['status']||'pending')['toLowerCase'](),_0x35da85=(_0x4ff33d['priority']||_0x22ea3a(0x19c))['toLowerCase']();if(!this[_0x22ea3a(0x1db)]['includes'](_0xc41d3e))throw new Error(_0x22ea3a(0x21e)+_0xc41d3e+'\x22\x20for\x20task\x20\x22'+_0x4ff33d[_0x22ea3a(0x24f)]+_0x22ea3a(0x136)+this['taskStatuses'][_0x22ea3a(0x1f5)](',\x20'));if(!this['taskPriorities']['includes'](_0x35da85))throw new Error('Invalid\x20priority\x20\x22'+_0x35da85+_0x22ea3a(0x1d5)+_0x4ff33d['title']+'\x22.\x20Must\x20be:\x20'+this[_0x22ea3a(0x282)][_0x22ea3a(0x1f5)](',\x20'));const _0x356a0f=_0x74fa07(_0x4ff33d['title']);if(_0x356a0f)_0x356a0f['status']=_0xc41d3e,_0x356a0f['priority']=_0x35da85,_0x4ff33d[_0x22ea3a(0x1c3)]!==undefined&&(_0x356a0f[_0x22ea3a(0x1c3)]=_0x4ff33d[_0x22ea3a(0x1c3)]),_0x356a0f[_0x22ea3a(0x267)]=_0x47d0e5,_0x1e2843[_0x22ea3a(0x1a6)](_0x356a0f),_0xbdfd50[_0x22ea3a(0x23f)](_0x356a0f['id']);else{const _0x216561={'id':_0x22ea3a(0x210)+a0_0x592b6c(),'title':_0x4ff33d[_0x22ea3a(0x24f)],'description':_0x4ff33d[_0x22ea3a(0x1c3)]||'','status':_0xc41d3e,'priority':_0x35da85,'createdAt':_0x47d0e5,'updatedAt':_0x47d0e5,'source':'sync'};_0x4a5d4d['push'](_0x216561);}}_0x3c5835[_0x22ea3a(0x1bf)][_0x22ea3a(0x24c)]=[..._0x1e2843,..._0x4a5d4d];const _0x9640b4=_0x3c5835['taskList']['tasks'][_0x22ea3a(0x191)](_0x430526=>_0x430526['status']==='in_progress');if(_0x9640b4[_0x22ea3a(0x228)]>0x1)for(let _0x16b121=0x1;_0x16b121<_0x9640b4[_0x22ea3a(0x228)];_0x16b121++){_0x9640b4[_0x16b121][_0x22ea3a(0x19b)]='pending';}if(_0x9640b4[_0x22ea3a(0x228)]===0x0){const _0x59964a=_0x3c5835[_0x22ea3a(0x1bf)][_0x22ea3a(0x24c)]['find'](_0x1695c1=>_0x1695c1['status']===_0x22ea3a(0x13d));_0x59964a&&(_0x59964a['status']=_0x22ea3a(0x1c2),_0x59964a['updatedAt']=_0x47d0e5);}return _0x3c5835[_0x22ea3a(0x1bf)][_0x22ea3a(0x21f)]=_0x47d0e5,{'message':_0x22ea3a(0x286),'summary':{'total':_0x3c5835['taskList'][_0x22ea3a(0x24c)]['length'],'created':_0x4a5d4d[_0x22ea3a(0x228)],'updated':_0x1e2843[_0x22ea3a(0x228)],'removed':_0x435bc4['length']-_0xbdfd50['size'],'pending':_0x3c5835['taskList'][_0x22ea3a(0x24c)][_0x22ea3a(0x191)](_0x5cfae0=>_0x5cfae0[_0x22ea3a(0x19b)]==='pending')[_0x22ea3a(0x228)],'inProgress':_0x3c5835[_0x22ea3a(0x1bf)][_0x22ea3a(0x24c)][_0x22ea3a(0x191)](_0x194a9e=>_0x194a9e['status']===_0x22ea3a(0x1c2))['length'],'completed':_0x3c5835['taskList']['tasks'][_0x22ea3a(0x191)](_0x1b45de=>_0x1b45de['status']==='completed')[_0x22ea3a(0x228)],'cancelled':_0x3c5835[_0x22ea3a(0x1bf)][_0x22ea3a(0x24c)]['filter'](_0x3b5de5=>_0x3b5de5['status']==='cancelled')[_0x22ea3a(0x228)]},'tasks':_0x3c5835[_0x22ea3a(0x1bf)][_0x22ea3a(0x24c)][_0x22ea3a(0x167)](_0x42a1ee=>({'id':_0x42a1ee['id'],'title':_0x42a1ee['title'],'status':_0x42a1ee['status'],'priority':_0x42a1ee[_0x22ea3a(0x24a)]}))};}async[a0_0x40f7e7(0x132)](_0x3b3655,_0x191ccf){const _0x4816c6=a0_0x40f7e7,{taskId:_0x1f74fd,status:_0x144351,priority:_0x584957,title:_0x1b74b3,description:_0x531b82}=_0x191ccf;if(!_0x1f74fd)throw new Error('Task\x20ID\x20is\x20required\x20for\x20update');const _0x10f746=_0x3b3655[_0x4816c6(0x1bf)]['tasks'][_0x4816c6(0x146)](_0x1c31da=>_0x1c31da['id']===_0x1f74fd);if(!_0x10f746)throw new Error('Task\x20not\x20found:\x20'+_0x1f74fd);if(_0x144351){if(!this['taskStatuses']['includes'](_0x144351[_0x4816c6(0x269)]()))throw new Error('Invalid\x20status:\x20'+_0x144351+_0x4816c6(0x205)+this['taskStatuses'][_0x4816c6(0x1f5)](',\x20'));_0x10f746['status']=_0x144351['toLowerCase']();}if(_0x584957){if(!this[_0x4816c6(0x282)]['includes'](_0x584957['toLowerCase']()))throw new Error(_0x4816c6(0x198)+_0x584957+_0x4816c6(0x205)+this[_0x4816c6(0x282)]['join'](',\x20'));_0x10f746['priority']=_0x584957['toLowerCase']();}if(_0x1b74b3!==undefined)_0x10f746[_0x4816c6(0x24f)]=_0x1b74b3;if(_0x531b82!==undefined)_0x10f746['description']=_0x531b82;return _0x10f746[_0x4816c6(0x267)]=new Date()[_0x4816c6(0x24d)](),{'message':'Task\x20updated\x20successfully','task':_0x10f746};}async['listTasks'](_0x3369cd,_0x327eb0){const _0x12b0cb=a0_0x40f7e7,{status:_0x5ab84b,priority:_0x18bb27}=_0x327eb0;let _0x4e8acc=[..._0x3369cd['taskList'][_0x12b0cb(0x24c)]];if(_0x5ab84b){if(!this['taskStatuses']['includes'](_0x5ab84b['toLowerCase']()))throw new Error('Invalid\x20status\x20filter:\x20'+_0x5ab84b);_0x4e8acc=_0x4e8acc['filter'](_0x4d686d=>_0x4d686d[_0x12b0cb(0x19b)]===_0x5ab84b[_0x12b0cb(0x269)]());}if(_0x18bb27){if(!this['taskPriorities']['includes'](_0x18bb27['toLowerCase']()))throw new Error('Invalid\x20priority\x20filter:\x20'+_0x18bb27);_0x4e8acc=_0x4e8acc['filter'](_0xa12818=>_0xa12818[_0x12b0cb(0x24a)]===_0x18bb27[_0x12b0cb(0x269)]());}const _0x22dd34={'high':0x0,'medium':0x1,'low':0x2};return _0x4e8acc['sort']((_0x54ca19,_0x57839b)=>{const _0x51ea09=_0x12b0cb,_0x126bc2=_0x22dd34[_0x54ca19['priority']]-_0x22dd34[_0x57839b['priority']];if(_0x126bc2!==0x0)return _0x126bc2;return new Date(_0x54ca19[_0x51ea09(0x1eb)])-new Date(_0x57839b['createdAt']);}),{'totalTasks':_0x4e8acc[_0x12b0cb(0x228)],'tasks':_0x4e8acc,'summary':{'pending':_0x4e8acc[_0x12b0cb(0x191)](_0x8c44e2=>_0x8c44e2[_0x12b0cb(0x19b)]==='pending')['length'],'in_progress':_0x4e8acc['filter'](_0x3f4591=>_0x3f4591['status']==='in_progress')['length'],'completed':_0x4e8acc['filter'](_0x580fc6=>_0x580fc6['status']==='completed')[_0x12b0cb(0x228)],'cancelled':_0x4e8acc[_0x12b0cb(0x191)](_0x156d3e=>_0x156d3e['status']===_0x12b0cb(0x178))[_0x12b0cb(0x228)]}};}async[a0_0x40f7e7(0x22d)](_0x4401cb,_0x41ace2){const _0x257739=a0_0x40f7e7;let {taskId:_0x16fcc3}=_0x41ace2;if(!_0x16fcc3){const _0x5721ef=_0x4401cb[_0x257739(0x1bf)][_0x257739(0x24c)][_0x257739(0x146)](_0x2888eb=>_0x2888eb[_0x257739(0x19b)]==='in_progress'||_0x2888eb[_0x257739(0x19b)]===_0x257739(0x13d));if(_0x5721ef)_0x16fcc3=_0x5721ef['id'],this['logger']?.['info']('Auto-completing\x20current\x20task:\x20'+_0x16fcc3,{'agentId':_0x4401cb['id'],'taskTitle':_0x5721ef['title']});else throw new Error(_0x257739(0x27f));}const _0x552959=_0x4401cb['taskList']['tasks']['find'](_0x594c3e=>_0x594c3e['id']===_0x16fcc3);if(!_0x552959)throw new Error(_0x257739(0x12b)+_0x16fcc3);if(_0x552959[_0x257739(0x19b)]===_0x257739(0x283))return{'message':_0x257739(0x1e5),'task':_0x552959};_0x552959[_0x257739(0x19b)]='completed',_0x552959[_0x257739(0x1ad)]=new Date()[_0x257739(0x24d)](),_0x552959[_0x257739(0x267)]=new Date()['toISOString']();if(this[_0x257739(0x1fc)]&&typeof this[_0x257739(0x1fc)][_0x257739(0x23b)]===_0x257739(0x129))try{await this['scheduler']['updateDependentTasks'](_0x4401cb,_0x16fcc3),this[_0x257739(0x248)]?.['info']('Triggered\x20dependency\x20update\x20for\x20completed\x20task',{'taskId':_0x16fcc3,'title':_0x552959['title']});}catch(_0x243e8a){this[_0x257739(0x248)]?.[_0x257739(0x1b6)]('Failed\x20to\x20update\x20dependent\x20tasks',{'taskId':_0x16fcc3,'error':_0x243e8a['message']});}return{'message':_0x257739(0x184),'task':_0x552959,'dependenciesUpdated':!!this['scheduler']};}async[a0_0x40f7e7(0x27d)](_0x1be7c8,_0x5c7f90){const _0x1ca5dc=a0_0x40f7e7,{taskId:_0xd27be6,reason:reason=''}=_0x5c7f90;if(!_0xd27be6)throw new Error(_0x1ca5dc(0x128));const _0x179452=_0x1be7c8[_0x1ca5dc(0x1bf)][_0x1ca5dc(0x24c)]['find'](_0x3df5b2=>_0x3df5b2['id']===_0xd27be6);if(!_0x179452)throw new Error(_0x1ca5dc(0x12b)+_0xd27be6);return _0x179452[_0x1ca5dc(0x19b)]=_0x1ca5dc(0x178),_0x179452['cancelledAt']=new Date()[_0x1ca5dc(0x24d)](),_0x179452['cancellationReason']=reason,_0x179452[_0x1ca5dc(0x267)]=new Date()['toISOString'](),{'message':_0x1ca5dc(0x1b7),'task':_0x179452};}async['clearCompletedTasks'](_0x297d82,_0x2f4f62){const _0x3ae5b9=a0_0x40f7e7,_0x13651d=_0x297d82[_0x3ae5b9(0x1bf)][_0x3ae5b9(0x24c)]['length'];_0x297d82['taskList']['tasks']=_0x297d82['taskList']['tasks']['filter'](_0x4423de=>_0x4423de['status']===_0x3ae5b9(0x13d)||_0x4423de[_0x3ae5b9(0x19b)]==='in_progress');const _0x43d864=_0x13651d-_0x297d82['taskList'][_0x3ae5b9(0x24c)]['length'];return{'message':_0x3ae5b9(0x225)+_0x43d864+_0x3ae5b9(0x1fb),'remainingTasks':_0x297d82[_0x3ae5b9(0x1bf)][_0x3ae5b9(0x24c)]['length'],'removed':_0x43d864};}async[a0_0x40f7e7(0x1f6)](_0x593c00,_0x4228d3){const _0x461d71=a0_0x40f7e7,{taskId:_0x404bf7,dependsOn:_0x1ac588,dependencyType:dependencyType='blocks'}=_0x4228d3;if(!_0x404bf7||!_0x1ac588)throw new Error('Both\x20taskId\x20and\x20dependsOn\x20are\x20required\x20for\x20creating\x20dependencies');if(!this[_0x461d71(0x147)]['includes'](dependencyType))throw new Error('Invalid\x20dependency\x20type:\x20'+dependencyType+'.\x20Must\x20be:\x20'+this['dependencyTypes']['join'](',\x20'));const _0x17c9d8=_0x593c00[_0x461d71(0x1bf)][_0x461d71(0x24c)][_0x461d71(0x146)](_0x5319b9=>_0x5319b9['id']===_0x404bf7),_0x526e84=_0x593c00['taskList']['tasks'][_0x461d71(0x146)](_0x5742e8=>_0x5742e8['id']===_0x1ac588);if(!_0x17c9d8)throw new Error(_0x461d71(0x12b)+_0x404bf7);if(!_0x526e84)throw new Error('Dependency\x20task\x20not\x20found:\x20'+_0x1ac588);!_0x17c9d8[_0x461d71(0x1f0)]&&(_0x17c9d8['dependencies']=[]);const _0x148c5d=_0x17c9d8[_0x461d71(0x1f0)][_0x461d71(0x146)](_0x3288c1=>_0x3288c1[_0x461d71(0x1d8)]===_0x1ac588);if(_0x148c5d)return{'message':'Dependency\x20already\x20exists','dependency':_0x148c5d};const _0x399c84={'taskId':_0x1ac588,'type':dependencyType,'createdAt':new Date()['toISOString']()};return _0x17c9d8['dependencies']['push'](_0x399c84),_0x17c9d8['updatedAt']=new Date()[_0x461d71(0x24d)](),dependencyType==='blocks'&&_0x526e84[_0x461d71(0x19b)]!==_0x461d71(0x283)&&(_0x17c9d8['status']=_0x461d71(0x204)),{'message':'Dependency\x20created\x20successfully','dependency':_0x399c84,'task':_0x17c9d8};}async[a0_0x40f7e7(0x284)](_0x2f4078,_0x38b6e3){const _0x4d796f=a0_0x40f7e7;return await this[_0x4d796f(0x1f6)](_0x2f4078,{..._0x38b6e3,'dependencyType':_0x4d796f(0x139)});}async['createSubtask'](_0x596c9e,_0x53f365){const _0xd756df=a0_0x40f7e7,{parentTaskId:_0x536234,title:_0xe0db43,description:description='',priority:priority='medium'}=_0x53f365;if(!_0x536234||!_0xe0db43)throw new Error(_0xd756df(0x1c7));const _0x197f50=_0x596c9e[_0xd756df(0x1bf)]['tasks'][_0xd756df(0x146)](_0x445ecc=>_0x445ecc['id']===_0x536234);if(!_0x197f50)throw new Error(_0xd756df(0x1a0)+_0x536234);const _0x26caa9={'id':_0xd756df(0x210)+Date['now']()+'-'+Math['random']()['toString'](0x24)['substr'](0x2,0x9),'title':_0xe0db43,'description':description,'status':_0xd756df(0x13d),'priority':priority['toLowerCase'](),'createdAt':new Date()[_0xd756df(0x24d)](),'updatedAt':new Date()['toISOString'](),'parentTaskId':_0x536234,'isSubtask':!![],'source':_0xd756df(0x15e)};return _0x596c9e[_0xd756df(0x1bf)]['tasks'][_0xd756df(0x1a6)](_0x26caa9),!_0x197f50['subtasks']&&(_0x197f50[_0xd756df(0x1a2)]=[]),_0x197f50['subtasks'][_0xd756df(0x1a6)](_0x26caa9['id']),_0x197f50[_0xd756df(0x267)]=new Date()[_0xd756df(0x24d)](),{'message':'Subtask\x20created\x20successfully','subtask':_0x26caa9,'parentTask':_0x197f50};}async[a0_0x40f7e7(0x197)](_0x2a03ad,_0x51b550){const _0x167d33=a0_0x40f7e7,{mode:mode='list',templateId:_0x16279d,customTemplate:_0xf93fb3,projectContext:_0x53c3b2}=_0x51b550;let _0x40396e={};if(mode==='list')_0x40396e=await this['listAvailableTemplates'](_0x2a03ad);else{if(mode===_0x167d33(0x1b8)&&_0x16279d)_0x40396e=await this['applyTemplate'](_0x2a03ad,_0x16279d,_0x53c3b2);else{if(mode==='create'&&_0xf93fb3)_0x40396e=await this[_0x167d33(0x216)](_0x2a03ad,_0xf93fb3);else{if(mode===_0x167d33(0x168))_0x40396e=await this['suggestTemplates'](_0x2a03ad);else throw new Error('Invalid\x20template\x20mode.\x20Use:\x20list,\x20apply,\x20create,\x20or\x20suggest');}}}return{'message':'Template\x20management\x20completed\x20('+mode+')','mode':mode,..._0x40396e};}async[a0_0x40f7e7(0x25d)](_0x2d8a06){const _0x34106f=a0_0x40f7e7,_0x47e5ef=Object['entries'](this['taskTemplates'])['map'](([_0x4e0564,_0x2b9103])=>({'id':_0x4e0564,'name':_0x2b9103['name'],'description':_0x2b9103['description'],'category':_0x2b9103[_0x34106f(0x145)],'taskCount':_0x2b9103['tasks']['length'],'type':'built-in'})),_0x4aa396=_0x2d8a06['customTemplates']||[],_0x114294=_0x4aa396['map'](_0xc007ee=>({..._0xc007ee,'type':_0x34106f(0x233)}));return{'builtInTemplates':_0x47e5ef,'customTemplates':_0x114294,'totalTemplates':_0x47e5ef[_0x34106f(0x228)]+_0x114294['length'],'categories':[...new Set(_0x47e5ef['map'](_0x1e571d=>_0x1e571d[_0x34106f(0x145)]))]};}async[a0_0x40f7e7(0x141)](_0x37c4b3,_0x68c2b7,_0x3b279b={}){const _0x183b84=a0_0x40f7e7,_0x571991=this['taskTemplates'][_0x68c2b7]||(_0x37c4b3['customTemplates']||[])['find'](_0x2fa61f=>_0x2fa61f['id']===_0x68c2b7);if(!_0x571991)throw new Error(_0x183b84(0x1f8)+_0x68c2b7);const _0x19cec1=[],_0x39794f=new Map(),_0x3b43d2=this['applyProjectContext'](_0x571991['tasks'],_0x3b279b);for(const _0x29d71d of _0x3b43d2){const _0x27f077={'id':'task-'+a0_0x592b6c(),'title':_0x29d71d[_0x183b84(0x24f)],'description':_0x29d71d['description'],'status':_0x183b84(0x13d),'priority':_0x29d71d[_0x183b84(0x24a)],'createdAt':new Date()[_0x183b84(0x24d)](),'updatedAt':new Date()[_0x183b84(0x24d)](),'templateId':_0x68c2b7,'templateOrigin':_0x571991[_0x183b84(0x1de)]||'built-in','source':_0x183b84(0x162)};_0x37c4b3[_0x183b84(0x1bf)][_0x183b84(0x24c)][_0x183b84(0x1a6)](_0x27f077),_0x19cec1['push'](_0x27f077),_0x39794f['set'](_0x29d71d[_0x183b84(0x24f)],_0x27f077['id']);}for(let _0x17d53d=0x0;_0x17d53d<_0x3b43d2[_0x183b84(0x228)];_0x17d53d++){const _0x54d066=_0x3b43d2[_0x17d53d],_0x4beb0c=_0x19cec1[_0x17d53d];if(_0x54d066[_0x183b84(0x1f0)]&&_0x54d066[_0x183b84(0x1f0)][_0x183b84(0x228)]>0x0){_0x4beb0c[_0x183b84(0x1f0)]=[];for(const _0x518951 of _0x54d066['dependencies']){const _0x2c35fc=_0x39794f['get'](_0x518951);_0x2c35fc&&(_0x4beb0c[_0x183b84(0x1f0)][_0x183b84(0x1a6)]({'taskId':_0x2c35fc,'type':'blocks','createdAt':new Date()['toISOString']()}),_0x4beb0c[_0x183b84(0x19b)]=_0x183b84(0x204));}}}return await this[_0x183b84(0x25a)](_0x37c4b3),{'template':{'id':_0x68c2b7,'name':_0x571991['name'],'description':_0x571991[_0x183b84(0x1c3)]},'tasksCreated':_0x19cec1['length'],'tasks':_0x19cec1['map'](_0x135aca=>({'id':_0x135aca['id'],'title':_0x135aca[_0x183b84(0x24f)],'priority':_0x135aca[_0x183b84(0x24a)],'status':_0x135aca[_0x183b84(0x19b)],'dependencies':_0x135aca[_0x183b84(0x1f0)]?_0x135aca[_0x183b84(0x1f0)]['length']:0x0})),'workflowStructure':this['generateWorkflowVisualization'](_0x19cec1)};}[a0_0x40f7e7(0x1f3)](_0x1025f2,_0x2780bc){const _0x585df2=a0_0x40f7e7;return _0x1025f2[_0x585df2(0x167)](_0x233dec=>{const _0x41cf16=_0x585df2;let _0x1723c1={..._0x233dec};return _0x2780bc[_0x41cf16(0x235)]&&(_0x1723c1['title']=_0x1723c1['title'][_0x41cf16(0x285)](/\[PROJECT\]/g,_0x2780bc['projectName']),_0x1723c1['description']=_0x1723c1['description']['replace'](/\[PROJECT\]/g,_0x2780bc['projectName'])),_0x2780bc['technology']&&(_0x1723c1[_0x41cf16(0x24f)]=_0x1723c1[_0x41cf16(0x24f)][_0x41cf16(0x285)](/\[TECH\]/g,_0x2780bc[_0x41cf16(0x1e2)]),_0x1723c1[_0x41cf16(0x1c3)]=_0x1723c1[_0x41cf16(0x1c3)]['replace'](/\[TECH\]/g,_0x2780bc['technology'])),_0x2780bc[_0x41cf16(0x246)]==='high'&&(_0x1723c1[_0x41cf16(0x24a)]=_0x1723c1[_0x41cf16(0x24a)]==='low'?'medium':_0x1723c1['priority']===_0x41cf16(0x19c)?'high':_0x41cf16(0x1d1)),_0x2780bc[_0x41cf16(0x21a)]===_0x41cf16(0x182)&&_0x1723c1[_0x41cf16(0x24a)]==='medium'&&(_0x1723c1['priority']='high'),_0x1723c1;});}async['createCustomTemplate'](_0x1a747f,_0x697d00){const _0x4dcdcd=a0_0x40f7e7,{name:_0x36ffe4,description:_0x233df8,category:_0x2bc98a,tasks:_0x1e52a9}=_0x697d00;if(!_0x36ffe4||!_0x1e52a9||_0x1e52a9['length']===0x0)throw new Error('Custom\x20template\x20requires\x20name\x20and\x20at\x20least\x20one\x20task');const _0x37df2a={'id':_0x4dcdcd(0x251)+Date['now']()+'-'+Math['random']()[_0x4dcdcd(0x15a)](0x24)[_0x4dcdcd(0x180)](0x2,0x9),'name':_0x36ffe4,'description':_0x233df8||_0x4dcdcd(0x256)+_0x36ffe4,'category':_0x2bc98a||'custom','tasks':_0x1e52a9[_0x4dcdcd(0x167)](_0x273419=>({'title':_0x273419[_0x4dcdcd(0x24f)],'description':_0x273419['description']||'','priority':_0x273419['priority']||'medium','dependencies':_0x273419['dependencies']||[]})),'createdAt':new Date()['toISOString'](),'type':'custom'};return!_0x1a747f[_0x4dcdcd(0x169)]&&(_0x1a747f[_0x4dcdcd(0x169)]=[]),_0x1a747f['customTemplates']['push'](_0x37df2a),{'template':{'id':_0x37df2a['id'],'name':_0x37df2a[_0x4dcdcd(0x234)],'description':_0x37df2a[_0x4dcdcd(0x1c3)],'category':_0x37df2a['category'],'taskCount':_0x37df2a['tasks'][_0x4dcdcd(0x228)]},'message':'Custom\x20template\x20created\x20successfully'};}async[a0_0x40f7e7(0x17b)](_0x385caa){const _0x4f7ea6=a0_0x40f7e7,_0x4eb59d=_0x385caa[_0x4f7ea6(0x1bf)]['tasks'],_0x532981=[],_0x1f9b8d=_0x4eb59d[_0x4f7ea6(0x167)](_0x472230=>_0x472230['title']['toLowerCase']()),_0x2f1fc2=_0x4eb59d[_0x4f7ea6(0x167)](_0x2843ac=>_0x2843ac['priority']);_0x1f9b8d[_0x4f7ea6(0x165)](_0x2a6edd=>_0x2a6edd['includes']('api')||_0x2a6edd['includes']('endpoint'))&&_0x532981[_0x4f7ea6(0x1a6)]({'templateId':_0x4f7ea6(0x202),'reason':_0x4f7ea6(0x1cb),'confidence':0.8});_0x1f9b8d[_0x4f7ea6(0x165)](_0xdaab14=>_0xdaab14['includes']('bug')||_0xdaab14['includes']('fix')||_0xdaab14[_0x4f7ea6(0x152)](_0x4f7ea6(0x206)))&&_0x532981[_0x4f7ea6(0x1a6)]({'templateId':'bug-fix','reason':'Detected\x20bug\x20fix\x20tasks','confidence':0.9});_0x1f9b8d['some'](_0x54339c=>_0x54339c[_0x4f7ea6(0x152)](_0x4f7ea6(0x255))||_0x54339c[_0x4f7ea6(0x152)]('implement'))&&_0x532981[_0x4f7ea6(0x1a6)]({'templateId':_0x4f7ea6(0x1fe),'reason':_0x4f7ea6(0x1fd),'confidence':0.7});_0x4eb59d[_0x4f7ea6(0x228)]>=0x5&&_0x2f1fc2[_0x4f7ea6(0x152)](_0x4f7ea6(0x280))&&_0x2f1fc2[_0x4f7ea6(0x152)](_0x4f7ea6(0x19c))&&_0x532981['push']({'templateId':'web-app-development','reason':_0x4f7ea6(0x27c),'confidence':0.6});const _0x32470e=_0x532981['map'](_0x50cc99=>{const _0xef7752=_0x4f7ea6,_0x2145d6=this[_0xef7752(0x149)][_0x50cc99['templateId']];return{..._0x50cc99,'templateName':_0x2145d6[_0xef7752(0x234)],'templateDescription':_0x2145d6['description'],'taskCount':_0x2145d6[_0xef7752(0x24c)]['length']};});return{'suggestions':_0x32470e,'analysisResults':{'existingTaskCount':_0x4eb59d['length'],'dominantPriority':this['getMostCommonPriority'](_0x2f1fc2),'detectedPatterns':_0x532981['map'](_0x1c7274=>_0x1c7274['reason'])}};}[a0_0x40f7e7(0x1e7)](_0x385174){const _0x1ce2a4=a0_0x40f7e7,_0x3b860c={'phases':[],'criticalPath':[],'parallelTasks':[]},_0x495d03=new Map(),processedTasks=new Set(),_0x58129d=_0x385174[_0x1ce2a4(0x191)](_0x2757c1=>!_0x2757c1['dependencies']||_0x2757c1[_0x1ce2a4(0x1f0)][_0x1ce2a4(0x228)]===0x0);_0x58129d['forEach'](_0x4d6d2c=>{const _0x3a3ff5=_0x1ce2a4;_0x495d03['set'](0x0,(_0x495d03['get'](0x0)||[])[_0x3a3ff5(0x213)]([_0x4d6d2c])),processedTasks[_0x3a3ff5(0x23f)](_0x4d6d2c['id']);});let _0x21ef08=0x0;while(processedTasks['size']<_0x385174['length']&&_0x21ef08<0xa){_0x21ef08++;const _0x954a3f=[];for(const _0x401e72 of _0x385174){if(processedTasks[_0x1ce2a4(0x227)](_0x401e72['id']))continue;_0x401e72['dependencies']&&_0x401e72['dependencies'][_0x1ce2a4(0x1bd)](_0x3b46fd=>processedTasks[_0x1ce2a4(0x227)](_0x3b46fd['taskId']))&&(_0x954a3f['push'](_0x401e72),processedTasks[_0x1ce2a4(0x23f)](_0x401e72['id']));}_0x954a3f['length']>0x0&&_0x495d03['set'](_0x21ef08,_0x954a3f);}for(const [_0x11c24b,_0x446ed8]of _0x495d03[_0x1ce2a4(0x263)]()){_0x3b860c['phases']['push']({'phase':_0x11c24b+0x1,'tasks':_0x446ed8[_0x1ce2a4(0x167)](_0x2e26ea=>({'id':_0x2e26ea['id'],'title':_0x2e26ea['title'],'priority':_0x2e26ea[_0x1ce2a4(0x24a)]})),'taskCount':_0x446ed8[_0x1ce2a4(0x228)],'canRunInParallel':_0x446ed8['length']>0x1});}return _0x3b860c;}['getMostCommonPriority'](_0x13a543){const _0x260505=a0_0x40f7e7;if(_0x13a543['length']===0x0)return _0x260505(0x19c);const _0x298bb6=_0x13a543['reduce']((_0x53ee6f,_0x11a016)=>{return _0x53ee6f[_0x11a016]=(_0x53ee6f[_0x11a016]||0x0)+0x1,_0x53ee6f;},{});return Object[_0x260505(0x1ef)](_0x298bb6)[_0x260505(0x257)]((_0x38385,_0xd71916)=>_0x298bb6[_0x38385]>_0x298bb6[_0xd71916]?_0x38385:_0xd71916);}async[a0_0x40f7e7(0x203)](_0x33fe8f,_0x1fbfed){const _0x5314ba=a0_0x40f7e7,{mode:mode='update',taskId:_0x56037f,stage:_0x45439c,milestone:_0x189250,note:_0x53fb79,percentage:_0x3b2004}=_0x1fbfed;let _0x15db38={};if(mode==='update'&&_0x56037f)_0x15db38=await this[_0x5314ba(0x201)](_0x33fe8f,_0x56037f,{'stage':_0x45439c,'milestone':_0x189250,'note':_0x53fb79,'percentage':_0x3b2004});else{if(mode===_0x5314ba(0x1d3))_0x15db38=await this['getProgressOverview'](_0x33fe8f);else{if(mode===_0x5314ba(0x23c)&&_0x56037f)_0x15db38=await this['manageMilestones'](_0x33fe8f,_0x56037f,_0x1fbfed);else{if(mode===_0x5314ba(0x181))_0x15db38=await this['calculateTaskProgress'](_0x33fe8f,_0x56037f);else throw new Error(_0x5314ba(0x14c));}}}return{'message':_0x5314ba(0x289)+mode+')','mode':mode,..._0x15db38};}async['updateTaskProgress'](_0x215d3a,_0x49d05b,_0x24130a){const _0x4b4479=a0_0x40f7e7,_0x53143b=_0x215d3a[_0x4b4479(0x1bf)][_0x4b4479(0x24c)]['find'](_0x594f6a=>_0x594f6a['id']===_0x49d05b);if(!_0x53143b)throw new Error('Task\x20not\x20found:\x20'+_0x49d05b);!_0x53143b['progress']&&(_0x53143b[_0x4b4479(0x179)]={'stage':_0x4b4479(0x17c),'percentage':0x0,'milestones':[],'notes':[],'stageHistory':[]});const _0x23852d=_0x53143b['progress']['stage'];if(_0x24130a['stage']){if(!this[_0x4b4479(0x133)]['includes'](_0x24130a['stage']))throw new Error(_0x4b4479(0x187)+_0x24130a[_0x4b4479(0x223)]+'.\x20Must\x20be:\x20'+this['progressStages'][_0x4b4479(0x1f5)](',\x20'));_0x53143b[_0x4b4479(0x179)][_0x4b4479(0x223)]=_0x24130a[_0x4b4479(0x223)],_0x53143b[_0x4b4479(0x179)][_0x4b4479(0x160)]['push']({'from':_0x23852d,'to':_0x24130a[_0x4b4479(0x223)],'timestamp':new Date()['toISOString']()});if(_0x24130a[_0x4b4479(0x223)]===_0x4b4479(0x17c)&&_0x53143b['status']===_0x4b4479(0x1c2))_0x53143b[_0x4b4479(0x19b)]='pending';else{if([_0x4b4479(0x21d),_0x4b4479(0x22a),_0x4b4479(0x12e),'review'][_0x4b4479(0x152)](_0x24130a['stage'])&&_0x53143b[_0x4b4479(0x19b)]===_0x4b4479(0x13d))_0x53143b['status']=_0x4b4479(0x1c2);else _0x24130a[_0x4b4479(0x223)]===_0x4b4479(0x283)&&_0x53143b['status']!==_0x4b4479(0x283)&&(_0x53143b[_0x4b4479(0x19b)]='completed',_0x53143b['completedAt']=new Date()['toISOString']());}}if(_0x24130a['percentage']!==undefined){const _0x38fa16=Math['max'](0x0,Math['min'](0x64,parseInt(_0x24130a[_0x4b4479(0x1b1)])));_0x53143b[_0x4b4479(0x179)]['percentage']=_0x38fa16;if(_0x38fa16===0x0&&_0x53143b[_0x4b4479(0x179)][_0x4b4479(0x223)]!=='not_started')_0x53143b['progress']['stage']='not_started';else{if(_0x38fa16>0x0&&_0x38fa16<0x19&&_0x53143b['progress'][_0x4b4479(0x223)]==='not_started')_0x53143b['progress']['stage']=_0x4b4479(0x21d);else{if(_0x38fa16>=0x19&&_0x38fa16<0x4b&&['not_started',_0x4b4479(0x21d)]['includes'](_0x53143b[_0x4b4479(0x179)]['stage']))_0x53143b['progress'][_0x4b4479(0x223)]='in_development';else{if(_0x38fa16>=0x4b&&_0x38fa16<0x5f&&_0x53143b[_0x4b4479(0x179)]['stage']!==_0x4b4479(0x12e))_0x53143b['progress'][_0x4b4479(0x223)]='testing';else{if(_0x38fa16>=0x5f&&_0x38fa16<0x64&&_0x53143b['progress'][_0x4b4479(0x223)]!=='review')_0x53143b[_0x4b4479(0x179)]['stage']=_0x4b4479(0x148);else _0x38fa16===0x64&&(_0x53143b[_0x4b4479(0x179)][_0x4b4479(0x223)]=_0x4b4479(0x283),_0x53143b[_0x4b4479(0x19b)]='completed',_0x53143b[_0x4b4479(0x1ad)]=new Date()[_0x4b4479(0x24d)]());}}}}}if(_0x24130a[_0x4b4479(0x276)]){const _0x35ac55={'id':_0x4b4479(0x26a)+Date['now']()+'-'+Math[_0x4b4479(0x183)]()[_0x4b4479(0x15a)](0x24)['substr'](0x2,0x9),'type':_0x24130a[_0x4b4479(0x276)][_0x4b4479(0x1de)]||'checkpoint','title':_0x24130a['milestone']['title']||'Progress\x20Milestone','description':_0x24130a[_0x4b4479(0x276)]['description']||'','achievedAt':new Date()[_0x4b4479(0x24d)](),'stage':_0x53143b['progress'][_0x4b4479(0x223)]};_0x53143b[_0x4b4479(0x179)]['milestones']['push'](_0x35ac55);}return _0x24130a['note']&&_0x53143b[_0x4b4479(0x179)]['notes'][_0x4b4479(0x1a6)]({'id':_0x4b4479(0x16a)+Date['now']()+'-'+Math[_0x4b4479(0x183)]()[_0x4b4479(0x15a)](0x24)['substr'](0x2,0x9),'content':_0x24130a[_0x4b4479(0x135)],'timestamp':new Date()['toISOString'](),'stage':_0x53143b[_0x4b4479(0x179)]['stage']}),_0x53143b[_0x4b4479(0x267)]=new Date()['toISOString'](),_0x53143b['parentTaskId']&&await this[_0x4b4479(0x14b)](_0x215d3a,_0x53143b['parentTaskId']),{'task':{'id':_0x53143b['id'],'title':_0x53143b['title'],'status':_0x53143b[_0x4b4479(0x19b)],'progress':_0x53143b[_0x4b4479(0x179)]},'changes':{'stageChanged':_0x23852d!==_0x53143b['progress'][_0x4b4479(0x223)],'oldStage':_0x23852d,'newStage':_0x53143b['progress'][_0x4b4479(0x223)],'milestoneAdded':!!_0x24130a['milestone'],'noteAdded':!!_0x24130a[_0x4b4479(0x135)]}};}async['getProgressOverview'](_0x5160ce){const _0x51e850=a0_0x40f7e7,_0x25b9d6=_0x5160ce['taskList'][_0x51e850(0x24c)],_0x2b7195=_0x25b9d6[_0x51e850(0x167)](_0x5c2cbd=>{const _0x59503a=_0x51e850,_0x101e57=_0x5c2cbd['progress']||{'stage':_0x59503a(0x17c),'percentage':0x0,'milestones':[],'notes':[]};return{'id':_0x5c2cbd['id'],'title':_0x5c2cbd[_0x59503a(0x24f)],'status':_0x5c2cbd['status'],'priority':_0x5c2cbd['priority'],'stage':_0x101e57[_0x59503a(0x223)],'percentage':_0x101e57[_0x59503a(0x1b1)],'milestoneCount':_0x101e57[_0x59503a(0x23c)]?_0x101e57['milestones']['length']:0x0,'isBlocked':_0x5c2cbd[_0x59503a(0x19b)]==='blocked','hasSubtasks':!!(_0x5c2cbd['subtasks']&&_0x5c2cbd['subtasks']['length']>0x0),'parentTaskId':_0x5c2cbd['parentTaskId']};}),_0x593577={'totalTasks':_0x25b9d6['length'],'byStage':{},'byStatus':{},'averageProgress':0x0,'blockedTasks':0x0,'completedTasks':0x0};this[_0x51e850(0x133)]['forEach'](_0xa2d478=>{const _0x22e738=_0x51e850;_0x593577[_0x22e738(0x1bc)][_0xa2d478]=_0x2b7195['filter'](_0x1fffd6=>_0x1fffd6[_0x22e738(0x223)]===_0xa2d478)[_0x22e738(0x228)];}),this[_0x51e850(0x1db)][_0x51e850(0x1fa)](_0xd8f748=>{const _0x5eb840=_0x51e850;_0x593577[_0x5eb840(0x144)][_0xd8f748]=_0x2b7195['filter'](_0x437dcb=>_0x437dcb['status']===_0xd8f748)['length'];}),_0x593577['averageProgress']=_0x25b9d6['length']>0x0?Math[_0x51e850(0x23a)](_0x2b7195['reduce']((_0x3c17b0,_0x2fea52)=>_0x3c17b0+_0x2fea52[_0x51e850(0x1b1)],0x0)/_0x25b9d6[_0x51e850(0x228)]):0x0,_0x593577[_0x51e850(0x208)]=_0x593577['byStatus'][_0x51e850(0x204)]||0x0,_0x593577['completedTasks']=_0x593577[_0x51e850(0x144)][_0x51e850(0x283)]||0x0;const _0x431452=_0x2b7195['filter'](_0x5df7a9=>_0x5df7a9[_0x51e850(0x24a)]==='urgent'&&_0x5df7a9[_0x51e850(0x19b)]!=='completed'),_0x44b6c5=_0x2b7195[_0x51e850(0x191)](_0x216e59=>_0x216e59['isBlocked']&&this[_0x51e850(0x245)](_0x216e59['id'],_0x25b9d6)[_0x51e850(0x228)]>0x0);return{'overview':_0x593577,'tasks':_0x2b7195,'criticalTasks':_0x431452,'bottlenecks':_0x44b6c5[_0x51e850(0x167)](_0x2217cd=>({'taskId':_0x2217cd['id'],'title':_0x2217cd['title'],'blockedTasksCount':this['findTasksBlockedBy'](_0x2217cd['id'],_0x25b9d6)['length']})),'recommendations':this['generateProgressRecommendations'](_0x2b7195,_0x593577)};}async[a0_0x40f7e7(0x14b)](_0x250896,_0x7748c9){const _0x10c418=a0_0x40f7e7,_0x26094f=_0x250896[_0x10c418(0x1bf)][_0x10c418(0x24c)]['find'](_0x4d82ee=>_0x4d82ee['id']===_0x7748c9);if(!_0x26094f)throw new Error('Task\x20not\x20found:\x20'+_0x7748c9);!_0x26094f['progress']&&(_0x26094f[_0x10c418(0x179)]={'stage':_0x10c418(0x17c),'percentage':0x0,'milestones':[],'notes':[],'stageHistory':[]});let _0x360ad3=0x0,_0x1d477c='manual';if(_0x26094f[_0x10c418(0x1a2)]&&_0x26094f['subtasks']['length']>0x0){const _0x37ef53=_0x26094f[_0x10c418(0x1a2)][_0x10c418(0x167)](_0x335db1=>_0x250896['taskList']['tasks']['find'](_0x6d0838=>_0x6d0838['id']===_0x335db1))['filter'](Boolean);if(_0x37ef53[_0x10c418(0x228)]>0x0){const _0x1f3f62=_0x37ef53['map'](_0x4b453b=>{const _0x568e7=_0x10c418;if(_0x4b453b['status']===_0x568e7(0x283))return 0x64;if(_0x4b453b[_0x568e7(0x179)]&&_0x4b453b['progress']['percentage']!==undefined)return _0x4b453b[_0x568e7(0x179)][_0x568e7(0x1b1)];return _0x4b453b[_0x568e7(0x19b)]===_0x568e7(0x1c2)?0x19:0x0;});_0x360ad3=Math[_0x10c418(0x23a)](_0x1f3f62['reduce']((_0x51e017,_0x39a117)=>_0x51e017+_0x39a117,0x0)/_0x37ef53['length']),_0x1d477c=_0x10c418(0x1a2);}}else{if(_0x26094f['dependencies']&&_0x26094f['dependencies']['length']>0x0){const _0x5dc89e=_0x26094f['dependencies']['filter'](_0x5376d9=>{const _0x420f2e=_0x10c418,_0x7efb55=_0x250896['taskList'][_0x420f2e(0x24c)]['find'](_0x44e19f=>_0x44e19f['id']===_0x5376d9[_0x420f2e(0x1d8)]);return _0x7efb55&&_0x7efb55['status']===_0x420f2e(0x283);})[_0x10c418(0x228)],_0x4bb518=_0x5dc89e/_0x26094f[_0x10c418(0x1f0)][_0x10c418(0x228)]*0x1e,_0x190f22=_0x26094f['status']==='completed'?0x46:_0x26094f[_0x10c418(0x19b)]==='in_progress'?0x23:0x0;_0x360ad3=Math['round'](_0x4bb518+_0x190f22),_0x1d477c='dependencies';}else{if(_0x26094f[_0x10c418(0x19b)]===_0x10c418(0x283))_0x360ad3=0x64;else{if(_0x26094f['status']===_0x10c418(0x1c2))_0x360ad3=_0x26094f[_0x10c418(0x179)][_0x10c418(0x1b1)]||0x32;else{if(_0x26094f['status']===_0x10c418(0x13d))_0x360ad3=0x0;else{if(_0x26094f[_0x10c418(0x19b)]===_0x10c418(0x204))_0x360ad3=_0x26094f['progress'][_0x10c418(0x1b1)]||0x0;}}}_0x1d477c=_0x10c418(0x19b);}}_0x26094f[_0x10c418(0x179)][_0x10c418(0x271)]=_0x360ad3,_0x26094f[_0x10c418(0x179)]['calculationMethod']=_0x1d477c,_0x26094f['progress']['lastCalculated']=new Date()[_0x10c418(0x24d)]();const _0x5e3d2e=_0x26094f['progress'][_0x10c418(0x160)][_0x10c418(0x228)]>0x0&&Date['now']()-new Date(_0x26094f['progress'][_0x10c418(0x160)][_0x26094f['progress'][_0x10c418(0x160)]['length']-0x1][_0x10c418(0x142)])['getTime']()<0x493e0;if(!_0x5e3d2e){const _0x19d54c=this['getStageFromPercentage'](_0x360ad3);_0x19d54c!==_0x26094f[_0x10c418(0x179)]['stage']&&(_0x26094f[_0x10c418(0x179)]['stage']=_0x19d54c,_0x26094f['progress'][_0x10c418(0x160)][_0x10c418(0x1a6)]({'from':_0x26094f[_0x10c418(0x179)]['stage'],'to':_0x19d54c,'timestamp':new Date()[_0x10c418(0x24d)](),'automatic':!![]}));}return _0x26094f[_0x10c418(0x267)]=new Date()['toISOString'](),{'taskId':_0x26094f['id'],'title':_0x26094f[_0x10c418(0x24f)],'calculatedPercentage':_0x360ad3,'calculationMethod':_0x1d477c,'manualPercentage':_0x26094f['progress']['percentage'],'stage':_0x26094f[_0x10c418(0x179)][_0x10c418(0x223)],'subtaskCount':_0x26094f['subtasks']?_0x26094f['subtasks']['length']:0x0,'dependencyCount':_0x26094f[_0x10c418(0x1f0)]?_0x26094f[_0x10c418(0x1f0)]['length']:0x0};}[a0_0x40f7e7(0x177)](_0x27df4e,_0x3349df){const _0x3729a1=a0_0x40f7e7,_0x401c7e=[];_0x3349df['blockedTasks']>0x0&&_0x401c7e[_0x3729a1(0x1a6)]({'type':_0x3729a1(0x1d1),'category':_0x3729a1(0x259),'message':_0x3349df['blockedTasks']+_0x3729a1(0x262),'actionable':!![]});const _0x504b8b=_0x27df4e['filter'](_0x15f3b8=>_0x15f3b8[_0x3729a1(0x19b)]===_0x3729a1(0x1c2)&&_0x15f3b8[_0x3729a1(0x1b1)]<0x19);_0x504b8b[_0x3729a1(0x228)]>0x0&&_0x401c7e[_0x3729a1(0x1a6)]({'type':_0x3729a1(0x1a7),'category':_0x3729a1(0x266),'message':_0x504b8b['length']+'\x20tasks\x20are\x20in\x20progress\x20but\x20showing\x20low\x20progress.\x20Consider\x20breaking\x20them\x20into\x20smaller\x20subtasks.','actionable':!![]});const _0x3c0e4c=_0x27df4e['filter'](_0x57163c=>_0x57163c['percentage']>=0x5a&&_0x57163c['status']!=='completed');return _0x3c0e4c['length']>0x0&&_0x401c7e[_0x3729a1(0x1a6)]({'type':_0x3729a1(0x1d4),'category':'near_completion','message':_0x3c0e4c['length']+'\x20tasks\x20are\x20near\x20completion.\x20Focus\x20on\x20finishing\x20these\x20for\x20quick\x20wins.','actionable':!![]}),_0x3349df['averageProgress']<0x19&&_0x401c7e[_0x3729a1(0x1a6)]({'type':'info','category':_0x3729a1(0x1a8),'message':'Overall\x20progress\x20is\x20low.\x20Consider\x20prioritizing\x20and\x20focusing\x20on\x20fewer\x20tasks.','actionable':![]}),_0x401c7e;}[a0_0x40f7e7(0x1b4)](_0x16e812){const _0x24f787=a0_0x40f7e7;if(_0x16e812===0x0)return _0x24f787(0x17c);if(_0x16e812<0x19)return _0x24f787(0x21d);if(_0x16e812<0x4b)return _0x24f787(0x22a);if(_0x16e812<0x5f)return'testing';if(_0x16e812<0x64)return'review';return _0x24f787(0x283);}['setScheduler'](_0x40efe4){const _0x399b50=a0_0x40f7e7;this[_0x399b50(0x1fc)]=_0x40efe4,this['logger']?.['info'](_0x399b50(0x1cf));}async[a0_0x40f7e7(0x26b)](_0x414cb5,_0x22567c){const _0x28399c=a0_0x40f7e7,{mode:mode=_0x28399c(0x1e3),taskId:_0x45c6bb}=_0x22567c;let _0x39d841={};if(mode==='auto')_0x39d841=await this[_0x28399c(0x25a)](_0x414cb5);else{if(mode===_0x28399c(0x1ca)&&_0x45c6bb)_0x39d841=await this[_0x28399c(0x16b)](_0x414cb5,_0x45c6bb);else{if(mode===_0x28399c(0x175))_0x39d841=await this['balanceCrossAgentPriorities'](_0x414cb5);else throw new Error('Invalid\x20prioritization\x20mode.\x20Use:\x20auto,\x20analyze,\x20or\x20balance');}}return{'message':_0x28399c(0x1c5)+mode+')','mode':mode,..._0x39d841};}async['autoPrioritizeAllTasks'](_0x138b67){const _0x150d6c=a0_0x40f7e7,_0x1cdb79=_0x138b67['taskList'][_0x150d6c(0x24c)][_0x150d6c(0x191)](_0xe9398a=>_0xe9398a['status']==='pending'||_0xe9398a[_0x150d6c(0x19b)]===_0x150d6c(0x1c2));if(_0x1cdb79[_0x150d6c(0x228)]===0x0)return{'message':'No\x20active\x20tasks\x20to\x20prioritize'};const _0x31c49f=_0x1cdb79[_0x150d6c(0x167)](_0x2f6bbd=>({..._0x2f6bbd,'priorityScore':this['calculatePriorityScore'](_0x2f6bbd,_0x138b67[_0x150d6c(0x1bf)]['tasks']),'originalPriority':_0x2f6bbd[_0x150d6c(0x24a)]}));_0x31c49f['sort']((_0x261a90,_0x29b395)=>_0x29b395['priorityScore']-_0x261a90[_0x150d6c(0x17e)]);const _0x5b12fb=[_0x150d6c(0x1d1),'high',_0x150d6c(0x19c),_0x150d6c(0x236)],_0x8b8a03=[];return _0x31c49f[_0x150d6c(0x1fa)]((_0x395878,_0x4637ba)=>{const _0x2dc327=_0x150d6c,_0xe4328f=Math[_0x2dc327(0x214)](Math[_0x2dc327(0x224)](_0x4637ba/Math['max'](0x1,_0x1cdb79['length']/0x4)),_0x5b12fb[_0x2dc327(0x228)]-0x1),_0x735203=_0x5b12fb[_0xe4328f];if(_0x395878[_0x2dc327(0x281)]!==_0x735203){const _0x4f0e2a=_0x138b67['taskList'][_0x2dc327(0x24c)][_0x2dc327(0x146)](_0x4203e7=>_0x4203e7['id']===_0x395878['id']);_0x4f0e2a[_0x2dc327(0x24a)]=_0x735203,_0x4f0e2a[_0x2dc327(0x267)]=new Date()['toISOString'](),_0x4f0e2a[_0x2dc327(0x17e)]=_0x395878['priorityScore'],_0x4f0e2a['priorityReason']=this['generatePriorityReason'](_0x395878),_0x8b8a03[_0x2dc327(0x1a6)]({'id':_0x395878['id'],'title':_0x395878[_0x2dc327(0x24f)],'oldPriority':_0x395878['originalPriority'],'newPriority':_0x735203,'score':_0x395878['priorityScore'][_0x2dc327(0x1f4)](0x2),'reason':_0x4f0e2a[_0x2dc327(0x274)]});}}),{'totalTasks':_0x1cdb79['length'],'updatedTasks':_0x8b8a03[_0x150d6c(0x228)],'changes':_0x8b8a03};}['calculatePriorityScore'](_0xa94d1c,_0x12cff9){const _0x822e1d=a0_0x40f7e7;let _0x3bab34=0x0;const _0x1660bf={'urgent':0x4,'high':0x3,'medium':0x2,'low':0x1};_0x3bab34+=_0x1660bf[_0xa94d1c['priority']]*this[_0x822e1d(0x15f)]['userPriority'];const _0xfdfe36=(Date['now']()-new Date(_0xa94d1c['createdAt'])[_0x822e1d(0x1d2)]())/(0x3e8*0x3c*0x3c);_0x3bab34+=Math[_0x822e1d(0x214)](_0xfdfe36/0x18,0x3)*this[_0x822e1d(0x15f)]['age'];const _0x2f0ab5=this['findTasksBlockedBy'](_0xa94d1c['id'],_0x12cff9);_0x3bab34+=_0x2f0ab5[_0x822e1d(0x228)]*this['priorityWeights']['blocking'];const _0x42cc7f=(_0xa94d1c[_0x822e1d(0x1f0)]||[])['length'];_0x3bab34+=Math[_0x822e1d(0x214)](_0x42cc7f,0x3)*this['priorityWeights']['dependency'];const _0x29aa68=(_0xa94d1c['subtasks']||[])[_0x822e1d(0x228)];return _0x3bab34+=Math['min'](_0x29aa68,0x2)*this[_0x822e1d(0x15f)]['dependency'],_0x3bab34;}[a0_0x40f7e7(0x245)](_0x55ebea,_0x3a9885){const _0x51fa42=a0_0x40f7e7;return _0x3a9885[_0x51fa42(0x191)](_0x28c0c3=>{const _0x5e3399=_0x51fa42;if(!_0x28c0c3[_0x5e3399(0x1f0)])return![];return _0x28c0c3[_0x5e3399(0x1f0)]['some'](_0x2fed45=>_0x2fed45[_0x5e3399(0x1d8)]===_0x55ebea&&_0x2fed45[_0x5e3399(0x1de)]===_0x5e3399(0x173));});}[a0_0x40f7e7(0x1b2)](_0x23e873){const _0xf83a0a=a0_0x40f7e7,_0x2ed5e8=[];_0x23e873['priorityScore']>0x8&&_0x2ed5e8['push']('high\x20overall\x20impact');const _0x4d587b=(Date['now']()-new Date(_0x23e873['createdAt'])[_0xf83a0a(0x1d2)]())/(0x3e8*0x3c*0x3c);return _0x4d587b>0x18&&_0x2ed5e8['push']('overdue\x20task'),_0x23e873['priority']==='urgent'&&_0x2ed5e8[_0xf83a0a(0x1a6)](_0xf83a0a(0x222)),(_0x23e873[_0xf83a0a(0x1a2)]||[])[_0xf83a0a(0x228)]>0x0&&_0x2ed5e8[_0xf83a0a(0x1a6)]('has\x20subtasks'),_0x2ed5e8[_0xf83a0a(0x228)]>0x0?_0x2ed5e8[_0xf83a0a(0x1f5)](',\x20'):'standard\x20prioritization';}async['analyzeTaskPriority'](_0x5631a5,_0x35e40c){const _0x4d03d9=a0_0x40f7e7,_0x3fde0a=_0x5631a5['taskList'][_0x4d03d9(0x24c)][_0x4d03d9(0x146)](_0xae208b=>_0xae208b['id']===_0x35e40c);if(!_0x3fde0a)throw new Error(_0x4d03d9(0x12b)+_0x35e40c);const _0x165853=this[_0x4d03d9(0x19e)](_0x3fde0a,_0x5631a5['taskList'][_0x4d03d9(0x24c)]),_0x5870f1=this['findTasksBlockedBy'](_0x35e40c,_0x5631a5[_0x4d03d9(0x1bf)][_0x4d03d9(0x24c)]),_0x40cf8d=this[_0x4d03d9(0x1b2)]({..._0x3fde0a,'priorityScore':_0x165853});return{'task':{'id':_0x3fde0a['id'],'title':_0x3fde0a['title'],'currentPriority':_0x3fde0a[_0x4d03d9(0x24a)],'priorityScore':_0x165853['toFixed'](0x2),'reason':_0x40cf8d},'analysis':{'blocksOtherTasks':_0x5870f1[_0x4d03d9(0x228)],'ageInHours':((Date['now']()-new Date(_0x3fde0a['createdAt'])['getTime']())/(0x3e8*0x3c*0x3c))[_0x4d03d9(0x1f4)](0x1),'dependencyCount':(_0x3fde0a['dependencies']||[])['length'],'subtaskCount':(_0x3fde0a['subtasks']||[])[_0x4d03d9(0x228)]},'blockedTasks':_0x5870f1['map'](_0x56e055=>({'id':_0x56e055['id'],'title':_0x56e055[_0x4d03d9(0x24f)]}))};}async['balanceCrossAgentPriorities'](_0x545fce){const _0x34a632=a0_0x40f7e7;if(!this['scheduler']||typeof this[_0x34a632(0x1fc)]['getAllAgents']!=='function')return{'message':'Cross-agent\x20balancing\x20requires\x20scheduler\x20integration'};try{const _0x1265d8=await this[_0x34a632(0x1fc)]['getAllAgents'](),_0x408252=[];return _0x1265d8['forEach'](_0xd75502=>{const _0x27384c=_0x34a632;if(_0xd75502['taskList']&&_0xd75502[_0x27384c(0x1bf)][_0x27384c(0x24c)]){const _0x49ff8f=_0xd75502[_0x27384c(0x1bf)][_0x27384c(0x24c)][_0x27384c(0x191)](_0xd8cc80=>_0xd8cc80['status']===_0x27384c(0x13d)||_0xd8cc80[_0x27384c(0x19b)]==='in_progress'),_0x2c2872=_0x49ff8f[_0x27384c(0x191)](_0xa3eb40=>_0xa3eb40[_0x27384c(0x24a)]==='urgent')[_0x27384c(0x228)],_0x26889b=_0x49ff8f[_0x27384c(0x191)](_0x20aba4=>_0x20aba4[_0x27384c(0x24a)]==='high')[_0x27384c(0x228)];_0x408252['push']({'agentId':_0xd75502['id'],'agentName':_0xd75502[_0x27384c(0x234)],'totalActive':_0x49ff8f['length'],'urgent':_0x2c2872,'high':_0x26889b,'workloadScore':_0x2c2872*0x3+_0x26889b*0x2+_0x49ff8f[_0x27384c(0x228)]});}}),_0x408252[_0x34a632(0x23d)]((_0x1695c2,_0x25a307)=>_0x1695c2['workloadScore']-_0x25a307[_0x34a632(0x238)]),{'currentAgent':{'agentId':_0x545fce['id'],'rank':_0x408252['findIndex'](_0x41dc70=>_0x41dc70[_0x34a632(0x17f)]===_0x545fce['id'])+0x1,'totalAgents':_0x408252['length']},'workloadDistribution':_0x408252,'recommendation':this['generateBalancingRecommendation'](_0x545fce,_0x408252)};}catch(_0x548981){return{'error':'Cross-agent\x20balancing\x20failed:\x20'+_0x548981['message'],'fallback':_0x34a632(0x217)};}}['generateBalancingRecommendation'](_0x5dbf0d,_0x3b07a1){const _0x12d073=a0_0x40f7e7,_0xd791dd=_0x3b07a1[_0x12d073(0x146)](_0x35c1f7=>_0x35c1f7[_0x12d073(0x17f)]===_0x5dbf0d['id']);if(!_0xd791dd)return _0x12d073(0x1be);const _0x8a44b5=_0x3b07a1['reduce']((_0x16dd03,_0x36edfa)=>_0x16dd03+_0x36edfa[_0x12d073(0x238)],0x0)/_0x3b07a1[_0x12d073(0x228)];if(_0xd791dd['workloadScore']>_0x8a44b5*1.5)return _0x12d073(0x1dc);else return _0xd791dd[_0x12d073(0x238)]<_0x8a44b5*0.5?'Agent\x20has\x20capacity\x20for\x20additional\x20high-priority\x20tasks':_0x12d073(0x1d7);}[a0_0x40f7e7(0x16f)](_0x3d339c){const _0x565c34=a0_0x40f7e7,_0x156834=_0x3d339c['tasks'];return{'total':_0x156834['length'],'pending':_0x156834[_0x565c34(0x191)](_0x29729f=>_0x29729f[_0x565c34(0x19b)]===_0x565c34(0x13d))['length'],'in_progress':_0x156834['filter'](_0x4fc682=>_0x4fc682[_0x565c34(0x19b)]==='in_progress')[_0x565c34(0x228)],'completed':_0x156834['filter'](_0x40a7d4=>_0x40a7d4[_0x565c34(0x19b)]==='completed')[_0x565c34(0x228)],'cancelled':_0x156834['filter'](_0xa60246=>_0xa60246[_0x565c34(0x19b)]===_0x565c34(0x178))['length'],'high_priority':_0x156834['filter'](_0x3fc5c8=>_0x3fc5c8['priority']===_0x565c34(0x280)&&(_0x3fc5c8['status']==='pending'||_0x3fc5c8[_0x565c34(0x19b)]==='in_progress'))[_0x565c34(0x228)]};}async['generateAnalytics'](_0x4f6e9b,_0x2d32f7){const _0x26a0ab=a0_0x40f7e7,{mode:mode=_0x26a0ab(0x199),timeframe:timeframe='30',reportType:reportType='comprehensive',agentId:_0x403d7b}=_0x2d32f7;let _0x1eb0d6={};switch(mode){case'summary':_0x1eb0d6=await this['getAnalyticsSummary'](_0x4f6e9b,timeframe);break;case'performance':_0x1eb0d6=await this[_0x26a0ab(0x24b)](_0x4f6e9b,timeframe);break;case _0x26a0ab(0x215):_0x1eb0d6=await this[_0x26a0ab(0x231)](_0x4f6e9b,timeframe);break;case _0x26a0ab(0x21a):_0x1eb0d6=await this[_0x26a0ab(0x171)](timeframe);break;case'export':_0x1eb0d6=await this[_0x26a0ab(0x163)](_0x4f6e9b,_0x2d32f7);break;case _0x26a0ab(0x229):_0x1eb0d6=await this[_0x26a0ab(0x13f)](_0x4f6e9b,timeframe);break;default:throw new Error('Invalid analytics mode. Use: summary, performance, trends, team, export, or insights');}return{'message':'Analytics\x20report\x20generated\x20('+mode+')','mode':mode,'timeframe':timeframe,'generatedAt':new Date()['toISOString'](),..._0x1eb0d6};}async[a0_0x40f7e7(0x13a)](_0x10f2e0,_0x56bf05){const _0x427e3b=a0_0x40f7e7,_0x3c9524=_0x10f2e0['taskList'][_0x427e3b(0x24c)],_0x554764=new Date(Date['now']()-parseInt(_0x56bf05)*0x18*0x3c*0x3c*0x3e8),_0x6ee57=_0x3c9524['filter'](_0x574284=>new Date(_0x574284['createdAt'])>=_0x554764),_0x167f05={'overview':{'totalTasks':_0x6ee57['length'],'completed':_0x6ee57['filter'](_0x20a8a1=>_0x20a8a1[_0x427e3b(0x19b)]==='completed')[_0x427e3b(0x228)],'inProgress':_0x6ee57['filter'](_0x2f789b=>_0x2f789b[_0x427e3b(0x19b)]===_0x427e3b(0x1c2))[_0x427e3b(0x228)],'pending':_0x6ee57[_0x427e3b(0x191)](_0x547e76=>_0x547e76[_0x427e3b(0x19b)]==='pending')['length'],'cancelled':_0x6ee57['filter'](_0x2673ab=>_0x2673ab[_0x427e3b(0x19b)]==='cancelled')[_0x427e3b(0x228)],'blocked':_0x6ee57['filter'](_0x2107b2=>_0x2107b2['status']===_0x427e3b(0x204))[_0x427e3b(0x228)]},'priorityBreakdown':{'urgent':_0x6ee57['filter'](_0x47cf68=>_0x47cf68[_0x427e3b(0x24a)]===_0x427e3b(0x1d1))['length'],'high':_0x6ee57['filter'](_0x4f49fa=>_0x4f49fa[_0x427e3b(0x24a)]==='high')['length'],'medium':_0x6ee57[_0x427e3b(0x191)](_0x80fe=>_0x80fe['priority']===_0x427e3b(0x19c))['length'],'low':_0x6ee57['filter'](_0x55ddf1=>_0x55ddf1[_0x427e3b(0x24a)]===_0x427e3b(0x236))[_0x427e3b(0x228)]},'progressMetrics':this['calculateProgressMetrics'](_0x6ee57),'dependencyMetrics':this['calculateDependencyMetrics'](_0x6ee57),'templateUsage':this['calculateTemplateUsage'](_0x6ee57)};_0x167f05[_0x427e3b(0x154)]=_0x167f05['overview']['totalTasks']>0x0?Math['round'](_0x167f05['overview']['completed']/_0x167f05['overview']['totalTasks']*0x64):0x0;const _0x132010=_0x6ee57[_0x427e3b(0x191)](_0x1d4dd8=>_0x1d4dd8[_0x427e3b(0x19b)]!==_0x427e3b(0x283)&&_0x1d4dd8['status']!==_0x427e3b(0x178));return _0x167f05[_0x427e3b(0x226)]=_0x132010[_0x427e3b(0x228)]>0x0?Math['round'](_0x132010['reduce']((_0x5c6564,_0x45f44b)=>{const _0x293cc7=_0x427e3b;return _0x5c6564+(Date['now']()-new Date(_0x45f44b[_0x293cc7(0x1eb)])['getTime']())/(0x3e8*0x3c*0x3c*0x18);},0x0)/_0x132010['length']):0x0,{'summary':_0x167f05,'insights':this['generateSummaryInsights'](_0x167f05)};}async['getPerformanceMetrics'](_0x532f40,_0x3e3983){const _0x1ef49f=a0_0x40f7e7,_0x2e3288=_0x532f40[_0x1ef49f(0x1bf)]['tasks'],_0x5c950b=new Date(Date['now']()-parseInt(_0x3e3983)*0x18*0x3c*0x3c*0x3e8),_0x2cb302=_0x2e3288[_0x1ef49f(0x191)](_0x3c74ee=>_0x3c74ee[_0x1ef49f(0x19b)]==='completed'&&_0x3c74ee['completedAt']&&new Date(_0x3c74ee['completedAt'])>=_0x5c950b),_0x5c4793={'productivity':{'tasksCompleted':_0x2cb302[_0x1ef49f(0x228)],'completionRate':this[_0x1ef49f(0x1ed)](_0x2e3288,_0x3e3983),'averageCompletionTime':this['calculateAverageCompletionTime'](_0x2cb302),'velocityTrend':this[_0x1ef49f(0x1ee)](_0x2e3288,_0x3e3983)},'quality':{'blockedTasksRate':this['calculateBlockedTasksRate'](_0x2e3288),'cancelledTasksRate':this['calculateCancelledTasksRate'](_0x2e3288,_0x3e3983),'reworkRate':this['calculateReworkRate'](_0x2e3288,_0x3e3983)},'efficiency':{'priorityAccuracy':this[_0x1ef49f(0x249)](_0x2cb302),'dependencyHandling':this[_0x1ef49f(0x241)](_0x2e3288),'progressConsistency':this['calculateProgressConsistency'](_0x2e3288)}};return{'metrics':_0x5c4793,'recommendations':this[_0x1ef49f(0x143)](_0x5c4793)};}async[a0_0x40f7e7(0x231)](_0x226bc8,_0x25e020){const _0x5319dd=a0_0x40f7e7,_0x46a03a=_0x226bc8[_0x5319dd(0x1bf)]['tasks'],_0x45b667=parseInt(_0x25e020),_0x21c4b6={'daily':this['calculateDailyTrends'](_0x46a03a,_0x45b667),'weekly':this['calculateWeeklyTrends'](_0x46a03a,_0x45b667),'priorityTrends':this[_0x5319dd(0x174)](_0x46a03a,_0x45b667),'progressTrends':this['calculateProgressTrends'](_0x46a03a,_0x45b667)};return{'trends':_0x21c4b6,'forecasts':this[_0x5319dd(0x13b)](_0x21c4b6),'patterns':this['identifyPatterns'](_0x21c4b6)};}async['getTeamAnalytics'](_0x4218ae){const _0x335757=a0_0x40f7e7;if(!this[_0x335757(0x1fc)]||!this['scheduler'][_0x335757(0x18f)])throw new Error(_0x335757(0x253));const _0x5e7316=await this[_0x335757(0x1fc)]['getAllAgents'](),_0x116dd9=new Date(Date[_0x335757(0x1bb)]()-parseInt(_0x4218ae)*0x18*0x3c*0x3c*0x3e8),_0x192d55={'agents':[],'aggregatedMetrics':{'totalTasks':0x0,'totalCompleted':0x0,'averageWorkload':0x0,'topPerformers':[],'bottlenecks':[]}};for(const _0x457126 of _0x5e7316){if(!_0x457126[_0x335757(0x1bf)]||!_0x457126['taskList']['tasks'])continue;const _0x5f3859=_0x457126[_0x335757(0x1bf)][_0x335757(0x24c)],_0x567972=_0x5f3859['filter'](_0x32ced2=>new Date(_0x32ced2[_0x335757(0x1eb)])>=_0x116dd9),_0x8149d7={'agentId':_0x457126['id'],'agentName':_0x457126['name'],'totalTasks':_0x567972['length'],'completed':_0x567972['filter'](_0x332fbe=>_0x332fbe[_0x335757(0x19b)]==='completed')['length'],'pending':_0x567972[_0x335757(0x191)](_0x3125e3=>_0x3125e3['status']==='pending')[_0x335757(0x228)],'inProgress':_0x567972[_0x335757(0x191)](_0x514209=>_0x514209['status']==='in_progress')[_0x335757(0x228)],'workloadScore':this[_0x335757(0x1a9)](_0x5f3859),'completionRate':_0x567972[_0x335757(0x228)]>0x0?Math['round'](_0x567972[_0x335757(0x191)](_0x25cdca=>_0x25cdca['status']===_0x335757(0x283))['length']/_0x567972[_0x335757(0x228)]*0x64):0x0};_0x192d55[_0x335757(0x26f)]['push'](_0x8149d7),_0x192d55[_0x335757(0x151)][_0x335757(0x277)]+=_0x8149d7['totalTasks'],_0x192d55['aggregatedMetrics'][_0x335757(0x13c)]+=_0x8149d7['completed'];}return _0x192d55[_0x335757(0x151)]['teamCompletionRate']=_0x192d55['aggregatedMetrics']['totalTasks']>0x0?Math[_0x335757(0x23a)](_0x192d55['aggregatedMetrics'][_0x335757(0x13c)]/_0x192d55['aggregatedMetrics'][_0x335757(0x277)]*0x64):0x0,_0x192d55['aggregatedMetrics']['averageWorkload']=_0x192d55[_0x335757(0x26f)]['length']>0x0?Math['round'](_0x192d55[_0x335757(0x26f)][_0x335757(0x257)]((_0x55ce8a,_0x10767a)=>_0x55ce8a+_0x10767a[_0x335757(0x238)],0x0)/_0x192d55['agents'][_0x335757(0x228)]):0x0,_0x192d55['aggregatedMetrics'][_0x335757(0x14a)]=_0x192d55['agents'][_0x335757(0x191)](_0x3e4692=>_0x3e4692['completionRate']>=0x50)[_0x335757(0x23d)]((_0x1312d0,_0x3a93b6)=>_0x3a93b6[_0x335757(0x154)]-_0x1312d0[_0x335757(0x154)])['slice'](0x0,0x3),_0x192d55['aggregatedMetrics']['bottlenecks']=_0x192d55[_0x335757(0x26f)][_0x335757(0x191)](_0x38d7bb=>_0x38d7bb['workloadScore']>_0x192d55['aggregatedMetrics']['averageWorkload']*1.5)[_0x335757(0x23d)]((_0x5ed420,_0x5105a2)=>_0x5105a2['workloadScore']-_0x5ed420['workloadScore']),{'teamAnalytics':_0x192d55,'workloadDistribution':this['analyzeWorkloadDistribution'](_0x192d55['agents']),'collaborationMetrics':this['analyzeCollaborationMetrics'](_0x5e7316)};}async['exportAnalytics'](_0x42639d,_0x2dffad){const _0x7d4238=a0_0x40f7e7,{format:format='json',includeRawData:includeRawData=![],timeframe:timeframe='30'}=_0x2dffad,_0x50f448={'metadata':{'agentId':_0x42639d['id'],'agentName':_0x42639d['name'],'exportedAt':new Date()[_0x7d4238(0x24d)](),'timeframe':timeframe+_0x7d4238(0x140),'format':format},'summary':await this['getAnalyticsSummary'](_0x42639d,timeframe),'performance':await this['getPerformanceMetrics'](_0x42639d,timeframe),'trends':await this[_0x7d4238(0x231)](_0x42639d,timeframe)};if(includeRawData){const _0x44520a=new Date(Date[_0x7d4238(0x1bb)]()-parseInt(timeframe)*0x18*0x3c*0x3c*0x3e8);_0x50f448['rawData']={'tasks':_0x42639d['taskList']['tasks']['filter'](_0x378e1b=>new Date(_0x378e1b[_0x7d4238(0x1eb)])>=_0x44520a)};}let exportedData;switch(format[_0x7d4238(0x269)]()){case'json':exportedData=JSON['stringify'](_0x50f448,null,0x2);break;case _0x7d4238(0x1d0):exportedData=this[_0x7d4238(0x200)](_0x50f448);break;case _0x7d4238(0x199):exportedData=this['generateTextSummary'](_0x50f448);break;default:throw new Error('Invalid export format. Use: json, csv, or summary');}return{'exportData':exportedData,'format':format,'size':exportedData[_0x7d4238(0x228)],'records':_0x50f448[_0x7d4238(0x1a5)]?_0x50f448['rawData']['tasks']['length']:0x0};}async[a0_0x40f7e7(0x13f)](_0x2d1b4b,_0x4e97e4){const _0x44caa0=a0_0x40f7e7,_0x5e1044=await this['getAnalyticsSummary'](_0x2d1b4b,_0x4e97e4),_0x1ab910=await this[_0x44caa0(0x24b)](_0x2d1b4b,_0x4e97e4),_0x571a5e=await this['getTrendAnalysis'](_0x2d1b4b,_0x4e97e4),_0x2e0653={'productivity':this['generateProductivityInsights'](_0x5e1044,_0x1ab910,_0x571a5e),'workflow':this[_0x44caa0(0x138)](_0x5e1044,_0x1ab910,_0x571a5e),'optimization':this['generateOptimizationInsights'](_0x5e1044,_0x1ab910,_0x571a5e),'predictions':this['generatePredictions'](_0x571a5e)};return{'insights':_0x2e0653,'actionItems':this['generateActionItems'](_0x2e0653),'priorities':this['generatePriorityRecommendations'](_0x2e0653)};}[a0_0x40f7e7(0x195)](_0x4c1dd1){const _0x497270=a0_0x40f7e7,_0x175cbd=_0x4c1dd1['filter'](_0x273e27=>_0x273e27[_0x497270(0x179)]);if(_0x175cbd['length']===0x0)return{'averageProgress':0x0,'stageDistribution':{}};const _0x9dbb40=Math['round'](_0x175cbd['reduce']((_0x48cd31,_0x24552d)=>_0x48cd31+(_0x24552d['progress']['percentage']||0x0),0x0)/_0x175cbd[_0x497270(0x228)]),_0x179722={};return this[_0x497270(0x133)][_0x497270(0x1fa)](_0x29c24b=>{const _0x221c19=_0x497270;_0x179722[_0x29c24b]=_0x175cbd[_0x221c19(0x191)](_0x20304f=>_0x20304f[_0x221c19(0x179)][_0x221c19(0x223)]===_0x29c24b)['length'];}),{'averageProgress':_0x9dbb40,'stageDistribution':_0x179722};}[a0_0x40f7e7(0x261)](_0xb0540b){const _0x3f9b33=a0_0x40f7e7,_0x218887=_0xb0540b['filter'](_0x4328dd=>_0x4328dd[_0x3f9b33(0x1f0)]&&_0x4328dd[_0x3f9b33(0x1f0)][_0x3f9b33(0x228)]>0x0),_0xb98f1e=_0xb0540b[_0x3f9b33(0x191)](_0xcff3c5=>_0xcff3c5['status']==='blocked')['length'];return{'tasksWithDependencies':_0x218887[_0x3f9b33(0x228)],'averageDependencies':_0x218887['length']>0x0?Math[_0x3f9b33(0x23a)](_0x218887['reduce']((_0x949f3d,_0x5a7a84)=>_0x949f3d+_0x5a7a84[_0x3f9b33(0x1f0)]['length'],0x0)/_0x218887['length']):0x0,'blockedTasks':_0xb98f1e,'dependencyChainLength':this[_0x3f9b33(0x1b3)](_0xb0540b)};}[a0_0x40f7e7(0x18e)](_0x7bc83d){const _0x9d573b=a0_0x40f7e7,_0x361d83=_0x7bc83d['filter'](_0x1cfce3=>_0x1cfce3['source']===_0x9d573b(0x162)),_0x1c612e={};return _0x361d83[_0x9d573b(0x1fa)](_0x49be4e=>{const _0x4de95d=_0x9d573b,_0x1cfbeb=_0x49be4e['templateId']||_0x4de95d(0x1cd);_0x1c612e[_0x1cfbeb]=(_0x1c612e[_0x1cfbeb]||0x0)+0x1;}),{'totalTemplateGenerated':_0x361d83[_0x9d573b(0x228)],'templateDistribution':_0x1c612e,'templateEfficiency':this[_0x9d573b(0x1a1)](_0x361d83)};}[a0_0x40f7e7(0x1ed)](_0x15bb6a,_0x2d45ac){const _0xf4581=a0_0x40f7e7,_0x24085a=new Date(Date[_0xf4581(0x1bb)]()-parseInt(_0x2d45ac)*0x18*0x3c*0x3c*0x3e8),_0xf2de3a=_0x15bb6a['filter'](_0x1c7152=>new Date(_0x1c7152[_0xf4581(0x1eb)])>=_0x24085a);return _0xf2de3a['length']>0x0?Math[_0xf4581(0x23a)](_0xf2de3a['filter'](_0x4f9bda=>_0x4f9bda['status']==='completed')[_0xf4581(0x228)]/_0xf2de3a['length']*0x64):0x0;}['calculateAverageCompletionTime'](_0x324026){const _0x2a89bf=a0_0x40f7e7;if(_0x324026['length']===0x0)return 0x0;const _0x21477b=_0x324026['map'](_0x40b895=>{const _0x51889e=a0_0x2f3d,_0x30b276=new Date(_0x40b895[_0x51889e(0x1eb)]),_0x39aed3=new Date(_0x40b895['completedAt']);return(_0x39aed3-_0x30b276)/(0x3e8*0x3c*0x3c*0x18);});return Math['round'](_0x21477b[_0x2a89bf(0x257)]((_0x417305,_0x5d6863)=>_0x417305+_0x5d6863,0x0)/_0x21477b['length']*0xa)/0xa;}['generateSummaryInsights'](_0x533963){const _0x1b9e45=a0_0x40f7e7,_0x507809=[];return _0x533963['completionRate']<0x32&&_0x507809['push']('Completion\x20rate\x20is\x20below\x2050%.\x20Consider\x20reviewing\x20task\x20prioritization\x20and\x20blocking\x20issues.'),_0x533963[_0x1b9e45(0x226)]>0x7&&_0x507809['push'](_0x1b9e45(0x26d)+_0x533963[_0x1b9e45(0x226)]+'\x20days).\x20Focus\x20on\x20completing\x20older\x20tasks.'),_0x533963[_0x1b9e45(0x196)]['urgent']>_0x533963['overview'][_0x1b9e45(0x277)]*0.3&&_0x507809['push']('High\x20proportion\x20of\x20urgent\x20tasks.\x20Consider\x20better\x20planning\x20and\x20early\x20issue\x20identification.'),_0x507809;}['generatePerformanceRecommendations'](_0x4fbfcb){const _0x33f7af=a0_0x40f7e7,_0x2b2900=[];return _0x4fbfcb[_0x33f7af(0x25c)]['completionRate']<0x46&&_0x2b2900[_0x33f7af(0x1a6)](_0x33f7af(0x242)),_0x4fbfcb[_0x33f7af(0x273)][_0x33f7af(0x22b)]>0x14&&_0x2b2900['push']('High\x20blocked\x20task\x20rate\x20-\x20review\x20dependency\x20management\x20and\x20resource\x20allocation'),_0x4fbfcb[_0x33f7af(0x19f)]['priorityAccuracy']<0x3c&&_0x2b2900['push'](_0x33f7af(0x153)),_0x2b2900;}['calculateWorkloadScore'](_0x479305){const _0x287303=a0_0x40f7e7,_0x4e34b6=_0x479305[_0x287303(0x191)](_0x49aa2a=>_0x49aa2a[_0x287303(0x19b)]===_0x287303(0x13d)||_0x49aa2a['status']===_0x287303(0x1c2)),_0x207c5a=_0x4e34b6['filter'](_0x2b564c=>_0x2b564c['priority']===_0x287303(0x1d1))['length'],_0x40cf77=_0x4e34b6[_0x287303(0x191)](_0x1e0a83=>_0x1e0a83[_0x287303(0x24a)]==='high')[_0x287303(0x228)];return _0x207c5a*0x3+_0x40cf77*0x2+_0x4e34b6[_0x287303(0x228)];}['calculateMaxDependencyChain'](_0x4cd4b6){const _0x1e05ef=a0_0x40f7e7;return Math[_0x1e05ef(0x14f)](0x0,..._0x4cd4b6[_0x1e05ef(0x167)](_0x16c25a=>_0x16c25a[_0x1e05ef(0x1f0)]?_0x16c25a['dependencies'][_0x1e05ef(0x228)]:0x0));}['calculateTemplateEfficiency'](_0xca9d11){const _0x4d4b38=a0_0x40f7e7;if(_0xca9d11[_0x4d4b38(0x228)]===0x0)return 0x64;const _0x36b4ca=_0xca9d11['filter'](_0x4af530=>_0x4af530[_0x4d4b38(0x19b)]===_0x4d4b38(0x283))['length'];return Math[_0x4d4b38(0x23a)](_0x36b4ca/_0xca9d11['length']*0x64);}['calculateVelocityTrend'](_0x3e112a,_0x90cdd8){const _0x5bdc52=a0_0x40f7e7,_0x15e4e6=new Date(Date['now']()-parseInt(_0x90cdd8)*0x18*0x3c*0x3c*0x3e8),_0x45304a=_0x3e112a[_0x5bdc52(0x191)](_0x527f8e=>_0x527f8e['status']===_0x5bdc52(0x283)&&_0x527f8e[_0x5bdc52(0x1ad)]&&new Date(_0x527f8e['completedAt'])>=_0x15e4e6)[_0x5bdc52(0x228)];return Math['round'](_0x45304a/parseInt(_0x90cdd8)*0x7);}['calculateBlockedTasksRate'](_0x516e45){const _0x820e82=a0_0x40f7e7,_0x17367d=_0x516e45['filter'](_0xd1113b=>_0xd1113b['status']!=='completed'&&_0xd1113b['status']!=='cancelled');if(_0x17367d['length']===0x0)return 0x0;const _0x4a6fb5=_0x516e45[_0x820e82(0x191)](_0x54f35a=>_0x54f35a[_0x820e82(0x19b)]==='blocked')[_0x820e82(0x228)];return Math['round'](_0x4a6fb5/_0x17367d[_0x820e82(0x228)]*0x64);}[a0_0x40f7e7(0x19d)](_0x497e38,_0x4c4691){const _0x43869b=a0_0x40f7e7,_0x7c6b10=new Date(Date[_0x43869b(0x1bb)]()-parseInt(_0x4c4691)*0x18*0x3c*0x3c*0x3e8),_0x50d650=_0x497e38['filter'](_0x665121=>new Date(_0x665121[_0x43869b(0x1eb)])>=_0x7c6b10);if(_0x50d650[_0x43869b(0x228)]===0x0)return 0x0;const _0x104209=_0x50d650['filter'](_0x4dd85e=>_0x4dd85e['status']==='cancelled')[_0x43869b(0x228)];return Math[_0x43869b(0x23a)](_0x104209/_0x50d650[_0x43869b(0x228)]*0x64);}[a0_0x40f7e7(0x1ae)](_0x5f16ea,_0x13c567){const _0x5549fe=a0_0x40f7e7,_0x47bb26=new Date(Date['now']()-parseInt(_0x13c567)*0x18*0x3c*0x3c*0x3e8),_0x97dde3=_0x5f16ea[_0x5549fe(0x191)](_0x2c2b6c=>new Date(_0x2c2b6c[_0x5549fe(0x1eb)])>=_0x47bb26),_0x3dac69=_0x97dde3['filter'](_0x15cbed=>_0x15cbed['progress']&&_0x15cbed['progress'][_0x5549fe(0x160)]&&_0x15cbed['progress']['stageHistory'][_0x5549fe(0x165)](_0x1df322=>this[_0x5549fe(0x133)]['indexOf'](_0x1df322['to'])<this['progressStages']['indexOf'](_0x1df322[_0x5549fe(0x1a4)])))['length'];return _0x97dde3[_0x5549fe(0x228)]>0x0?Math[_0x5549fe(0x23a)](_0x3dac69/_0x97dde3['length']*0x64):0x0;}[a0_0x40f7e7(0x249)](_0x200feb){const _0x3c704c=a0_0x40f7e7;if(_0x200feb[_0x3c704c(0x228)]===0x0)return 0x64;const _0x3deea7=_0x200feb[_0x3c704c(0x191)](_0x3ca6d9=>{const _0x4ff32a=_0x3c704c;if(!['urgent','high'][_0x4ff32a(0x152)](_0x3ca6d9['priority']))return![];const _0x2a48f5=new Date(_0x3ca6d9['createdAt']),_0x1c3e5f=new Date(_0x3ca6d9['completedAt']),_0x562594=(_0x1c3e5f-_0x2a48f5)/(0x3e8*0x3c*0x3c*0x18);return _0x562594<=0x3;})['length'],_0x337902=_0x200feb[_0x3c704c(0x191)](_0x446f49=>['urgent','high'][_0x3c704c(0x152)](_0x446f49['priority']))['length'];return _0x337902>0x0?Math[_0x3c704c(0x23a)](_0x3deea7/_0x337902*0x64):0x64;}[a0_0x40f7e7(0x241)](_0xe378fb){const _0x435da8=a0_0x40f7e7,_0x232941=_0xe378fb['filter'](_0x5e19ad=>_0x5e19ad[_0x435da8(0x1f0)]&&_0x5e19ad[_0x435da8(0x1f0)][_0x435da8(0x228)]>0x0);if(_0x232941[_0x435da8(0x228)]===0x0)return 0x64;const _0x429dd6=_0x232941[_0x435da8(0x191)](_0x119958=>_0x119958['status']!==_0x435da8(0x204))['length'];return Math['round'](_0x429dd6/_0x232941[_0x435da8(0x228)]*0x64);}[a0_0x40f7e7(0x218)](_0x516c41){const _0x21b566=a0_0x40f7e7,_0x241f15=_0x516c41['filter'](_0x132a44=>_0x132a44[_0x21b566(0x179)]&&_0x132a44[_0x21b566(0x179)]['percentage']!==undefined);if(_0x241f15['length']===0x0)return 0x64;const _0x4447dd=_0x241f15[_0x21b566(0x191)](_0x2c612e=>{const _0x6f385c=_0x21b566,_0x14520f=_0x2c612e['progress']['stage'],_0x3b6846=_0x2c612e['progress']['percentage'];if(_0x14520f==='not_started'&&_0x3b6846===0x0)return!![];if(_0x14520f===_0x6f385c(0x21d)&&_0x3b6846>0x0&&_0x3b6846<0x19)return!![];if(_0x14520f===_0x6f385c(0x22a)&&_0x3b6846>=0x19&&_0x3b6846<0x4b)return!![];if(_0x14520f==='testing'&&_0x3b6846>=0x4b&&_0x3b6846<0x5f)return!![];if(_0x14520f===_0x6f385c(0x148)&&_0x3b6846>=0x5f&&_0x3b6846<0x64)return!![];if(_0x14520f===_0x6f385c(0x283)&&_0x3b6846===0x64)return!![];return![];})['length'];return Math[_0x21b566(0x23a)](_0x4447dd/_0x241f15['length']*0x64);}['calculateDailyTrends'](_0x396de2,_0x480bc5){const _0x226e9d=a0_0x40f7e7,_0x41fbda=[];for(let _0x5d9290=0x0;_0x5d9290<_0x480bc5;_0x5d9290++){const _0x3cc2bc=new Date(Date[_0x226e9d(0x1bb)]()-_0x5d9290*0x18*0x3c*0x3c*0x3e8),_0x3f4175=new Date(_0x3cc2bc[_0x226e9d(0x1e1)](),_0x3cc2bc[_0x226e9d(0x156)](),_0x3cc2bc[_0x226e9d(0x1e4)]()),_0x3ca6c0=new Date(_0x3f4175['getTime']()+0x18*0x3c*0x3c*0x3e8),_0x201f05=_0x396de2[_0x226e9d(0x191)](_0x287905=>{const _0x5b85fc=new Date(_0x287905['createdAt']);return _0x5b85fc>=_0x3f4175&&_0x5b85fc<_0x3ca6c0;});_0x41fbda['unshift']({'date':_0x3f4175['toISOString']()['split']('T')[0x0],'created':_0x201f05['length'],'completed':_0x201f05['filter'](_0x98d98=>_0x98d98[_0x226e9d(0x19b)]===_0x226e9d(0x283))[_0x226e9d(0x228)]});}return _0x41fbda;}[a0_0x40f7e7(0x240)](_0x1271f7,_0x32b422){const _0x482f0d=a0_0x40f7e7,_0x2a4013=Math[_0x482f0d(0x1a3)](_0x32b422/0x7),_0x6b99ab=[];for(let _0xeebc25=0x0;_0xeebc25<_0x2a4013;_0xeebc25++){const _0x4008be=new Date(Date['now']()-(_0xeebc25+0x1)*0x7*0x18*0x3c*0x3c*0x3e8),_0x46d0ab=new Date(Date[_0x482f0d(0x1bb)]()-_0xeebc25*0x7*0x18*0x3c*0x3c*0x3e8),_0x36e93f=_0x1271f7['filter'](_0x11d2e3=>{const _0x16f403=new Date(_0x11d2e3['createdAt']);return _0x16f403>=_0x4008be&&_0x16f403<_0x46d0ab;});_0x6b99ab[_0x482f0d(0x1f2)]({'week':'Week\x20'+(_0x2a4013-_0xeebc25),'created':_0x36e93f[_0x482f0d(0x228)],'completed':_0x36e93f['filter'](_0x22e47b=>_0x22e47b['status']===_0x482f0d(0x283))[_0x482f0d(0x228)]});}return _0x6b99ab;}[a0_0x40f7e7(0x174)](_0x1ee087,_0x513a8d){const _0x52ffb8=a0_0x40f7e7,_0x2dacef=new Date(Date[_0x52ffb8(0x1bb)]()-_0x513a8d*0x18*0x3c*0x3c*0x3e8),_0x26e89d=_0x1ee087[_0x52ffb8(0x191)](_0x3b3ee1=>new Date(_0x3b3ee1['createdAt'])>=_0x2dacef);return{'urgent':_0x26e89d['filter'](_0x2c5174=>_0x2c5174['priority']==='urgent')[_0x52ffb8(0x228)],'high':_0x26e89d[_0x52ffb8(0x191)](_0x1f41da=>_0x1f41da['priority']===_0x52ffb8(0x280))[_0x52ffb8(0x228)],'medium':_0x26e89d['filter'](_0x48fc43=>_0x48fc43[_0x52ffb8(0x24a)]==='medium')['length'],'low':_0x26e89d[_0x52ffb8(0x191)](_0x48ecdc=>_0x48ecdc[_0x52ffb8(0x24a)]===_0x52ffb8(0x236))['length']};}[a0_0x40f7e7(0x20d)](_0x2aefc2,_0x2d116f){const _0x2d876b=a0_0x40f7e7,_0x2ea0a1=new Date(Date[_0x2d876b(0x1bb)]()-_0x2d116f*0x18*0x3c*0x3c*0x3e8),_0x20f108=_0x2aefc2['filter'](_0x49101a=>new Date(_0x49101a[_0x2d876b(0x1eb)])>=_0x2ea0a1),_0x27ba12=_0x20f108['filter'](_0x3159b1=>_0x3159b1['progress']),_0x5b2dd3={};return this[_0x2d876b(0x133)]['forEach'](_0x544784=>{const _0x4bfcdf=_0x2d876b;_0x5b2dd3[_0x544784]=_0x27ba12[_0x4bfcdf(0x191)](_0x37130d=>_0x37130d[_0x4bfcdf(0x179)][_0x4bfcdf(0x223)]===_0x544784)[_0x4bfcdf(0x228)];}),_0x5b2dd3;}['generateForecasts'](_0x3a3b57){const _0x3df1f1=a0_0x40f7e7;return{'predictedCompletions':this['predictFutureCompletions'](_0x3a3b57['daily']),'workloadForecast':this['predictWorkloadTrend'](_0x3a3b57[_0x3df1f1(0x12f)]),'priorityShift':this['predictPriorityShift'](_0x3a3b57[_0x3df1f1(0x1c9)])};}['identifyPatterns'](_0x15c8da){return{'peakDays':this['identifyPeakActivityDays'](_0x15c8da['daily']),'cyclicalPatterns':this['identifyCyclicalPatterns'](_0x15c8da['weekly']),'priorityPatterns':this['identifyPriorityPatterns'](_0x15c8da['priorityTrends'])};}[a0_0x40f7e7(0x20c)](_0x2952a2){const _0x5b56e8=a0_0x40f7e7;if(_0x2952a2[_0x5b56e8(0x228)]<0x7)return _0x5b56e8(0x150);const _0x19dbd6=_0x2952a2[_0x5b56e8(0x20a)](-0x7)[_0x5b56e8(0x257)]((_0x311ce4,_0x3c4cc8)=>_0x311ce4+_0x3c4cc8[_0x5b56e8(0x283)],0x0)/0x7;return Math[_0x5b56e8(0x23a)](_0x19dbd6)+'\x20tasks/day\x20predicted';}[a0_0x40f7e7(0x1b0)](_0x4055ef){const _0x2e28e0=a0_0x40f7e7;if(_0x4055ef['length']<0x2)return _0x2e28e0(0x22c);const _0x25ebe3=_0x4055ef[_0x4055ef[_0x2e28e0(0x228)]-0x1][_0x2e28e0(0x254)],_0x979d46=_0x4055ef[_0x4055ef[_0x2e28e0(0x228)]-0x2][_0x2e28e0(0x254)],_0x15fb9d=(_0x25ebe3-_0x979d46)/_0x979d46*0x64;if(_0x15fb9d>0x14)return _0x2e28e0(0x15c);if(_0x15fb9d<-0x14)return'Decreasing\x20workload';return _0x2e28e0(0x1ba);}[a0_0x40f7e7(0x268)](_0x65e12a){const _0xf30b19=a0_0x40f7e7,_0x285101=Object[_0xf30b19(0x16c)](_0x65e12a)['reduce']((_0x41a917,_0x105bdd)=>_0x41a917+_0x105bdd,0x0);if(_0x285101===0x0)return'No\x20priority\x20data';const _0x86146f=_0x65e12a[_0xf30b19(0x1d1)]/_0x285101*0x64;if(_0x86146f>0x1e)return'High\x20urgent\x20task\x20ratio\x20-\x20plan\x20for\x20capacity';return'Balanced\x20priority\x20distribution';}[a0_0x40f7e7(0x1ea)](_0x36ed73){const _0x4747d1=a0_0x40f7e7,_0x86c664=Math[_0x4747d1(0x14f)](..._0x36ed73['map'](_0x13cd2c=>_0x13cd2c['created']));return _0x36ed73['filter'](_0x1d5e29=>_0x1d5e29[_0x4747d1(0x254)]===_0x86c664)['map'](_0x2bbd35=>_0x2bbd35['date']);}[a0_0x40f7e7(0x237)](_0x509d8e){if(_0x509d8e['length']<0x4)return'Insufficient\x20data\x20for\x20pattern\x20analysis';return'Weekly\x20patterns\x20detected\x20-\x20further\x20analysis\x20available';}[a0_0x40f7e7(0x27b)](_0xe9cc8){const _0xa75c07=a0_0x40f7e7,_0x49e06f=Object['values'](_0xe9cc8)['reduce']((_0x235854,_0x547dc1)=>_0x235854+_0x547dc1,0x0);if(_0x49e06f===0x0)return'No\x20priority\x20patterns';const _0x548eff=Object[_0xa75c07(0x263)](_0xe9cc8)['reduce']((_0xe2d389,[_0x4c63b3,_0x4dd9bc])=>_0x4dd9bc>_0xe2d389['count']?{'priority':_0x4c63b3,'count':_0x4dd9bc}:_0xe2d389,{'priority':'','count':0x0});return _0x548eff[_0xa75c07(0x24a)]+'\x20priority\x20tasks\x20dominate\x20('+Math['round'](_0x548eff[_0xa75c07(0x279)]/_0x49e06f*0x64)+'%)';}['generateProductivityInsights'](_0x2e18fa,_0x8cf46d,_0x5bf26a){const _0x1fbbe3=a0_0x40f7e7,_0x1d52c4=[];if(_0x8cf46d[_0x1fbbe3(0x25f)][_0x1fbbe3(0x25c)]['completionRate']>0x50)_0x1d52c4['push'](_0x1fbbe3(0x20e));else _0x8cf46d[_0x1fbbe3(0x25f)][_0x1fbbe3(0x25c)][_0x1fbbe3(0x154)]<0x32&&_0x1d52c4[_0x1fbbe3(0x1a6)](_0x1fbbe3(0x134));return _0x2e18fa['summary'][_0x1fbbe3(0x226)]>0xa&&_0x1d52c4['push']('Tasks\x20are\x20aging\x20significantly\x20-\x20prioritize\x20older\x20tasks'),_0x1d52c4;}['generateWorkflowInsights'](_0x38e7a5,_0x566c80,_0x16f29d){const _0x4171c1=a0_0x40f7e7,_0x53634b=[];return _0x38e7a5[_0x4171c1(0x199)]['dependencyMetrics']['blockedTasks']>0x3&&_0x53634b['push']('Multiple\x20blocked\x20tasks\x20-\x20review\x20dependency\x20management'),_0x38e7a5['summary'][_0x4171c1(0x220)][_0x4171c1(0x212)]>_0x38e7a5[_0x4171c1(0x199)][_0x4171c1(0x1d3)]['totalTasks']*0.5&&_0x53634b[_0x4171c1(0x1a6)]('Heavy\x20template\x20usage\x20-\x20consider\x20workflow\x20optimization'),_0x53634b;}[a0_0x40f7e7(0x185)](_0x4e6adb,_0x5c28f0,_0xa1eab8){const _0x4cdeb0=a0_0x40f7e7,_0x37d0ed=[];return _0x5c28f0[_0x4cdeb0(0x25f)][_0x4cdeb0(0x19f)]['priorityAccuracy']<0x46&&_0x37d0ed['push'](_0x4cdeb0(0x250)),_0x5c28f0['metrics']['quality']['blockedTasksRate']>0xf&&_0x37d0ed['push'](_0x4cdeb0(0x239)),_0x37d0ed;}[a0_0x40f7e7(0x1c8)](_0x9a13ec){const _0x4e93fb=a0_0x40f7e7;return[_0x9a13ec['forecasts'][_0x4e93fb(0x26c)],_0x9a13ec[_0x4e93fb(0x192)][_0x4e93fb(0x131)],_0x9a13ec[_0x4e93fb(0x192)][_0x4e93fb(0x14e)]];}[a0_0x40f7e7(0x27a)](_0x5620d8){const _0x38e4b5=a0_0x40f7e7,_0x5e417c=[..._0x5620d8[_0x38e4b5(0x25c)],..._0x5620d8[_0x38e4b5(0x272)],..._0x5620d8['optimization']];return _0x5e417c['map']((_0x531b26,_0x55a63f)=>({'id':_0x38e4b5(0x1e6)+(_0x55a63f+0x1),'description':_0x531b26,'priority':_0x531b26[_0x38e4b5(0x152)](_0x38e4b5(0x1d1))||_0x531b26['includes']('critical')?_0x38e4b5(0x280):_0x38e4b5(0x19c),'category':_0x531b26[_0x38e4b5(0x152)]('productivity')?_0x38e4b5(0x25c):_0x531b26['includes']('workflow')?_0x38e4b5(0x272):_0x38e4b5(0x1e0)}));}[a0_0x40f7e7(0x1c6)](_0x4377d5){const _0x324b2e=a0_0x40f7e7,_0x4269f2=[];return _0x4377d5['productivity'][_0x324b2e(0x165)](_0x4a64c8=>_0x4a64c8[_0x324b2e(0x152)](_0x324b2e(0x25b)))&&_0x4269f2[_0x324b2e(0x1a6)]({'priority':_0x324b2e(0x1d1),'action':_0x324b2e(0x158),'impact':'high'}),_0x4377d5[_0x324b2e(0x272)]['some'](_0x4e8440=>_0x4e8440[_0x324b2e(0x152)](_0x324b2e(0x16d)))&&_0x4269f2['push']({'priority':_0x324b2e(0x280),'action':_0x324b2e(0x232),'impact':'medium'}),_0x4269f2;}['analyzeWorkloadDistribution'](_0x409e9d){const _0xd750b=a0_0x40f7e7;if(_0x409e9d['length']===0x0)return{'balance':'No\x20agents','distribution':[]};const _0x25182f=_0x409e9d['map'](_0x2d8c79=>_0x2d8c79[_0xd750b(0x238)]),_0x35e21a=_0x25182f[_0xd750b(0x257)]((_0x23ea73,_0x2ae158)=>_0x23ea73+_0x2ae158,0x0)/_0x25182f['length'],_0x2f19ab=Math[_0xd750b(0x14f)](..._0x25182f['map'](_0x404f1f=>Math['abs'](_0x404f1f-_0x35e21a)));return{'balance':_0x2f19ab>_0x35e21a*0.5?_0xd750b(0x25e):'Balanced','distribution':_0x409e9d['map'](_0x120ef2=>({'agent':_0x120ef2['agentName'],'workload':_0x120ef2[_0xd750b(0x238)],'deviation':Math['round']((_0x120ef2['workloadScore']-_0x35e21a)/_0x35e21a*0x64)}))};}[a0_0x40f7e7(0x1d9)](_0x4b119d){const _0x5bf77c=a0_0x40f7e7;return{'totalAgents':_0x4b119d['length'],'activeAgents':_0x4b119d[_0x5bf77c(0x191)](_0x249ddd=>_0x249ddd['taskList']&&_0x249ddd[_0x5bf77c(0x1bf)]['tasks']['length']>0x0)['length'],'collaborationScore':Math[_0x5bf77c(0x23a)](Math[_0x5bf77c(0x183)]()*0x64)};}[a0_0x40f7e7(0x200)](_0x2daf8d){const _0x39301c=a0_0x40f7e7,_0x4868d8=[_0x39301c(0x1dd),'Value'],_0x59dcbe=[[_0x39301c(0x157),_0x2daf8d[_0x39301c(0x199)]['summary']['overview']['totalTasks']],['Completed\x20Tasks',_0x2daf8d[_0x39301c(0x199)][_0x39301c(0x199)]['overview']['completed']],[_0x39301c(0x1ff),_0x2daf8d['summary'][_0x39301c(0x199)]['completionRate']+'%'],[_0x39301c(0x18d),_0x2daf8d['summary'][_0x39301c(0x199)][_0x39301c(0x226)]+_0x39301c(0x140)]];return[_0x4868d8,..._0x59dcbe]['map'](_0x2762e1=>_0x2762e1['join'](','))[_0x39301c(0x1f5)]('\x0a');}[a0_0x40f7e7(0x127)](_0x483d36){const _0x57f0fe=a0_0x40f7e7,_0x5d7676=_0x483d36['summary']['summary'];return('\x0aAnalytics\x20Summary\x0a================\x0aTotal\x20Tasks:\x20'+_0x5d7676['overview']['totalTasks']+'\x0aCompleted:\x20'+_0x5d7676[_0x57f0fe(0x1d3)]['completed']+'\x20('+_0x5d7676['completionRate']+_0x57f0fe(0x1f1)+_0x5d7676['overview']['inProgress']+'\x0aPending:\x20'+_0x5d7676[_0x57f0fe(0x1d3)]['pending']+_0x57f0fe(0x244)+_0x5d7676[_0x57f0fe(0x226)]+'\x20days\x0a\x0aKey\x20Insights:\x0a'+_0x483d36[_0x57f0fe(0x199)][_0x57f0fe(0x229)][_0x57f0fe(0x167)](_0x4f8df1=>'-\x20'+_0x4f8df1)[_0x57f0fe(0x1f5)]('\x0a')+'\x0a\x20\x20\x20\x20')[_0x57f0fe(0x264)]();}['formatResult'](_0x5cd1f4){const _0x49430f=a0_0x40f7e7;if(!_0x5cd1f4['success'])return _0x49430f(0x287)+_0x5cd1f4['error'];const _0x3c55f5=['TaskManager:\x20'+_0x5cd1f4['action']+'\x20completed'];return _0x5cd1f4['result'][_0x49430f(0x1ab)]&&_0x3c55f5[_0x49430f(0x1a6)](_0x49430f(0x155)+_0x5cd1f4[_0x49430f(0x1f9)][_0x49430f(0x1ab)]['status']+']\x20'+_0x5cd1f4['result'][_0x49430f(0x1ab)]['title']+'\x20('+_0x5cd1f4['result']['task']['id']+')'),_0x5cd1f4['result'][_0x49430f(0x24c)]&&(_0x3c55f5[_0x49430f(0x1a6)]('Found\x20'+_0x5cd1f4['result'][_0x49430f(0x24c)]['length']+_0x49430f(0x15b)),_0x5cd1f4['result']['tasks'][_0x49430f(0x1fa)](_0x457c55=>{_0x3c55f5['push']('\x20\x20-\x20['+_0x457c55['status']+']\x20'+_0x457c55['title']+'\x20(Priority:\x20'+_0x457c55['priority']+')');})),_0x5cd1f4[_0x49430f(0x199)]&&_0x3c55f5['push'](_0x49430f(0x137)+_0x5cd1f4['summary']['pending']+_0x49430f(0x18a)+_0x5cd1f4['summary']['in_progress']+'\x20in\x20progress,\x20'+_0x5cd1f4[_0x49430f(0x199)]['completed']+_0x49430f(0x1c0)),_0x3c55f5['join']('\x0a');}}export default TaskManagerTool;
|