nova-terminal-assistant 0.1.0

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.

Potentially problematic release.


This version of nova-terminal-assistant might be problematic. Click here for more details.

Files changed (192) hide show
  1. package/README.md +358 -0
  2. package/bin/nova +38 -0
  3. package/bin/nova.js +12 -0
  4. package/package.json +67 -0
  5. package/src/cli/commands/SmartCompletion.ts +458 -0
  6. package/src/cli/index.ts +5 -0
  7. package/src/cli/startup/IFlowRepl.ts +212 -0
  8. package/src/cli/startup/InkBasedRepl.ts +1056 -0
  9. package/src/cli/startup/InteractiveRepl.ts +2833 -0
  10. package/src/cli/startup/NovaApp.ts +1861 -0
  11. package/src/cli/startup/index.ts +4 -0
  12. package/src/cli/startup/parseArgs.ts +293 -0
  13. package/src/cli/test-modules.ts +27 -0
  14. package/src/cli/ui/IFlowDropdown.ts +425 -0
  15. package/src/cli/ui/ModernReplUI.ts +276 -0
  16. package/src/cli/ui/SimpleSelector2.ts +215 -0
  17. package/src/cli/ui/components/ConfirmDialog.ts +176 -0
  18. package/src/cli/ui/components/ErrorPanel.ts +364 -0
  19. package/src/cli/ui/components/InkAppRunner.tsx +67 -0
  20. package/src/cli/ui/components/InkComponents.tsx +613 -0
  21. package/src/cli/ui/components/NovaInkApp.tsx +312 -0
  22. package/src/cli/ui/components/ProgressBar.ts +177 -0
  23. package/src/cli/ui/components/ProgressIndicator.ts +298 -0
  24. package/src/cli/ui/components/QuickActions.ts +396 -0
  25. package/src/cli/ui/components/SimpleErrorPanel.ts +231 -0
  26. package/src/cli/ui/components/StatusBar.ts +194 -0
  27. package/src/cli/ui/components/ThinkingBlockRenderer.ts +401 -0
  28. package/src/cli/ui/components/index.ts +27 -0
  29. package/src/cli/ui/ink-prototype.tsx +347 -0
  30. package/src/cli/utils/CliUI.ts +336 -0
  31. package/src/cli/utils/CompletionHelper.ts +388 -0
  32. package/src/cli/utils/EnhancedCompleter.test.ts +226 -0
  33. package/src/cli/utils/EnhancedCompleter.ts +513 -0
  34. package/src/cli/utils/ErrorEnhancer.ts +429 -0
  35. package/src/cli/utils/OutputFormatter.ts +193 -0
  36. package/src/cli/utils/index.ts +9 -0
  37. package/src/core/agents/AgentOrchestrator.ts +515 -0
  38. package/src/core/agents/index.ts +17 -0
  39. package/src/core/audit/AuditLogger.ts +509 -0
  40. package/src/core/audit/index.ts +11 -0
  41. package/src/core/auth/AuthManager.d.ts.map +1 -0
  42. package/src/core/auth/AuthManager.ts +138 -0
  43. package/src/core/auth/index.d.ts.map +1 -0
  44. package/src/core/auth/index.ts +2 -0
  45. package/src/core/config/ConfigManager.d.ts.map +1 -0
  46. package/src/core/config/ConfigManager.test.ts +183 -0
  47. package/src/core/config/ConfigManager.ts +1219 -0
  48. package/src/core/config/index.d.ts.map +1 -0
  49. package/src/core/config/index.ts +1 -0
  50. package/src/core/context/ContextBuilder.d.ts.map +1 -0
  51. package/src/core/context/ContextBuilder.ts +171 -0
  52. package/src/core/context/ContextCompressor.d.ts.map +1 -0
  53. package/src/core/context/ContextCompressor.ts +642 -0
  54. package/src/core/context/LayeredMemoryManager.ts +657 -0
  55. package/src/core/context/MemoryDiscovery.d.ts.map +1 -0
  56. package/src/core/context/MemoryDiscovery.ts +175 -0
  57. package/src/core/context/defaultSystemPrompt.d.ts.map +1 -0
  58. package/src/core/context/defaultSystemPrompt.ts +35 -0
  59. package/src/core/context/index.d.ts.map +1 -0
  60. package/src/core/context/index.ts +22 -0
  61. package/src/core/extensions/SkillGenerator.ts +421 -0
  62. package/src/core/extensions/SkillInstaller.d.ts.map +1 -0
  63. package/src/core/extensions/SkillInstaller.ts +257 -0
  64. package/src/core/extensions/SkillRegistry.d.ts.map +1 -0
  65. package/src/core/extensions/SkillRegistry.ts +361 -0
  66. package/src/core/extensions/SkillValidator.ts +525 -0
  67. package/src/core/extensions/index.ts +15 -0
  68. package/src/core/index.d.ts.map +1 -0
  69. package/src/core/index.ts +42 -0
  70. package/src/core/mcp/McpManager.d.ts.map +1 -0
  71. package/src/core/mcp/McpManager.ts +632 -0
  72. package/src/core/mcp/index.d.ts.map +1 -0
  73. package/src/core/mcp/index.ts +2 -0
  74. package/src/core/model/ModelClient.d.ts.map +1 -0
  75. package/src/core/model/ModelClient.ts +217 -0
  76. package/src/core/model/ModelConnectionTester.ts +363 -0
  77. package/src/core/model/ModelValidator.ts +348 -0
  78. package/src/core/model/index.d.ts.map +1 -0
  79. package/src/core/model/index.ts +6 -0
  80. package/src/core/model/providers/AnthropicProvider.d.ts.map +1 -0
  81. package/src/core/model/providers/AnthropicProvider.ts +279 -0
  82. package/src/core/model/providers/CodingPlanProvider.d.ts.map +1 -0
  83. package/src/core/model/providers/CodingPlanProvider.ts +210 -0
  84. package/src/core/model/providers/OllamaCloudProvider.d.ts.map +1 -0
  85. package/src/core/model/providers/OllamaCloudProvider.ts +405 -0
  86. package/src/core/model/providers/OllamaManager.d.ts.map +1 -0
  87. package/src/core/model/providers/OllamaManager.ts +201 -0
  88. package/src/core/model/providers/OllamaProvider.d.ts.map +1 -0
  89. package/src/core/model/providers/OllamaProvider.ts +73 -0
  90. package/src/core/model/providers/OpenAICompatibleProvider.d.ts.map +1 -0
  91. package/src/core/model/providers/OpenAICompatibleProvider.ts +327 -0
  92. package/src/core/model/providers/OpenAIProvider.d.ts.map +1 -0
  93. package/src/core/model/providers/OpenAIProvider.ts +29 -0
  94. package/src/core/model/providers/index.d.ts.map +1 -0
  95. package/src/core/model/providers/index.ts +12 -0
  96. package/src/core/model/types.d.ts.map +1 -0
  97. package/src/core/model/types.ts +77 -0
  98. package/src/core/security/ApprovalManager.d.ts.map +1 -0
  99. package/src/core/security/ApprovalManager.ts +174 -0
  100. package/src/core/security/FileFilter.d.ts.map +1 -0
  101. package/src/core/security/FileFilter.ts +141 -0
  102. package/src/core/security/HookExecutor.d.ts.map +1 -0
  103. package/src/core/security/HookExecutor.ts +178 -0
  104. package/src/core/security/SandboxExecutor.ts +447 -0
  105. package/src/core/security/index.d.ts.map +1 -0
  106. package/src/core/security/index.ts +8 -0
  107. package/src/core/session/AgentLoop.d.ts.map +1 -0
  108. package/src/core/session/AgentLoop.ts +501 -0
  109. package/src/core/session/SessionManager.d.ts.map +1 -0
  110. package/src/core/session/SessionManager.test.ts +183 -0
  111. package/src/core/session/SessionManager.ts +460 -0
  112. package/src/core/session/index.d.ts.map +1 -0
  113. package/src/core/session/index.ts +3 -0
  114. package/src/core/telemetry/Telemetry.d.ts.map +1 -0
  115. package/src/core/telemetry/Telemetry.ts +90 -0
  116. package/src/core/telemetry/TelemetryService.ts +531 -0
  117. package/src/core/telemetry/index.d.ts.map +1 -0
  118. package/src/core/telemetry/index.ts +12 -0
  119. package/src/core/testing/AutoFixer.ts +385 -0
  120. package/src/core/testing/ErrorAnalyzer.ts +499 -0
  121. package/src/core/testing/TestRunner.ts +265 -0
  122. package/src/core/testing/agent-cli-tests.ts +538 -0
  123. package/src/core/testing/index.ts +11 -0
  124. package/src/core/tools/ToolRegistry.d.ts.map +1 -0
  125. package/src/core/tools/ToolRegistry.test.ts +206 -0
  126. package/src/core/tools/ToolRegistry.ts +260 -0
  127. package/src/core/tools/impl/EditFileTool.d.ts.map +1 -0
  128. package/src/core/tools/impl/EditFileTool.ts +97 -0
  129. package/src/core/tools/impl/ListDirectoryTool.d.ts.map +1 -0
  130. package/src/core/tools/impl/ListDirectoryTool.ts +142 -0
  131. package/src/core/tools/impl/MemoryTool.d.ts.map +1 -0
  132. package/src/core/tools/impl/MemoryTool.ts +102 -0
  133. package/src/core/tools/impl/ReadFileTool.d.ts.map +1 -0
  134. package/src/core/tools/impl/ReadFileTool.ts +58 -0
  135. package/src/core/tools/impl/SearchContentTool.d.ts.map +1 -0
  136. package/src/core/tools/impl/SearchContentTool.ts +94 -0
  137. package/src/core/tools/impl/SearchFileTool.d.ts.map +1 -0
  138. package/src/core/tools/impl/SearchFileTool.ts +61 -0
  139. package/src/core/tools/impl/ShellTool.d.ts.map +1 -0
  140. package/src/core/tools/impl/ShellTool.ts +118 -0
  141. package/src/core/tools/impl/TaskTool.d.ts.map +1 -0
  142. package/src/core/tools/impl/TaskTool.ts +207 -0
  143. package/src/core/tools/impl/TodoTool.d.ts.map +1 -0
  144. package/src/core/tools/impl/TodoTool.ts +122 -0
  145. package/src/core/tools/impl/WebFetchTool.d.ts.map +1 -0
  146. package/src/core/tools/impl/WebFetchTool.ts +103 -0
  147. package/src/core/tools/impl/WebSearchTool.d.ts.map +1 -0
  148. package/src/core/tools/impl/WebSearchTool.ts +89 -0
  149. package/src/core/tools/impl/WriteFileTool.d.ts.map +1 -0
  150. package/src/core/tools/impl/WriteFileTool.ts +49 -0
  151. package/src/core/tools/impl/index.d.ts.map +1 -0
  152. package/src/core/tools/impl/index.ts +16 -0
  153. package/src/core/tools/index.d.ts.map +1 -0
  154. package/src/core/tools/index.ts +7 -0
  155. package/src/core/tools/schemas/execution.d.ts.map +1 -0
  156. package/src/core/tools/schemas/execution.ts +42 -0
  157. package/src/core/tools/schemas/file.d.ts.map +1 -0
  158. package/src/core/tools/schemas/file.ts +119 -0
  159. package/src/core/tools/schemas/index.d.ts.map +1 -0
  160. package/src/core/tools/schemas/index.ts +11 -0
  161. package/src/core/tools/schemas/memory.d.ts.map +1 -0
  162. package/src/core/tools/schemas/memory.ts +52 -0
  163. package/src/core/tools/schemas/orchestration.d.ts.map +1 -0
  164. package/src/core/tools/schemas/orchestration.ts +44 -0
  165. package/src/core/tools/schemas/search.d.ts.map +1 -0
  166. package/src/core/tools/schemas/search.ts +112 -0
  167. package/src/core/tools/schemas/todo.d.ts.map +1 -0
  168. package/src/core/tools/schemas/todo.ts +32 -0
  169. package/src/core/tools/schemas/web.d.ts.map +1 -0
  170. package/src/core/tools/schemas/web.ts +86 -0
  171. package/src/core/types/config.d.ts.map +1 -0
  172. package/src/core/types/config.ts +200 -0
  173. package/src/core/types/errors.d.ts.map +1 -0
  174. package/src/core/types/errors.ts +204 -0
  175. package/src/core/types/index.d.ts.map +1 -0
  176. package/src/core/types/index.ts +8 -0
  177. package/src/core/types/session.d.ts.map +1 -0
  178. package/src/core/types/session.ts +216 -0
  179. package/src/core/types/tools.d.ts.map +1 -0
  180. package/src/core/types/tools.ts +157 -0
  181. package/src/core/utils/CheckpointManager.d.ts.map +1 -0
  182. package/src/core/utils/CheckpointManager.ts +327 -0
  183. package/src/core/utils/Logger.d.ts.map +1 -0
  184. package/src/core/utils/Logger.ts +98 -0
  185. package/src/core/utils/RetryManager.ts +471 -0
  186. package/src/core/utils/TokenCounter.d.ts.map +1 -0
  187. package/src/core/utils/TokenCounter.ts +414 -0
  188. package/src/core/utils/VectorMemoryStore.ts +440 -0
  189. package/src/core/utils/helpers.d.ts.map +1 -0
  190. package/src/core/utils/helpers.ts +89 -0
  191. package/src/core/utils/index.d.ts.map +1 -0
  192. package/src/core/utils/index.ts +19 -0
@@ -0,0 +1,515 @@
1
+ // ============================================================================
2
+ // AgentOrchestrator - Multi-agent coordination system
3
+ // ============================================================================
4
+
5
+ import { createLogger } from '../utils/Logger.js';
6
+ import { generateId } from '../utils/helpers.js';
7
+ import type { Message, SessionId } from '../types/session.js';
8
+ import type { ToolDefinition } from '../types/tools.js';
9
+
10
+ const logger = createLogger('AgentOrchestrator');
11
+
12
+ // ============================================================================
13
+ // Types
14
+ // ============================================================================
15
+
16
+ /**
17
+ * Agent role definitions
18
+ */
19
+ export type AgentRole = 'coordinator' | 'coder' | 'tester' | 'reviewer' | 'architect' | 'doc-writer';
20
+
21
+ /**
22
+ * Sub-agent configuration
23
+ */
24
+ export interface SubAgentConfig {
25
+ id: string;
26
+ role: AgentRole;
27
+ name: string;
28
+ description: string;
29
+ systemPrompt: string;
30
+ tools: string[]; // Tool names this agent can use
31
+ contextBudget: number; // Max tokens for context
32
+ modelPreferences?: {
33
+ model?: string;
34
+ temperature?: number;
35
+ maxTokens?: number;
36
+ };
37
+ }
38
+
39
+ /**
40
+ * Task to be delegated to an agent
41
+ */
42
+ export interface AgentTask {
43
+ id: string;
44
+ description: string;
45
+ type: 'code' | 'test' | 'review' | 'design' | 'doc' | 'analysis';
46
+ priority: 'low' | 'medium' | 'high';
47
+ dependencies: string[]; // Task IDs that must complete first
48
+ input: {
49
+ files?: string[];
50
+ context?: string;
51
+ requirements?: string[];
52
+ };
53
+ assignedAgent?: AgentRole;
54
+ }
55
+
56
+ /**
57
+ * Result from an agent execution
58
+ */
59
+ export interface AgentResult {
60
+ taskId: string;
61
+ agentId: string;
62
+ status: 'success' | 'partial' | 'failed';
63
+ output: {
64
+ summary: string;
65
+ details?: string;
66
+ artifacts?: Array<{
67
+ type: 'file' | 'code' | 'test' | 'doc';
68
+ path?: string;
69
+ content?: string;
70
+ }>;
71
+ recommendations?: string[];
72
+ };
73
+ metrics: {
74
+ tokensUsed: number;
75
+ duration: number;
76
+ toolCalls: number;
77
+ };
78
+ error?: string;
79
+ }
80
+
81
+ /**
82
+ * Orchestrator state
83
+ */
84
+ export interface OrchestratorState {
85
+ sessionId: SessionId;
86
+ tasks: Map<string, AgentTask>;
87
+ results: Map<string, AgentResult>;
88
+ activeAgents: Set<string>;
89
+ completedTasks: Set<string>;
90
+ }
91
+
92
+ // ============================================================================
93
+ // Agent Definitions
94
+ // ============================================================================
95
+
96
+ /**
97
+ * Built-in agent configurations
98
+ */
99
+ const BUILTIN_AGENTS: Record<AgentRole, SubAgentConfig> = {
100
+ coordinator: {
101
+ id: 'coordinator',
102
+ role: 'coordinator',
103
+ name: 'Coordinator Agent',
104
+ description: 'Orchestrates tasks and coordinates other agents',
105
+ systemPrompt: `You are the Coordinator Agent. Your role is to:
106
+ - Analyze complex tasks and break them into subtasks
107
+ - Assign subtasks to appropriate specialized agents
108
+ - Monitor progress and handle dependencies
109
+ - Aggregate results and provide unified responses
110
+
111
+ Always think step-by-step and maintain clear communication with other agents.`,
112
+ tools: ['read_file', 'list_directory', 'search_content'],
113
+ contextBudget: 8000,
114
+ },
115
+
116
+ coder: {
117
+ id: 'coder',
118
+ role: 'coder',
119
+ name: 'Coder Agent',
120
+ description: 'Writes and modifies code',
121
+ systemPrompt: `You are the Coder Agent. Your role is to:
122
+ - Write clean, efficient, and well-documented code
123
+ - Follow project coding conventions
124
+ - Implement features and fix bugs
125
+ - Ensure code is testable and maintainable
126
+
127
+ Always consider edge cases and error handling. Write code incrementally and verify changes.`,
128
+ tools: ['read_file', 'write_file', 'edit_file', 'search_content', 'execute_command'],
129
+ contextBudget: 16000,
130
+ modelPreferences: { temperature: 0.2 },
131
+ },
132
+
133
+ tester: {
134
+ id: 'tester',
135
+ role: 'tester',
136
+ name: 'Tester Agent',
137
+ description: 'Writes and runs tests, analyzes failures',
138
+ systemPrompt: `You are the Tester Agent. Your role is to:
139
+ - Write comprehensive unit and integration tests
140
+ - Run tests and analyze failures
141
+ - Identify edge cases and boundary conditions
142
+ - Suggest improvements to test coverage
143
+
144
+ Focus on meaningful tests that verify behavior, not just coverage numbers.`,
145
+ tools: ['read_file', 'write_file', 'edit_file', 'execute_command', 'search_content'],
146
+ contextBudget: 12000,
147
+ },
148
+
149
+ reviewer: {
150
+ id: 'reviewer',
151
+ role: 'reviewer',
152
+ name: 'Code Reviewer Agent',
153
+ description: 'Reviews code for quality, security, and best practices',
154
+ systemPrompt: `You are the Code Reviewer Agent. Your role is to:
155
+ - Review code for correctness and quality
156
+ - Identify potential bugs and security issues
157
+ - Check adherence to coding standards
158
+ - Suggest improvements and optimizations
159
+
160
+ Be thorough but constructive. Focus on actionable feedback.`,
161
+ tools: ['read_file', 'search_content', 'list_directory'],
162
+ contextBudget: 12000,
163
+ },
164
+
165
+ architect: {
166
+ id: 'architect',
167
+ role: 'architect',
168
+ name: 'Architect Agent',
169
+ description: 'Designs system architecture and makes high-level decisions',
170
+ systemPrompt: `You are the Architect Agent. Your role is to:
171
+ - Design system architecture and component interactions
172
+ - Make technology and design decisions
173
+ - Identify potential scalability and maintainability issues
174
+ - Create technical documentation and diagrams
175
+
176
+ Think at a high level while remaining practical.`,
177
+ tools: ['read_file', 'list_directory', 'search_content', 'write_file'],
178
+ contextBudget: 16000,
179
+ },
180
+
181
+ 'doc-writer': {
182
+ id: 'doc-writer',
183
+ role: 'doc-writer',
184
+ name: 'Documentation Agent',
185
+ description: 'Writes and updates documentation',
186
+ systemPrompt: `You are the Documentation Agent. Your role is to:
187
+ - Write clear and comprehensive documentation
188
+ - Update existing documentation to reflect changes
189
+ - Create API documentation and usage examples
190
+ - Maintain consistency in documentation style
191
+
192
+ Focus on clarity and completeness. Include examples where helpful.`,
193
+ tools: ['read_file', 'write_file', 'edit_file', 'search_content'],
194
+ contextBudget: 8000,
195
+ },
196
+ };
197
+
198
+ // ============================================================================
199
+ // AgentOrchestrator
200
+ // ============================================================================
201
+
202
+ /**
203
+ * Multi-agent orchestrator for complex task coordination
204
+ */
205
+ export class AgentOrchestrator {
206
+ private agents: Map<AgentRole, SubAgentConfig> = new Map();
207
+ private state: OrchestratorState;
208
+ private callbacks: {
209
+ onTaskStart?: (task: AgentTask, agent: SubAgentConfig) => void;
210
+ onTaskComplete?: (result: AgentResult) => void;
211
+ onProgress?: (message: string) => void;
212
+ } = {};
213
+
214
+ constructor(sessionId: SessionId) {
215
+ // Register built-in agents
216
+ for (const [role, config] of Object.entries(BUILTIN_AGENTS)) {
217
+ this.agents.set(role as AgentRole, config);
218
+ }
219
+
220
+ // Initialize state
221
+ this.state = {
222
+ sessionId,
223
+ tasks: new Map(),
224
+ results: new Map(),
225
+ activeAgents: new Set(),
226
+ completedTasks: new Set(),
227
+ };
228
+ }
229
+
230
+ // -----------------------------------------------------------------------
231
+ // Configuration
232
+ // -----------------------------------------------------------------------
233
+
234
+ /**
235
+ * Register a custom agent
236
+ */
237
+ registerAgent(config: SubAgentConfig): void {
238
+ this.agents.set(config.role, config);
239
+ logger.info(`Registered agent: ${config.name} (${config.role})`);
240
+ }
241
+
242
+ /**
243
+ * Set callbacks for monitoring
244
+ */
245
+ setCallbacks(callbacks: typeof this.callbacks): void {
246
+ this.callbacks = { ...this.callbacks, ...callbacks };
247
+ }
248
+
249
+ // -----------------------------------------------------------------------
250
+ // Task Management
251
+ // -----------------------------------------------------------------------
252
+
253
+ /**
254
+ * Create a new task
255
+ */
256
+ createTask(
257
+ description: string,
258
+ type: AgentTask['type'],
259
+ options: Partial<Omit<AgentTask, 'id' | 'description' | 'type'>> = {}
260
+ ): AgentTask {
261
+ const task: AgentTask = {
262
+ id: generateId(),
263
+ description,
264
+ type,
265
+ priority: options.priority ?? 'medium',
266
+ dependencies: options.dependencies ?? [],
267
+ input: options.input ?? {},
268
+ assignedAgent: options.assignedAgent,
269
+ };
270
+
271
+ this.state.tasks.set(task.id, task);
272
+ logger.debug(`Created task: ${task.id}`, { type, description });
273
+
274
+ return task;
275
+ }
276
+
277
+ /**
278
+ * Get tasks ready to execute (dependencies satisfied)
279
+ */
280
+ getReadyTasks(): AgentTask[] {
281
+ const ready: AgentTask[] = [];
282
+
283
+ for (const [id, task] of this.state.tasks) {
284
+ // Skip completed tasks
285
+ if (this.state.completedTasks.has(id)) continue;
286
+
287
+ // Check dependencies
288
+ const depsMet = task.dependencies.every(depId =>
289
+ this.state.completedTasks.has(depId)
290
+ );
291
+
292
+ if (depsMet) {
293
+ ready.push(task);
294
+ }
295
+ }
296
+
297
+ return ready;
298
+ }
299
+
300
+ /**
301
+ * Select best agent for a task
302
+ */
303
+ selectAgent(task: AgentTask): SubAgentConfig | null {
304
+ // If agent is explicitly assigned, use it
305
+ if (task.assignedAgent && this.agents.has(task.assignedAgent)) {
306
+ return this.agents.get(task.assignedAgent)!;
307
+ }
308
+
309
+ // Auto-select based on task type
310
+ const roleMap: Record<AgentTask['type'], AgentRole> = {
311
+ code: 'coder',
312
+ test: 'tester',
313
+ review: 'reviewer',
314
+ design: 'architect',
315
+ doc: 'doc-writer',
316
+ analysis: 'coordinator',
317
+ };
318
+
319
+ const role = roleMap[task.type];
320
+ return this.agents.get(role) ?? null;
321
+ }
322
+
323
+ // -----------------------------------------------------------------------
324
+ // Execution
325
+ // -----------------------------------------------------------------------
326
+
327
+ /**
328
+ * Execute a single task
329
+ */
330
+ async executeTask(
331
+ task: AgentTask,
332
+ executeFn: (agent: SubAgentConfig, task: AgentTask) => Promise<AgentResult>
333
+ ): Promise<AgentResult> {
334
+ const agent = this.selectAgent(task);
335
+
336
+ if (!agent) {
337
+ return {
338
+ taskId: task.id,
339
+ agentId: 'none',
340
+ status: 'failed',
341
+ output: { summary: 'No suitable agent found for task' },
342
+ metrics: { tokensUsed: 0, duration: 0, toolCalls: 0 },
343
+ error: 'No suitable agent found',
344
+ };
345
+ }
346
+
347
+ this.state.activeAgents.add(agent.id);
348
+ this.callbacks.onTaskStart?.(task, agent);
349
+
350
+ const startTime = Date.now();
351
+
352
+ try {
353
+ const result = await executeFn(agent, task);
354
+ result.metrics.duration = Date.now() - startTime;
355
+
356
+ this.state.results.set(task.id, result);
357
+ this.state.completedTasks.add(task.id);
358
+
359
+ this.callbacks.onTaskComplete?.(result);
360
+
361
+ return result;
362
+ } catch (error) {
363
+ const result: AgentResult = {
364
+ taskId: task.id,
365
+ agentId: agent.id,
366
+ status: 'failed',
367
+ output: { summary: 'Execution failed' },
368
+ metrics: {
369
+ tokensUsed: 0,
370
+ duration: Date.now() - startTime,
371
+ toolCalls: 0,
372
+ },
373
+ error: error instanceof Error ? error.message : String(error),
374
+ };
375
+
376
+ this.state.results.set(task.id, result);
377
+ this.callbacks.onTaskComplete?.(result);
378
+
379
+ return result;
380
+ } finally {
381
+ this.state.activeAgents.delete(agent.id);
382
+ }
383
+ }
384
+
385
+ /**
386
+ * Execute all pending tasks
387
+ */
388
+ async executeAll(
389
+ executeFn: (agent: SubAgentConfig, task: AgentTask) => Promise<AgentResult>,
390
+ options: { parallel?: boolean; maxConcurrent?: number } = {}
391
+ ): Promise<AgentResult[]> {
392
+ const { parallel = false, maxConcurrent = 3 } = options;
393
+ const results: AgentResult[] = [];
394
+
395
+ while (true) {
396
+ const readyTasks = this.getReadyTasks();
397
+
398
+ if (readyTasks.length === 0) {
399
+ // Check if there are pending tasks with unmet dependencies
400
+ const pending = Array.from(this.state.tasks.values())
401
+ .filter(t => !this.state.completedTasks.has(t.id));
402
+
403
+ if (pending.length > 0) {
404
+ logger.warn('Deadlock detected: tasks with unmet dependencies', {
405
+ pending: pending.map(t => t.id)
406
+ });
407
+ break;
408
+ }
409
+
410
+ // All tasks completed
411
+ break;
412
+ }
413
+
414
+ if (parallel) {
415
+ // Execute up to maxConcurrent tasks in parallel
416
+ const batch = readyTasks.slice(0, maxConcurrent);
417
+ const batchResults = await Promise.all(
418
+ batch.map(task => this.executeTask(task, executeFn))
419
+ );
420
+ results.push(...batchResults);
421
+ } else {
422
+ // Execute sequentially
423
+ for (const task of readyTasks) {
424
+ const result = await this.executeTask(task, executeFn);
425
+ results.push(result);
426
+ }
427
+ }
428
+ }
429
+
430
+ return results;
431
+ }
432
+
433
+ // -----------------------------------------------------------------------
434
+ // State Management
435
+ // -----------------------------------------------------------------------
436
+
437
+ /**
438
+ * Get orchestrator state
439
+ */
440
+ getState(): OrchestratorState {
441
+ return {
442
+ ...this.state,
443
+ tasks: new Map(this.state.tasks),
444
+ results: new Map(this.state.results),
445
+ activeAgents: new Set(this.state.activeAgents),
446
+ completedTasks: new Set(this.state.completedTasks),
447
+ };
448
+ }
449
+
450
+ /**
451
+ * Get result for a task
452
+ */
453
+ getResult(taskId: string): AgentResult | undefined {
454
+ return this.state.results.get(taskId);
455
+ }
456
+
457
+ /**
458
+ * Get all results
459
+ */
460
+ getAllResults(): AgentResult[] {
461
+ return Array.from(this.state.results.values());
462
+ }
463
+
464
+ /**
465
+ * Get execution summary
466
+ */
467
+ getSummary(): {
468
+ totalTasks: number;
469
+ completed: number;
470
+ failed: number;
471
+ totalTokens: number;
472
+ totalDuration: number;
473
+ } {
474
+ const results = Array.from(this.state.results.values());
475
+
476
+ return {
477
+ totalTasks: this.state.tasks.size,
478
+ completed: results.filter(r => r.status !== 'failed').length,
479
+ failed: results.filter(r => r.status === 'failed').length,
480
+ totalTokens: results.reduce((sum, r) => sum + r.metrics.tokensUsed, 0),
481
+ totalDuration: results.reduce((sum, r) => sum + r.metrics.duration, 0),
482
+ };
483
+ }
484
+
485
+ /**
486
+ * Reset orchestrator state
487
+ */
488
+ reset(): void {
489
+ this.state = {
490
+ sessionId: this.state.sessionId,
491
+ tasks: new Map(),
492
+ results: new Map(),
493
+ activeAgents: new Set(),
494
+ completedTasks: new Set(),
495
+ };
496
+ }
497
+ }
498
+
499
+ // ============================================================================
500
+ // Factory function
501
+ // ============================================================================
502
+
503
+ /**
504
+ * Create an agent orchestrator
505
+ */
506
+ export function createAgentOrchestrator(sessionId: SessionId): AgentOrchestrator {
507
+ return new AgentOrchestrator(sessionId);
508
+ }
509
+
510
+ /**
511
+ * Get built-in agent configurations
512
+ */
513
+ export function getBuiltinAgents(): Record<AgentRole, SubAgentConfig> {
514
+ return { ...BUILTIN_AGENTS };
515
+ }
@@ -0,0 +1,17 @@
1
+ // ============================================================================
2
+ // Agents Module - Multi-agent orchestration system
3
+ // ============================================================================
4
+
5
+ export {
6
+ AgentOrchestrator,
7
+ createAgentOrchestrator,
8
+ getBuiltinAgents
9
+ } from './AgentOrchestrator.js';
10
+
11
+ export type {
12
+ AgentRole,
13
+ SubAgentConfig,
14
+ AgentTask,
15
+ AgentResult,
16
+ OrchestratorState,
17
+ } from './AgentOrchestrator.js';