musubi-sdd 3.0.0 → 3.5.1
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/bin/musubi-browser.js +0 -0
- package/bin/musubi-change.js +623 -10
- package/bin/musubi-convert.js +0 -0
- package/bin/musubi-gui.js +0 -0
- package/bin/musubi-orchestrate.js +456 -0
- package/bin/musubi-trace.js +393 -0
- package/bin/musubi-validate.js +0 -10
- package/package.json +3 -2
- package/src/analyzers/impact-analyzer.js +682 -0
- package/src/integrations/cicd.js +782 -0
- package/src/integrations/documentation.js +740 -0
- package/src/integrations/examples.js +789 -0
- package/src/integrations/index.js +23 -0
- package/src/integrations/platforms.js +929 -0
- package/src/managers/delta-spec.js +484 -0
- package/src/monitoring/incident-manager.js +890 -0
- package/src/monitoring/index.js +633 -0
- package/src/monitoring/observability.js +938 -0
- package/src/monitoring/release-manager.js +622 -0
- package/src/orchestration/index.js +168 -0
- package/src/orchestration/orchestration-engine.js +409 -0
- package/src/orchestration/pattern-registry.js +319 -0
- package/src/orchestration/patterns/auto.js +386 -0
- package/src/orchestration/patterns/group-chat.js +395 -0
- package/src/orchestration/patterns/human-in-loop.js +506 -0
- package/src/orchestration/patterns/nested.js +322 -0
- package/src/orchestration/patterns/sequential.js +278 -0
- package/src/orchestration/patterns/swarm.js +395 -0
- package/src/orchestration/workflow-orchestrator.js +738 -0
- package/src/reporters/coverage-report.js +452 -0
- package/src/reporters/traceability-matrix-report.js +684 -0
- package/src/steering/advanced-validation.js +812 -0
- package/src/steering/auto-updater.js +670 -0
- package/src/steering/index.js +119 -0
- package/src/steering/quality-metrics.js +650 -0
- package/src/steering/template-constraints.js +789 -0
- package/src/templates/agents/claude-code/skills/agent-assistant/SKILL.md +22 -0
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/mlops-guide.md +350 -0
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/model-card-template.md +246 -0
- package/src/templates/agents/claude-code/skills/api-designer/api-patterns.md +336 -0
- package/src/templates/agents/claude-code/skills/api-designer/openapi-template.md +376 -0
- package/src/templates/agents/claude-code/skills/bug-hunter/root-cause-analysis.md +177 -0
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/dependency-graph-patterns.md +348 -0
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/impact-analysis-template.md +246 -0
- package/src/templates/agents/claude-code/skills/cloud-architect/aws-patterns.md +239 -0
- package/src/templates/agents/claude-code/skills/cloud-architect/azure-patterns.md +300 -0
- package/src/templates/agents/claude-code/skills/cloud-architect/terraform-templates/azure-webapp.tf +337 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/best-practices.md +155 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/review-checklist.md +184 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/review-standards.md +272 -0
- package/src/templates/agents/claude-code/skills/constitution-enforcer/constitutional-articles.md +449 -0
- package/src/templates/agents/claude-code/skills/constitution-enforcer/phase-minus-one-gates.md +375 -0
- package/src/templates/agents/claude-code/skills/database-administrator/backup-recovery.md +331 -0
- package/src/templates/agents/claude-code/skills/database-administrator/tuning-guide.md +314 -0
- package/src/templates/agents/claude-code/skills/database-schema-designer/schema-patterns.md +335 -0
- package/src/templates/agents/claude-code/skills/devops-engineer/ci-cd-templates.md +443 -0
- package/src/templates/agents/claude-code/skills/devops-engineer/pipeline-templates/github-actions.yml +311 -0
- package/src/templates/agents/claude-code/skills/devops-engineer/pipeline-templates/gitlab-ci.yml +255 -0
- package/src/templates/agents/claude-code/skills/issue-resolver/SKILL.md +21 -0
- package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +90 -28
- package/src/templates/agents/claude-code/skills/orchestrator/patterns.md +266 -0
- package/src/templates/agents/claude-code/skills/orchestrator/selection-matrix.md +185 -0
- package/src/templates/agents/claude-code/skills/performance-engineer/optimization-playbook.md +306 -0
- package/src/templates/agents/claude-code/skills/performance-optimizer/benchmark-template.md +272 -0
- package/src/templates/agents/claude-code/skills/performance-optimizer/optimization-patterns.md +273 -0
- package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +32 -0
- package/src/templates/agents/claude-code/skills/project-manager/agile-ceremonies.md +283 -0
- package/src/templates/agents/claude-code/skills/project-manager/project-templates.md +345 -0
- package/src/templates/agents/claude-code/skills/quality-assurance/qa-plan-template.md +219 -0
- package/src/templates/agents/claude-code/skills/release-coordinator/feature-flag-guide.md +312 -0
- package/src/templates/agents/claude-code/skills/release-coordinator/release-plan-template.md +230 -0
- package/src/templates/agents/claude-code/skills/requirements-analyst/ears-format.md +259 -0
- package/src/templates/agents/claude-code/skills/requirements-analyst/validation-rules.md +359 -0
- package/src/templates/agents/claude-code/skills/security-auditor/audit-checklists.md +243 -0
- package/src/templates/agents/claude-code/skills/security-auditor/owasp-top-10.md +349 -0
- package/src/templates/agents/claude-code/skills/security-auditor/vulnerability-patterns.md +295 -0
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/SKILL.md +27 -0
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/incident-response-template.md +286 -0
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/observability-patterns.md +359 -0
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/slo-sli-guide.md +302 -0
- package/src/templates/agents/claude-code/skills/software-developer/solid-principles.md +348 -0
- package/src/templates/agents/claude-code/skills/software-developer/test-first-workflow.md +370 -0
- package/src/templates/agents/claude-code/skills/steering/SKILL.md +30 -0
- package/src/templates/agents/claude-code/skills/steering/auto-update-rules.md +328 -0
- package/src/templates/agents/claude-code/skills/system-architect/adr-template.md +295 -0
- package/src/templates/agents/claude-code/skills/system-architect/c4-model-guide.md +328 -0
- package/src/templates/agents/claude-code/skills/technical-writer/doc-templates/documentation-templates.md +436 -0
- package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +21 -0
- package/src/templates/agents/claude-code/skills/test-engineer/ears-test-mapping.md +444 -0
- package/src/templates/agents/claude-code/skills/test-engineer/test-types.md +425 -0
- package/src/templates/agents/claude-code/skills/traceability-auditor/coverage-matrix-template.md +131 -0
- package/src/templates/agents/claude-code/skills/traceability-auditor/gap-detection-rules.md +227 -0
- package/src/templates/agents/claude-code/skills/ui-ux-designer/SKILL.md +27 -0
- package/src/templates/agents/claude-code/skills/ui-ux-designer/accessibility-guidelines.md +318 -0
- package/src/templates/agents/claude-code/skills/ui-ux-designer/design-system-components.md +345 -0
- package/src/templates/agents/codex/AGENTS.md +36 -1
- package/src/templates/agents/cursor/AGENTS.md +36 -1
- package/src/templates/agents/gemini-cli/GEMINI.md +36 -1
- package/src/templates/agents/github-copilot/AGENTS.md +65 -1
- package/src/templates/agents/qwen-code/QWEN.md +36 -1
- package/src/templates/agents/windsurf/AGENTS.md +36 -1
- package/src/templates/shared/delta-spec-template.md +246 -0
- package/src/validators/constitutional-validator.js +494 -0
- package/src/validators/delta-format.js +474 -0
- package/src/validators/traceability-validator.js +561 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MUSUBI Orchestration Module
|
|
3
|
+
*
|
|
4
|
+
* Multi-skill orchestration with ag2-inspired patterns:
|
|
5
|
+
* - Auto: Automatic skill selection based on task
|
|
6
|
+
* - Sequential: Linear skill execution
|
|
7
|
+
* - Nested: Hierarchical skill delegation
|
|
8
|
+
* - GroupChat: Multi-skill collaborative discussion
|
|
9
|
+
* - Swarm: Parallel skill execution (coming soon)
|
|
10
|
+
* - HumanInLoop: Validation gates
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
OrchestrationEngine,
|
|
15
|
+
ExecutionContext,
|
|
16
|
+
PatternType,
|
|
17
|
+
ExecutionStatus,
|
|
18
|
+
Priority
|
|
19
|
+
} = require('./orchestration-engine');
|
|
20
|
+
|
|
21
|
+
const {
|
|
22
|
+
PatternRegistry,
|
|
23
|
+
PatternMetadata,
|
|
24
|
+
BasePattern,
|
|
25
|
+
createDefaultRegistry
|
|
26
|
+
} = require('./pattern-registry');
|
|
27
|
+
|
|
28
|
+
const {
|
|
29
|
+
SequentialPattern,
|
|
30
|
+
SequentialOptions,
|
|
31
|
+
createSequentialPattern
|
|
32
|
+
} = require('./patterns/sequential');
|
|
33
|
+
|
|
34
|
+
const {
|
|
35
|
+
AutoPattern,
|
|
36
|
+
ConfidenceLevel,
|
|
37
|
+
createAutoPattern
|
|
38
|
+
} = require('./patterns/auto');
|
|
39
|
+
|
|
40
|
+
const {
|
|
41
|
+
NestedPattern,
|
|
42
|
+
createNestedPattern
|
|
43
|
+
} = require('./patterns/nested');
|
|
44
|
+
|
|
45
|
+
const {
|
|
46
|
+
GroupChatPattern,
|
|
47
|
+
DiscussionMode,
|
|
48
|
+
ConsensusType,
|
|
49
|
+
createGroupChatPattern
|
|
50
|
+
} = require('./patterns/group-chat');
|
|
51
|
+
|
|
52
|
+
const {
|
|
53
|
+
HumanInLoopPattern,
|
|
54
|
+
GateType,
|
|
55
|
+
GateResult,
|
|
56
|
+
createHumanInLoopPattern
|
|
57
|
+
} = require('./patterns/human-in-loop');
|
|
58
|
+
|
|
59
|
+
const {
|
|
60
|
+
SwarmPattern,
|
|
61
|
+
PLabel,
|
|
62
|
+
SwarmStrategy,
|
|
63
|
+
createSwarmPattern
|
|
64
|
+
} = require('./patterns/swarm');
|
|
65
|
+
|
|
66
|
+
const {
|
|
67
|
+
WorkflowOrchestrator,
|
|
68
|
+
StepType,
|
|
69
|
+
WorkflowState,
|
|
70
|
+
SDDWorkflowTemplates,
|
|
71
|
+
createWorkflowOrchestrator
|
|
72
|
+
} = require('./workflow-orchestrator');
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Create a fully configured orchestration engine
|
|
76
|
+
* with default patterns registered
|
|
77
|
+
*
|
|
78
|
+
* @param {object} options - Engine options
|
|
79
|
+
* @returns {OrchestrationEngine} Configured engine
|
|
80
|
+
*/
|
|
81
|
+
function createOrchestrationEngine(options = {}) {
|
|
82
|
+
const engine = new OrchestrationEngine(options);
|
|
83
|
+
const registry = createDefaultRegistry();
|
|
84
|
+
|
|
85
|
+
// Register built-in patterns
|
|
86
|
+
registry.register(PatternType.SEQUENTIAL, createSequentialPattern());
|
|
87
|
+
registry.register(PatternType.AUTO, createAutoPattern());
|
|
88
|
+
registry.register(PatternType.NESTED, createNestedPattern());
|
|
89
|
+
registry.register(PatternType.GROUP_CHAT, createGroupChatPattern());
|
|
90
|
+
registry.register(PatternType.HUMAN_IN_LOOP, createHumanInLoopPattern());
|
|
91
|
+
registry.register(PatternType.SWARM, createSwarmPattern());
|
|
92
|
+
|
|
93
|
+
// Register patterns with engine
|
|
94
|
+
registry.registerWithEngine(engine);
|
|
95
|
+
|
|
96
|
+
return engine;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Create an orchestration engine with custom patterns
|
|
101
|
+
*
|
|
102
|
+
* @param {object} options - Engine options
|
|
103
|
+
* @param {object[]} patterns - Custom patterns to register
|
|
104
|
+
* @returns {OrchestrationEngine} Configured engine
|
|
105
|
+
*/
|
|
106
|
+
function createCustomOrchestrationEngine(options = {}, patterns = []) {
|
|
107
|
+
const engine = new OrchestrationEngine(options);
|
|
108
|
+
|
|
109
|
+
// Register custom patterns
|
|
110
|
+
for (const { name, pattern } of patterns) {
|
|
111
|
+
engine.registerPattern(name, pattern);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return engine;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module.exports = {
|
|
118
|
+
// Core engine
|
|
119
|
+
OrchestrationEngine,
|
|
120
|
+
ExecutionContext,
|
|
121
|
+
createOrchestrationEngine,
|
|
122
|
+
createCustomOrchestrationEngine,
|
|
123
|
+
|
|
124
|
+
// Registry
|
|
125
|
+
PatternRegistry,
|
|
126
|
+
PatternMetadata,
|
|
127
|
+
BasePattern,
|
|
128
|
+
createDefaultRegistry,
|
|
129
|
+
|
|
130
|
+
// Patterns
|
|
131
|
+
SequentialPattern,
|
|
132
|
+
SequentialOptions,
|
|
133
|
+
createSequentialPattern,
|
|
134
|
+
|
|
135
|
+
AutoPattern,
|
|
136
|
+
ConfidenceLevel,
|
|
137
|
+
createAutoPattern,
|
|
138
|
+
|
|
139
|
+
NestedPattern,
|
|
140
|
+
createNestedPattern,
|
|
141
|
+
|
|
142
|
+
GroupChatPattern,
|
|
143
|
+
DiscussionMode,
|
|
144
|
+
ConsensusType,
|
|
145
|
+
createGroupChatPattern,
|
|
146
|
+
|
|
147
|
+
HumanInLoopPattern,
|
|
148
|
+
GateType,
|
|
149
|
+
GateResult,
|
|
150
|
+
createHumanInLoopPattern,
|
|
151
|
+
|
|
152
|
+
SwarmPattern,
|
|
153
|
+
PLabel,
|
|
154
|
+
SwarmStrategy,
|
|
155
|
+
createSwarmPattern,
|
|
156
|
+
|
|
157
|
+
// Workflow Orchestrator
|
|
158
|
+
WorkflowOrchestrator,
|
|
159
|
+
StepType,
|
|
160
|
+
WorkflowState,
|
|
161
|
+
SDDWorkflowTemplates,
|
|
162
|
+
createWorkflowOrchestrator,
|
|
163
|
+
|
|
164
|
+
// Constants
|
|
165
|
+
PatternType,
|
|
166
|
+
ExecutionStatus,
|
|
167
|
+
Priority
|
|
168
|
+
};
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OrchestrationEngine - Core engine for multi-skill orchestration
|
|
3
|
+
*
|
|
4
|
+
* Implements ag2-inspired patterns for skill coordination:
|
|
5
|
+
* - Auto: Automatic skill selection based on task
|
|
6
|
+
* - Sequential: Linear skill execution
|
|
7
|
+
* - Nested: Hierarchical skill delegation
|
|
8
|
+
* - GroupChat: Multi-skill collaborative discussion
|
|
9
|
+
* - Swarm: Parallel skill execution
|
|
10
|
+
* - HumanInLoop: Validation gates
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const EventEmitter = require('events');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Orchestration pattern types
|
|
17
|
+
*/
|
|
18
|
+
const PatternType = {
|
|
19
|
+
AUTO: 'auto',
|
|
20
|
+
SEQUENTIAL: 'sequential',
|
|
21
|
+
NESTED: 'nested',
|
|
22
|
+
GROUP_CHAT: 'group-chat',
|
|
23
|
+
SWARM: 'swarm',
|
|
24
|
+
HUMAN_IN_LOOP: 'human-in-loop'
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Execution status
|
|
29
|
+
*/
|
|
30
|
+
const ExecutionStatus = {
|
|
31
|
+
PENDING: 'pending',
|
|
32
|
+
RUNNING: 'running',
|
|
33
|
+
COMPLETED: 'completed',
|
|
34
|
+
FAILED: 'failed',
|
|
35
|
+
CANCELLED: 'cancelled',
|
|
36
|
+
WAITING_FOR_HUMAN: 'waiting-for-human'
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Task priority levels
|
|
41
|
+
*/
|
|
42
|
+
const Priority = {
|
|
43
|
+
P0: 0, // Critical - must complete first
|
|
44
|
+
P1: 1, // High - important
|
|
45
|
+
P2: 2, // Medium - nice to have
|
|
46
|
+
P3: 3 // Low - future enhancement
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Execution context for a task
|
|
51
|
+
*/
|
|
52
|
+
class ExecutionContext {
|
|
53
|
+
constructor(options = {}) {
|
|
54
|
+
this.id = options.id || this._generateId();
|
|
55
|
+
this.parentId = options.parentId || null;
|
|
56
|
+
this.task = options.task || '';
|
|
57
|
+
this.priority = options.priority ?? Priority.P1;
|
|
58
|
+
this.status = ExecutionStatus.PENDING;
|
|
59
|
+
this.skill = options.skill || null;
|
|
60
|
+
this.input = options.input || {};
|
|
61
|
+
this.output = null;
|
|
62
|
+
this.error = null;
|
|
63
|
+
this.children = [];
|
|
64
|
+
this.metadata = options.metadata || {};
|
|
65
|
+
this.startTime = null;
|
|
66
|
+
this.endTime = null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
_generateId() {
|
|
70
|
+
return `exec-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
start() {
|
|
74
|
+
this.status = ExecutionStatus.RUNNING;
|
|
75
|
+
this.startTime = new Date();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
complete(output) {
|
|
79
|
+
this.status = ExecutionStatus.COMPLETED;
|
|
80
|
+
this.output = output;
|
|
81
|
+
this.endTime = new Date();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
fail(error) {
|
|
85
|
+
this.status = ExecutionStatus.FAILED;
|
|
86
|
+
this.error = error instanceof Error ? error.message : error;
|
|
87
|
+
this.endTime = new Date();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
cancel() {
|
|
91
|
+
this.status = ExecutionStatus.CANCELLED;
|
|
92
|
+
this.endTime = new Date();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
waitForHuman() {
|
|
96
|
+
this.status = ExecutionStatus.WAITING_FOR_HUMAN;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
getDuration() {
|
|
100
|
+
if (!this.startTime) return 0;
|
|
101
|
+
const end = this.endTime || new Date();
|
|
102
|
+
return end - this.startTime;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
toJSON() {
|
|
106
|
+
return {
|
|
107
|
+
id: this.id,
|
|
108
|
+
parentId: this.parentId,
|
|
109
|
+
task: this.task,
|
|
110
|
+
priority: this.priority,
|
|
111
|
+
status: this.status,
|
|
112
|
+
skill: this.skill,
|
|
113
|
+
input: this.input,
|
|
114
|
+
output: this.output,
|
|
115
|
+
error: this.error,
|
|
116
|
+
children: this.children.map(c => c.toJSON ? c.toJSON() : c),
|
|
117
|
+
metadata: this.metadata,
|
|
118
|
+
startTime: this.startTime,
|
|
119
|
+
endTime: this.endTime,
|
|
120
|
+
duration: this.getDuration()
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* OrchestrationEngine - Main orchestration engine
|
|
127
|
+
*/
|
|
128
|
+
class OrchestrationEngine extends EventEmitter {
|
|
129
|
+
constructor(options = {}) {
|
|
130
|
+
super();
|
|
131
|
+
this.patterns = new Map();
|
|
132
|
+
this.skills = new Map();
|
|
133
|
+
this.activeContexts = new Map();
|
|
134
|
+
this.config = {
|
|
135
|
+
maxConcurrent: options.maxConcurrent || 5,
|
|
136
|
+
timeout: options.timeout || 300000, // 5 minutes default
|
|
137
|
+
retryCount: options.retryCount || 3,
|
|
138
|
+
retryDelay: options.retryDelay || 1000,
|
|
139
|
+
...options
|
|
140
|
+
};
|
|
141
|
+
this.skillResolver = options.skillResolver || null;
|
|
142
|
+
this.humanGate = options.humanGate || null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Register an orchestration pattern
|
|
147
|
+
* @param {string} name - Pattern name
|
|
148
|
+
* @param {object} pattern - Pattern implementation
|
|
149
|
+
*/
|
|
150
|
+
registerPattern(name, pattern) {
|
|
151
|
+
if (!pattern || typeof pattern.execute !== 'function') {
|
|
152
|
+
throw new Error(`Pattern '${name}' must have an execute method`);
|
|
153
|
+
}
|
|
154
|
+
this.patterns.set(name, pattern);
|
|
155
|
+
this.emit('patternRegistered', { name, pattern });
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Get a registered pattern
|
|
161
|
+
* @param {string} name - Pattern name
|
|
162
|
+
* @returns {object|null} Pattern implementation
|
|
163
|
+
*/
|
|
164
|
+
getPattern(name) {
|
|
165
|
+
return this.patterns.get(name) || null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* List all registered patterns
|
|
170
|
+
* @returns {string[]} Pattern names
|
|
171
|
+
*/
|
|
172
|
+
listPatterns() {
|
|
173
|
+
return Array.from(this.patterns.keys());
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Register a skill for orchestration
|
|
178
|
+
* @param {string} name - Skill name
|
|
179
|
+
* @param {object} skill - Skill definition
|
|
180
|
+
*/
|
|
181
|
+
registerSkill(name, skill) {
|
|
182
|
+
if (!skill) {
|
|
183
|
+
throw new Error(`Skill '${name}' cannot be null`);
|
|
184
|
+
}
|
|
185
|
+
this.skills.set(name, skill);
|
|
186
|
+
this.emit('skillRegistered', { name, skill });
|
|
187
|
+
return this;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Get a registered skill
|
|
192
|
+
* @param {string} name - Skill name
|
|
193
|
+
* @returns {object|null} Skill definition
|
|
194
|
+
*/
|
|
195
|
+
getSkill(name) {
|
|
196
|
+
return this.skills.get(name) || null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* List all registered skills
|
|
201
|
+
* @returns {string[]} Skill names
|
|
202
|
+
*/
|
|
203
|
+
listSkills() {
|
|
204
|
+
return Array.from(this.skills.keys());
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Execute a task using the specified pattern
|
|
209
|
+
* @param {string} patternName - Pattern to use
|
|
210
|
+
* @param {object} options - Execution options
|
|
211
|
+
* @returns {Promise<ExecutionContext>} Execution result
|
|
212
|
+
*/
|
|
213
|
+
async execute(patternName, options = {}) {
|
|
214
|
+
const pattern = this.patterns.get(patternName);
|
|
215
|
+
if (!pattern) {
|
|
216
|
+
throw new Error(`Unknown pattern: ${patternName}`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const context = new ExecutionContext({
|
|
220
|
+
task: options.task || '',
|
|
221
|
+
priority: options.priority,
|
|
222
|
+
skill: options.skill,
|
|
223
|
+
input: options.input || {},
|
|
224
|
+
metadata: {
|
|
225
|
+
pattern: patternName,
|
|
226
|
+
...options.metadata
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
this.activeContexts.set(context.id, context);
|
|
231
|
+
this.emit('executionStarted', context);
|
|
232
|
+
|
|
233
|
+
try {
|
|
234
|
+
context.start();
|
|
235
|
+
|
|
236
|
+
const result = await this._executeWithTimeout(
|
|
237
|
+
() => pattern.execute(context, this),
|
|
238
|
+
this.config.timeout
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
context.complete(result);
|
|
242
|
+
this.emit('executionCompleted', context);
|
|
243
|
+
} catch (error) {
|
|
244
|
+
context.fail(error);
|
|
245
|
+
this.emit('executionFailed', { context, error });
|
|
246
|
+
} finally {
|
|
247
|
+
this.activeContexts.delete(context.id);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return context;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Execute with timeout
|
|
255
|
+
* @private
|
|
256
|
+
*/
|
|
257
|
+
async _executeWithTimeout(fn, timeout) {
|
|
258
|
+
return new Promise((resolve, reject) => {
|
|
259
|
+
const timer = setTimeout(() => {
|
|
260
|
+
reject(new Error(`Execution timeout after ${timeout}ms`));
|
|
261
|
+
}, timeout);
|
|
262
|
+
|
|
263
|
+
Promise.resolve(fn())
|
|
264
|
+
.then(result => {
|
|
265
|
+
clearTimeout(timer);
|
|
266
|
+
resolve(result);
|
|
267
|
+
})
|
|
268
|
+
.catch(error => {
|
|
269
|
+
clearTimeout(timer);
|
|
270
|
+
reject(error);
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Execute a skill directly
|
|
277
|
+
* @param {string} skillName - Skill to execute
|
|
278
|
+
* @param {object} input - Skill input
|
|
279
|
+
* @param {ExecutionContext} parentContext - Parent context
|
|
280
|
+
* @returns {Promise<any>} Skill output
|
|
281
|
+
*/
|
|
282
|
+
async executeSkill(skillName, input, parentContext = null) {
|
|
283
|
+
const skill = this.skills.get(skillName);
|
|
284
|
+
if (!skill) {
|
|
285
|
+
throw new Error(`Unknown skill: ${skillName}`);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const context = new ExecutionContext({
|
|
289
|
+
task: `Execute skill: ${skillName}`,
|
|
290
|
+
skill: skillName,
|
|
291
|
+
input,
|
|
292
|
+
parentId: parentContext?.id,
|
|
293
|
+
metadata: { directExecution: true }
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
if (parentContext) {
|
|
297
|
+
parentContext.children.push(context);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
this.emit('skillExecutionStarted', { skillName, context });
|
|
301
|
+
|
|
302
|
+
try {
|
|
303
|
+
context.start();
|
|
304
|
+
|
|
305
|
+
let result;
|
|
306
|
+
if (typeof skill.execute === 'function') {
|
|
307
|
+
result = await skill.execute(input, this);
|
|
308
|
+
} else if (typeof skill === 'function') {
|
|
309
|
+
result = await skill(input, this);
|
|
310
|
+
} else {
|
|
311
|
+
throw new Error(`Skill '${skillName}' is not executable`);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
context.complete(result);
|
|
315
|
+
this.emit('skillExecutionCompleted', { skillName, context });
|
|
316
|
+
return result;
|
|
317
|
+
} catch (error) {
|
|
318
|
+
context.fail(error);
|
|
319
|
+
this.emit('skillExecutionFailed', { skillName, context, error });
|
|
320
|
+
throw error;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Resolve the best skill for a task
|
|
326
|
+
* @param {string} task - Task description
|
|
327
|
+
* @returns {Promise<string|null>} Skill name
|
|
328
|
+
*/
|
|
329
|
+
async resolveSkill(task) {
|
|
330
|
+
if (this.skillResolver) {
|
|
331
|
+
return this.skillResolver.resolve(task, this.listSkills());
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Default: return first matching skill based on keywords
|
|
335
|
+
const taskLower = task.toLowerCase();
|
|
336
|
+
for (const [name, skill] of this.skills) {
|
|
337
|
+
const keywords = skill.keywords || [name];
|
|
338
|
+
if (keywords.some(k => taskLower.includes(k.toLowerCase()))) {
|
|
339
|
+
return name;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Request human validation
|
|
348
|
+
* @param {ExecutionContext} context - Current context
|
|
349
|
+
* @param {string} question - Question for human
|
|
350
|
+
* @returns {Promise<any>} Human response
|
|
351
|
+
*/
|
|
352
|
+
async requestHumanValidation(context, question) {
|
|
353
|
+
context.waitForHuman();
|
|
354
|
+
this.emit('humanValidationRequested', { context, question });
|
|
355
|
+
|
|
356
|
+
if (this.humanGate) {
|
|
357
|
+
return this.humanGate.request(question, context);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Default: auto-approve
|
|
361
|
+
return { approved: true, feedback: 'Auto-approved (no human gate configured)' };
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Get execution status
|
|
366
|
+
* @returns {object} Status summary
|
|
367
|
+
*/
|
|
368
|
+
getStatus() {
|
|
369
|
+
const contexts = Array.from(this.activeContexts.values());
|
|
370
|
+
return {
|
|
371
|
+
activeExecutions: contexts.length,
|
|
372
|
+
patterns: this.listPatterns(),
|
|
373
|
+
skills: this.listSkills(),
|
|
374
|
+
contexts: contexts.map(c => c.toJSON())
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Cancel an execution
|
|
380
|
+
* @param {string} contextId - Context ID to cancel
|
|
381
|
+
*/
|
|
382
|
+
cancel(contextId) {
|
|
383
|
+
const context = this.activeContexts.get(contextId);
|
|
384
|
+
if (context) {
|
|
385
|
+
context.cancel();
|
|
386
|
+
this.activeContexts.delete(contextId);
|
|
387
|
+
this.emit('executionCancelled', context);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Cancel all active executions
|
|
393
|
+
*/
|
|
394
|
+
cancelAll() {
|
|
395
|
+
for (const [id, context] of this.activeContexts) {
|
|
396
|
+
context.cancel();
|
|
397
|
+
this.emit('executionCancelled', context);
|
|
398
|
+
}
|
|
399
|
+
this.activeContexts.clear();
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
module.exports = {
|
|
404
|
+
OrchestrationEngine,
|
|
405
|
+
ExecutionContext,
|
|
406
|
+
PatternType,
|
|
407
|
+
ExecutionStatus,
|
|
408
|
+
Priority
|
|
409
|
+
};
|