claude-flow-novice 2.0.3 โ 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/cli/commands/guidance.js +487 -668
- package/dist/src/cli/commands/index-validate.js +18 -29
- package/dist/src/cli/commands/mcp-troubleshoot.js +230 -282
- package/dist/src/cli/commands/neural-goal-init.js +92 -125
- package/dist/src/cli/commands/swarm-exec.js +317 -393
- package/dist/src/cli/commands/swarm.js +1 -1
- package/dist/src/cli/commands/validate-framework.js +983 -1100
- package/dist/src/cli/commands/validate.js +144 -223
- package/dist/src/cli/simple-commands/__tests__/agent.test.js +265 -277
- package/dist/src/cli/simple-commands/__tests__/memory.test.js +6 -7
- package/dist/src/cli/simple-commands/__tests__/swarm.test.js +373 -356
- package/dist/src/cli/simple-commands/__tests__/task.test.js +6 -7
- package/dist/src/cli/simple-commands/agent.js +157 -193
- package/dist/src/cli/simple-commands/analysis.js +336 -446
- package/dist/src/cli/simple-commands/automation-executor.js +1095 -1339
- package/dist/src/cli/simple-commands/automation.js +481 -469
- package/dist/src/cli/simple-commands/batch-manager.js +261 -313
- package/dist/src/cli/simple-commands/claude-telemetry.js +241 -267
- package/dist/src/cli/simple-commands/claude-track.js +68 -90
- package/dist/src/cli/simple-commands/concurrent-display.js +266 -320
- package/dist/src/cli/simple-commands/config.js +245 -290
- package/dist/src/cli/simple-commands/coordination.js +182 -234
- package/dist/src/cli/simple-commands/enhanced-ui-views.js +812 -615
- package/dist/src/cli/simple-commands/enhanced-webui-complete.js +922 -981
- package/dist/src/cli/simple-commands/fix-hook-variables.js +274 -294
- package/dist/src/cli/simple-commands/github/gh-coordinator.js +378 -457
- package/dist/src/cli/simple-commands/github/github-api.js +535 -574
- package/dist/src/cli/simple-commands/github/init.js +276 -303
- package/dist/src/cli/simple-commands/github.js +222 -247
- package/dist/src/cli/simple-commands/goal.js +51 -63
- package/dist/src/cli/simple-commands/hive-mind/auto-save-middleware.js +208 -278
- package/dist/src/cli/simple-commands/hive-mind/communication.js +601 -696
- package/dist/src/cli/simple-commands/hive-mind/core.js +907 -979
- package/dist/src/cli/simple-commands/hive-mind/db-optimizer.js +406 -655
- package/dist/src/cli/simple-commands/hive-mind/mcp-wrapper.js +1125 -1245
- package/dist/src/cli/simple-commands/hive-mind/memory.js +854 -1090
- package/dist/src/cli/simple-commands/hive-mind/performance-optimizer.js +459 -574
- package/dist/src/cli/simple-commands/hive-mind/performance-test.js +263 -347
- package/dist/src/cli/simple-commands/hive-mind/queen.js +727 -768
- package/dist/src/cli/simple-commands/hive-mind/session-manager.js +745 -1049
- package/dist/src/cli/simple-commands/hive-mind-optimize.js +227 -283
- package/dist/src/cli/simple-commands/hive-mind-wizard.js +174 -217
- package/dist/src/cli/simple-commands/hive-mind.js +1842 -2283
- package/dist/src/cli/simple-commands/hive.js +90 -79
- package/dist/src/cli/simple-commands/hook-safety.js +431 -521
- package/dist/src/cli/simple-commands/hooks/session-start-soul.js +203 -254
- package/dist/src/cli/simple-commands/hooks.js +1064 -1204
- package/dist/src/cli/simple-commands/init/agent-copier.js +294 -319
- package/dist/src/cli/simple-commands/init/batch-init.js +496 -562
- package/dist/src/cli/simple-commands/init/claude-commands/claude-flow-commands.js +13 -19
- package/dist/src/cli/simple-commands/init/claude-commands/optimized-claude-flow-commands.js +13 -19
- package/dist/src/cli/simple-commands/init/claude-commands/optimized-slash-commands.js +61 -88
- package/dist/src/cli/simple-commands/init/claude-commands/optimized-sparc-commands.js +125 -150
- package/dist/src/cli/simple-commands/init/claude-commands/slash-commands.js +42 -49
- package/dist/src/cli/simple-commands/init/claude-commands/sparc-commands.js +43 -61
- package/dist/src/cli/simple-commands/init/copy-revised-templates.js +141 -147
- package/dist/src/cli/simple-commands/init/executable-wrapper.js +31 -44
- package/dist/src/cli/simple-commands/init/gitignore-updater.js +64 -90
- package/dist/src/cli/simple-commands/init/help.js +104 -107
- package/dist/src/cli/simple-commands/init/hive-mind-init.js +509 -528
- package/dist/src/cli/simple-commands/init/index.js +1510 -1759
- package/dist/src/cli/simple-commands/init/performance-monitor.js +234 -317
- package/dist/src/cli/simple-commands/init/rollback/backup-manager.js +441 -504
- package/dist/src/cli/simple-commands/init/rollback/index.js +289 -364
- package/dist/src/cli/simple-commands/init/rollback/recovery-manager.js +652 -728
- package/dist/src/cli/simple-commands/init/rollback/rollback-executor.js +416 -481
- package/dist/src/cli/simple-commands/init/rollback/state-tracker.js +369 -448
- package/dist/src/cli/simple-commands/init/sparc/roo-readme.js +1 -2
- package/dist/src/cli/simple-commands/init/sparc/roomodes-config.js +122 -99
- package/dist/src/cli/simple-commands/init/sparc/workflows.js +32 -37
- package/dist/src/cli/simple-commands/init/sparc-structure.js +55 -62
- package/dist/src/cli/simple-commands/init/template-copier.js +421 -533
- package/dist/src/cli/simple-commands/init/templates/coordination-md.js +3 -6
- package/dist/src/cli/simple-commands/init/templates/enhanced-templates.js +344 -318
- package/dist/src/cli/simple-commands/init/templates/github-safe-enhanced.js +173 -218
- package/dist/src/cli/simple-commands/init/templates/github-safe.js +65 -75
- package/dist/src/cli/simple-commands/init/templates/memory-bank-md.js +3 -6
- package/dist/src/cli/simple-commands/init/templates/readme-files.js +2 -4
- package/dist/src/cli/simple-commands/init/templates/safe-hook-patterns.js +187 -230
- package/dist/src/cli/simple-commands/init/templates/sparc-modes.js +53 -80
- package/dist/src/cli/simple-commands/init/templates/verification-claude-md.js +101 -85
- package/dist/src/cli/simple-commands/init/validation/config-validator.js +283 -330
- package/dist/src/cli/simple-commands/init/validation/health-checker.js +495 -561
- package/dist/src/cli/simple-commands/init/validation/index.js +302 -358
- package/dist/src/cli/simple-commands/init/validation/mode-validator.js +308 -359
- package/dist/src/cli/simple-commands/init/validation/post-init-validator.js +389 -366
- package/dist/src/cli/simple-commands/init/validation/pre-init-validator.js +270 -268
- package/dist/src/cli/simple-commands/init/validation/test-runner.js +427 -447
- package/dist/src/cli/simple-commands/init.js +1 -2
- package/dist/src/cli/simple-commands/mcp-health.js +131 -158
- package/dist/src/cli/simple-commands/mcp-integration-layer.js +533 -634
- package/dist/src/cli/simple-commands/mcp.js +345 -400
- package/dist/src/cli/simple-commands/memory-consolidation.js +426 -537
- package/dist/src/cli/simple-commands/memory.js +247 -311
- package/dist/src/cli/simple-commands/migrate-hooks.js +39 -46
- package/dist/src/cli/simple-commands/monitor.js +294 -363
- package/dist/src/cli/simple-commands/neural.js +51 -65
- package/dist/src/cli/simple-commands/pair-autofix-only.js +538 -662
- package/dist/src/cli/simple-commands/pair-basic.js +528 -656
- package/dist/src/cli/simple-commands/pair-old.js +430 -543
- package/dist/src/cli/simple-commands/pair-working.js +615 -751
- package/dist/src/cli/simple-commands/pair.js +615 -751
- package/dist/src/cli/simple-commands/performance-hooks.js +83 -111
- package/dist/src/cli/simple-commands/performance-metrics.js +348 -433
- package/dist/src/cli/simple-commands/process-ui-enhanced.js +708 -787
- package/dist/src/cli/simple-commands/process-ui.js +230 -254
- package/dist/src/cli/simple-commands/realtime-update-system.js +525 -611
- package/dist/src/cli/simple-commands/sparc/architecture.js +1704 -1530
- package/dist/src/cli/simple-commands/sparc/commands.js +438 -516
- package/dist/src/cli/simple-commands/sparc/completion.js +1224 -1481
- package/dist/src/cli/simple-commands/sparc/coordinator.js +913 -978
- package/dist/src/cli/simple-commands/sparc/index.js +241 -298
- package/dist/src/cli/simple-commands/sparc/phase-base.js +314 -390
- package/dist/src/cli/simple-commands/sparc/pseudocode.js +965 -869
- package/dist/src/cli/simple-commands/sparc/refinement.js +980 -1273
- package/dist/src/cli/simple-commands/sparc/specification.js +559 -645
- package/dist/src/cli/simple-commands/sparc-modes/architect.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/ask.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/code.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/debug.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/devops.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/docs-writer.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/generic.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/index.js +47 -55
- package/dist/src/cli/simple-commands/sparc-modes/integration.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/mcp.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/monitoring.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/optimization.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/security-review.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/sparc-orchestrator.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/spec-pseudocode.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/supabase-admin.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/swarm.js +101 -87
- package/dist/src/cli/simple-commands/sparc-modes/tdd.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/tutorial.js +1 -1
- package/dist/src/cli/simple-commands/sparc.js +465 -493
- package/dist/src/cli/simple-commands/start-ui.js +108 -132
- package/dist/src/cli/simple-commands/start-wrapper.js +240 -268
- package/dist/src/cli/simple-commands/start.js +1 -1
- package/dist/src/cli/simple-commands/status.js +254 -275
- package/dist/src/cli/simple-commands/stream-chain-clean.js +128 -171
- package/dist/src/cli/simple-commands/stream-chain-fixed.js +61 -82
- package/dist/src/cli/simple-commands/stream-chain-real.js +267 -331
- package/dist/src/cli/simple-commands/stream-chain-working.js +211 -263
- package/dist/src/cli/simple-commands/stream-chain.js +260 -318
- package/dist/src/cli/simple-commands/stream-processor.js +290 -315
- package/dist/src/cli/simple-commands/swarm-executor.js +189 -222
- package/dist/src/cli/simple-commands/swarm-metrics-integration.js +208 -300
- package/dist/src/cli/simple-commands/swarm-ui.js +623 -703
- package/dist/src/cli/simple-commands/swarm-webui-integration.js +258 -286
- package/dist/src/cli/simple-commands/swarm.js +887 -1082
- package/dist/src/cli/simple-commands/task.js +161 -206
- package/dist/src/cli/simple-commands/timestamp-fix.js +59 -89
- package/dist/src/cli/simple-commands/token-tracker.js +258 -316
- package/dist/src/cli/simple-commands/tool-execution-framework.js +433 -519
- package/dist/src/cli/simple-commands/train-and-stream.js +275 -331
- package/dist/src/cli/simple-commands/training-pipeline.js +619 -725
- package/dist/src/cli/simple-commands/training.js +170 -227
- package/dist/src/cli/simple-commands/verification-hooks.js +261 -284
- package/dist/src/cli/simple-commands/verification-integration.js +389 -417
- package/dist/src/cli/simple-commands/verification-training-integration.js +486 -606
- package/dist/src/cli/simple-commands/verification.js +493 -513
- package/dist/src/cli/simple-commands/web-server.js +766 -836
- package/dist/src/cli/simple-commands/webui-validator.js +106 -124
- package/dist/src/coordination/event-bus/demo-wasm-integration.js +212 -251
- package/dist/src/coordination/event-bus/qe-event-bus.js +608 -748
- package/dist/src/coordination/event-bus/qe-event-bus.test.js +379 -454
- package/dist/src/coordination/iteration-tracker.js +363 -454
- package/dist/src/enterprise/analytics-manager.js +1135 -0
- package/dist/src/enterprise/audit-manager.js +1115 -0
- package/dist/src/enterprise/cloud-manager.js +891 -0
- package/dist/src/enterprise/deployment-manager.js +966 -0
- package/dist/src/enterprise/index.js +6 -0
- package/dist/src/enterprise/project-manager.js +584 -0
- package/dist/src/enterprise/security-manager.js +991 -0
- package/dist/src/index.js +1 -1
- package/dist/src/mcp/DEPRECATED.js +46 -60
- package/dist/src/mcp/fixes/mcp-error-fixes.js +115 -134
- package/dist/src/mcp/implementations/agent-tracker.js +114 -128
- package/dist/src/mcp/implementations/daa-tools.js +292 -350
- package/dist/src/mcp/implementations/workflow-tools.js +329 -361
- package/dist/src/mcp/mcp-config-manager.js +1183 -1331
- package/dist/src/mcp/mcp-server-novice-simplified.js +11 -17
- package/dist/src/mcp/mcp-server-novice.js +11 -17
- package/dist/src/mcp/mcp-server-sdk.js +11 -17
- package/dist/src/mcp/mcp-server.js +1620 -1484
- package/dist/src/mcp/ruv-swarm-wrapper.js +209 -239
- package/dist/src/memory/advanced-serializer.js +609 -589
- package/dist/src/memory/enhanced-examples.js +220 -305
- package/dist/src/memory/enhanced-memory.js +295 -336
- package/dist/src/memory/enhanced-session-serializer.js +408 -492
- package/dist/src/memory/fallback-memory-system.js +900 -1021
- package/dist/src/memory/fallback-store.js +93 -131
- package/dist/src/memory/high-performance-serialization.js +592 -730
- package/dist/src/memory/in-memory-store.js +161 -213
- package/dist/src/memory/index.js +123 -157
- package/dist/src/memory/lock-free-structures.js +578 -764
- package/dist/src/memory/memory-mapped-persistence.js +585 -766
- package/dist/src/memory/memory-pressure-manager.js +569 -707
- package/dist/src/memory/migration.js +358 -445
- package/dist/src/memory/shared-memory.js +641 -768
- package/dist/src/memory/sqlite-store.js +245 -325
- package/dist/src/memory/sqlite-wrapper.js +122 -151
- package/dist/src/memory/swarm-memory.js +470 -603
- package/dist/src/memory/test-example.js +126 -134
- package/dist/src/memory/ultra-fast-memory-store.js +622 -821
- package/dist/src/memory/unified-memory-manager.js +356 -437
- package/dist/src/migration/index.js +92 -0
- package/dist/src/migration/logger.js +121 -0
- package/dist/src/migration/migration-analyzer.js +268 -0
- package/dist/src/migration/migration-runner.js +522 -0
- package/dist/src/migration/migration-validator.js +285 -0
- package/dist/src/migration/progress-reporter.js +150 -0
- package/dist/src/migration/rollback-manager.js +321 -0
- package/dist/src/migration/tests/migration-system.test.js +7 -0
- package/dist/src/migration/types.js +3 -0
- package/dist/src/swarm/CodeRefactoringSwarm.js +777 -952
- package/dist/src/swarm/__tests__/integration.test.js +227 -0
- package/dist/src/swarm/__tests__/prompt-copier.test.js +344 -0
- package/dist/src/swarm/advanced-orchestrator.js +1095 -0
- package/dist/src/swarm/claude-code-interface.js +961 -0
- package/dist/src/swarm/claude-flow-executor.js +229 -0
- package/dist/src/swarm/consensus-coordinator.js +475 -0
- package/dist/src/swarm/coordinator.js +2993 -0
- package/dist/src/swarm/direct-executor.js +1180 -0
- package/dist/src/swarm/error-recovery/advanced-error-detection.js +691 -0
- package/dist/src/swarm/error-recovery/automated-recovery-workflows.js +998 -0
- package/dist/src/swarm/error-recovery/error-recovery-coordinator.js +1197 -0
- package/dist/src/swarm/error-recovery/recovery-monitoring.js +772 -0
- package/dist/src/swarm/error-recovery/resilience-architecture.js +714 -0
- package/dist/src/swarm/error-recovery/self-healing-mechanisms.js +1319 -0
- package/dist/src/swarm/error-recovery/test-error-recovery-effectiveness.js +808 -0
- package/dist/src/swarm/executor-v2.js +322 -0
- package/dist/src/swarm/executor.js +815 -0
- package/dist/src/swarm/hive-mind-integration.js +703 -0
- package/dist/src/swarm/index.js +41 -0
- package/dist/src/swarm/json-output-aggregator.js +267 -0
- package/dist/src/swarm/large-scale-coordinator.js +542 -0
- package/dist/src/swarm/mcp-integration-wrapper.js +628 -0
- package/dist/src/swarm/memory.js +1117 -0
- package/dist/src/swarm/optimizations/__tests__/optimization.test.js +348 -0
- package/dist/src/swarm/optimizations/async-file-manager.js +285 -0
- package/dist/src/swarm/optimizations/circular-buffer.js +162 -0
- package/dist/src/swarm/optimizations/connection-pool.js +244 -0
- package/dist/src/swarm/optimizations/index.js +28 -0
- package/dist/src/swarm/optimizations/optimized-executor.js +320 -0
- package/dist/src/swarm/optimizations/ttl-map.js +234 -0
- package/dist/src/swarm/prompt-cli.js +200 -0
- package/dist/src/swarm/prompt-copier-enhanced.js +202 -0
- package/dist/src/swarm/prompt-copier.js +381 -0
- package/dist/src/swarm/prompt-manager.js +295 -0
- package/dist/src/swarm/prompt-utils.js +310 -0
- package/dist/src/swarm/result-aggregator.js +718 -0
- package/dist/src/swarm/sparc-executor.js +1568 -0
- package/dist/src/swarm/strategies/auto.js +758 -0
- package/dist/src/swarm/strategies/base.js +128 -0
- package/dist/src/swarm/strategies/research.js +914 -0
- package/dist/src/swarm/strategies/strategy-metrics-patch.js +2 -0
- package/dist/src/swarm/types.js +52 -0
- package/dist/src/swarm/workers/copy-worker.js +56 -0
- package/dist/src/utils/__tests__/github-cli-safety-wrapper.test.js +332 -400
- package/dist/src/utils/github-cli-safe.js +56 -64
- package/dist/src/utils/github-cli-safety-wrapper.js +451 -546
- package/dist/src/utils/npx-isolated-cache.js +104 -119
- package/dist/src/utils/preference-manager.js +622 -652
- package/dist/src/utils/timezone-utils.js +86 -105
- package/dist/src/validators/epic-config-schema.js +214 -0
- package/dist/src/validators/index.js +10 -0
- package/dist/src/validators/swarm-init-validator.js +259 -0
- package/dist/src/validators/todowrite-batching-validator.js +215 -0
- package/dist/src/validators/todowrite-integration.js +187 -0
- package/package.json +2 -2
|
@@ -4,469 +4,371 @@
|
|
|
4
4
|
* This module provides the core infrastructure for executing automation
|
|
5
5
|
* workflows with Claude CLI integration, while preserving existing
|
|
6
6
|
* swarm and hive-mind functionality.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { join, dirname } from 'path';
|
|
12
|
-
import { printSuccess, printError, printWarning } from '../utils.js';
|
|
13
|
-
|
|
7
|
+
*/ import { promises as fs } from "fs";
|
|
8
|
+
import { spawn } from "child_process";
|
|
9
|
+
import { join } from "path";
|
|
10
|
+
import { printSuccess, printError } from "../utils.js";
|
|
14
11
|
// Simple ID generator
|
|
15
12
|
function generateId(prefix = 'id') {
|
|
16
|
-
|
|
13
|
+
return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
17
14
|
}
|
|
18
|
-
|
|
19
15
|
/**
|
|
20
16
|
* WorkflowExecutor - Core class for executing automation workflows
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
constructor(options = {}) {
|
|
24
|
-
this.options = {
|
|
25
|
-
enableClaude: false,
|
|
26
|
-
nonInteractive: false,
|
|
27
|
-
outputFormat: 'text',
|
|
28
|
-
maxConcurrency: 3,
|
|
29
|
-
timeout: 3600000, // 1 hour default
|
|
30
|
-
logLevel: 'info',
|
|
31
|
-
...options,
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
// Increase timeout for ML workflows
|
|
35
|
-
if (options.workflowType === 'ml' || options.workflowName?.toLowerCase().includes('mle')) {
|
|
36
|
-
this.options.timeout = 7200000; // 2 hours for ML workflows
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Execution state
|
|
40
|
-
this.executionId = generateId('workflow-exec');
|
|
41
|
-
this.startTime = Date.now();
|
|
42
|
-
this.activeTasks = new Map();
|
|
43
|
-
this.claudeInstances = new Map();
|
|
44
|
-
this.results = new Map();
|
|
45
|
-
this.errors = [];
|
|
46
|
-
this.currentWorkflow = null;
|
|
47
|
-
|
|
48
|
-
// Stream chaining support
|
|
49
|
-
this.taskOutputStreams = new Map(); // Store output streams for chaining
|
|
50
|
-
this.enableChaining = options.enableChaining !== false; // Default to true
|
|
51
|
-
|
|
52
|
-
// Hooks integration
|
|
53
|
-
this.hooksEnabled = true;
|
|
54
|
-
this.sessionId = generateId('automation-session');
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
17
|
+
*/ export class WorkflowExecutor {
|
|
18
|
+
/**
|
|
58
19
|
* Execute a workflow from JSON definition
|
|
59
|
-
*/
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
20
|
+
*/ async executeWorkflow(workflowData, variables = {}) {
|
|
21
|
+
try {
|
|
22
|
+
// Store workflow for reference
|
|
23
|
+
this.currentWorkflow = workflowData;
|
|
24
|
+
if (this.options.logLevel === 'quiet') {
|
|
25
|
+
console.log(`๐ Executing workflow: ${this.executionId}`);
|
|
26
|
+
} else {
|
|
27
|
+
console.log(`๐ Starting workflow execution: ${this.executionId}`);
|
|
28
|
+
console.log(`๐ Workflow: ${workflowData.name}`);
|
|
29
|
+
console.log(`๐ฏ Strategy: MLE-STAR Machine Learning Engineering`);
|
|
30
|
+
if (this.options.enableClaude) {
|
|
31
|
+
console.log(`๐ค Claude CLI Integration: Enabled`);
|
|
32
|
+
}
|
|
33
|
+
if (this.options.nonInteractive) {
|
|
34
|
+
console.log(`๐ฅ๏ธ Non-Interactive Mode: Enabled`);
|
|
35
|
+
if (this.options.outputFormat === 'stream-json') {
|
|
36
|
+
console.log();
|
|
37
|
+
console.log('โ Running MLE-STAR workflow with Claude CLI integration');
|
|
38
|
+
console.log(' โฟ Command format: claude --print --output-format stream-json --verbose --dangerously-skip-permissions');
|
|
39
|
+
console.log(' โฟ Each agent will show real-time stream output below');
|
|
40
|
+
console.log(' โฟ Interactive-style formatting enabled');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
79
44
|
console.log();
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
45
|
+
// Pre-execution hooks
|
|
46
|
+
if (this.hooksEnabled) {
|
|
47
|
+
await this.executeHook('pre-task', {
|
|
48
|
+
description: `Execute workflow: ${workflowData.name}`,
|
|
49
|
+
sessionId: this.sessionId
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// Validate workflow
|
|
53
|
+
this.validateWorkflow(workflowData);
|
|
54
|
+
// Apply variable substitutions
|
|
55
|
+
const processedWorkflow = this.applyVariables(workflowData, variables);
|
|
56
|
+
// Initialize agents if Claude integration is enabled
|
|
57
|
+
if (this.options.enableClaude) {
|
|
58
|
+
await this.initializeClaudeAgents(processedWorkflow.agents);
|
|
59
|
+
}
|
|
60
|
+
// Execute workflow phases
|
|
61
|
+
const result = await this.executeWorkflowTasks(processedWorkflow);
|
|
62
|
+
// Post-execution hooks
|
|
63
|
+
if (this.hooksEnabled) {
|
|
64
|
+
await this.executeHook('post-task', {
|
|
65
|
+
taskId: this.executionId,
|
|
66
|
+
sessionId: this.sessionId,
|
|
67
|
+
result: result.success ? 'success' : 'failure'
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
const duration = Date.now() - this.startTime;
|
|
71
|
+
if (result.success) {
|
|
72
|
+
printSuccess(`โ
Workflow completed successfully in ${this.formatDuration(duration)}`);
|
|
73
|
+
console.log(`๐ Tasks: ${result.completedTasks}/${result.totalTasks} completed`);
|
|
74
|
+
console.log(`๐ Execution ID: ${this.executionId}`);
|
|
75
|
+
} else {
|
|
76
|
+
printError(`โ Workflow failed after ${this.formatDuration(duration)}`);
|
|
77
|
+
console.log(`๐ Tasks: ${result.completedTasks}/${result.totalTasks} completed`);
|
|
78
|
+
console.log(`โ Errors: ${this.errors.length}`);
|
|
79
|
+
}
|
|
80
|
+
// Cleanup Claude instances
|
|
81
|
+
if (this.options.enableClaude) {
|
|
82
|
+
await this.cleanupClaudeInstances();
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
} catch (error) {
|
|
86
|
+
printError(`Workflow execution failed: ${error.message}`);
|
|
87
|
+
await this.cleanupClaudeInstances();
|
|
88
|
+
throw error;
|
|
87
89
|
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
console.log();
|
|
91
|
-
|
|
92
|
-
// Pre-execution hooks
|
|
93
|
-
if (this.hooksEnabled) {
|
|
94
|
-
await this.executeHook('pre-task', {
|
|
95
|
-
description: `Execute workflow: ${workflowData.name}`,
|
|
96
|
-
sessionId: this.sessionId,
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Validate workflow
|
|
101
|
-
this.validateWorkflow(workflowData);
|
|
102
|
-
|
|
103
|
-
// Apply variable substitutions
|
|
104
|
-
const processedWorkflow = this.applyVariables(workflowData, variables);
|
|
105
|
-
|
|
106
|
-
// Initialize agents if Claude integration is enabled
|
|
107
|
-
if (this.options.enableClaude) {
|
|
108
|
-
await this.initializeClaudeAgents(processedWorkflow.agents);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Execute workflow phases
|
|
112
|
-
const result = await this.executeWorkflowTasks(processedWorkflow);
|
|
113
|
-
|
|
114
|
-
// Post-execution hooks
|
|
115
|
-
if (this.hooksEnabled) {
|
|
116
|
-
await this.executeHook('post-task', {
|
|
117
|
-
taskId: this.executionId,
|
|
118
|
-
sessionId: this.sessionId,
|
|
119
|
-
result: result.success ? 'success' : 'failure',
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const duration = Date.now() - this.startTime;
|
|
124
|
-
|
|
125
|
-
if (result.success) {
|
|
126
|
-
printSuccess(`โ
Workflow completed successfully in ${this.formatDuration(duration)}`);
|
|
127
|
-
console.log(`๐ Tasks: ${result.completedTasks}/${result.totalTasks} completed`);
|
|
128
|
-
console.log(`๐ Execution ID: ${this.executionId}`);
|
|
129
|
-
} else {
|
|
130
|
-
printError(`โ Workflow failed after ${this.formatDuration(duration)}`);
|
|
131
|
-
console.log(`๐ Tasks: ${result.completedTasks}/${result.totalTasks} completed`);
|
|
132
|
-
console.log(`โ Errors: ${this.errors.length}`);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Cleanup Claude instances
|
|
136
|
-
if (this.options.enableClaude) {
|
|
137
|
-
await this.cleanupClaudeInstances();
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return result;
|
|
141
|
-
} catch (error) {
|
|
142
|
-
printError(`Workflow execution failed: ${error.message}`);
|
|
143
|
-
await this.cleanupClaudeInstances();
|
|
144
|
-
throw error;
|
|
145
90
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
/**
|
|
91
|
+
/**
|
|
149
92
|
* Initialize Claude CLI instances for agents
|
|
150
|
-
*/
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
this.errors.push({
|
|
203
|
-
type: 'master_coordinator_initialization',
|
|
204
|
-
error: error.message,
|
|
205
|
-
timestamp: new Date(),
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
console.log();
|
|
93
|
+
*/ async initializeClaudeAgents(agents) {
|
|
94
|
+
if (!agents || agents.length === 0) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
// Check if Claude CLI is available
|
|
98
|
+
if (!await this.isClaudeAvailable()) {
|
|
99
|
+
throw new Error('Claude CLI not found. Please install Claude Code: https://claude.ai/code');
|
|
100
|
+
}
|
|
101
|
+
if (this.options.nonInteractive) {
|
|
102
|
+
// Non-interactive mode: agents are spawned per task instead
|
|
103
|
+
if (this.options.logLevel !== 'quiet') {
|
|
104
|
+
console.log(`๐ค Non-interactive mode: Claude instances will be spawned per task`);
|
|
105
|
+
console.log(`๐ Each task will launch its own Claude process with specific prompts`);
|
|
106
|
+
}
|
|
107
|
+
return;
|
|
108
|
+
} else {
|
|
109
|
+
// Interactive mode: spawn single Claude instance with master coordination prompt
|
|
110
|
+
console.log(`๐ค Interactive mode: Initializing single Claude instance for workflow coordination...`);
|
|
111
|
+
try {
|
|
112
|
+
// Create master coordination prompt for all agents and workflow
|
|
113
|
+
const masterPrompt = this.createMasterCoordinationPrompt(agents);
|
|
114
|
+
// Spawn single Claude instance for workflow coordination
|
|
115
|
+
const claudeProcess = await this.spawnClaudeInstance({
|
|
116
|
+
id: 'master-coordinator',
|
|
117
|
+
name: 'Workflow Coordinator',
|
|
118
|
+
type: 'coordinator'
|
|
119
|
+
}, masterPrompt);
|
|
120
|
+
// Store as master coordinator
|
|
121
|
+
this.claudeInstances.set('master-coordinator', {
|
|
122
|
+
process: claudeProcess,
|
|
123
|
+
agent: {
|
|
124
|
+
id: 'master-coordinator',
|
|
125
|
+
name: 'Workflow Coordinator',
|
|
126
|
+
type: 'coordinator'
|
|
127
|
+
},
|
|
128
|
+
status: 'active',
|
|
129
|
+
startTime: Date.now(),
|
|
130
|
+
agents: agents
|
|
131
|
+
});
|
|
132
|
+
console.log(` โ
Master Workflow Coordinator (PID: ${claudeProcess.pid})`);
|
|
133
|
+
console.log(` ๐ฏ Coordinating ${agents.length} sub-agents via concurrent streams`);
|
|
134
|
+
console.log(` ๐ Agents: ${agents.map((a)=>a.name).join(', ')}`);
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.error(` โ Failed to initialize master coordinator: ${error.message}`);
|
|
137
|
+
this.errors.push({
|
|
138
|
+
type: 'master_coordinator_initialization',
|
|
139
|
+
error: error.message,
|
|
140
|
+
timestamp: new Date()
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
console.log();
|
|
144
|
+
}
|
|
210
145
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
/**
|
|
146
|
+
/**
|
|
214
147
|
* Check if Claude CLI is available
|
|
215
|
-
*/
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
148
|
+
*/ async isClaudeAvailable() {
|
|
149
|
+
try {
|
|
150
|
+
const { execSync } = await import("child_process");
|
|
151
|
+
execSync('which claude', {
|
|
152
|
+
stdio: 'ignore'
|
|
153
|
+
});
|
|
154
|
+
return true;
|
|
155
|
+
} catch {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
223
158
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
/**
|
|
159
|
+
/**
|
|
227
160
|
* Spawn a Claude CLI instance for an agent
|
|
228
161
|
* @param {Object} agent - The agent configuration
|
|
229
162
|
* @param {string} prompt - The prompt for the agent
|
|
230
163
|
* @param {Object} options - Additional options
|
|
231
164
|
* @param {Stream} options.inputStream - Optional input stream from previous agent
|
|
232
165
|
* @param {boolean} options.enableChaining - Whether to enable stream-json chaining
|
|
233
|
-
*/
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
claudeArgs.push('--input-format', 'stream-json');
|
|
166
|
+
*/ async spawnClaudeInstance(agent1, prompt, options = {}) {
|
|
167
|
+
const claudeArgs = [];
|
|
168
|
+
// Add flags based on mode
|
|
169
|
+
if (this.options.nonInteractive) {
|
|
170
|
+
// Non-interactive mode: use --print with stream-json output
|
|
171
|
+
claudeArgs.push('--print');
|
|
172
|
+
if (this.options.outputFormat === 'stream-json') {
|
|
173
|
+
claudeArgs.push('--output-format', 'stream-json');
|
|
174
|
+
claudeArgs.push('--verbose'); // Required for stream-json
|
|
175
|
+
// Add input format if we're chaining from a previous agent
|
|
176
|
+
if (options.inputStream) {
|
|
177
|
+
claudeArgs.push('--input-format', 'stream-json');
|
|
178
|
+
}
|
|
179
|
+
}
|
|
248
180
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
const displayPrompt = prompt.length > 100 ? prompt.substring(0, 100) + '...' : prompt;
|
|
261
|
-
const flagsDisplay = this.options.nonInteractive
|
|
262
|
-
? this.options.outputFormat === 'stream-json'
|
|
263
|
-
? options.inputStream
|
|
264
|
-
? '--print --input-format stream-json --output-format stream-json --verbose --dangerously-skip-permissions'
|
|
265
|
-
: '--print --output-format stream-json --verbose --dangerously-skip-permissions'
|
|
266
|
-
: '--print --dangerously-skip-permissions'
|
|
267
|
-
: '--dangerously-skip-permissions';
|
|
268
|
-
console.log(
|
|
269
|
-
` ๐ค Spawning Claude for ${agent.name}: claude ${flagsDisplay} "${displayPrompt}"`,
|
|
270
|
-
);
|
|
271
|
-
} else if (this.options.logLevel !== 'quiet') {
|
|
272
|
-
console.log(` ๐ Starting ${agent.name}`);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// Determine stdio configuration based on mode and chaining
|
|
276
|
-
const stdioConfig = this.options.nonInteractive
|
|
277
|
-
? [options.inputStream ? 'pipe' : 'inherit', 'pipe', 'pipe'] // Non-interactive: pipe for chaining
|
|
278
|
-
: ['inherit', 'inherit', 'inherit']; // Interactive: inherit all for normal Claude interaction
|
|
279
|
-
|
|
280
|
-
// Spawn Claude process
|
|
281
|
-
const claudeProcess = spawn('claude', claudeArgs, {
|
|
282
|
-
stdio: stdioConfig,
|
|
283
|
-
shell: false,
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
// If we have an input stream, pipe it to Claude's stdin
|
|
287
|
-
if (options.inputStream && claudeProcess.stdin) {
|
|
288
|
-
console.log(` ๐ Chaining: Piping output from previous agent to ${agent.name}`);
|
|
289
|
-
options.inputStream.pipe(claudeProcess.stdin);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// Handle stdout with stream processor for better formatting (only in non-interactive mode)
|
|
293
|
-
if (
|
|
294
|
-
this.options.nonInteractive &&
|
|
295
|
-
this.options.outputFormat === 'stream-json' &&
|
|
296
|
-
claudeProcess.stdout
|
|
297
|
-
) {
|
|
298
|
-
// Import and use stream processor
|
|
299
|
-
const { createStreamProcessor } = await import('./stream-processor.js');
|
|
300
|
-
const streamProcessor = createStreamProcessor(agent.name, this.getAgentIcon(agent.id), {
|
|
301
|
-
verbose: this.options.logLevel === 'debug',
|
|
302
|
-
logLevel: this.options.logLevel,
|
|
303
|
-
taskId: agent.taskId,
|
|
304
|
-
agentId: agent.id,
|
|
305
|
-
display: null, // Interactive-style formatting instead of concurrent display
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
// Pipe stdout through processor
|
|
309
|
-
claudeProcess.stdout.pipe(streamProcessor);
|
|
310
|
-
|
|
311
|
-
// Handle stderr for non-interactive mode
|
|
312
|
-
claudeProcess.stderr.on('data', (data) => {
|
|
313
|
-
const message = data.toString().trim();
|
|
314
|
-
if (message) {
|
|
315
|
-
console.error(` โ [${agent.name}] Error: ${message}`);
|
|
181
|
+
// Always skip permissions for automated workflows (both interactive and non-interactive)
|
|
182
|
+
claudeArgs.push('--dangerously-skip-permissions');
|
|
183
|
+
// Always add the prompt as the final argument
|
|
184
|
+
claudeArgs.push(prompt);
|
|
185
|
+
// Only show command details in verbose mode
|
|
186
|
+
if (this.options.logLevel === 'debug') {
|
|
187
|
+
const displayPrompt = prompt.length > 100 ? prompt.substring(0, 100) + '...' : prompt;
|
|
188
|
+
const flagsDisplay = this.options.nonInteractive ? this.options.outputFormat === 'stream-json' ? options.inputStream ? '--print --input-format stream-json --output-format stream-json --verbose --dangerously-skip-permissions' : '--print --output-format stream-json --verbose --dangerously-skip-permissions' : '--print --dangerously-skip-permissions' : '--dangerously-skip-permissions';
|
|
189
|
+
console.log(` ๐ค Spawning Claude for ${agent1.name}: claude ${flagsDisplay} "${displayPrompt}"`);
|
|
190
|
+
} else if (this.options.logLevel !== 'quiet') {
|
|
191
|
+
console.log(` ๐ Starting ${agent1.name}`);
|
|
316
192
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
193
|
+
// Determine stdio configuration based on mode and chaining
|
|
194
|
+
const stdioConfig = this.options.nonInteractive ? [
|
|
195
|
+
options.inputStream ? 'pipe' : 'inherit',
|
|
196
|
+
'pipe',
|
|
197
|
+
'pipe'
|
|
198
|
+
] // Non-interactive: pipe for chaining
|
|
199
|
+
: [
|
|
200
|
+
'inherit',
|
|
201
|
+
'inherit',
|
|
202
|
+
'inherit'
|
|
203
|
+
]; // Interactive: inherit all for normal Claude interaction
|
|
204
|
+
// Spawn Claude process
|
|
205
|
+
const claudeProcess = spawn('claude', claudeArgs, {
|
|
206
|
+
stdio: stdioConfig,
|
|
207
|
+
shell: false
|
|
208
|
+
});
|
|
209
|
+
// If we have an input stream, pipe it to Claude's stdin
|
|
210
|
+
if (options.inputStream && claudeProcess.stdin) {
|
|
211
|
+
console.log(` ๐ Chaining: Piping output from previous agent to ${agent1.name}`);
|
|
212
|
+
options.inputStream.pipe(claudeProcess.stdin);
|
|
213
|
+
}
|
|
214
|
+
// Handle stdout with stream processor for better formatting (only in non-interactive mode)
|
|
215
|
+
if (this.options.nonInteractive && this.options.outputFormat === 'stream-json' && claudeProcess.stdout) {
|
|
216
|
+
// Import and use stream processor
|
|
217
|
+
const { createStreamProcessor } = await import("./stream-processor.js");
|
|
218
|
+
const streamProcessor = createStreamProcessor(agent1.name, this.getAgentIcon(agent1.id), {
|
|
219
|
+
verbose: this.options.logLevel === 'debug',
|
|
220
|
+
logLevel: this.options.logLevel,
|
|
221
|
+
taskId: agent1.taskId,
|
|
222
|
+
agentId: agent1.id,
|
|
223
|
+
display: null
|
|
224
|
+
});
|
|
225
|
+
// Pipe stdout through processor
|
|
226
|
+
claudeProcess.stdout.pipe(streamProcessor);
|
|
227
|
+
// Handle stderr for non-interactive mode
|
|
228
|
+
claudeProcess.stderr.on('data', (data)=>{
|
|
229
|
+
const message = data.toString().trim();
|
|
230
|
+
if (message) {
|
|
231
|
+
console.error(` โ [${agent1.name}] Error: ${message}`);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
} else if (this.options.nonInteractive && this.options.outputFormat !== 'stream-json') {
|
|
235
|
+
// For non-interactive non-stream-json output, show stdout directly
|
|
236
|
+
claudeProcess.stdout.on('data', (data)=>{
|
|
237
|
+
console.log(data.toString().trimEnd());
|
|
238
|
+
});
|
|
239
|
+
claudeProcess.stderr.on('data', (data)=>{
|
|
240
|
+
console.error(data.toString().trimEnd());
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
// Note: In interactive mode, stdio is inherited so Claude handles its own I/O
|
|
244
|
+
// Handle process events
|
|
245
|
+
claudeProcess.on('error', (error)=>{
|
|
246
|
+
console.error(`โ Claude instance error for ${agent1.name}:`, error.message);
|
|
247
|
+
this.errors.push({
|
|
248
|
+
type: 'claude_instance_error',
|
|
249
|
+
agent: agent1.id,
|
|
250
|
+
error: error.message,
|
|
251
|
+
timestamp: new Date()
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
claudeProcess.on('exit', (code)=>{
|
|
255
|
+
const instance = this.claudeInstances.get(agent1.id);
|
|
256
|
+
if (instance) {
|
|
257
|
+
instance.status = code === 0 ? 'completed' : 'failed';
|
|
258
|
+
instance.exitCode = code;
|
|
259
|
+
instance.endTime = Date.now();
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
return claudeProcess;
|
|
327
263
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
// Handle process events
|
|
331
|
-
claudeProcess.on('error', (error) => {
|
|
332
|
-
console.error(`โ Claude instance error for ${agent.name}:`, error.message);
|
|
333
|
-
this.errors.push({
|
|
334
|
-
type: 'claude_instance_error',
|
|
335
|
-
agent: agent.id,
|
|
336
|
-
error: error.message,
|
|
337
|
-
timestamp: new Date(),
|
|
338
|
-
});
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
claudeProcess.on('exit', (code) => {
|
|
342
|
-
const instance = this.claudeInstances.get(agent.id);
|
|
343
|
-
if (instance) {
|
|
344
|
-
instance.status = code === 0 ? 'completed' : 'failed';
|
|
345
|
-
instance.exitCode = code;
|
|
346
|
-
instance.endTime = Date.now();
|
|
347
|
-
}
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
return claudeProcess;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
/**
|
|
264
|
+
/**
|
|
354
265
|
* Handle Claude stream events
|
|
355
|
-
*/
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
console.log(` [${agent.name}] ${event.type}: ${JSON.stringify(event)}`);
|
|
397
|
-
}
|
|
398
|
-
}
|
|
266
|
+
*/ handleClaudeStreamEvent(agent1, event) {
|
|
267
|
+
if (this.options.outputFormat === 'stream-json') {
|
|
268
|
+
// Create concise formatted JSON with summary
|
|
269
|
+
const summary = this.getEventSummary(event);
|
|
270
|
+
const icon = this.getEventIcon(event.type);
|
|
271
|
+
// Simplified output for better readability
|
|
272
|
+
const output = {
|
|
273
|
+
t: new Date().toISOString().split('T')[1].split('.')[0],
|
|
274
|
+
agent: `${this.getAgentIcon(agent1.id)} ${agent1.name}`,
|
|
275
|
+
phase: this.currentPhase,
|
|
276
|
+
event: `${icon} ${summary}`
|
|
277
|
+
};
|
|
278
|
+
// Add relevant details based on event type
|
|
279
|
+
if (event.type === 'tool_use' && event.name) {
|
|
280
|
+
output.tool = event.name;
|
|
281
|
+
} else if (event.type === 'error' && event.error) {
|
|
282
|
+
output.error = event.error;
|
|
283
|
+
}
|
|
284
|
+
console.log(JSON.stringify(output));
|
|
285
|
+
} else {
|
|
286
|
+
// Format output for text mode
|
|
287
|
+
switch(event.type){
|
|
288
|
+
case 'tool_use':
|
|
289
|
+
console.log(` [${agent1.name}] ๐ง Using tool: ${event.name}`);
|
|
290
|
+
break;
|
|
291
|
+
case 'message':
|
|
292
|
+
console.log(` [${agent1.name}] ๐ฌ ${event.content}`);
|
|
293
|
+
break;
|
|
294
|
+
case 'completion':
|
|
295
|
+
console.log(` [${agent1.name}] โ
Task completed`);
|
|
296
|
+
break;
|
|
297
|
+
case 'error':
|
|
298
|
+
console.error(` [${agent1.name}] โ Error: ${event.error}`);
|
|
299
|
+
break;
|
|
300
|
+
default:
|
|
301
|
+
// Log other events in debug mode
|
|
302
|
+
if (this.options.logLevel === 'debug') {
|
|
303
|
+
console.log(` [${agent1.name}] ${event.type}: ${JSON.stringify(event)}`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
399
307
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
/**
|
|
308
|
+
/**
|
|
403
309
|
* Get a brief summary of an event
|
|
404
|
-
*/
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
310
|
+
*/ getEventSummary(event) {
|
|
311
|
+
switch(event.type){
|
|
312
|
+
case 'tool_use':
|
|
313
|
+
return `Using ${event.name} tool`;
|
|
314
|
+
case 'message':
|
|
315
|
+
return event.content?.substring(0, 100) + (event.content?.length > 100 ? '...' : '');
|
|
316
|
+
case 'completion':
|
|
317
|
+
return 'Task completed successfully';
|
|
318
|
+
case 'error':
|
|
319
|
+
return `Error: ${event.error}`;
|
|
320
|
+
case 'status':
|
|
321
|
+
return event.status || 'Status update';
|
|
322
|
+
default:
|
|
323
|
+
return event.type;
|
|
324
|
+
}
|
|
419
325
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
/**
|
|
326
|
+
/**
|
|
423
327
|
* Get icon for event type
|
|
424
|
-
*/
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
/**
|
|
328
|
+
*/ getEventIcon(eventType) {
|
|
329
|
+
const icons = {
|
|
330
|
+
tool_use: '๐ง',
|
|
331
|
+
message: '๐ฌ',
|
|
332
|
+
completion: 'โ
',
|
|
333
|
+
error: 'โ',
|
|
334
|
+
status: '๐',
|
|
335
|
+
init: '๐',
|
|
336
|
+
thinking: '๐ค',
|
|
337
|
+
result: '๐'
|
|
338
|
+
};
|
|
339
|
+
return icons[eventType] || '๐';
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
440
342
|
* Create task-specific Claude prompt with comprehensive MLE-STAR instructions
|
|
441
|
-
*/
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
343
|
+
*/ createTaskPrompt(task, agent1, workflow) {
|
|
344
|
+
// Use the claudePrompt from the task if available
|
|
345
|
+
if (task.claudePrompt) {
|
|
346
|
+
// Apply variable substitutions to the prompt
|
|
347
|
+
let basePrompt = task.claudePrompt;
|
|
348
|
+
const allVariables = {
|
|
349
|
+
...workflow.variables,
|
|
350
|
+
...task.input
|
|
351
|
+
};
|
|
352
|
+
for (const [key, value] of Object.entries(allVariables)){
|
|
353
|
+
const pattern = new RegExp(`\\$\\{${key}\\}`, 'g');
|
|
354
|
+
basePrompt = basePrompt.replace(pattern, value);
|
|
355
|
+
}
|
|
356
|
+
// Create comprehensive task prompt with MLE-STAR methodology
|
|
357
|
+
return `๐ฏ MLE-STAR AGENT TASK EXECUTION
|
|
456
358
|
|
|
457
|
-
You are the **${
|
|
359
|
+
You are the **${agent1.name}** (${agent1.type}) in a coordinated MLE-STAR automation workflow.
|
|
458
360
|
|
|
459
361
|
๐ IMMEDIATE TASK:
|
|
460
362
|
${basePrompt}
|
|
461
363
|
|
|
462
364
|
๐ค AGENT ROLE & SPECIALIZATION:
|
|
463
|
-
${this.getAgentRoleDescription(
|
|
365
|
+
${this.getAgentRoleDescription(agent1.type)}
|
|
464
366
|
|
|
465
367
|
๐ฏ AGENT CAPABILITIES:
|
|
466
|
-
${
|
|
368
|
+
${agent1.config?.capabilities?.join(', ') || 'general automation'}
|
|
467
369
|
|
|
468
370
|
๐ฌ MLE-STAR METHODOLOGY FOCUS:
|
|
469
|
-
${this.getMethodologyGuidance(
|
|
371
|
+
${this.getMethodologyGuidance(agent1.type)}
|
|
470
372
|
|
|
471
373
|
๐ง COORDINATION REQUIREMENTS:
|
|
472
374
|
1. **HOOKS INTEGRATION** (CRITICAL):
|
|
@@ -475,20 +377,20 @@ ${this.getMethodologyGuidance(agent.type)}
|
|
|
475
377
|
- WHEN complete: \`npx claude-flow@alpha hooks post-task --task-id "${task.id}"\`
|
|
476
378
|
|
|
477
379
|
2. **MEMORY STORAGE** (CRITICAL):
|
|
478
|
-
- Store findings: \`npx claude-flow@alpha memory store "agent/${
|
|
479
|
-
- Store results: \`npx claude-flow@alpha memory store "agent/${
|
|
380
|
+
- Store findings: \`npx claude-flow@alpha memory store "agent/${agent1.id}/findings" "[your_findings]"\`
|
|
381
|
+
- Store results: \`npx claude-flow@alpha memory store "agent/${agent1.id}/results" "[your_results]"\`
|
|
480
382
|
- Check other agents: \`npx claude-flow@alpha memory search "agent/*"\`
|
|
481
383
|
|
|
482
384
|
3. **SESSION COORDINATION**:
|
|
483
385
|
- Session ID: ${this.sessionId}
|
|
484
386
|
- Execution ID: ${this.executionId}
|
|
485
387
|
- Task ID: ${task.id}
|
|
486
|
-
- Agent ID: ${
|
|
388
|
+
- Agent ID: ${agent1.id}
|
|
487
389
|
|
|
488
390
|
4. **WORKFLOW PIPELINE AWARENESS**:
|
|
489
|
-
- Your position: ${this.getAgentPositionInPipeline(
|
|
490
|
-
- Coordinate with: ${this.getCoordinationPartners(
|
|
491
|
-
- File naming: Use \`${
|
|
391
|
+
- Your position: ${this.getAgentPositionInPipeline(agent1.type)}
|
|
392
|
+
- Coordinate with: ${this.getCoordinationPartners(agent1.type)}
|
|
393
|
+
- File naming: Use \`${agent1.id}_[component].[ext]\` convention
|
|
492
394
|
|
|
493
395
|
5. **OUTPUT REQUIREMENTS**:
|
|
494
396
|
- Use detailed progress reporting
|
|
@@ -512,33 +414,30 @@ ${this.getMethodologyGuidance(agent.type)}
|
|
|
512
414
|
- Ready for next pipeline phase
|
|
513
415
|
|
|
514
416
|
Begin execution now with the hooks pre-task command.`;
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
417
|
+
} else {
|
|
418
|
+
// Fallback to full agent prompt
|
|
419
|
+
return this.createAgentPrompt(agent1);
|
|
420
|
+
}
|
|
518
421
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
/**
|
|
422
|
+
/**
|
|
522
423
|
* Create agent-specific Claude prompt
|
|
523
|
-
*/
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
return `You are the ${agent.name} in a coordinated MLE-STAR automation workflow.
|
|
424
|
+
*/ createAgentPrompt(agent1) {
|
|
425
|
+
const { config } = agent1;
|
|
426
|
+
const capabilities = config?.capabilities?.join(', ') || 'general automation';
|
|
427
|
+
return `You are the ${agent1.name} in a coordinated MLE-STAR automation workflow.
|
|
529
428
|
|
|
530
|
-
๐ฏ AGENT ROLE: ${
|
|
429
|
+
๐ฏ AGENT ROLE: ${agent1.type.toUpperCase()}
|
|
531
430
|
๐ CAPABILITIES: ${capabilities}
|
|
532
|
-
๐ AGENT ID: ${
|
|
431
|
+
๐ AGENT ID: ${agent1.id}
|
|
533
432
|
|
|
534
433
|
CRITICAL COORDINATION REQUIREMENTS:
|
|
535
434
|
1. HOOKS: Use claude-flow-novice hooks for coordination:
|
|
536
435
|
- Run "npx claude-flow@alpha hooks pre-task --description '[your task]'" before starting
|
|
537
436
|
- Run "npx claude-flow@alpha hooks post-edit --file '[file]'" after each file operation
|
|
538
|
-
- Run "npx claude-flow@alpha hooks post-task --task-id '${
|
|
437
|
+
- Run "npx claude-flow@alpha hooks post-task --task-id '${agent1.id}'" when complete
|
|
539
438
|
|
|
540
439
|
2. MEMORY: Store all findings and results:
|
|
541
|
-
- Use "npx claude-flow@alpha memory store 'agent/${
|
|
440
|
+
- Use "npx claude-flow@alpha memory store 'agent/${agent1.id}/[key]' '[value]'" for important data
|
|
542
441
|
- Check "npx claude-flow@alpha memory search 'agent/*'" for coordination with other agents
|
|
543
442
|
|
|
544
443
|
3. SESSION: Maintain session coordination:
|
|
@@ -549,27 +448,24 @@ AGENT-SPECIFIC CONFIGURATION:
|
|
|
549
448
|
${JSON.stringify(config, null, 2)}
|
|
550
449
|
|
|
551
450
|
MLE-STAR METHODOLOGY FOCUS:
|
|
552
|
-
${this.getMethodologyGuidance(
|
|
451
|
+
${this.getMethodologyGuidance(agent1.type)}
|
|
553
452
|
|
|
554
453
|
WORKFLOW COORDINATION:
|
|
555
454
|
- Work with other agents in the pipeline: Search โ Foundation โ Refinement โ Ensemble โ Validation
|
|
556
455
|
- Share findings through memory system
|
|
557
|
-
- Use proper file naming conventions: ${
|
|
456
|
+
- Use proper file naming conventions: ${agent1.id}_[component].[ext]
|
|
558
457
|
- Follow MLE-STAR best practices for your role
|
|
559
458
|
|
|
560
459
|
Execute your role in the MLE-STAR workflow with full coordination and hook integration.`;
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
/**
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
564
462
|
* Create master coordination prompt for interactive mode
|
|
565
|
-
*/
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
return `๐ MLE-STAR WORKFLOW COORDINATION MASTER
|
|
463
|
+
*/ createMasterCoordinationPrompt(agents) {
|
|
464
|
+
const workflowData = this.currentWorkflow || {
|
|
465
|
+
name: 'MLE-STAR Workflow',
|
|
466
|
+
description: 'Machine Learning Engineering via Search and Targeted Refinement'
|
|
467
|
+
};
|
|
468
|
+
return `๐ MLE-STAR WORKFLOW COORDINATION MASTER
|
|
573
469
|
|
|
574
470
|
You are the MASTER COORDINATOR for a comprehensive MLE-STAR (Machine Learning Engineering via Search and Targeted Refinement) workflow.
|
|
575
471
|
|
|
@@ -579,15 +475,11 @@ You are the MASTER COORDINATOR for a comprehensive MLE-STAR (Machine Learning En
|
|
|
579
475
|
๐ SESSION ID: ${this.sessionId}
|
|
580
476
|
|
|
581
477
|
๐ค SUB-AGENTS TO COORDINATE (${agents.length} total):
|
|
582
|
-
${agents
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
๐ Capabilities: ${agent.config?.capabilities?.join(', ') || 'general automation'}
|
|
588
|
-
๐ ID: ${agent.id}`,
|
|
589
|
-
)
|
|
590
|
-
.join('')}
|
|
478
|
+
${agents.map((agent1, index)=>`
|
|
479
|
+
${index + 1}. ${agent1.name} (${agent1.type})
|
|
480
|
+
๐ฏ Role: ${this.getAgentRoleDescription(agent1.type)}
|
|
481
|
+
๐ Capabilities: ${agent1.config?.capabilities?.join(', ') || 'general automation'}
|
|
482
|
+
๐ ID: ${agent1.id}`).join('')}
|
|
591
483
|
|
|
592
484
|
๐ง CRITICAL: USE CONCURRENT STREAMS FOR PARALLEL EXECUTION
|
|
593
485
|
|
|
@@ -638,28 +530,24 @@ METHODOLOGY PHASES:
|
|
|
638
530
|
${this.getMasterMethodologyGuide()}
|
|
639
531
|
|
|
640
532
|
๐ BEGIN: Start by deploying all sub-agents with detailed prompts using the Task tool for concurrent execution. Each agent should receive comprehensive instructions for their specific MLE-STAR role.`;
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
/**
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
644
535
|
* Get agent role description for coordination
|
|
645
|
-
*/
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
/**
|
|
536
|
+
*/ getAgentRoleDescription(agentType) {
|
|
537
|
+
const roles = {
|
|
538
|
+
researcher: 'Web Search & Foundation Discovery - Find state-of-the-art approaches',
|
|
539
|
+
coder: 'Model Implementation & Training Pipeline - Build foundation models',
|
|
540
|
+
optimizer: 'Performance Tuning & Architecture Refinement - Optimize models',
|
|
541
|
+
analyst: 'Ensemble Methods & Meta-Learning - Combine multiple approaches',
|
|
542
|
+
tester: 'Validation & Debugging - Ensure quality and performance',
|
|
543
|
+
coordinator: 'Workflow Orchestration - Manage overall pipeline'
|
|
544
|
+
};
|
|
545
|
+
return roles[agentType] || 'Specialized automation task execution';
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
659
548
|
* Get comprehensive methodology guide for master coordinator
|
|
660
|
-
*/
|
|
661
|
-
|
|
662
|
-
return `
|
|
549
|
+
*/ getMasterMethodologyGuide() {
|
|
550
|
+
return `
|
|
663
551
|
PHASE 1 - SEARCH & FOUNDATION (Parallel):
|
|
664
552
|
๐ฌ Search Agent: Research ML approaches, algorithms, and best practices
|
|
665
553
|
๐ป Foundation Agent: Implement baseline models and training infrastructure
|
|
@@ -676,928 +564,796 @@ COORDINATION KEY POINTS:
|
|
|
676
564
|
- Maintain communication through progress updates
|
|
677
565
|
- Each phase builds on previous phases
|
|
678
566
|
- Final deliverable: Production-ready ML pipeline`;
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
/**
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
682
569
|
* Get agent position in MLE-STAR pipeline
|
|
683
|
-
*/
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
/**
|
|
570
|
+
*/ getAgentPositionInPipeline(agentType) {
|
|
571
|
+
const positions = {
|
|
572
|
+
researcher: 'Phase 1: Search & Foundation Discovery (Parallel with Foundation)',
|
|
573
|
+
coder: 'Phase 1: Foundation Model Building (Parallel with Search)',
|
|
574
|
+
optimizer: 'Phase 2: Refinement & Optimization (Sequential, depends on Phase 1)',
|
|
575
|
+
analyst: 'Phase 3: Ensemble & Meta-Learning (Parallel with Validation)',
|
|
576
|
+
tester: 'Phase 3: Validation & Debugging (Parallel with Ensemble)',
|
|
577
|
+
coordinator: 'All Phases: Workflow Orchestration & Coordination'
|
|
578
|
+
};
|
|
579
|
+
return positions[agentType] || 'Specialized task execution';
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
697
582
|
* Get coordination partners for agent type
|
|
698
|
-
*/
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
/**
|
|
583
|
+
*/ getCoordinationPartners(agentType) {
|
|
584
|
+
const partners = {
|
|
585
|
+
researcher: 'Foundation Agent (parallel), Refinement Agent (handoff)',
|
|
586
|
+
coder: 'Search Agent (parallel), Refinement Agent (handoff)',
|
|
587
|
+
optimizer: 'Search & Foundation Agents (input), Ensemble & Validation Agents (handoff)',
|
|
588
|
+
analyst: 'Refinement Agent (input), Validation Agent (parallel)',
|
|
589
|
+
tester: 'All previous agents (validation), Ensemble Agent (parallel)',
|
|
590
|
+
coordinator: 'All agents (orchestration and monitoring)'
|
|
591
|
+
};
|
|
592
|
+
return partners[agentType] || 'Other workflow agents as needed';
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
712
595
|
* Get methodology guidance for agent type
|
|
713
|
-
*/
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
researcher: `SEARCH PHASE - Web Research & Foundation Discovery:
|
|
596
|
+
*/ getMethodologyGuidance(agentType) {
|
|
597
|
+
const guidance = {
|
|
598
|
+
researcher: `SEARCH PHASE - Web Research & Foundation Discovery:
|
|
717
599
|
- Search for state-of-the-art ML approaches for the problem domain
|
|
718
600
|
- Find winning Kaggle solutions and benchmark results
|
|
719
601
|
- Identify promising model architectures and techniques
|
|
720
602
|
- Document implementation examples and model cards
|
|
721
603
|
- Focus on proven, recent approaches with good performance`,
|
|
722
|
-
|
|
723
|
-
coder: `FOUNDATION PHASE - Initial Model Building:
|
|
604
|
+
coder: `FOUNDATION PHASE - Initial Model Building:
|
|
724
605
|
- Analyze dataset characteristics and problem type
|
|
725
606
|
- Implement baseline models based on research findings
|
|
726
607
|
- Create robust preprocessing pipelines
|
|
727
608
|
- Build modular, testable code components
|
|
728
609
|
- Establish performance baselines for comparison`,
|
|
729
|
-
|
|
730
|
-
optimizer: `REFINEMENT PHASE - Targeted Component Optimization:
|
|
610
|
+
optimizer: `REFINEMENT PHASE - Targeted Component Optimization:
|
|
731
611
|
- Perform ablation analysis to identify high-impact components
|
|
732
612
|
- Focus deep optimization on most impactful pipeline elements
|
|
733
613
|
- Use iterative improvement with structured feedback
|
|
734
614
|
- Implement advanced feature engineering techniques
|
|
735
615
|
- Optimize hyperparameters systematically`,
|
|
736
|
-
|
|
737
|
-
architect: `ENSEMBLE PHASE - Intelligent Model Combination:
|
|
616
|
+
architect: `ENSEMBLE PHASE - Intelligent Model Combination:
|
|
738
617
|
- Create sophisticated ensemble strategies beyond simple averaging
|
|
739
618
|
- Implement stacking with meta-learners
|
|
740
619
|
- Use dynamic weighting and mixture of experts
|
|
741
620
|
- Apply Bayesian model averaging where appropriate
|
|
742
621
|
- Optimize ensemble composition for maximum performance`,
|
|
743
|
-
|
|
744
|
-
tester: `VALIDATION PHASE - Comprehensive Testing & Debugging:
|
|
622
|
+
tester: `VALIDATION PHASE - Comprehensive Testing & Debugging:
|
|
745
623
|
- Implement rigorous cross-validation strategies
|
|
746
624
|
- Detect and prevent data leakage
|
|
747
625
|
- Perform error analysis and debugging
|
|
748
626
|
- Validate model robustness and generalization
|
|
749
627
|
- Ensure production readiness with quality checks`,
|
|
750
|
-
|
|
751
|
-
coordinator: `ORCHESTRATION PHASE - Workflow Management:
|
|
628
|
+
coordinator: `ORCHESTRATION PHASE - Workflow Management:
|
|
752
629
|
- Coordinate between all agents and phases
|
|
753
630
|
- Monitor progress and performance metrics
|
|
754
631
|
- Manage resource allocation and scheduling
|
|
755
632
|
- Handle error recovery and workflow adaptation
|
|
756
|
-
- Prepare final deployment and documentation
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
'Focus on your specialized capabilities and coordinate with other agents.'
|
|
762
|
-
);
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
/**
|
|
633
|
+
- Prepare final deployment and documentation`
|
|
634
|
+
};
|
|
635
|
+
return guidance[agentType] || 'Focus on your specialized capabilities and coordinate with other agents.';
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
766
638
|
* Execute workflow tasks with dependency management
|
|
767
|
-
*/
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
639
|
+
*/ async executeWorkflowTasks(workflow) {
|
|
640
|
+
const { tasks, dependencies = {} } = workflow;
|
|
641
|
+
let completedTasks = 0;
|
|
642
|
+
let failedTasks = 0;
|
|
643
|
+
const totalTasks = tasks.length;
|
|
644
|
+
// Task status tracking
|
|
645
|
+
const taskStatuses = new Map();
|
|
646
|
+
tasks.forEach((task)=>{
|
|
647
|
+
taskStatuses.set(task.id, {
|
|
648
|
+
name: task.name || task.id,
|
|
649
|
+
status: 'pending',
|
|
650
|
+
agent: task.assignTo,
|
|
651
|
+
startTime: null,
|
|
652
|
+
endTime: null,
|
|
653
|
+
summary: ''
|
|
654
|
+
});
|
|
655
|
+
});
|
|
656
|
+
// Create task execution plan based on dependencies
|
|
657
|
+
const executionPlan = this.createExecutionPlan(tasks, dependencies);
|
|
658
|
+
console.log(`๐ Executing ${totalTasks} tasks in ${executionPlan.length} phases...`);
|
|
659
|
+
console.log();
|
|
660
|
+
// Note: Concurrent display disabled in favor of interactive-style stream processing
|
|
661
|
+
let concurrentDisplay = null;
|
|
662
|
+
// if (this.options.nonInteractive && this.options.outputFormat === 'stream-json') {
|
|
663
|
+
// const { createConcurrentDisplay } = await import('./concurrent-display.js');
|
|
664
|
+
//
|
|
665
|
+
// // Get all agents and their tasks
|
|
666
|
+
// const agentTasks = workflow.agents?.map(agent => ({
|
|
667
|
+
// id: agent.id,
|
|
668
|
+
// name: agent.name,
|
|
669
|
+
// type: agent.type,
|
|
670
|
+
// tasks: tasks.filter(t => t.assignTo === agent.id).map(t => t.name)
|
|
671
|
+
// })) || [];
|
|
672
|
+
//
|
|
673
|
+
// concurrentDisplay = createConcurrentDisplay(agentTasks);
|
|
674
|
+
// concurrentDisplay.start();
|
|
675
|
+
//
|
|
676
|
+
// // Store reference for stream processors
|
|
677
|
+
// this.concurrentDisplay = concurrentDisplay;
|
|
678
|
+
// }
|
|
679
|
+
// Execute tasks phase by phase
|
|
680
|
+
for (const [phaseIndex, phaseTasks] of executionPlan.entries()){
|
|
681
|
+
this.currentPhase = `Phase ${phaseIndex + 1}`;
|
|
682
|
+
// Show regular task board or update concurrent display
|
|
683
|
+
if (!concurrentDisplay) {
|
|
684
|
+
if (this.options.logLevel === 'quiet') {
|
|
685
|
+
console.log(`\n๐ Phase ${phaseIndex + 1}: Running ${phaseTasks.length} tasks`);
|
|
686
|
+
} else {
|
|
687
|
+
console.log(`\n๐ Phase ${phaseIndex + 1}: ${phaseTasks.length} concurrent tasks`);
|
|
688
|
+
}
|
|
689
|
+
this.displayTaskBoard(taskStatuses, phaseTasks);
|
|
690
|
+
}
|
|
691
|
+
// Mark tasks as in-progress
|
|
692
|
+
phaseTasks.forEach((task)=>{
|
|
693
|
+
const status = taskStatuses.get(task.id);
|
|
694
|
+
status.status = 'in-progress';
|
|
695
|
+
status.startTime = Date.now();
|
|
696
|
+
});
|
|
697
|
+
// Execute tasks in this phase (potentially in parallel)
|
|
698
|
+
const phasePromises = phaseTasks.map(async (task)=>{
|
|
699
|
+
const taskStatus = taskStatuses.get(task.id);
|
|
700
|
+
try {
|
|
701
|
+
// Show task starting
|
|
702
|
+
console.log(`\n ๐ Starting: ${task.name || task.id}`);
|
|
703
|
+
console.log(` Agent: ${task.assignTo}`);
|
|
704
|
+
console.log(` Description: ${task.description?.substring(0, 80)}...`);
|
|
705
|
+
const result = await this.executeTask(task, workflow);
|
|
706
|
+
taskStatus.status = result.success ? 'completed' : 'failed';
|
|
707
|
+
taskStatus.endTime = Date.now();
|
|
708
|
+
taskStatus.summary = result.success ? `โ
Completed in ${this.formatDuration(result.duration)}` : `โ Failed: ${result.error?.message || 'Unknown error'}`;
|
|
709
|
+
return result;
|
|
710
|
+
} catch (error) {
|
|
711
|
+
taskStatus.status = 'failed';
|
|
712
|
+
taskStatus.endTime = Date.now();
|
|
713
|
+
taskStatus.summary = `โ Error: ${error.message}`;
|
|
714
|
+
throw error;
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
// Wait for all phase tasks to complete
|
|
718
|
+
const phaseResults = await Promise.allSettled(phasePromises);
|
|
719
|
+
// Process phase results
|
|
720
|
+
for (const [taskIndex, result] of phaseResults.entries()){
|
|
721
|
+
const task = phaseTasks[taskIndex];
|
|
722
|
+
const taskStatus = taskStatuses.get(task.id);
|
|
723
|
+
if (result.status === 'fulfilled' && result.value.success) {
|
|
724
|
+
completedTasks++;
|
|
725
|
+
this.results.set(task.id, result.value);
|
|
726
|
+
} else {
|
|
727
|
+
failedTasks++;
|
|
728
|
+
const error = result.status === 'rejected' ? result.reason : result.value.error;
|
|
729
|
+
this.errors.push({
|
|
730
|
+
type: 'task_execution',
|
|
731
|
+
task: task.id,
|
|
732
|
+
error: error.message || error,
|
|
733
|
+
timestamp: new Date()
|
|
734
|
+
});
|
|
735
|
+
// Check if we should fail fast
|
|
736
|
+
if (workflow.settings?.failurePolicy === 'fail-fast') {
|
|
737
|
+
console.log(`\n๐ Failing fast due to task failure`);
|
|
738
|
+
break;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
// Show updated task board
|
|
743
|
+
if (!concurrentDisplay) {
|
|
744
|
+
console.log(`\n๐ Phase ${phaseIndex + 1} Complete:`);
|
|
745
|
+
this.displayTaskBoard(taskStatuses);
|
|
746
|
+
}
|
|
747
|
+
// Stop if fail-fast and we have failures
|
|
748
|
+
if (workflow.settings?.failurePolicy === 'fail-fast' && failedTasks > 0) {
|
|
749
|
+
break;
|
|
750
|
+
}
|
|
859
751
|
}
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
// Process phase results
|
|
866
|
-
for (const [taskIndex, result] of phaseResults.entries()) {
|
|
867
|
-
const task = phaseTasks[taskIndex];
|
|
868
|
-
const taskStatus = taskStatuses.get(task.id);
|
|
869
|
-
|
|
870
|
-
if (result.status === 'fulfilled' && result.value.success) {
|
|
871
|
-
completedTasks++;
|
|
872
|
-
this.results.set(task.id, result.value);
|
|
752
|
+
// Final summary
|
|
753
|
+
if (!concurrentDisplay) {
|
|
754
|
+
console.log(`\n๐ Final Workflow Summary:`);
|
|
755
|
+
this.displayTaskBoard(taskStatuses);
|
|
873
756
|
} else {
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
type: 'task_execution',
|
|
878
|
-
task: task.id,
|
|
879
|
-
error: error.message || error,
|
|
880
|
-
timestamp: new Date(),
|
|
881
|
-
});
|
|
882
|
-
|
|
883
|
-
// Check if we should fail fast
|
|
884
|
-
if (workflow.settings?.failurePolicy === 'fail-fast') {
|
|
885
|
-
console.log(`\n๐ Failing fast due to task failure`);
|
|
886
|
-
break;
|
|
887
|
-
}
|
|
757
|
+
// Stop concurrent display
|
|
758
|
+
concurrentDisplay.stop();
|
|
759
|
+
console.log(); // Add some space after display
|
|
888
760
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
break;
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
// Final summary
|
|
904
|
-
if (!concurrentDisplay) {
|
|
905
|
-
console.log(`\n๐ Final Workflow Summary:`);
|
|
906
|
-
this.displayTaskBoard(taskStatuses);
|
|
907
|
-
} else {
|
|
908
|
-
// Stop concurrent display
|
|
909
|
-
concurrentDisplay.stop();
|
|
910
|
-
console.log(); // Add some space after display
|
|
761
|
+
return {
|
|
762
|
+
success: failedTasks === 0,
|
|
763
|
+
totalTasks,
|
|
764
|
+
completedTasks,
|
|
765
|
+
failedTasks,
|
|
766
|
+
executionId: this.executionId,
|
|
767
|
+
duration: Date.now() - this.startTime,
|
|
768
|
+
results: Object.fromEntries(this.results),
|
|
769
|
+
errors: this.errors
|
|
770
|
+
};
|
|
911
771
|
}
|
|
912
|
-
|
|
913
|
-
return {
|
|
914
|
-
success: failedTasks === 0,
|
|
915
|
-
totalTasks,
|
|
916
|
-
completedTasks,
|
|
917
|
-
failedTasks,
|
|
918
|
-
executionId: this.executionId,
|
|
919
|
-
duration: Date.now() - this.startTime,
|
|
920
|
-
results: Object.fromEntries(this.results),
|
|
921
|
-
errors: this.errors,
|
|
922
|
-
};
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
/**
|
|
772
|
+
/**
|
|
926
773
|
* Display task board showing current status
|
|
927
|
-
*/
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
const activeTasks = Array.from(taskStatuses.values()).filter(
|
|
936
|
-
(s) => s.status === 'in-progress',
|
|
937
|
-
).length;
|
|
938
|
-
console.log(`๐ Progress: ${completedTasks}/${totalTasks} completed, ${activeTasks} active`);
|
|
939
|
-
return;
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
const frames = ['โ ', 'โ ', 'โ น', 'โ ธ', 'โ ผ', 'โ ด', 'โ ฆ', 'โ ง', 'โ ', 'โ '];
|
|
943
|
-
const frameIndex = Math.floor(Date.now() / 100) % frames.length;
|
|
944
|
-
const spinner = frames[frameIndex];
|
|
945
|
-
|
|
946
|
-
console.log('\nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
947
|
-
console.log('โ ๐ค CONCURRENT TASK STATUS โ');
|
|
948
|
-
console.log('โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ');
|
|
949
|
-
|
|
950
|
-
// Group by status
|
|
951
|
-
const statusGroups = {
|
|
952
|
-
'in-progress': [],
|
|
953
|
-
completed: [],
|
|
954
|
-
failed: [],
|
|
955
|
-
pending: [],
|
|
956
|
-
};
|
|
957
|
-
|
|
958
|
-
taskStatuses.forEach((status, taskId) => {
|
|
959
|
-
statusGroups[status.status].push({ taskId, ...status });
|
|
960
|
-
});
|
|
961
|
-
|
|
962
|
-
// Show in-progress tasks with animation
|
|
963
|
-
if (statusGroups['in-progress'].length > 0) {
|
|
964
|
-
console.log(
|
|
965
|
-
`โ ${spinner} RUNNING (${statusGroups['in-progress'].length} agents): โ`,
|
|
966
|
-
);
|
|
967
|
-
statusGroups['in-progress'].forEach((task) => {
|
|
968
|
-
const duration = task.startTime ? this.formatDuration(Date.now() - task.startTime) : '';
|
|
969
|
-
const progress = this.getProgressBar(Date.now() - task.startTime, 60000); // 1 min expected
|
|
970
|
-
const agentIcon = this.getAgentIcon(task.agent);
|
|
971
|
-
console.log(
|
|
972
|
-
`โ ${agentIcon} ${task.name.padEnd(25)} ${progress} ${duration.padStart(8)} โ`,
|
|
973
|
-
);
|
|
974
|
-
});
|
|
975
|
-
}
|
|
976
|
-
|
|
977
|
-
// Show completed tasks
|
|
978
|
-
if (statusGroups['completed'].length > 0) {
|
|
979
|
-
console.log(
|
|
980
|
-
`โ โ
COMPLETED (${statusGroups['completed'].length}): โ`,
|
|
981
|
-
);
|
|
982
|
-
statusGroups['completed'].forEach((task) => {
|
|
983
|
-
const duration =
|
|
984
|
-
task.endTime && task.startTime ? this.formatDuration(task.endTime - task.startTime) : '';
|
|
985
|
-
console.log(`โ โ ${task.name.padEnd(35)} ${duration.padStart(10)} โ`);
|
|
986
|
-
});
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
// Show failed tasks
|
|
990
|
-
if (statusGroups['failed'].length > 0) {
|
|
991
|
-
console.log(
|
|
992
|
-
`โ โ FAILED (${statusGroups['failed'].length}): โ`,
|
|
993
|
-
);
|
|
994
|
-
statusGroups['failed'].forEach((task) => {
|
|
995
|
-
const errorMsg = (task.summary || '').substring(0, 25);
|
|
996
|
-
console.log(`โ โ ${task.name.padEnd(25)} ${errorMsg.padEnd(20)} โ`);
|
|
997
|
-
});
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
// Show pending tasks count
|
|
1001
|
-
if (statusGroups['pending'].length > 0) {
|
|
1002
|
-
console.log(
|
|
1003
|
-
`โ โณ QUEUED: ${statusGroups['pending'].length} tasks waiting โ`,
|
|
1004
|
-
);
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
// Summary stats
|
|
1008
|
-
const total = taskStatuses.size;
|
|
1009
|
-
const completed = statusGroups['completed'].length;
|
|
1010
|
-
const failed = statusGroups['failed'].length;
|
|
1011
|
-
const progress = total > 0 ? Math.floor(((completed + failed) / total) * 100) : 0;
|
|
1012
|
-
|
|
1013
|
-
console.log('โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ');
|
|
1014
|
-
console.log(
|
|
1015
|
-
`โ ๐ Progress: ${progress}% (${completed}/${total}) โ โก Active: ${statusGroups['in-progress'].length} โ โ Failed: ${failed} โ`,
|
|
1016
|
-
);
|
|
1017
|
-
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
/**
|
|
1021
|
-
* Get progress bar visualization
|
|
1022
|
-
*/
|
|
1023
|
-
getProgressBar(elapsed, expected) {
|
|
1024
|
-
const progress = Math.min(elapsed / expected, 1);
|
|
1025
|
-
const filled = Math.floor(progress * 10);
|
|
1026
|
-
const empty = 10 - filled;
|
|
1027
|
-
return '[' + 'โ'.repeat(filled) + 'โ'.repeat(empty) + ']';
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1030
|
-
/**
|
|
1031
|
-
* Get agent icon based on type
|
|
1032
|
-
*/
|
|
1033
|
-
getAgentIcon(agentId) {
|
|
1034
|
-
const icons = {
|
|
1035
|
-
search: '๐',
|
|
1036
|
-
foundation: '๐๏ธ',
|
|
1037
|
-
refinement: '๐ง',
|
|
1038
|
-
ensemble: '๐ฏ',
|
|
1039
|
-
validation: 'โ
',
|
|
1040
|
-
coordinator: '๐ฎ',
|
|
1041
|
-
researcher: '๐ฌ',
|
|
1042
|
-
coder: '๐ป',
|
|
1043
|
-
optimizer: 'โก',
|
|
1044
|
-
architect: '๐๏ธ',
|
|
1045
|
-
tester: '๐งช',
|
|
1046
|
-
};
|
|
1047
|
-
|
|
1048
|
-
// Extract agent type from ID
|
|
1049
|
-
const type = agentId?.split('_')[0] || 'default';
|
|
1050
|
-
return icons[type] || '๐ค';
|
|
1051
|
-
}
|
|
1052
|
-
|
|
1053
|
-
/**
|
|
1054
|
-
* Execute a single task
|
|
1055
|
-
*/
|
|
1056
|
-
async executeTask(task, workflow) {
|
|
1057
|
-
const startTime = Date.now();
|
|
1058
|
-
|
|
1059
|
-
try {
|
|
1060
|
-
// Store task execution in memory if hooks enabled
|
|
1061
|
-
if (this.hooksEnabled) {
|
|
1062
|
-
await this.executeHook('notify', {
|
|
1063
|
-
message: `Starting task: ${task.name || task.id}`,
|
|
1064
|
-
sessionId: this.sessionId,
|
|
1065
|
-
});
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
if (this.options.nonInteractive && this.options.outputFormat === 'stream-json') {
|
|
1069
|
-
console.log(`\nโ ${task.name || task.id} - Starting Execution`);
|
|
1070
|
-
console.log(` โฟ ${task.description}`);
|
|
1071
|
-
console.log(` โฟ Agent: ${task.assignTo}`);
|
|
1072
|
-
} else {
|
|
1073
|
-
console.log(` ๐ Executing: ${task.description}`);
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
// For demonstration/testing mode (when Claude integration is disabled)
|
|
1077
|
-
// we simulate successful task completion
|
|
1078
|
-
if (!this.options.enableClaude) {
|
|
1079
|
-
// Simulate variable execution time
|
|
1080
|
-
const executionTime = Math.min(
|
|
1081
|
-
1000 + Math.random() * 3000, // 1-4 seconds simulation
|
|
1082
|
-
task.timeout || 30000,
|
|
1083
|
-
);
|
|
1084
|
-
|
|
1085
|
-
await new Promise((resolve) => setTimeout(resolve, executionTime));
|
|
1086
|
-
|
|
1087
|
-
// Simulate successful completion for demo/testing
|
|
1088
|
-
const result = {
|
|
1089
|
-
success: true,
|
|
1090
|
-
taskId: task.id,
|
|
1091
|
-
duration: Date.now() - startTime,
|
|
1092
|
-
output: {
|
|
1093
|
-
status: 'completed',
|
|
1094
|
-
agent: task.assignTo,
|
|
1095
|
-
executionTime: Date.now() - startTime,
|
|
1096
|
-
metadata: {
|
|
1097
|
-
timestamp: new Date().toISOString(),
|
|
1098
|
-
executionId: this.executionId,
|
|
1099
|
-
mode: 'simulation',
|
|
1100
|
-
},
|
|
1101
|
-
},
|
|
1102
|
-
};
|
|
1103
|
-
|
|
1104
|
-
// Store result in memory
|
|
1105
|
-
if (this.hooksEnabled) {
|
|
1106
|
-
await this.storeTaskResult(task.id, result.output);
|
|
774
|
+
*/ displayTaskBoard(taskStatuses, highlightTasks = []) {
|
|
775
|
+
// In quiet mode, just show simple progress
|
|
776
|
+
if (this.options.logLevel === 'quiet') {
|
|
777
|
+
const totalTasks = taskStatuses.size;
|
|
778
|
+
const completedTasks = Array.from(taskStatuses.values()).filter((s)=>s.status === 'completed').length;
|
|
779
|
+
const activeTasks = Array.from(taskStatuses.values()).filter((s)=>s.status === 'in-progress').length;
|
|
780
|
+
console.log(`๐ Progress: ${completedTasks}/${totalTasks} completed, ${activeTasks} active`);
|
|
781
|
+
return;
|
|
1107
782
|
}
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
783
|
+
const frames = [
|
|
784
|
+
'โ ',
|
|
785
|
+
'โ ',
|
|
786
|
+
'โ น',
|
|
787
|
+
'โ ธ',
|
|
788
|
+
'โ ผ',
|
|
789
|
+
'โ ด',
|
|
790
|
+
'โ ฆ',
|
|
791
|
+
'โ ง',
|
|
792
|
+
'โ ',
|
|
793
|
+
'โ '
|
|
794
|
+
];
|
|
795
|
+
const frameIndex = Math.floor(Date.now() / 100) % frames.length;
|
|
796
|
+
const spinner = frames[frameIndex];
|
|
797
|
+
console.log('\nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
798
|
+
console.log('โ ๐ค CONCURRENT TASK STATUS โ');
|
|
799
|
+
console.log('โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ');
|
|
800
|
+
// Group by status
|
|
801
|
+
const statusGroups = {
|
|
802
|
+
'in-progress': [],
|
|
803
|
+
completed: [],
|
|
804
|
+
failed: [],
|
|
805
|
+
pending: []
|
|
806
|
+
};
|
|
807
|
+
taskStatuses.forEach((status, taskId)=>{
|
|
808
|
+
statusGroups[status.status].push({
|
|
809
|
+
taskId,
|
|
810
|
+
...status
|
|
1128
811
|
});
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
812
|
+
});
|
|
813
|
+
// Show in-progress tasks with animation
|
|
814
|
+
if (statusGroups['in-progress'].length > 0) {
|
|
815
|
+
console.log(`โ ${spinner} RUNNING (${statusGroups['in-progress'].length} agents): โ`);
|
|
816
|
+
statusGroups['in-progress'].forEach((task)=>{
|
|
817
|
+
const duration = task.startTime ? this.formatDuration(Date.now() - task.startTime) : '';
|
|
818
|
+
const progress = this.getProgressBar(Date.now() - task.startTime, 60000); // 1 min expected
|
|
819
|
+
const agentIcon = this.getAgentIcon(task.agent);
|
|
820
|
+
console.log(`โ ${agentIcon} ${task.name.padEnd(25)} ${progress} ${duration.padStart(8)} โ`);
|
|
1132
821
|
});
|
|
1133
|
-
});
|
|
1134
|
-
|
|
1135
|
-
// For interactive mode, we use a longer timeout since user interaction is involved
|
|
1136
|
-
const timeout = Math.max(this.options.timeout, 1800000); // 30 minutes minimum for interactive
|
|
1137
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
1138
|
-
setTimeout(() => reject(new Error('Interactive session timeout')), timeout);
|
|
1139
|
-
});
|
|
1140
|
-
|
|
1141
|
-
try {
|
|
1142
|
-
await Promise.race([completionPromise, timeoutPromise]);
|
|
1143
|
-
|
|
1144
|
-
const result = {
|
|
1145
|
-
success: true,
|
|
1146
|
-
taskId: task.id,
|
|
1147
|
-
duration: Date.now() - startTime,
|
|
1148
|
-
output: {
|
|
1149
|
-
status: 'completed',
|
|
1150
|
-
agent: 'master-coordinator',
|
|
1151
|
-
executionTime: Date.now() - startTime,
|
|
1152
|
-
metadata: {
|
|
1153
|
-
timestamp: new Date().toISOString(),
|
|
1154
|
-
executionId: this.executionId,
|
|
1155
|
-
mode: 'interactive-coordination',
|
|
1156
|
-
},
|
|
1157
|
-
},
|
|
1158
|
-
};
|
|
1159
|
-
|
|
1160
|
-
// Store result in memory
|
|
1161
|
-
if (this.hooksEnabled) {
|
|
1162
|
-
await this.storeTaskResult(task.id, result.output);
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
return result;
|
|
1166
|
-
} catch (error) {
|
|
1167
|
-
throw new Error(`Task execution failed: ${error.message}`);
|
|
1168
|
-
}
|
|
1169
822
|
}
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
if (!agent) {
|
|
1177
|
-
throw new Error(`No agent definition found for: ${task.assignTo}`);
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
// Create task-specific prompt
|
|
1181
|
-
const taskPrompt = this.createTaskPrompt(task, agent, workflow);
|
|
1182
|
-
|
|
1183
|
-
// Check if we should chain from a previous task
|
|
1184
|
-
let chainOptions = {};
|
|
1185
|
-
if (
|
|
1186
|
-
this.enableChaining &&
|
|
1187
|
-
this.options.outputFormat === 'stream-json' &&
|
|
1188
|
-
task.depends?.length > 0
|
|
1189
|
-
) {
|
|
1190
|
-
// Get the output stream from the last dependency
|
|
1191
|
-
const lastDependency = task.depends[task.depends.length - 1];
|
|
1192
|
-
const dependencyStream = this.taskOutputStreams.get(lastDependency);
|
|
1193
|
-
if (dependencyStream) {
|
|
1194
|
-
console.log(` ๐ Enabling stream chaining from ${lastDependency} to ${task.id}`);
|
|
1195
|
-
chainOptions.inputStream = dependencyStream;
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1199
|
-
// Spawn Claude instance for this specific task
|
|
1200
|
-
const taskClaudeProcess = await this.spawnClaudeInstance(agent, taskPrompt, chainOptions);
|
|
1201
|
-
|
|
1202
|
-
// Store the output stream for potential chaining
|
|
1203
|
-
if (
|
|
1204
|
-
this.enableChaining &&
|
|
1205
|
-
this.options.outputFormat === 'stream-json' &&
|
|
1206
|
-
taskClaudeProcess.stdout
|
|
1207
|
-
) {
|
|
1208
|
-
this.taskOutputStreams.set(task.id, taskClaudeProcess.stdout);
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
// Store the instance
|
|
1212
|
-
this.claudeInstances.set(agent.id, {
|
|
1213
|
-
process: taskClaudeProcess,
|
|
1214
|
-
agent: agent,
|
|
1215
|
-
status: 'active',
|
|
1216
|
-
startTime: Date.now(),
|
|
1217
|
-
taskId: task.id,
|
|
1218
|
-
});
|
|
1219
|
-
|
|
1220
|
-
// Wait for task completion or timeout
|
|
1221
|
-
// Use longer timeout for ML tasks
|
|
1222
|
-
const baseTimeout = this.options.timeout || 60000;
|
|
1223
|
-
const isMLTask =
|
|
1224
|
-
task.type?.toLowerCase().includes('ml') ||
|
|
1225
|
-
task.type?.toLowerCase().includes('model') ||
|
|
1226
|
-
task.type?.toLowerCase().includes('search') ||
|
|
1227
|
-
task.type?.toLowerCase().includes('analysis') ||
|
|
1228
|
-
this.options.workflowType === 'ml';
|
|
1229
|
-
const timeout = task.timeout || (isMLTask ? Math.max(baseTimeout, 300000) : baseTimeout); // Min 5 minutes for ML tasks
|
|
1230
|
-
|
|
1231
|
-
if (this.options.logLevel === 'debug' || this.options.verbose) {
|
|
1232
|
-
console.log(
|
|
1233
|
-
` โฑ๏ธ Timeout: ${this.formatDuration(timeout)} (Base: ${this.formatDuration(baseTimeout)}, ML Task: ${isMLTask})`,
|
|
1234
|
-
);
|
|
1235
|
-
}
|
|
1236
|
-
|
|
1237
|
-
const completionPromise = new Promise((resolve, reject) => {
|
|
1238
|
-
taskClaudeProcess.on('exit', (code) => {
|
|
1239
|
-
if (code === 0) {
|
|
1240
|
-
resolve({ success: true, code });
|
|
1241
|
-
} else {
|
|
1242
|
-
reject(new Error(`Process exited with code ${code}`));
|
|
1243
|
-
}
|
|
823
|
+
// Show completed tasks
|
|
824
|
+
if (statusGroups['completed'].length > 0) {
|
|
825
|
+
console.log(`โ โ
COMPLETED (${statusGroups['completed'].length}): โ`);
|
|
826
|
+
statusGroups['completed'].forEach((task)=>{
|
|
827
|
+
const duration = task.endTime && task.startTime ? this.formatDuration(task.endTime - task.startTime) : '';
|
|
828
|
+
console.log(`โ โ ${task.name.padEnd(35)} ${duration.padStart(10)} โ`);
|
|
1244
829
|
});
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
830
|
+
}
|
|
831
|
+
// Show failed tasks
|
|
832
|
+
if (statusGroups['failed'].length > 0) {
|
|
833
|
+
console.log(`โ โ FAILED (${statusGroups['failed'].length}): โ`);
|
|
834
|
+
statusGroups['failed'].forEach((task)=>{
|
|
835
|
+
const errorMsg = (task.summary || '').substring(0, 25);
|
|
836
|
+
console.log(`โ โ ${task.name.padEnd(25)} ${errorMsg.padEnd(20)} โ`);
|
|
1248
837
|
});
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
838
|
+
}
|
|
839
|
+
// Show pending tasks count
|
|
840
|
+
if (statusGroups['pending'].length > 0) {
|
|
841
|
+
console.log(`โ โณ QUEUED: ${statusGroups['pending'].length} tasks waiting โ`);
|
|
842
|
+
}
|
|
843
|
+
// Summary stats
|
|
844
|
+
const total = taskStatuses.size;
|
|
845
|
+
const completed = statusGroups['completed'].length;
|
|
846
|
+
const failed = statusGroups['failed'].length;
|
|
847
|
+
const progress = total > 0 ? Math.floor((completed + failed) / total * 100) : 0;
|
|
848
|
+
console.log('โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ');
|
|
849
|
+
console.log(`โ ๐ Progress: ${progress}% (${completed}/${total}) โ โก Active: ${statusGroups['in-progress'].length} โ โ Failed: ${failed} โ`);
|
|
850
|
+
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* Get progress bar visualization
|
|
854
|
+
*/ getProgressBar(elapsed, expected) {
|
|
855
|
+
const progress = Math.min(elapsed / expected, 1);
|
|
856
|
+
const filled = Math.floor(progress * 10);
|
|
857
|
+
const empty = 10 - filled;
|
|
858
|
+
return '[' + 'โ'.repeat(filled) + 'โ'.repeat(empty) + ']';
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Get agent icon based on type
|
|
862
|
+
*/ getAgentIcon(agentId) {
|
|
863
|
+
const icons = {
|
|
864
|
+
search: '๐',
|
|
865
|
+
foundation: '๐๏ธ',
|
|
866
|
+
refinement: '๐ง',
|
|
867
|
+
ensemble: '๐ฏ',
|
|
868
|
+
validation: 'โ
',
|
|
869
|
+
coordinator: '๐ฎ',
|
|
870
|
+
researcher: '๐ฌ',
|
|
871
|
+
coder: '๐ป',
|
|
872
|
+
optimizer: 'โก',
|
|
873
|
+
architect: '๐๏ธ',
|
|
874
|
+
tester: '๐งช'
|
|
875
|
+
};
|
|
876
|
+
// Extract agent type from ID
|
|
877
|
+
const type = agentId?.split('_')[0] || 'default';
|
|
878
|
+
return icons[type] || '๐ค';
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* Execute a single task
|
|
882
|
+
*/ async executeTask(task, workflow) {
|
|
883
|
+
const startTime = Date.now();
|
|
884
|
+
try {
|
|
885
|
+
// Store task execution in memory if hooks enabled
|
|
1277
886
|
if (this.hooksEnabled) {
|
|
1278
|
-
|
|
887
|
+
await this.executeHook('notify', {
|
|
888
|
+
message: `Starting task: ${task.name || task.id}`,
|
|
889
|
+
sessionId: this.sessionId
|
|
890
|
+
});
|
|
1279
891
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
// Use existing Claude instance
|
|
1287
|
-
// In a full implementation, this would send the task to the running instance
|
|
1288
|
-
// For now, we'll spawn a new instance per task for simplicity
|
|
1289
|
-
|
|
1290
|
-
const agent = claudeInstance.agent;
|
|
1291
|
-
const taskPrompt = this.createTaskPrompt(task, agent, workflow);
|
|
1292
|
-
|
|
1293
|
-
// Check if we should chain from a previous task
|
|
1294
|
-
let chainOptions = {};
|
|
1295
|
-
if (
|
|
1296
|
-
this.enableChaining &&
|
|
1297
|
-
this.options.outputFormat === 'stream-json' &&
|
|
1298
|
-
task.depends?.length > 0
|
|
1299
|
-
) {
|
|
1300
|
-
// Get the output stream from the last dependency
|
|
1301
|
-
const lastDependency = task.depends[task.depends.length - 1];
|
|
1302
|
-
const dependencyStream = this.taskOutputStreams.get(lastDependency);
|
|
1303
|
-
if (dependencyStream) {
|
|
1304
|
-
console.log(` ๐ Enabling stream chaining from ${lastDependency} to ${task.id}`);
|
|
1305
|
-
chainOptions.inputStream = dependencyStream;
|
|
892
|
+
if (this.options.nonInteractive && this.options.outputFormat === 'stream-json') {
|
|
893
|
+
console.log(`\nโ ${task.name || task.id} - Starting Execution`);
|
|
894
|
+
console.log(` โฟ ${task.description}`);
|
|
895
|
+
console.log(` โฟ Agent: ${task.assignTo}`);
|
|
896
|
+
} else {
|
|
897
|
+
console.log(` ๐ Executing: ${task.description}`);
|
|
1306
898
|
}
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
899
|
+
// For demonstration/testing mode (when Claude integration is disabled)
|
|
900
|
+
// we simulate successful task completion
|
|
901
|
+
if (!this.options.enableClaude) {
|
|
902
|
+
// Simulate variable execution time
|
|
903
|
+
const executionTime = Math.min(1000 + Math.random() * 3000, task.timeout || 30000);
|
|
904
|
+
await new Promise((resolve)=>setTimeout(resolve, executionTime));
|
|
905
|
+
// Simulate successful completion for demo/testing
|
|
906
|
+
const result = {
|
|
907
|
+
success: true,
|
|
908
|
+
taskId: task.id,
|
|
909
|
+
duration: Date.now() - startTime,
|
|
910
|
+
output: {
|
|
911
|
+
status: 'completed',
|
|
912
|
+
agent: task.assignTo,
|
|
913
|
+
executionTime: Date.now() - startTime,
|
|
914
|
+
metadata: {
|
|
915
|
+
timestamp: new Date().toISOString(),
|
|
916
|
+
executionId: this.executionId,
|
|
917
|
+
mode: 'simulation'
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
};
|
|
921
|
+
// Store result in memory
|
|
922
|
+
if (this.hooksEnabled) {
|
|
923
|
+
await this.storeTaskResult(task.id, result.output);
|
|
924
|
+
}
|
|
925
|
+
return result;
|
|
926
|
+
} else {
|
|
927
|
+
// When Claude integration is enabled, delegate to actual Claude instance
|
|
928
|
+
// Check if we have a master coordinator (interactive mode)
|
|
929
|
+
const masterCoordinator = this.claudeInstances.get('master-coordinator');
|
|
930
|
+
if (masterCoordinator && !this.options.nonInteractive) {
|
|
931
|
+
// Interactive mode: All tasks are coordinated by the master coordinator
|
|
932
|
+
console.log(` ๐ฏ Task delegated to Master Coordinator: ${task.description}`);
|
|
933
|
+
// In interactive mode, the master coordinator handles all tasks
|
|
934
|
+
// We just wait for the master coordinator process to complete
|
|
935
|
+
const completionPromise = new Promise((resolve, reject)=>{
|
|
936
|
+
masterCoordinator.process.on('exit', (code)=>{
|
|
937
|
+
if (code === 0) {
|
|
938
|
+
resolve({
|
|
939
|
+
success: true,
|
|
940
|
+
code
|
|
941
|
+
});
|
|
942
|
+
} else {
|
|
943
|
+
reject(new Error(`Master coordinator exited with code ${code}`));
|
|
944
|
+
}
|
|
945
|
+
});
|
|
946
|
+
masterCoordinator.process.on('error', (err)=>{
|
|
947
|
+
reject(err);
|
|
948
|
+
});
|
|
949
|
+
});
|
|
950
|
+
// For interactive mode, we use a longer timeout since user interaction is involved
|
|
951
|
+
const timeout = Math.max(this.options.timeout, 1800000); // 30 minutes minimum for interactive
|
|
952
|
+
const timeoutPromise = new Promise((_, reject)=>{
|
|
953
|
+
setTimeout(()=>reject(new Error('Interactive session timeout')), timeout);
|
|
954
|
+
});
|
|
955
|
+
try {
|
|
956
|
+
await Promise.race([
|
|
957
|
+
completionPromise,
|
|
958
|
+
timeoutPromise
|
|
959
|
+
]);
|
|
960
|
+
const result = {
|
|
961
|
+
success: true,
|
|
962
|
+
taskId: task.id,
|
|
963
|
+
duration: Date.now() - startTime,
|
|
964
|
+
output: {
|
|
965
|
+
status: 'completed',
|
|
966
|
+
agent: 'master-coordinator',
|
|
967
|
+
executionTime: Date.now() - startTime,
|
|
968
|
+
metadata: {
|
|
969
|
+
timestamp: new Date().toISOString(),
|
|
970
|
+
executionId: this.executionId,
|
|
971
|
+
mode: 'interactive-coordination'
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
};
|
|
975
|
+
// Store result in memory
|
|
976
|
+
if (this.hooksEnabled) {
|
|
977
|
+
await this.storeTaskResult(task.id, result.output);
|
|
978
|
+
}
|
|
979
|
+
return result;
|
|
980
|
+
} catch (error) {
|
|
981
|
+
throw new Error(`Task execution failed: ${error.message}`);
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
// Non-interactive mode or no master coordinator: use individual Claude instances
|
|
985
|
+
const claudeInstance = this.claudeInstances.get(task.assignTo);
|
|
986
|
+
if (!claudeInstance) {
|
|
987
|
+
// If no pre-spawned instance, create one for this task
|
|
988
|
+
const agent1 = workflow.agents.find((a)=>a.id === task.assignTo);
|
|
989
|
+
if (!agent1) {
|
|
990
|
+
throw new Error(`No agent definition found for: ${task.assignTo}`);
|
|
991
|
+
}
|
|
992
|
+
// Create task-specific prompt
|
|
993
|
+
const taskPrompt = this.createTaskPrompt(task, agent1, workflow);
|
|
994
|
+
// Check if we should chain from a previous task
|
|
995
|
+
let chainOptions = {};
|
|
996
|
+
if (this.enableChaining && this.options.outputFormat === 'stream-json' && task.depends?.length > 0) {
|
|
997
|
+
// Get the output stream from the last dependency
|
|
998
|
+
const lastDependency = task.depends[task.depends.length - 1];
|
|
999
|
+
const dependencyStream = this.taskOutputStreams.get(lastDependency);
|
|
1000
|
+
if (dependencyStream) {
|
|
1001
|
+
console.log(` ๐ Enabling stream chaining from ${lastDependency} to ${task.id}`);
|
|
1002
|
+
chainOptions.inputStream = dependencyStream;
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
// Spawn Claude instance for this specific task
|
|
1006
|
+
const taskClaudeProcess = await this.spawnClaudeInstance(agent1, taskPrompt, chainOptions);
|
|
1007
|
+
// Store the output stream for potential chaining
|
|
1008
|
+
if (this.enableChaining && this.options.outputFormat === 'stream-json' && taskClaudeProcess.stdout) {
|
|
1009
|
+
this.taskOutputStreams.set(task.id, taskClaudeProcess.stdout);
|
|
1010
|
+
}
|
|
1011
|
+
// Store the instance
|
|
1012
|
+
this.claudeInstances.set(agent1.id, {
|
|
1013
|
+
process: taskClaudeProcess,
|
|
1014
|
+
agent: agent1,
|
|
1015
|
+
status: 'active',
|
|
1016
|
+
startTime: Date.now(),
|
|
1017
|
+
taskId: task.id
|
|
1018
|
+
});
|
|
1019
|
+
// Wait for task completion or timeout
|
|
1020
|
+
// Use longer timeout for ML tasks
|
|
1021
|
+
const baseTimeout = this.options.timeout || 60000;
|
|
1022
|
+
const isMLTask = task.type?.toLowerCase().includes('ml') || task.type?.toLowerCase().includes('model') || task.type?.toLowerCase().includes('search') || task.type?.toLowerCase().includes('analysis') || this.options.workflowType === 'ml';
|
|
1023
|
+
const timeout = task.timeout || (isMLTask ? Math.max(baseTimeout, 300000) : baseTimeout); // Min 5 minutes for ML tasks
|
|
1024
|
+
if (this.options.logLevel === 'debug' || this.options.verbose) {
|
|
1025
|
+
console.log(` โฑ๏ธ Timeout: ${this.formatDuration(timeout)} (Base: ${this.formatDuration(baseTimeout)}, ML Task: ${isMLTask})`);
|
|
1026
|
+
}
|
|
1027
|
+
const completionPromise = new Promise((resolve, reject)=>{
|
|
1028
|
+
taskClaudeProcess.on('exit', (code)=>{
|
|
1029
|
+
if (code === 0) {
|
|
1030
|
+
resolve({
|
|
1031
|
+
success: true,
|
|
1032
|
+
code
|
|
1033
|
+
});
|
|
1034
|
+
} else {
|
|
1035
|
+
reject(new Error(`Process exited with code ${code}`));
|
|
1036
|
+
}
|
|
1037
|
+
});
|
|
1038
|
+
taskClaudeProcess.on('error', (err)=>{
|
|
1039
|
+
reject(err);
|
|
1040
|
+
});
|
|
1041
|
+
});
|
|
1042
|
+
const timeoutPromise = new Promise((_, reject)=>{
|
|
1043
|
+
// Use a much longer timeout for ML tasks since Claude is actively working
|
|
1044
|
+
const actualTimeout = isMLTask ? Math.max(timeout, 600000) : timeout; // 10 min minimum for ML
|
|
1045
|
+
setTimeout(()=>reject(new Error('Task timeout')), actualTimeout);
|
|
1046
|
+
});
|
|
1047
|
+
try {
|
|
1048
|
+
await Promise.race([
|
|
1049
|
+
completionPromise,
|
|
1050
|
+
timeoutPromise
|
|
1051
|
+
]);
|
|
1052
|
+
const result = {
|
|
1053
|
+
success: true,
|
|
1054
|
+
taskId: task.id,
|
|
1055
|
+
duration: Date.now() - startTime,
|
|
1056
|
+
output: {
|
|
1057
|
+
status: 'completed',
|
|
1058
|
+
agent: task.assignTo,
|
|
1059
|
+
executionTime: Date.now() - startTime,
|
|
1060
|
+
metadata: {
|
|
1061
|
+
timestamp: new Date().toISOString(),
|
|
1062
|
+
executionId: this.executionId,
|
|
1063
|
+
mode: 'claude-task-execution'
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
};
|
|
1067
|
+
// Store result in memory
|
|
1068
|
+
if (this.hooksEnabled) {
|
|
1069
|
+
await this.storeTaskResult(task.id, result.output);
|
|
1070
|
+
}
|
|
1071
|
+
return result;
|
|
1072
|
+
} catch (error) {
|
|
1073
|
+
throw error;
|
|
1074
|
+
}
|
|
1075
|
+
} else {
|
|
1076
|
+
// Use existing Claude instance
|
|
1077
|
+
// In a full implementation, this would send the task to the running instance
|
|
1078
|
+
// For now, we'll spawn a new instance per task for simplicity
|
|
1079
|
+
const agent1 = claudeInstance.agent;
|
|
1080
|
+
const taskPrompt = this.createTaskPrompt(task, agent1, workflow);
|
|
1081
|
+
// Check if we should chain from a previous task
|
|
1082
|
+
let chainOptions = {};
|
|
1083
|
+
if (this.enableChaining && this.options.outputFormat === 'stream-json' && task.depends?.length > 0) {
|
|
1084
|
+
// Get the output stream from the last dependency
|
|
1085
|
+
const lastDependency = task.depends[task.depends.length - 1];
|
|
1086
|
+
const dependencyStream = this.taskOutputStreams.get(lastDependency);
|
|
1087
|
+
if (dependencyStream) {
|
|
1088
|
+
console.log(` ๐ Enabling stream chaining from ${lastDependency} to ${task.id}`);
|
|
1089
|
+
chainOptions.inputStream = dependencyStream;
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
// For now, spawn a new instance for each task
|
|
1093
|
+
const taskClaudeProcess = await this.spawnClaudeInstance(agent1, taskPrompt, chainOptions);
|
|
1094
|
+
// Store the output stream for potential chaining
|
|
1095
|
+
if (this.enableChaining && this.options.outputFormat === 'stream-json' && taskClaudeProcess.stdout) {
|
|
1096
|
+
this.taskOutputStreams.set(task.id, taskClaudeProcess.stdout);
|
|
1097
|
+
}
|
|
1098
|
+
// Wait for completion
|
|
1099
|
+
// Use longer timeout for ML tasks
|
|
1100
|
+
const baseTimeout = this.options.timeout || 60000;
|
|
1101
|
+
const isMLTask = task.type?.toLowerCase().includes('ml') || task.type?.toLowerCase().includes('model') || task.type?.toLowerCase().includes('search') || task.type?.toLowerCase().includes('analysis') || this.options.workflowType === 'ml';
|
|
1102
|
+
const timeout = task.timeout || (isMLTask ? Math.max(baseTimeout, 300000) : baseTimeout); // Min 5 minutes for ML tasks
|
|
1103
|
+
if (this.options.logLevel === 'debug' || this.options.verbose) {
|
|
1104
|
+
console.log(` โฑ๏ธ Timeout: ${this.formatDuration(timeout)} (Base: ${this.formatDuration(baseTimeout)}, ML Task: ${isMLTask})`);
|
|
1105
|
+
}
|
|
1106
|
+
const completionPromise = new Promise((resolve, reject)=>{
|
|
1107
|
+
taskClaudeProcess.on('exit', (code)=>{
|
|
1108
|
+
if (code === 0) {
|
|
1109
|
+
resolve({
|
|
1110
|
+
success: true,
|
|
1111
|
+
code
|
|
1112
|
+
});
|
|
1113
|
+
} else {
|
|
1114
|
+
reject(new Error(`Process exited with code ${code}`));
|
|
1115
|
+
}
|
|
1116
|
+
});
|
|
1117
|
+
taskClaudeProcess.on('error', (err)=>{
|
|
1118
|
+
reject(err);
|
|
1119
|
+
});
|
|
1120
|
+
});
|
|
1121
|
+
const timeoutPromise = new Promise((_, reject)=>{
|
|
1122
|
+
// Use a much longer timeout for ML tasks since Claude is actively working
|
|
1123
|
+
const actualTimeout = isMLTask ? Math.max(timeout, 600000) : timeout; // 10 min minimum for ML
|
|
1124
|
+
setTimeout(()=>reject(new Error('Task timeout')), actualTimeout);
|
|
1125
|
+
});
|
|
1126
|
+
try {
|
|
1127
|
+
await Promise.race([
|
|
1128
|
+
completionPromise,
|
|
1129
|
+
timeoutPromise
|
|
1130
|
+
]);
|
|
1131
|
+
const result = {
|
|
1132
|
+
success: true,
|
|
1133
|
+
taskId: task.id,
|
|
1134
|
+
duration: Date.now() - startTime,
|
|
1135
|
+
output: {
|
|
1136
|
+
status: 'completed',
|
|
1137
|
+
agent: task.assignTo,
|
|
1138
|
+
executionTime: Date.now() - startTime,
|
|
1139
|
+
metadata: {
|
|
1140
|
+
timestamp: new Date().toISOString(),
|
|
1141
|
+
executionId: this.executionId,
|
|
1142
|
+
mode: 'claude-task-execution'
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
};
|
|
1146
|
+
// Store result in memory
|
|
1147
|
+
if (this.hooksEnabled) {
|
|
1148
|
+
await this.storeTaskResult(task.id, result.output);
|
|
1149
|
+
}
|
|
1150
|
+
return result;
|
|
1151
|
+
} catch (error) {
|
|
1152
|
+
throw error;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1380
1155
|
}
|
|
1381
|
-
|
|
1382
|
-
return
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1156
|
+
} catch (error) {
|
|
1157
|
+
return {
|
|
1158
|
+
success: false,
|
|
1159
|
+
taskId: task.id,
|
|
1160
|
+
duration: Date.now() - startTime,
|
|
1161
|
+
error: error
|
|
1162
|
+
};
|
|
1386
1163
|
}
|
|
1387
|
-
}
|
|
1388
|
-
} catch (error) {
|
|
1389
|
-
return {
|
|
1390
|
-
success: false,
|
|
1391
|
-
taskId: task.id,
|
|
1392
|
-
duration: Date.now() - startTime,
|
|
1393
|
-
error: error,
|
|
1394
|
-
};
|
|
1395
1164
|
}
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
/**
|
|
1165
|
+
/**
|
|
1399
1166
|
* Create execution plan based on task dependencies
|
|
1400
|
-
*/
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1167
|
+
*/ createExecutionPlan(tasks, dependencies) {
|
|
1168
|
+
const taskMap = new Map(tasks.map((task)=>[
|
|
1169
|
+
task.id,
|
|
1170
|
+
task
|
|
1171
|
+
]));
|
|
1172
|
+
const completed = new Set();
|
|
1173
|
+
const phases = [];
|
|
1174
|
+
while(completed.size < tasks.length){
|
|
1175
|
+
const readyTasks = tasks.filter((task)=>{
|
|
1176
|
+
if (completed.has(task.id)) return false;
|
|
1177
|
+
const deps = task.depends || dependencies[task.id] || [];
|
|
1178
|
+
return deps.every((dep)=>completed.has(dep));
|
|
1179
|
+
});
|
|
1180
|
+
if (readyTasks.length === 0) {
|
|
1181
|
+
throw new Error('Circular dependency detected or invalid dependencies');
|
|
1182
|
+
}
|
|
1183
|
+
phases.push(readyTasks);
|
|
1184
|
+
readyTasks.forEach((task)=>completed.add(task.id));
|
|
1185
|
+
}
|
|
1186
|
+
return phases;
|
|
1420
1187
|
}
|
|
1421
|
-
|
|
1422
|
-
return phases;
|
|
1423
|
-
}
|
|
1424
|
-
|
|
1425
|
-
/**
|
|
1188
|
+
/**
|
|
1426
1189
|
* Execute a hook command
|
|
1427
|
-
*/
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
console.debug(`Hook ${hookType} failed:`, error.message);
|
|
1190
|
+
*/ async executeHook(hookType, params) {
|
|
1191
|
+
try {
|
|
1192
|
+
const { execSync } = await import("child_process");
|
|
1193
|
+
let hookCommand = `npx claude-flow@alpha hooks ${hookType}`;
|
|
1194
|
+
if (params.description) {
|
|
1195
|
+
hookCommand += ` --description "${params.description}"`;
|
|
1196
|
+
}
|
|
1197
|
+
if (params.file) {
|
|
1198
|
+
hookCommand += ` --file "${params.file}"`;
|
|
1199
|
+
}
|
|
1200
|
+
if (params.taskId) {
|
|
1201
|
+
hookCommand += ` --task-id "${params.taskId}"`;
|
|
1202
|
+
}
|
|
1203
|
+
if (params.sessionId) {
|
|
1204
|
+
hookCommand += ` --session-id "${params.sessionId}"`;
|
|
1205
|
+
}
|
|
1206
|
+
if (params.message) {
|
|
1207
|
+
hookCommand += ` --message "${params.message}"`;
|
|
1208
|
+
}
|
|
1209
|
+
execSync(hookCommand, {
|
|
1210
|
+
stdio: 'pipe'
|
|
1211
|
+
});
|
|
1212
|
+
} catch (error) {
|
|
1213
|
+
// Hooks are optional, don't fail the workflow if they fail
|
|
1214
|
+
console.debug(`Hook ${hookType} failed:`, error.message);
|
|
1215
|
+
}
|
|
1454
1216
|
}
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
/**
|
|
1217
|
+
/**
|
|
1458
1218
|
* Store task result in memory
|
|
1459
|
-
*/
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
},
|
|
1470
|
-
);
|
|
1471
|
-
} catch (error) {
|
|
1472
|
-
console.debug(`Failed to store task result for ${taskId}:`, error.message);
|
|
1219
|
+
*/ async storeTaskResult(taskId, result) {
|
|
1220
|
+
try {
|
|
1221
|
+
const { execSync } = await import("child_process");
|
|
1222
|
+
const resultJson = JSON.stringify(result);
|
|
1223
|
+
execSync(`npx claude-flow@alpha memory store "workflow/${this.executionId}/${taskId}" '${resultJson}'`, {
|
|
1224
|
+
stdio: 'pipe'
|
|
1225
|
+
});
|
|
1226
|
+
} catch (error) {
|
|
1227
|
+
console.debug(`Failed to store task result for ${taskId}:`, error.message);
|
|
1228
|
+
}
|
|
1473
1229
|
}
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
/**
|
|
1230
|
+
/**
|
|
1477
1231
|
* Validate workflow definition
|
|
1478
|
-
*/
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
if (task.assignTo && !agentIds.has(task.assignTo)) {
|
|
1500
|
-
throw new Error(`Task ${task.id} assigned to unknown agent: ${task.assignTo}`);
|
|
1232
|
+
*/ validateWorkflow(workflow) {
|
|
1233
|
+
if (!workflow.name) {
|
|
1234
|
+
throw new Error('Workflow name is required');
|
|
1235
|
+
}
|
|
1236
|
+
if (!workflow.tasks || workflow.tasks.length === 0) {
|
|
1237
|
+
throw new Error('Workflow must contain at least one task');
|
|
1238
|
+
}
|
|
1239
|
+
// Validate task structure
|
|
1240
|
+
for (const task of workflow.tasks){
|
|
1241
|
+
if (!task.id || !task.type || !task.description) {
|
|
1242
|
+
throw new Error(`Task ${task.id || 'unknown'} is missing required fields`);
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
// Validate agent assignments
|
|
1246
|
+
if (workflow.agents) {
|
|
1247
|
+
const agentIds = new Set(workflow.agents.map((a)=>a.id));
|
|
1248
|
+
for (const task of workflow.tasks){
|
|
1249
|
+
if (task.assignTo && !agentIds.has(task.assignTo)) {
|
|
1250
|
+
throw new Error(`Task ${task.id} assigned to unknown agent: ${task.assignTo}`);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1501
1253
|
}
|
|
1502
|
-
}
|
|
1503
1254
|
}
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
/**
|
|
1255
|
+
/**
|
|
1507
1256
|
* Apply variable substitutions to workflow
|
|
1508
|
-
*/
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1257
|
+
*/ applyVariables(workflow, variables) {
|
|
1258
|
+
const allVariables = {
|
|
1259
|
+
...workflow.variables,
|
|
1260
|
+
...variables
|
|
1261
|
+
};
|
|
1262
|
+
const workflowStr = JSON.stringify(workflow);
|
|
1263
|
+
// Simple variable substitution
|
|
1264
|
+
let processedStr = workflowStr;
|
|
1265
|
+
for (const [key, value] of Object.entries(allVariables)){
|
|
1266
|
+
const pattern = new RegExp(`\\$\\{${key}\\}`, 'g');
|
|
1267
|
+
processedStr = processedStr.replace(pattern, value);
|
|
1268
|
+
}
|
|
1269
|
+
return JSON.parse(processedStr);
|
|
1518
1270
|
}
|
|
1519
|
-
|
|
1520
|
-
return JSON.parse(processedStr);
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1523
|
-
/**
|
|
1271
|
+
/**
|
|
1524
1272
|
* Cleanup Claude instances
|
|
1525
|
-
*/
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1273
|
+
*/ async cleanupClaudeInstances() {
|
|
1274
|
+
if (this.claudeInstances.size === 0) return;
|
|
1275
|
+
console.log('๐งน Cleaning up Claude instances...');
|
|
1276
|
+
for (const [agentId, instance] of this.claudeInstances.entries()){
|
|
1277
|
+
try {
|
|
1278
|
+
if (instance.process && !instance.process.killed) {
|
|
1279
|
+
instance.process.kill('SIGTERM');
|
|
1280
|
+
// Wait for graceful shutdown, then force kill if needed
|
|
1281
|
+
setTimeout(()=>{
|
|
1282
|
+
if (!instance.process.killed) {
|
|
1283
|
+
instance.process.kill('SIGKILL');
|
|
1284
|
+
}
|
|
1285
|
+
}, 5000);
|
|
1286
|
+
}
|
|
1287
|
+
console.log(` โ
Cleaned up ${instance.agent.name}`);
|
|
1288
|
+
} catch (error) {
|
|
1289
|
+
console.error(` โ Error cleaning up ${instance.agent.name}:`, error.message);
|
|
1540
1290
|
}
|
|
1541
|
-
}, 5000);
|
|
1542
1291
|
}
|
|
1543
|
-
|
|
1544
|
-
console.log(` โ
Cleaned up ${instance.agent.name}`);
|
|
1545
|
-
} catch (error) {
|
|
1546
|
-
console.error(` โ Error cleaning up ${instance.agent.name}:`, error.message);
|
|
1547
|
-
}
|
|
1292
|
+
this.claudeInstances.clear();
|
|
1548
1293
|
}
|
|
1549
|
-
|
|
1550
|
-
this.claudeInstances.clear();
|
|
1551
|
-
}
|
|
1552
|
-
|
|
1553
|
-
/**
|
|
1294
|
+
/**
|
|
1554
1295
|
* Format duration in human readable format
|
|
1555
|
-
*/
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1296
|
+
*/ formatDuration(ms) {
|
|
1297
|
+
const seconds = Math.floor(ms / 1000);
|
|
1298
|
+
const minutes = Math.floor(seconds / 60);
|
|
1299
|
+
const hours = Math.floor(minutes / 60);
|
|
1300
|
+
if (hours > 0) {
|
|
1301
|
+
return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
|
|
1302
|
+
} else if (minutes > 0) {
|
|
1303
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
1304
|
+
} else {
|
|
1305
|
+
return `${seconds}s`;
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
constructor(options = {}){
|
|
1309
|
+
this.options = {
|
|
1310
|
+
enableClaude: false,
|
|
1311
|
+
nonInteractive: false,
|
|
1312
|
+
outputFormat: 'text',
|
|
1313
|
+
maxConcurrency: 3,
|
|
1314
|
+
timeout: 3600000,
|
|
1315
|
+
logLevel: 'info',
|
|
1316
|
+
...options
|
|
1317
|
+
};
|
|
1318
|
+
// Increase timeout for ML workflows
|
|
1319
|
+
if (options.workflowType === 'ml' || options.workflowName?.toLowerCase().includes('mle')) {
|
|
1320
|
+
this.options.timeout = 7200000; // 2 hours for ML workflows
|
|
1321
|
+
}
|
|
1322
|
+
// Execution state
|
|
1323
|
+
this.executionId = generateId('workflow-exec');
|
|
1324
|
+
this.startTime = Date.now();
|
|
1325
|
+
this.activeTasks = new Map();
|
|
1326
|
+
this.claudeInstances = new Map();
|
|
1327
|
+
this.results = new Map();
|
|
1328
|
+
this.errors = [];
|
|
1329
|
+
this.currentWorkflow = null;
|
|
1330
|
+
// Stream chaining support
|
|
1331
|
+
this.taskOutputStreams = new Map(); // Store output streams for chaining
|
|
1332
|
+
this.enableChaining = options.enableChaining !== false; // Default to true
|
|
1333
|
+
// Hooks integration
|
|
1334
|
+
this.hooksEnabled = true;
|
|
1335
|
+
this.sessionId = generateId('automation-session');
|
|
1567
1336
|
}
|
|
1568
|
-
}
|
|
1569
1337
|
}
|
|
1570
|
-
|
|
1571
1338
|
/**
|
|
1572
1339
|
* Load workflow from file
|
|
1573
|
-
*/
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1340
|
+
*/ export async function loadWorkflowFromFile(filePath) {
|
|
1341
|
+
try {
|
|
1342
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
1343
|
+
if (filePath.endsWith('.json')) {
|
|
1344
|
+
return JSON.parse(content);
|
|
1345
|
+
} else if (filePath.endsWith('.yaml') || filePath.endsWith('.yml')) {
|
|
1346
|
+
// For now, just return error - YAML support can be added later
|
|
1347
|
+
throw new Error('YAML workflows not yet supported');
|
|
1348
|
+
} else {
|
|
1349
|
+
throw new Error('Unsupported workflow file format. Use .json or .yaml');
|
|
1350
|
+
}
|
|
1351
|
+
} catch (error) {
|
|
1352
|
+
throw new Error(`Failed to load workflow: ${error.message}`);
|
|
1585
1353
|
}
|
|
1586
|
-
} catch (error) {
|
|
1587
|
-
throw new Error(`Failed to load workflow: ${error.message}`);
|
|
1588
|
-
}
|
|
1589
1354
|
}
|
|
1590
|
-
|
|
1591
1355
|
/**
|
|
1592
1356
|
* Get default MLE-STAR workflow path
|
|
1593
|
-
*/
|
|
1594
|
-
|
|
1595
|
-
return join(
|
|
1596
|
-
process.cwd(),
|
|
1597
|
-
'src',
|
|
1598
|
-
'cli',
|
|
1599
|
-
'simple-commands',
|
|
1600
|
-
'templates',
|
|
1601
|
-
'mle-star-workflow.json',
|
|
1602
|
-
);
|
|
1357
|
+
*/ export function getMLEStarWorkflowPath() {
|
|
1358
|
+
return join(process.cwd(), 'src', 'cli', 'simple-commands', 'templates', 'mle-star-workflow.json');
|
|
1603
1359
|
}
|