musubi-sdd 5.0.0 → 5.6.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/README.ja.md +106 -48
- package/README.md +110 -32
- package/bin/musubi-analyze.js +74 -67
- package/bin/musubi-browser.js +27 -26
- package/bin/musubi-change.js +48 -47
- package/bin/musubi-checkpoint.js +10 -7
- package/bin/musubi-convert.js +25 -25
- package/bin/musubi-costs.js +27 -10
- package/bin/musubi-gui.js +52 -46
- package/bin/musubi-init.js +1952 -10
- package/bin/musubi-orchestrate.js +327 -239
- package/bin/musubi-remember.js +69 -56
- package/bin/musubi-resolve.js +53 -45
- package/bin/musubi-trace.js +51 -22
- package/bin/musubi-validate.js +39 -30
- package/bin/musubi-workflow.js +33 -34
- package/bin/musubi.js +39 -2
- package/package.json +1 -1
- package/src/agents/agent-loop.js +94 -95
- package/src/agents/agentic/code-generator.js +119 -109
- package/src/agents/agentic/code-reviewer.js +105 -108
- package/src/agents/agentic/index.js +4 -4
- package/src/agents/browser/action-executor.js +13 -13
- package/src/agents/browser/ai-comparator.js +11 -10
- package/src/agents/browser/context-manager.js +6 -6
- package/src/agents/browser/index.js +5 -5
- package/src/agents/browser/nl-parser.js +31 -46
- package/src/agents/browser/screenshot.js +2 -2
- package/src/agents/browser/test-generator.js +6 -4
- package/src/agents/function-tool.js +71 -65
- package/src/agents/index.js +7 -7
- package/src/agents/schema-generator.js +98 -94
- package/src/analyzers/ast-extractor.js +164 -145
- package/src/analyzers/codegraph-auto-update.js +858 -0
- package/src/analyzers/complexity-analyzer.js +536 -0
- package/src/analyzers/context-optimizer.js +247 -125
- package/src/analyzers/impact-analyzer.js +1 -1
- package/src/analyzers/large-project-analyzer.js +766 -0
- package/src/analyzers/repository-map.js +83 -80
- package/src/analyzers/security-analyzer.js +19 -11
- package/src/analyzers/stuck-detector.js +19 -17
- package/src/converters/index.js +78 -57
- package/src/converters/ir/types.js +12 -12
- package/src/converters/parsers/musubi-parser.js +134 -126
- package/src/converters/parsers/openapi-parser.js +70 -53
- package/src/converters/parsers/speckit-parser.js +239 -175
- package/src/converters/writers/musubi-writer.js +123 -118
- package/src/converters/writers/speckit-writer.js +124 -113
- package/src/generators/rust-migration-generator.js +512 -0
- package/src/gui/public/index.html +1365 -1211
- package/src/gui/server.js +41 -40
- package/src/gui/services/file-watcher.js +23 -8
- package/src/gui/services/project-scanner.js +26 -20
- package/src/gui/services/replanning-service.js +27 -23
- package/src/gui/services/traceability-service.js +8 -8
- package/src/gui/services/workflow-service.js +14 -7
- package/src/index.js +151 -0
- package/src/integrations/cicd.js +90 -104
- package/src/integrations/codegraph-mcp.js +643 -0
- package/src/integrations/documentation.js +142 -103
- package/src/integrations/examples.js +95 -80
- package/src/integrations/github-client.js +17 -17
- package/src/integrations/index.js +5 -5
- package/src/integrations/mcp/index.js +21 -21
- package/src/integrations/mcp/mcp-context-provider.js +76 -78
- package/src/integrations/mcp/mcp-discovery.js +74 -72
- package/src/integrations/mcp/mcp-tool-registry.js +99 -94
- package/src/integrations/mcp-connector.js +70 -66
- package/src/integrations/platforms.js +50 -49
- package/src/integrations/tool-discovery.js +37 -31
- package/src/llm-providers/anthropic-provider.js +11 -11
- package/src/llm-providers/base-provider.js +16 -18
- package/src/llm-providers/copilot-provider.js +22 -19
- package/src/llm-providers/index.js +26 -25
- package/src/llm-providers/ollama-provider.js +11 -11
- package/src/llm-providers/openai-provider.js +12 -12
- package/src/managers/agent-memory.js +36 -24
- package/src/managers/checkpoint-manager.js +4 -8
- package/src/managers/delta-spec.js +19 -19
- package/src/managers/index.js +13 -4
- package/src/managers/memory-condenser.js +35 -45
- package/src/managers/repo-skill-manager.js +57 -31
- package/src/managers/skill-loader.js +25 -22
- package/src/managers/skill-tools.js +36 -72
- package/src/managers/workflow.js +30 -22
- package/src/monitoring/cost-tracker.js +53 -44
- package/src/monitoring/incident-manager.js +123 -103
- package/src/monitoring/index.js +144 -134
- package/src/monitoring/observability.js +82 -59
- package/src/monitoring/quality-dashboard.js +51 -39
- package/src/monitoring/release-manager.js +70 -50
- package/src/orchestration/agent-skill-binding.js +39 -47
- package/src/orchestration/error-handler.js +65 -107
- package/src/orchestration/guardrails/base-guardrail.js +26 -24
- package/src/orchestration/guardrails/guardrail-rules.js +50 -64
- package/src/orchestration/guardrails/index.js +5 -5
- package/src/orchestration/guardrails/input-guardrail.js +58 -45
- package/src/orchestration/guardrails/output-guardrail.js +104 -81
- package/src/orchestration/guardrails/safety-check.js +79 -79
- package/src/orchestration/index.js +38 -55
- package/src/orchestration/mcp-tool-adapters.js +96 -99
- package/src/orchestration/orchestration-engine.js +21 -21
- package/src/orchestration/pattern-registry.js +60 -45
- package/src/orchestration/patterns/auto.js +34 -47
- package/src/orchestration/patterns/group-chat.js +59 -65
- package/src/orchestration/patterns/handoff.js +67 -65
- package/src/orchestration/patterns/human-in-loop.js +51 -72
- package/src/orchestration/patterns/nested.js +25 -40
- package/src/orchestration/patterns/sequential.js +35 -34
- package/src/orchestration/patterns/swarm.js +63 -56
- package/src/orchestration/patterns/triage.js +150 -109
- package/src/orchestration/reasoning/index.js +9 -9
- package/src/orchestration/reasoning/planning-engine.js +143 -140
- package/src/orchestration/reasoning/reasoning-engine.js +206 -144
- package/src/orchestration/reasoning/self-correction.js +121 -128
- package/src/orchestration/replanning/adaptive-goal-modifier.js +107 -112
- package/src/orchestration/replanning/alternative-generator.js +37 -42
- package/src/orchestration/replanning/config.js +63 -59
- package/src/orchestration/replanning/goal-progress-tracker.js +98 -100
- package/src/orchestration/replanning/index.js +24 -20
- package/src/orchestration/replanning/plan-evaluator.js +49 -50
- package/src/orchestration/replanning/plan-monitor.js +32 -28
- package/src/orchestration/replanning/proactive-path-optimizer.js +175 -178
- package/src/orchestration/replanning/replan-history.js +33 -26
- package/src/orchestration/replanning/replanning-engine.js +106 -108
- package/src/orchestration/skill-executor.js +107 -109
- package/src/orchestration/skill-registry.js +85 -89
- package/src/orchestration/workflow-examples.js +228 -231
- package/src/orchestration/workflow-executor.js +65 -68
- package/src/orchestration/workflow-orchestrator.js +72 -73
- package/src/phase4-integration.js +47 -40
- package/src/phase5-integration.js +89 -30
- package/src/reporters/coverage-report.js +82 -30
- package/src/reporters/hierarchical-reporter.js +498 -0
- package/src/reporters/traceability-matrix-report.js +29 -20
- package/src/resolvers/issue-resolver.js +43 -31
- package/src/steering/advanced-validation.js +133 -124
- package/src/steering/auto-updater.js +60 -73
- package/src/steering/index.js +6 -6
- package/src/steering/quality-metrics.js +41 -35
- package/src/steering/steering-auto-update.js +83 -86
- package/src/steering/steering-validator.js +98 -106
- package/src/steering/template-constraints.js +53 -54
- package/src/templates/agents/claude-code/CLAUDE.md +32 -32
- package/src/templates/agents/claude-code/skills/agent-assistant/SKILL.md +13 -5
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/mlops-guide.md +23 -23
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/model-card-template.md +60 -41
- package/src/templates/agents/claude-code/skills/api-designer/api-patterns.md +27 -19
- package/src/templates/agents/claude-code/skills/api-designer/openapi-template.md +11 -7
- package/src/templates/agents/claude-code/skills/bug-hunter/SKILL.md +4 -3
- package/src/templates/agents/claude-code/skills/bug-hunter/root-cause-analysis.md +37 -15
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/dependency-graph-patterns.md +36 -42
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/impact-analysis-template.md +69 -60
- package/src/templates/agents/claude-code/skills/cloud-architect/aws-patterns.md +31 -38
- package/src/templates/agents/claude-code/skills/cloud-architect/azure-patterns.md +28 -23
- package/src/templates/agents/claude-code/skills/code-reviewer/SKILL.md +61 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/best-practices.md +27 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/review-checklist.md +29 -10
- package/src/templates/agents/claude-code/skills/code-reviewer/review-standards.md +29 -24
- package/src/templates/agents/claude-code/skills/constitution-enforcer/SKILL.md +8 -6
- package/src/templates/agents/claude-code/skills/constitution-enforcer/constitutional-articles.md +62 -26
- package/src/templates/agents/claude-code/skills/constitution-enforcer/phase-minus-one-gates.md +35 -16
- package/src/templates/agents/claude-code/skills/database-administrator/backup-recovery.md +27 -17
- package/src/templates/agents/claude-code/skills/database-administrator/tuning-guide.md +25 -20
- package/src/templates/agents/claude-code/skills/database-schema-designer/schema-patterns.md +39 -22
- package/src/templates/agents/claude-code/skills/devops-engineer/ci-cd-templates.md +25 -22
- package/src/templates/agents/claude-code/skills/issue-resolver/SKILL.md +24 -21
- package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +148 -63
- package/src/templates/agents/claude-code/skills/orchestrator/patterns.md +35 -16
- package/src/templates/agents/claude-code/skills/orchestrator/selection-matrix.md +69 -64
- package/src/templates/agents/claude-code/skills/performance-engineer/optimization-playbook.md +47 -47
- package/src/templates/agents/claude-code/skills/performance-optimizer/SKILL.md +69 -0
- package/src/templates/agents/claude-code/skills/performance-optimizer/benchmark-template.md +63 -45
- package/src/templates/agents/claude-code/skills/performance-optimizer/optimization-patterns.md +33 -35
- package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +7 -6
- package/src/templates/agents/claude-code/skills/project-manager/agile-ceremonies.md +47 -28
- package/src/templates/agents/claude-code/skills/project-manager/project-templates.md +94 -78
- package/src/templates/agents/claude-code/skills/quality-assurance/SKILL.md +20 -17
- package/src/templates/agents/claude-code/skills/quality-assurance/qa-plan-template.md +63 -49
- package/src/templates/agents/claude-code/skills/release-coordinator/SKILL.md +5 -5
- package/src/templates/agents/claude-code/skills/release-coordinator/feature-flag-guide.md +30 -26
- package/src/templates/agents/claude-code/skills/release-coordinator/release-plan-template.md +67 -35
- package/src/templates/agents/claude-code/skills/requirements-analyst/ears-format.md +54 -42
- package/src/templates/agents/claude-code/skills/requirements-analyst/validation-rules.md +36 -33
- package/src/templates/agents/claude-code/skills/security-auditor/SKILL.md +77 -19
- package/src/templates/agents/claude-code/skills/security-auditor/audit-checklists.md +24 -24
- package/src/templates/agents/claude-code/skills/security-auditor/owasp-top-10.md +61 -20
- package/src/templates/agents/claude-code/skills/security-auditor/vulnerability-patterns.md +43 -11
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/incident-response-template.md +55 -25
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/observability-patterns.md +78 -68
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/slo-sli-guide.md +73 -53
- package/src/templates/agents/claude-code/skills/software-developer/solid-principles.md +83 -37
- package/src/templates/agents/claude-code/skills/software-developer/test-first-workflow.md +38 -31
- package/src/templates/agents/claude-code/skills/steering/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/steering/auto-update-rules.md +31 -0
- package/src/templates/agents/claude-code/skills/system-architect/adr-template.md +25 -7
- package/src/templates/agents/claude-code/skills/system-architect/c4-model-guide.md +74 -61
- package/src/templates/agents/claude-code/skills/technical-writer/doc-templates/documentation-templates.md +70 -52
- package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +2 -0
- package/src/templates/agents/claude-code/skills/test-engineer/ears-test-mapping.md +75 -71
- package/src/templates/agents/claude-code/skills/test-engineer/test-types.md +85 -63
- package/src/templates/agents/claude-code/skills/traceability-auditor/coverage-matrix-template.md +39 -36
- package/src/templates/agents/claude-code/skills/traceability-auditor/gap-detection-rules.md +22 -17
- package/src/templates/agents/claude-code/skills/ui-ux-designer/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/ui-ux-designer/accessibility-guidelines.md +49 -75
- package/src/templates/agents/claude-code/skills/ui-ux-designer/design-system-components.md +71 -59
- package/src/templates/agents/codex/AGENTS.md +74 -42
- package/src/templates/agents/cursor/AGENTS.md +74 -42
- package/src/templates/agents/gemini-cli/GEMINI.md +74 -42
- package/src/templates/agents/github-copilot/AGENTS.md +83 -51
- package/src/templates/agents/qwen-code/QWEN.md +74 -42
- package/src/templates/agents/windsurf/AGENTS.md +74 -42
- package/src/templates/architectures/README.md +41 -0
- package/src/templates/architectures/clean-architecture/README.md +113 -0
- package/src/templates/architectures/event-driven/README.md +162 -0
- package/src/templates/architectures/hexagonal/README.md +130 -0
- package/src/templates/index.js +6 -1
- package/src/templates/locale-manager.js +16 -16
- package/src/templates/shared/delta-spec-template.md +20 -13
- package/src/templates/shared/github-actions/musubi-issue-resolver.yml +5 -5
- package/src/templates/shared/github-actions/musubi-security-check.yml +3 -3
- package/src/templates/shared/github-actions/musubi-validate.yml +4 -4
- package/src/templates/shared/steering/structure.md +95 -0
- package/src/templates/skills/browser-agent.md +21 -16
- package/src/templates/skills/web-gui.md +8 -0
- package/src/templates/template-constraints.js +50 -53
- package/src/validators/advanced-validation.js +30 -36
- package/src/validators/constitutional-validator.js +77 -73
- package/src/validators/critic-system.js +49 -59
- package/src/validators/delta-format.js +59 -55
- package/src/validators/traceability-validator.js +7 -11
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Skill Executor - Execute skills with priority, retry, and guardrails
|
|
3
3
|
* Sprint 3.2: Skill System Architecture
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
5
|
* Features:
|
|
6
6
|
* - P-label priority execution (P0-P3)
|
|
7
7
|
* - Parallel and sequential execution
|
|
@@ -23,7 +23,7 @@ const ExecutionStatus = {
|
|
|
23
23
|
FAILED: 'failed',
|
|
24
24
|
CANCELLED: 'cancelled',
|
|
25
25
|
TIMEOUT: 'timeout',
|
|
26
|
-
SKIPPED: 'skipped'
|
|
26
|
+
SKIPPED: 'skipped',
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
/**
|
|
@@ -55,7 +55,7 @@ class ExecutionResult {
|
|
|
55
55
|
error: this.error,
|
|
56
56
|
duration: this.duration,
|
|
57
57
|
attempts: this.attempts,
|
|
58
|
-
metadata: this.metadata
|
|
58
|
+
metadata: this.metadata,
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -96,7 +96,7 @@ class ExecutionContext {
|
|
|
96
96
|
return new ExecutionContext({
|
|
97
97
|
...options,
|
|
98
98
|
parentContext: this,
|
|
99
|
-
variables: options.variables || {}
|
|
99
|
+
variables: options.variables || {},
|
|
100
100
|
});
|
|
101
101
|
}
|
|
102
102
|
}
|
|
@@ -107,27 +107,27 @@ class ExecutionContext {
|
|
|
107
107
|
class IOValidator {
|
|
108
108
|
constructor() {
|
|
109
109
|
this.typeValidators = {
|
|
110
|
-
string:
|
|
111
|
-
number:
|
|
112
|
-
boolean:
|
|
113
|
-
array:
|
|
114
|
-
object:
|
|
115
|
-
any: () => true
|
|
110
|
+
string: v => typeof v === 'string',
|
|
111
|
+
number: v => typeof v === 'number' && !isNaN(v),
|
|
112
|
+
boolean: v => typeof v === 'boolean',
|
|
113
|
+
array: v => Array.isArray(v),
|
|
114
|
+
object: v => typeof v === 'object' && v !== null && !Array.isArray(v),
|
|
115
|
+
any: () => true,
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
validateInput(input, schema) {
|
|
120
120
|
const errors = [];
|
|
121
|
-
|
|
121
|
+
|
|
122
122
|
for (const field of schema) {
|
|
123
123
|
const value = input[field.name];
|
|
124
|
-
|
|
124
|
+
|
|
125
125
|
// Required check
|
|
126
126
|
if (field.required && (value === undefined || value === null)) {
|
|
127
127
|
errors.push(`Missing required input: ${field.name}`);
|
|
128
128
|
continue;
|
|
129
129
|
}
|
|
130
|
-
|
|
130
|
+
|
|
131
131
|
// Type check
|
|
132
132
|
if (value !== undefined && value !== null && field.type) {
|
|
133
133
|
const validator = this.typeValidators[field.type];
|
|
@@ -135,7 +135,7 @@ class IOValidator {
|
|
|
135
135
|
errors.push(`Invalid type for ${field.name}: expected ${field.type}`);
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
|
-
|
|
138
|
+
|
|
139
139
|
// Custom validation
|
|
140
140
|
if (field.validate && value !== undefined) {
|
|
141
141
|
try {
|
|
@@ -148,23 +148,23 @@ class IOValidator {
|
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
|
-
|
|
151
|
+
|
|
152
152
|
return {
|
|
153
153
|
valid: errors.length === 0,
|
|
154
|
-
errors
|
|
154
|
+
errors,
|
|
155
155
|
};
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
validateOutput(output, schema) {
|
|
159
159
|
const errors = [];
|
|
160
|
-
|
|
160
|
+
|
|
161
161
|
for (const field of schema) {
|
|
162
162
|
const value = output?.[field.name];
|
|
163
|
-
|
|
163
|
+
|
|
164
164
|
if (field.required && (value === undefined || value === null)) {
|
|
165
165
|
errors.push(`Missing required output: ${field.name}`);
|
|
166
166
|
}
|
|
167
|
-
|
|
167
|
+
|
|
168
168
|
if (value !== undefined && value !== null && field.type) {
|
|
169
169
|
const validator = this.typeValidators[field.type];
|
|
170
170
|
if (validator && !validator(value)) {
|
|
@@ -172,10 +172,10 @@ class IOValidator {
|
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
|
-
|
|
175
|
+
|
|
176
176
|
return {
|
|
177
177
|
valid: errors.length === 0,
|
|
178
|
-
errors
|
|
178
|
+
errors,
|
|
179
179
|
};
|
|
180
180
|
}
|
|
181
181
|
}
|
|
@@ -192,21 +192,21 @@ class SkillExecutor extends EventEmitter {
|
|
|
192
192
|
this.activeExecutions = new Map();
|
|
193
193
|
this.executionHistory = [];
|
|
194
194
|
this.maxHistorySize = options.maxHistorySize || 1000;
|
|
195
|
-
|
|
195
|
+
|
|
196
196
|
// Hooks
|
|
197
197
|
this.hooks = {
|
|
198
198
|
beforeExecute: options.beforeExecute || [],
|
|
199
199
|
afterExecute: options.afterExecute || [],
|
|
200
|
-
onError: options.onError || []
|
|
200
|
+
onError: options.onError || [],
|
|
201
201
|
};
|
|
202
|
-
|
|
202
|
+
|
|
203
203
|
// Options
|
|
204
204
|
this.options = {
|
|
205
205
|
defaultTimeout: options.defaultTimeout || 30000,
|
|
206
206
|
maxConcurrent: options.maxConcurrent || 10,
|
|
207
|
-
enableMetrics: options.enableMetrics !== false
|
|
207
|
+
enableMetrics: options.enableMetrics !== false,
|
|
208
208
|
};
|
|
209
|
-
|
|
209
|
+
|
|
210
210
|
this._concurrentCount = 0;
|
|
211
211
|
}
|
|
212
212
|
|
|
@@ -218,58 +218,58 @@ class SkillExecutor extends EventEmitter {
|
|
|
218
218
|
if (!skillEntry) {
|
|
219
219
|
throw new Error(`Skill '${skillId}' not found`);
|
|
220
220
|
}
|
|
221
|
-
|
|
221
|
+
|
|
222
222
|
const { metadata, handler } = skillEntry;
|
|
223
|
-
|
|
223
|
+
|
|
224
224
|
if (!handler) {
|
|
225
225
|
throw new Error(`Skill '${skillId}' has no handler`);
|
|
226
226
|
}
|
|
227
|
-
|
|
227
|
+
|
|
228
228
|
// Create execution context
|
|
229
229
|
const context = new ExecutionContext({
|
|
230
230
|
skillId,
|
|
231
231
|
input,
|
|
232
232
|
variables: options.variables,
|
|
233
|
-
metadata: options.metadata
|
|
233
|
+
metadata: options.metadata,
|
|
234
234
|
});
|
|
235
|
-
|
|
235
|
+
|
|
236
236
|
// Create result
|
|
237
237
|
const result = new ExecutionResult({
|
|
238
238
|
skillId,
|
|
239
|
-
status: ExecutionStatus.PENDING
|
|
239
|
+
status: ExecutionStatus.PENDING,
|
|
240
240
|
});
|
|
241
|
-
|
|
241
|
+
|
|
242
242
|
// Track execution
|
|
243
243
|
this.activeExecutions.set(context.executionId, { context, result, cancelled: false });
|
|
244
|
-
|
|
244
|
+
|
|
245
245
|
try {
|
|
246
246
|
// Check concurrency limit
|
|
247
247
|
if (this._concurrentCount >= this.options.maxConcurrent) {
|
|
248
248
|
await this._waitForSlot();
|
|
249
249
|
}
|
|
250
250
|
this._concurrentCount++;
|
|
251
|
-
|
|
251
|
+
|
|
252
252
|
// Validate input
|
|
253
253
|
const inputValidation = this.validator.validateInput(input, metadata.inputs);
|
|
254
254
|
if (!inputValidation.valid) {
|
|
255
255
|
throw new Error(`Input validation failed: ${inputValidation.errors.join(', ')}`);
|
|
256
256
|
}
|
|
257
|
-
|
|
257
|
+
|
|
258
258
|
// Run guardrails (pre-execution)
|
|
259
259
|
await this._runGuardrails('pre', { skillId, input, context });
|
|
260
|
-
|
|
260
|
+
|
|
261
261
|
// Run beforeExecute hooks
|
|
262
262
|
for (const hook of this.hooks.beforeExecute) {
|
|
263
263
|
await hook(context, metadata);
|
|
264
264
|
}
|
|
265
|
-
|
|
265
|
+
|
|
266
266
|
// Start execution
|
|
267
267
|
result.status = ExecutionStatus.RUNNING;
|
|
268
268
|
result.startTime = Date.now();
|
|
269
269
|
context.startTime = result.startTime;
|
|
270
|
-
|
|
270
|
+
|
|
271
271
|
this.emit('execution-started', { executionId: context.executionId, skillId });
|
|
272
|
-
|
|
272
|
+
|
|
273
273
|
// Execute with retry
|
|
274
274
|
const output = await this._executeWithRetry(
|
|
275
275
|
handler,
|
|
@@ -278,68 +278,66 @@ class SkillExecutor extends EventEmitter {
|
|
|
278
278
|
options.timeout || metadata.timeout || this.options.defaultTimeout,
|
|
279
279
|
result
|
|
280
280
|
);
|
|
281
|
-
|
|
281
|
+
|
|
282
282
|
// Validate output
|
|
283
283
|
const outputValidation = this.validator.validateOutput(output, metadata.outputs);
|
|
284
284
|
if (!outputValidation.valid) {
|
|
285
285
|
throw new Error(`Output validation failed: ${outputValidation.errors.join(', ')}`);
|
|
286
286
|
}
|
|
287
|
-
|
|
287
|
+
|
|
288
288
|
// Run guardrails (post-execution)
|
|
289
289
|
await this._runGuardrails('post', { skillId, input, output, context });
|
|
290
|
-
|
|
290
|
+
|
|
291
291
|
// Complete
|
|
292
292
|
result.status = ExecutionStatus.COMPLETED;
|
|
293
293
|
result.output = output;
|
|
294
294
|
result.endTime = Date.now();
|
|
295
295
|
result.duration = result.endTime - result.startTime;
|
|
296
|
-
|
|
296
|
+
|
|
297
297
|
// Run afterExecute hooks
|
|
298
298
|
for (const hook of this.hooks.afterExecute) {
|
|
299
299
|
await hook(context, result);
|
|
300
300
|
}
|
|
301
|
-
|
|
301
|
+
|
|
302
302
|
// Record stats
|
|
303
303
|
if (this.options.enableMetrics) {
|
|
304
304
|
this.registry.recordExecution(skillId, true, result.duration);
|
|
305
305
|
}
|
|
306
|
-
|
|
307
|
-
this.emit('execution-completed', {
|
|
308
|
-
executionId: context.executionId,
|
|
309
|
-
skillId,
|
|
310
|
-
duration: result.duration
|
|
306
|
+
|
|
307
|
+
this.emit('execution-completed', {
|
|
308
|
+
executionId: context.executionId,
|
|
309
|
+
skillId,
|
|
310
|
+
duration: result.duration,
|
|
311
311
|
});
|
|
312
|
-
|
|
313
312
|
} catch (error) {
|
|
314
|
-
result.status = this.activeExecutions.get(context.executionId)?.cancelled
|
|
315
|
-
? ExecutionStatus.CANCELLED
|
|
313
|
+
result.status = this.activeExecutions.get(context.executionId)?.cancelled
|
|
314
|
+
? ExecutionStatus.CANCELLED
|
|
316
315
|
: ExecutionStatus.FAILED;
|
|
317
316
|
result.error = error.message;
|
|
318
317
|
result.endTime = Date.now();
|
|
319
318
|
result.duration = result.startTime ? result.endTime - result.startTime : 0;
|
|
320
|
-
|
|
319
|
+
|
|
321
320
|
// Run onError hooks
|
|
322
321
|
for (const hook of this.hooks.onError) {
|
|
323
322
|
await hook(error, context, result);
|
|
324
323
|
}
|
|
325
|
-
|
|
324
|
+
|
|
326
325
|
// Record stats
|
|
327
326
|
if (this.options.enableMetrics) {
|
|
328
327
|
this.registry.recordExecution(skillId, false, result.duration);
|
|
329
328
|
}
|
|
330
|
-
|
|
331
|
-
this.emit('execution-failed', {
|
|
332
|
-
executionId: context.executionId,
|
|
333
|
-
skillId,
|
|
334
|
-
error: error.message
|
|
329
|
+
|
|
330
|
+
this.emit('execution-failed', {
|
|
331
|
+
executionId: context.executionId,
|
|
332
|
+
skillId,
|
|
333
|
+
error: error.message,
|
|
335
334
|
});
|
|
336
|
-
|
|
337
335
|
} finally {
|
|
338
336
|
this._concurrentCount--;
|
|
339
337
|
this.activeExecutions.delete(context.executionId);
|
|
340
338
|
this._addToHistory(result);
|
|
341
339
|
}
|
|
342
|
-
|
|
340
|
+
|
|
343
341
|
return result;
|
|
344
342
|
}
|
|
345
343
|
|
|
@@ -352,7 +350,7 @@ class SkillExecutor extends EventEmitter {
|
|
|
352
350
|
const priorityOrder = { P0: 0, P1: 1, P2: 2, P3: 3 };
|
|
353
351
|
return (priorityOrder[a.priority] || 2) - (priorityOrder[b.priority] || 2);
|
|
354
352
|
});
|
|
355
|
-
|
|
353
|
+
|
|
356
354
|
// Group by priority
|
|
357
355
|
const priorityGroups = new Map();
|
|
358
356
|
for (const task of sortedTasks) {
|
|
@@ -362,51 +360,52 @@ class SkillExecutor extends EventEmitter {
|
|
|
362
360
|
}
|
|
363
361
|
priorityGroups.get(priority).push(task);
|
|
364
362
|
}
|
|
365
|
-
|
|
363
|
+
|
|
366
364
|
const results = new Map();
|
|
367
|
-
|
|
365
|
+
|
|
368
366
|
// Execute P0 first (blocking)
|
|
369
367
|
if (priorityGroups.has('P0')) {
|
|
370
368
|
for (const task of priorityGroups.get('P0')) {
|
|
371
369
|
const result = await this.execute(task.skillId, task.input, task.options);
|
|
372
370
|
results.set(task.skillId, result);
|
|
373
|
-
|
|
371
|
+
|
|
374
372
|
// P0 failure stops everything
|
|
375
373
|
if (!result.success && options.failFast !== false) {
|
|
376
374
|
return { results: Object.fromEntries(results), partial: true };
|
|
377
375
|
}
|
|
378
376
|
}
|
|
379
377
|
}
|
|
380
|
-
|
|
378
|
+
|
|
381
379
|
// Execute P1-P3 in parallel within each priority level
|
|
382
380
|
for (const priority of ['P1', 'P2', 'P3']) {
|
|
383
381
|
if (priorityGroups.has(priority)) {
|
|
384
382
|
const groupTasks = priorityGroups.get(priority);
|
|
385
383
|
const groupResults = await Promise.allSettled(
|
|
386
|
-
groupTasks.map(task =>
|
|
387
|
-
this.execute(task.skillId, task.input, task.options)
|
|
388
|
-
)
|
|
384
|
+
groupTasks.map(task => this.execute(task.skillId, task.input, task.options))
|
|
389
385
|
);
|
|
390
|
-
|
|
386
|
+
|
|
391
387
|
groupTasks.forEach((task, index) => {
|
|
392
388
|
const settled = groupResults[index];
|
|
393
389
|
if (settled.status === 'fulfilled') {
|
|
394
390
|
results.set(task.skillId, settled.value);
|
|
395
391
|
} else {
|
|
396
|
-
results.set(
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
392
|
+
results.set(
|
|
393
|
+
task.skillId,
|
|
394
|
+
new ExecutionResult({
|
|
395
|
+
skillId: task.skillId,
|
|
396
|
+
status: ExecutionStatus.FAILED,
|
|
397
|
+
error: settled.reason?.message || 'Unknown error',
|
|
398
|
+
})
|
|
399
|
+
);
|
|
401
400
|
}
|
|
402
401
|
});
|
|
403
402
|
}
|
|
404
403
|
}
|
|
405
|
-
|
|
404
|
+
|
|
406
405
|
return {
|
|
407
406
|
results: Object.fromEntries(results),
|
|
408
407
|
partial: false,
|
|
409
|
-
summary: this._summarizeResults(results)
|
|
408
|
+
summary: this._summarizeResults(results),
|
|
410
409
|
};
|
|
411
410
|
}
|
|
412
411
|
|
|
@@ -415,20 +414,20 @@ class SkillExecutor extends EventEmitter {
|
|
|
415
414
|
*/
|
|
416
415
|
async executeSequential(tasks, options = {}) {
|
|
417
416
|
const results = [];
|
|
418
|
-
|
|
417
|
+
|
|
419
418
|
for (const task of tasks) {
|
|
420
419
|
const result = await this.execute(task.skillId, task.input, task.options);
|
|
421
420
|
results.push(result);
|
|
422
|
-
|
|
421
|
+
|
|
423
422
|
if (!result.success && options.stopOnError !== false) {
|
|
424
423
|
break;
|
|
425
424
|
}
|
|
426
425
|
}
|
|
427
|
-
|
|
426
|
+
|
|
428
427
|
return {
|
|
429
428
|
results,
|
|
430
429
|
completed: results.length === tasks.length,
|
|
431
|
-
summary: this._summarizeResults(new Map(results.map(r => [r.skillId, r])))
|
|
430
|
+
summary: this._summarizeResults(new Map(results.map(r => [r.skillId, r]))),
|
|
432
431
|
};
|
|
433
432
|
}
|
|
434
433
|
|
|
@@ -438,29 +437,28 @@ class SkillExecutor extends EventEmitter {
|
|
|
438
437
|
async executeWithDependencies(skillId, input = {}, options = {}) {
|
|
439
438
|
const order = this.registry.resolveDependencies(skillId);
|
|
440
439
|
const results = new Map();
|
|
441
|
-
|
|
440
|
+
|
|
442
441
|
for (const depSkillId of order) {
|
|
443
442
|
// Use output from dependencies as input
|
|
444
|
-
const depInput =
|
|
445
|
-
? input
|
|
446
|
-
|
|
447
|
-
|
|
443
|
+
const depInput =
|
|
444
|
+
depSkillId === skillId ? input : this._mergeInputFromResults(results, depSkillId);
|
|
445
|
+
|
|
448
446
|
const result = await this.execute(depSkillId, depInput, options);
|
|
449
447
|
results.set(depSkillId, result);
|
|
450
|
-
|
|
448
|
+
|
|
451
449
|
if (!result.success) {
|
|
452
450
|
return {
|
|
453
451
|
results: Object.fromEntries(results),
|
|
454
452
|
failed: true,
|
|
455
|
-
failedAt: depSkillId
|
|
453
|
+
failedAt: depSkillId,
|
|
456
454
|
};
|
|
457
455
|
}
|
|
458
456
|
}
|
|
459
|
-
|
|
457
|
+
|
|
460
458
|
return {
|
|
461
459
|
results: Object.fromEntries(results),
|
|
462
460
|
failed: false,
|
|
463
|
-
finalResult: results.get(skillId)
|
|
461
|
+
finalResult: results.get(skillId),
|
|
464
462
|
};
|
|
465
463
|
}
|
|
466
464
|
|
|
@@ -522,46 +520,46 @@ class SkillExecutor extends EventEmitter {
|
|
|
522
520
|
const maxRetries = retryPolicy?.maxRetries || 0;
|
|
523
521
|
const backoffMs = retryPolicy?.backoffMs || 1000;
|
|
524
522
|
const backoffMultiplier = retryPolicy?.backoffMultiplier || 2;
|
|
525
|
-
|
|
523
|
+
|
|
526
524
|
let lastError;
|
|
527
525
|
let currentBackoff = backoffMs;
|
|
528
|
-
|
|
526
|
+
|
|
529
527
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
530
528
|
result.attempts = attempt + 1;
|
|
531
|
-
|
|
529
|
+
|
|
532
530
|
// Check if cancelled
|
|
533
531
|
const execution = this.activeExecutions.get(context.executionId);
|
|
534
532
|
if (execution?.cancelled) {
|
|
535
533
|
throw new Error('Execution cancelled');
|
|
536
534
|
}
|
|
537
|
-
|
|
535
|
+
|
|
538
536
|
try {
|
|
539
537
|
// Execute with timeout
|
|
540
538
|
const output = await this._executeWithTimeout(handler, context, timeout);
|
|
541
539
|
return output;
|
|
542
540
|
} catch (error) {
|
|
543
541
|
lastError = error;
|
|
544
|
-
|
|
542
|
+
|
|
545
543
|
// Check if retryable
|
|
546
544
|
if (!this._isRetryable(error)) {
|
|
547
545
|
throw error;
|
|
548
546
|
}
|
|
549
|
-
|
|
547
|
+
|
|
550
548
|
if (attempt < maxRetries) {
|
|
551
|
-
this.emit('execution-retry', {
|
|
552
|
-
executionId: context.executionId,
|
|
549
|
+
this.emit('execution-retry', {
|
|
550
|
+
executionId: context.executionId,
|
|
553
551
|
skillId: context.skillId,
|
|
554
552
|
attempt: attempt + 1,
|
|
555
553
|
maxRetries,
|
|
556
|
-
nextRetryMs: currentBackoff
|
|
554
|
+
nextRetryMs: currentBackoff,
|
|
557
555
|
});
|
|
558
|
-
|
|
556
|
+
|
|
559
557
|
await this._sleep(currentBackoff);
|
|
560
558
|
currentBackoff *= backoffMultiplier;
|
|
561
559
|
}
|
|
562
560
|
}
|
|
563
561
|
}
|
|
564
|
-
|
|
562
|
+
|
|
565
563
|
throw lastError;
|
|
566
564
|
}
|
|
567
565
|
|
|
@@ -570,7 +568,7 @@ class SkillExecutor extends EventEmitter {
|
|
|
570
568
|
const timeoutId = setTimeout(() => {
|
|
571
569
|
reject(new Error(`Execution timeout after ${timeout}ms`));
|
|
572
570
|
}, timeout);
|
|
573
|
-
|
|
571
|
+
|
|
574
572
|
Promise.resolve(handler(context.input, context))
|
|
575
573
|
.then(result => {
|
|
576
574
|
clearTimeout(timeoutId);
|
|
@@ -599,7 +597,7 @@ class SkillExecutor extends EventEmitter {
|
|
|
599
597
|
'Execution cancelled',
|
|
600
598
|
'Input validation failed',
|
|
601
599
|
'Output validation failed',
|
|
602
|
-
'Guardrail'
|
|
600
|
+
'Guardrail',
|
|
603
601
|
];
|
|
604
602
|
return !nonRetryable.some(msg => error.message.includes(msg));
|
|
605
603
|
}
|
|
@@ -625,7 +623,7 @@ class SkillExecutor extends EventEmitter {
|
|
|
625
623
|
let success = 0;
|
|
626
624
|
let failed = 0;
|
|
627
625
|
let totalDuration = 0;
|
|
628
|
-
|
|
626
|
+
|
|
629
627
|
for (const result of resultsMap.values()) {
|
|
630
628
|
if (result.success) {
|
|
631
629
|
success++;
|
|
@@ -634,17 +632,17 @@ class SkillExecutor extends EventEmitter {
|
|
|
634
632
|
}
|
|
635
633
|
totalDuration += result.duration || 0;
|
|
636
634
|
}
|
|
637
|
-
|
|
635
|
+
|
|
638
636
|
return {
|
|
639
637
|
total: resultsMap.size,
|
|
640
638
|
success,
|
|
641
639
|
failed,
|
|
642
640
|
totalDuration,
|
|
643
|
-
averageDuration: resultsMap.size > 0 ? totalDuration / resultsMap.size : 0
|
|
641
|
+
averageDuration: resultsMap.size > 0 ? totalDuration / resultsMap.size : 0,
|
|
644
642
|
};
|
|
645
643
|
}
|
|
646
644
|
|
|
647
|
-
_mergeInputFromResults(results,
|
|
645
|
+
_mergeInputFromResults(results, _skillId) {
|
|
648
646
|
// Simple merge - could be extended with explicit mappings
|
|
649
647
|
const merged = {};
|
|
650
648
|
for (const result of results.values()) {
|
|
@@ -661,5 +659,5 @@ module.exports = {
|
|
|
661
659
|
ExecutionResult,
|
|
662
660
|
ExecutionContext,
|
|
663
661
|
ExecutionStatus,
|
|
664
|
-
IOValidator
|
|
662
|
+
IOValidator,
|
|
665
663
|
};
|