aios-core 3.7.0 → 3.9.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/.aios-core/core/session/context-detector.js +3 -0
- package/.aios-core/core/session/context-loader.js +154 -0
- package/.aios-core/data/learned-patterns.yaml +3 -0
- package/.aios-core/data/workflow-patterns.yaml +347 -3
- package/.aios-core/development/agents/dev.md +6 -0
- package/.aios-core/development/agents/squad-creator.md +30 -0
- package/.aios-core/development/scripts/squad/squad-analyzer.js +638 -0
- package/.aios-core/development/scripts/squad/squad-extender.js +871 -0
- package/.aios-core/development/scripts/squad/squad-generator.js +107 -19
- package/.aios-core/development/scripts/squad/squad-migrator.js +3 -5
- package/.aios-core/development/scripts/squad/squad-validator.js +98 -0
- package/.aios-core/development/tasks/next.md +294 -0
- package/.aios-core/development/tasks/patterns.md +334 -0
- package/.aios-core/development/tasks/squad-creator-analyze.md +315 -0
- package/.aios-core/development/tasks/squad-creator-create.md +26 -3
- package/.aios-core/development/tasks/squad-creator-extend.md +411 -0
- package/.aios-core/development/tasks/squad-creator-validate.md +9 -1
- package/.aios-core/development/tasks/waves.md +205 -0
- package/.aios-core/development/templates/squad/agent-template.md +69 -0
- package/.aios-core/development/templates/squad/checklist-template.md +82 -0
- package/.aios-core/development/templates/squad/data-template.yaml +105 -0
- package/.aios-core/development/templates/squad/script-template.js +179 -0
- package/.aios-core/development/templates/squad/task-template.md +125 -0
- package/.aios-core/development/templates/squad/template-template.md +97 -0
- package/.aios-core/development/templates/squad/tool-template.js +103 -0
- package/.aios-core/development/templates/squad/workflow-template.yaml +108 -0
- package/.aios-core/infrastructure/scripts/test-generator.js +8 -8
- package/.aios-core/infrastructure/scripts/test-quality-assessment.js +5 -5
- package/.aios-core/infrastructure/scripts/test-utilities.js +3 -3
- package/.aios-core/install-manifest.yaml +97 -33
- package/.aios-core/quality/metrics-collector.js +27 -0
- package/.aios-core/scripts/session-context-loader.js +13 -254
- package/.aios-core/scripts/test-template-system.js +6 -6
- package/.aios-core/utils/aios-validator.js +25 -0
- package/.aios-core/workflow-intelligence/__tests__/confidence-scorer.test.js +334 -0
- package/.aios-core/workflow-intelligence/__tests__/integration.test.js +337 -0
- package/.aios-core/workflow-intelligence/__tests__/suggestion-engine.test.js +431 -0
- package/.aios-core/workflow-intelligence/__tests__/wave-analyzer.test.js +458 -0
- package/.aios-core/workflow-intelligence/__tests__/workflow-registry.test.js +302 -0
- package/.aios-core/workflow-intelligence/engine/confidence-scorer.js +305 -0
- package/.aios-core/workflow-intelligence/engine/output-formatter.js +285 -0
- package/.aios-core/workflow-intelligence/engine/suggestion-engine.js +603 -0
- package/.aios-core/workflow-intelligence/engine/wave-analyzer.js +676 -0
- package/.aios-core/workflow-intelligence/index.js +327 -0
- package/.aios-core/workflow-intelligence/learning/capture-hook.js +147 -0
- package/.aios-core/workflow-intelligence/learning/index.js +230 -0
- package/.aios-core/workflow-intelligence/learning/pattern-capture.js +340 -0
- package/.aios-core/workflow-intelligence/learning/pattern-store.js +498 -0
- package/.aios-core/workflow-intelligence/learning/pattern-validator.js +309 -0
- package/.aios-core/workflow-intelligence/registry/workflow-registry.js +358 -0
- package/package.json +1 -1
- package/src/installer/brownfield-upgrader.js +1 -1
- package/bin/aios-init.backup-v1.1.4.js +0 -352
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module workflow-intelligence
|
|
3
|
+
* @description Workflow Intelligence System (WIS) public API
|
|
4
|
+
* @story WIS-2 - Workflow Registry Enhancement
|
|
5
|
+
* @story WIS-4 - Wave Analysis Engine
|
|
6
|
+
* @version 1.1.0
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const wis = require('./.aios-core/workflow-intelligence');
|
|
10
|
+
*
|
|
11
|
+
* // Get workflow suggestions
|
|
12
|
+
* const suggestions = wis.getSuggestions({
|
|
13
|
+
* lastCommand: 'create-story',
|
|
14
|
+
* lastCommands: ['create-epic', 'create-story'],
|
|
15
|
+
* agentId: '@sm'
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* // Find matching workflow
|
|
19
|
+
* const workflow = wis.matchWorkflow(['create-epic', 'create-story']);
|
|
20
|
+
*
|
|
21
|
+
* // Get next steps for a state
|
|
22
|
+
* const nextSteps = wis.getNextSteps('epic_creation', 'stories_created');
|
|
23
|
+
*
|
|
24
|
+
* // Analyze waves for parallel execution (WIS-4)
|
|
25
|
+
* const waves = wis.analyzeWaves('story_development');
|
|
26
|
+
* console.log(waves.waves); // Wave groupings
|
|
27
|
+
* console.log(waves.criticalPath); // Critical path
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
'use strict';
|
|
31
|
+
|
|
32
|
+
const {
|
|
33
|
+
WorkflowRegistry,
|
|
34
|
+
createWorkflowRegistry,
|
|
35
|
+
DEFAULT_CACHE_TTL,
|
|
36
|
+
DEFAULT_PATTERNS_PATH
|
|
37
|
+
} = require('./registry/workflow-registry');
|
|
38
|
+
|
|
39
|
+
const {
|
|
40
|
+
ConfidenceScorer,
|
|
41
|
+
createConfidenceScorer,
|
|
42
|
+
SCORING_WEIGHTS
|
|
43
|
+
} = require('./engine/confidence-scorer');
|
|
44
|
+
|
|
45
|
+
const {
|
|
46
|
+
SuggestionEngine,
|
|
47
|
+
createSuggestionEngine,
|
|
48
|
+
SUGGESTION_CACHE_TTL,
|
|
49
|
+
LOW_CONFIDENCE_THRESHOLD
|
|
50
|
+
} = require('./engine/suggestion-engine');
|
|
51
|
+
|
|
52
|
+
const {
|
|
53
|
+
WaveAnalyzer,
|
|
54
|
+
CircularDependencyError,
|
|
55
|
+
createWaveAnalyzer,
|
|
56
|
+
analyzeWaves,
|
|
57
|
+
DEFAULT_TASK_DURATIONS
|
|
58
|
+
} = require('./engine/wave-analyzer');
|
|
59
|
+
|
|
60
|
+
const outputFormatter = require('./engine/output-formatter');
|
|
61
|
+
|
|
62
|
+
// Learning module (WIS-5)
|
|
63
|
+
let learningModule = null;
|
|
64
|
+
try {
|
|
65
|
+
learningModule = require('./learning');
|
|
66
|
+
} catch (error) {
|
|
67
|
+
// Learning module not yet available
|
|
68
|
+
learningModule = null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Singleton instances for default usage
|
|
73
|
+
*/
|
|
74
|
+
let defaultRegistry = null;
|
|
75
|
+
let defaultScorer = null;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Get or create the default registry instance
|
|
79
|
+
* @returns {WorkflowRegistry} Default registry instance
|
|
80
|
+
*/
|
|
81
|
+
function getDefaultRegistry() {
|
|
82
|
+
if (!defaultRegistry) {
|
|
83
|
+
defaultRegistry = createWorkflowRegistry();
|
|
84
|
+
}
|
|
85
|
+
return defaultRegistry;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Get or create the default scorer instance
|
|
90
|
+
* @returns {ConfidenceScorer} Default scorer instance
|
|
91
|
+
*/
|
|
92
|
+
function getDefaultScorer() {
|
|
93
|
+
if (!defaultScorer) {
|
|
94
|
+
defaultScorer = createConfidenceScorer();
|
|
95
|
+
}
|
|
96
|
+
return defaultScorer;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Get workflow suggestions with confidence scores
|
|
101
|
+
* @param {Object} context - Current session context
|
|
102
|
+
* @param {string} context.lastCommand - Last executed command
|
|
103
|
+
* @param {string[]} context.lastCommands - Recent command history
|
|
104
|
+
* @param {string} context.agentId - Current active agent
|
|
105
|
+
* @param {Object} context.projectState - Current project state
|
|
106
|
+
* @returns {Object[]} Ranked suggestions with scores
|
|
107
|
+
*/
|
|
108
|
+
function getSuggestions(context) {
|
|
109
|
+
if (!context) {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const registry = getDefaultRegistry();
|
|
114
|
+
const scorer = getDefaultScorer();
|
|
115
|
+
|
|
116
|
+
// Find matching workflow
|
|
117
|
+
const commands = context.lastCommands || (context.lastCommand ? [context.lastCommand] : []);
|
|
118
|
+
const match = registry.matchWorkflow(commands);
|
|
119
|
+
|
|
120
|
+
if (!match) {
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Find current state
|
|
125
|
+
const currentState = registry.findCurrentState(match.name, context.lastCommand);
|
|
126
|
+
|
|
127
|
+
if (!currentState) {
|
|
128
|
+
// Return first state's suggestions if we can't determine current state
|
|
129
|
+
const transitions = registry.getAllTransitions(match.name);
|
|
130
|
+
const firstState = Object.keys(transitions)[0];
|
|
131
|
+
|
|
132
|
+
if (!firstState) {
|
|
133
|
+
return [];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return formatSuggestions(
|
|
137
|
+
registry.getNextSteps(match.name, firstState),
|
|
138
|
+
match,
|
|
139
|
+
firstState,
|
|
140
|
+
scorer,
|
|
141
|
+
context
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Get next steps for current state
|
|
146
|
+
const nextSteps = registry.getNextSteps(match.name, currentState);
|
|
147
|
+
|
|
148
|
+
return formatSuggestions(nextSteps, match, currentState, scorer, context);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Format and score suggestions
|
|
153
|
+
* @param {Object[]} nextSteps - Raw next steps from registry
|
|
154
|
+
* @param {Object} match - Workflow match info
|
|
155
|
+
* @param {string} state - Current state
|
|
156
|
+
* @param {ConfidenceScorer} scorer - Scorer instance
|
|
157
|
+
* @param {Object} context - Session context
|
|
158
|
+
* @returns {Object[]} Formatted and scored suggestions
|
|
159
|
+
*/
|
|
160
|
+
function formatSuggestions(nextSteps, match, state, scorer, context) {
|
|
161
|
+
if (!nextSteps || nextSteps.length === 0) {
|
|
162
|
+
return [];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const transition = getDefaultRegistry().getTransitions(match.name, state);
|
|
166
|
+
const baseConfidence = transition?.confidence || 0.5;
|
|
167
|
+
|
|
168
|
+
return nextSteps.map(step => {
|
|
169
|
+
const suggestion = {
|
|
170
|
+
command: step.command,
|
|
171
|
+
args_template: step.args_template,
|
|
172
|
+
description: step.description,
|
|
173
|
+
priority: step.priority,
|
|
174
|
+
workflow: match.name,
|
|
175
|
+
state: state,
|
|
176
|
+
trigger: transition?.trigger,
|
|
177
|
+
agentSequence: match.workflow.agent_sequence,
|
|
178
|
+
keyCommands: match.workflow.key_commands
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// Calculate confidence score
|
|
182
|
+
const score = scorer.score(suggestion, context);
|
|
183
|
+
|
|
184
|
+
// Blend base confidence with calculated score
|
|
185
|
+
const finalScore = (baseConfidence * 0.4) + (score * 0.6);
|
|
186
|
+
|
|
187
|
+
return {
|
|
188
|
+
...suggestion,
|
|
189
|
+
confidence: Math.round(finalScore * 100) / 100
|
|
190
|
+
};
|
|
191
|
+
}).sort((a, b) => b.confidence - a.confidence);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Match command history to a workflow
|
|
196
|
+
* @param {string[]} commands - Command history
|
|
197
|
+
* @returns {Object|null} Matching workflow or null
|
|
198
|
+
*/
|
|
199
|
+
function matchWorkflow(commands) {
|
|
200
|
+
return getDefaultRegistry().matchWorkflow(commands);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Get next steps for a workflow state
|
|
205
|
+
* @param {string} workflowName - Workflow name
|
|
206
|
+
* @param {string} state - Current state
|
|
207
|
+
* @returns {Object[]} Next step suggestions
|
|
208
|
+
*/
|
|
209
|
+
function getNextSteps(workflowName, state) {
|
|
210
|
+
return getDefaultRegistry().getNextSteps(workflowName, state);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Get transitions for a workflow state
|
|
215
|
+
* @param {string} workflowName - Workflow name
|
|
216
|
+
* @param {string} state - Current state
|
|
217
|
+
* @returns {Object|null} Transition or null
|
|
218
|
+
*/
|
|
219
|
+
function getTransitions(workflowName, state) {
|
|
220
|
+
return getDefaultRegistry().getTransitions(workflowName, state);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Get a workflow by name
|
|
225
|
+
* @param {string} name - Workflow name
|
|
226
|
+
* @returns {Object|null} Workflow or null
|
|
227
|
+
*/
|
|
228
|
+
function getWorkflow(name) {
|
|
229
|
+
return getDefaultRegistry().getWorkflow(name);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Get all workflow names
|
|
234
|
+
* @returns {string[]} Workflow names
|
|
235
|
+
*/
|
|
236
|
+
function getWorkflowNames() {
|
|
237
|
+
return getDefaultRegistry().getWorkflowNames();
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Get workflows by agent
|
|
242
|
+
* @param {string} agentId - Agent identifier
|
|
243
|
+
* @returns {Object[]} Workflows involving this agent
|
|
244
|
+
*/
|
|
245
|
+
function getWorkflowsByAgent(agentId) {
|
|
246
|
+
return getDefaultRegistry().getWorkflowsByAgent(agentId);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Find current state based on last command
|
|
251
|
+
* @param {string} workflowName - Workflow name
|
|
252
|
+
* @param {string} lastCommand - Last command
|
|
253
|
+
* @returns {string|null} Current state or null
|
|
254
|
+
*/
|
|
255
|
+
function findCurrentState(workflowName, lastCommand) {
|
|
256
|
+
return getDefaultRegistry().findCurrentState(workflowName, lastCommand);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Get registry statistics
|
|
261
|
+
* @returns {Object} Statistics
|
|
262
|
+
*/
|
|
263
|
+
function getStats() {
|
|
264
|
+
return getDefaultRegistry().getStats();
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Invalidate registry cache
|
|
269
|
+
*/
|
|
270
|
+
function invalidateCache() {
|
|
271
|
+
if (defaultRegistry) {
|
|
272
|
+
defaultRegistry.invalidateCache();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Reset singleton instances (for testing)
|
|
278
|
+
*/
|
|
279
|
+
function reset() {
|
|
280
|
+
defaultRegistry = null;
|
|
281
|
+
defaultScorer = null;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
module.exports = {
|
|
285
|
+
// High-level API
|
|
286
|
+
getSuggestions,
|
|
287
|
+
matchWorkflow,
|
|
288
|
+
getNextSteps,
|
|
289
|
+
getTransitions,
|
|
290
|
+
getWorkflow,
|
|
291
|
+
getWorkflowNames,
|
|
292
|
+
getWorkflowsByAgent,
|
|
293
|
+
findCurrentState,
|
|
294
|
+
getStats,
|
|
295
|
+
invalidateCache,
|
|
296
|
+
reset,
|
|
297
|
+
|
|
298
|
+
// Wave Analysis API (WIS-4)
|
|
299
|
+
analyzeWaves,
|
|
300
|
+
createWaveAnalyzer,
|
|
301
|
+
|
|
302
|
+
// Pattern Learning API (WIS-5)
|
|
303
|
+
learning: learningModule,
|
|
304
|
+
|
|
305
|
+
// Factory functions
|
|
306
|
+
createWorkflowRegistry,
|
|
307
|
+
createConfidenceScorer,
|
|
308
|
+
createSuggestionEngine,
|
|
309
|
+
|
|
310
|
+
// Classes (for advanced usage)
|
|
311
|
+
WorkflowRegistry,
|
|
312
|
+
ConfidenceScorer,
|
|
313
|
+
SuggestionEngine,
|
|
314
|
+
WaveAnalyzer,
|
|
315
|
+
CircularDependencyError,
|
|
316
|
+
|
|
317
|
+
// Output formatting (for *next task)
|
|
318
|
+
outputFormatter,
|
|
319
|
+
|
|
320
|
+
// Constants
|
|
321
|
+
SCORING_WEIGHTS,
|
|
322
|
+
DEFAULT_CACHE_TTL,
|
|
323
|
+
DEFAULT_PATTERNS_PATH,
|
|
324
|
+
SUGGESTION_CACHE_TTL,
|
|
325
|
+
LOW_CONFIDENCE_THRESHOLD,
|
|
326
|
+
DEFAULT_TASK_DURATIONS
|
|
327
|
+
};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module CaptureHook
|
|
3
|
+
* @description Task completion hook for pattern capture
|
|
4
|
+
* @story WIS-5 - Pattern Capture (Internal)
|
|
5
|
+
* @version 1.0.0
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // In task completion flow
|
|
9
|
+
* const { onTaskComplete } = require('./workflow-intelligence/learning/capture-hook');
|
|
10
|
+
* await onTaskComplete('develop', { sessionId: 'abc123', agentId: '@dev' });
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const { createPatternCapture } = require('./pattern-capture');
|
|
16
|
+
const { createPatternValidator } = require('./pattern-validator');
|
|
17
|
+
const { createPatternStore } = require('./pattern-store');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Singleton instances
|
|
21
|
+
*/
|
|
22
|
+
let capture = null;
|
|
23
|
+
let validator = null;
|
|
24
|
+
let store = null;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Check if pattern capture is enabled
|
|
28
|
+
* @returns {boolean} True if enabled
|
|
29
|
+
*/
|
|
30
|
+
function isEnabled() {
|
|
31
|
+
return process.env.AIOS_PATTERN_CAPTURE !== 'false';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Get or create singleton instances
|
|
36
|
+
*/
|
|
37
|
+
function getInstances() {
|
|
38
|
+
if (!capture) {
|
|
39
|
+
capture = createPatternCapture();
|
|
40
|
+
}
|
|
41
|
+
if (!validator) {
|
|
42
|
+
validator = createPatternValidator();
|
|
43
|
+
}
|
|
44
|
+
if (!store) {
|
|
45
|
+
store = createPatternStore();
|
|
46
|
+
}
|
|
47
|
+
return { capture, validator, store };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Handle task completion event (non-blocking)
|
|
52
|
+
* @param {string} taskName - Name of completed task
|
|
53
|
+
* @param {Object} context - Task context
|
|
54
|
+
* @returns {Promise<Object>} Capture result
|
|
55
|
+
*/
|
|
56
|
+
async function onTaskComplete(taskName, context = {}) {
|
|
57
|
+
if (!isEnabled()) {
|
|
58
|
+
return { success: false, reason: 'disabled' };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
const { capture: cap, validator: val, store: st } = getInstances();
|
|
63
|
+
const result = await cap.onTaskComplete(taskName, context);
|
|
64
|
+
|
|
65
|
+
if (result.captured && result.pattern) {
|
|
66
|
+
// Validate and store
|
|
67
|
+
const validation = val.validate(result.pattern);
|
|
68
|
+
|
|
69
|
+
if (validation.valid) {
|
|
70
|
+
st.save(result.pattern);
|
|
71
|
+
return {
|
|
72
|
+
success: true,
|
|
73
|
+
action: 'stored',
|
|
74
|
+
patternId: result.pattern.id
|
|
75
|
+
};
|
|
76
|
+
} else {
|
|
77
|
+
return {
|
|
78
|
+
success: false,
|
|
79
|
+
reason: 'validation_failed',
|
|
80
|
+
errors: validation.errors
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
success: false,
|
|
87
|
+
reason: result.reason || 'not_captured'
|
|
88
|
+
};
|
|
89
|
+
} catch (error) {
|
|
90
|
+
// Silent failure - capture is non-critical
|
|
91
|
+
if (process.env.AIOS_DEBUG === 'true') {
|
|
92
|
+
console.debug('[PatternCapture] Hook failed:', error.message);
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
success: false,
|
|
96
|
+
reason: 'error',
|
|
97
|
+
error: error.message
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Mark session as failed (for error handling)
|
|
104
|
+
* @param {string} sessionId - Session identifier
|
|
105
|
+
*/
|
|
106
|
+
function markSessionFailed(sessionId) {
|
|
107
|
+
if (!isEnabled()) return;
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
const { capture: cap } = getInstances();
|
|
111
|
+
cap.markSessionFailed(sessionId);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
// Ignore errors
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Clear session buffer
|
|
119
|
+
* @param {string} sessionId - Optional session ID
|
|
120
|
+
*/
|
|
121
|
+
function clearSession(sessionId) {
|
|
122
|
+
if (!isEnabled()) return;
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
const { capture: cap } = getInstances();
|
|
126
|
+
cap.clearSession(sessionId);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
// Ignore errors
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Reset singleton instances (for testing)
|
|
134
|
+
*/
|
|
135
|
+
function reset() {
|
|
136
|
+
capture = null;
|
|
137
|
+
validator = null;
|
|
138
|
+
store = null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
module.exports = {
|
|
142
|
+
onTaskComplete,
|
|
143
|
+
markSessionFailed,
|
|
144
|
+
clearSession,
|
|
145
|
+
isEnabled,
|
|
146
|
+
reset
|
|
147
|
+
};
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module learning
|
|
3
|
+
* @description Pattern Learning module for Workflow Intelligence System
|
|
4
|
+
* @story WIS-5 - Pattern Capture (Internal)
|
|
5
|
+
* @version 1.0.0
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const learning = require('./.aios-core/workflow-intelligence/learning');
|
|
9
|
+
*
|
|
10
|
+
* // Capture a session pattern
|
|
11
|
+
* const capture = learning.createPatternCapture();
|
|
12
|
+
* const result = capture.captureSession({
|
|
13
|
+
* commands: ['validate-story-draft', 'develop', 'review-qa'],
|
|
14
|
+
* agentSequence: ['po', 'dev', 'qa'],
|
|
15
|
+
* success: true,
|
|
16
|
+
* timestamp: Date.now()
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Validate the pattern
|
|
20
|
+
* const validator = learning.createPatternValidator();
|
|
21
|
+
* const validation = validator.validate(result.pattern);
|
|
22
|
+
*
|
|
23
|
+
* // Store if valid
|
|
24
|
+
* if (validation.valid) {
|
|
25
|
+
* const store = learning.createPatternStore();
|
|
26
|
+
* store.save(result.pattern);
|
|
27
|
+
* }
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
'use strict';
|
|
31
|
+
|
|
32
|
+
const {
|
|
33
|
+
PatternCapture,
|
|
34
|
+
createPatternCapture,
|
|
35
|
+
DEFAULT_MIN_SEQUENCE_LENGTH,
|
|
36
|
+
KEY_WORKFLOW_COMMANDS
|
|
37
|
+
} = require('./pattern-capture');
|
|
38
|
+
|
|
39
|
+
const {
|
|
40
|
+
PatternValidator,
|
|
41
|
+
createPatternValidator,
|
|
42
|
+
DEFAULT_VALIDATION_RULES,
|
|
43
|
+
KNOWN_COMMANDS
|
|
44
|
+
} = require('./pattern-validator');
|
|
45
|
+
|
|
46
|
+
const {
|
|
47
|
+
PatternStore,
|
|
48
|
+
createPatternStore,
|
|
49
|
+
DEFAULT_STORAGE_PATH,
|
|
50
|
+
DEFAULT_MAX_PATTERNS,
|
|
51
|
+
DEFAULT_PRUNE_THRESHOLD,
|
|
52
|
+
PATTERN_STATUS
|
|
53
|
+
} = require('./pattern-store');
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Singleton instances for default usage
|
|
57
|
+
*/
|
|
58
|
+
let defaultCapture = null;
|
|
59
|
+
let defaultValidator = null;
|
|
60
|
+
let defaultStore = null;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get or create the default PatternCapture instance
|
|
64
|
+
* @returns {PatternCapture} Default capture instance
|
|
65
|
+
*/
|
|
66
|
+
function getDefaultCapture() {
|
|
67
|
+
if (!defaultCapture) {
|
|
68
|
+
defaultCapture = createPatternCapture();
|
|
69
|
+
}
|
|
70
|
+
return defaultCapture;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get or create the default PatternValidator instance
|
|
75
|
+
* @returns {PatternValidator} Default validator instance
|
|
76
|
+
*/
|
|
77
|
+
function getDefaultValidator() {
|
|
78
|
+
if (!defaultValidator) {
|
|
79
|
+
defaultValidator = createPatternValidator();
|
|
80
|
+
}
|
|
81
|
+
return defaultValidator;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Get or create the default PatternStore instance
|
|
86
|
+
* @returns {PatternStore} Default store instance
|
|
87
|
+
*/
|
|
88
|
+
function getDefaultStore() {
|
|
89
|
+
if (!defaultStore) {
|
|
90
|
+
defaultStore = createPatternStore();
|
|
91
|
+
}
|
|
92
|
+
return defaultStore;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Capture and store a pattern in one operation
|
|
97
|
+
* @param {Object} sessionData - Session data
|
|
98
|
+
* @returns {Object} Result with captured and stored status
|
|
99
|
+
*/
|
|
100
|
+
function captureAndStore(sessionData) {
|
|
101
|
+
const capture = getDefaultCapture();
|
|
102
|
+
const validator = getDefaultValidator();
|
|
103
|
+
const store = getDefaultStore();
|
|
104
|
+
|
|
105
|
+
// Capture
|
|
106
|
+
const captureResult = capture.captureSession(sessionData);
|
|
107
|
+
|
|
108
|
+
if (!captureResult.valid) {
|
|
109
|
+
return {
|
|
110
|
+
success: false,
|
|
111
|
+
stage: 'capture',
|
|
112
|
+
reason: captureResult.reason
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Validate
|
|
117
|
+
const validation = validator.validate(captureResult.pattern);
|
|
118
|
+
|
|
119
|
+
if (!validation.valid) {
|
|
120
|
+
return {
|
|
121
|
+
success: false,
|
|
122
|
+
stage: 'validation',
|
|
123
|
+
reason: validation.reason,
|
|
124
|
+
errors: validation.errors
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Check for duplicates
|
|
129
|
+
const existingPatterns = store.load().patterns;
|
|
130
|
+
const duplicateCheck = validator.isDuplicate(captureResult.pattern, existingPatterns);
|
|
131
|
+
|
|
132
|
+
if (duplicateCheck.isDuplicate) {
|
|
133
|
+
// Update existing pattern instead
|
|
134
|
+
const existing = existingPatterns.find(p => p.id === duplicateCheck.duplicateOf);
|
|
135
|
+
if (existing) {
|
|
136
|
+
store.save(existing); // This will increment occurrences
|
|
137
|
+
return {
|
|
138
|
+
success: true,
|
|
139
|
+
action: 'merged',
|
|
140
|
+
patternId: existing.id
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Store
|
|
146
|
+
const storeResult = store.save(captureResult.pattern);
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
success: true,
|
|
150
|
+
action: storeResult.action,
|
|
151
|
+
pattern: storeResult.pattern
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Get learned patterns for suggestions
|
|
157
|
+
* @param {Object} options - Options
|
|
158
|
+
* @param {boolean} options.activeOnly - Only return active/promoted patterns
|
|
159
|
+
* @returns {Object[]} Patterns
|
|
160
|
+
*/
|
|
161
|
+
function getLearnedPatterns(options = {}) {
|
|
162
|
+
const store = getDefaultStore();
|
|
163
|
+
|
|
164
|
+
if (options.activeOnly) {
|
|
165
|
+
return store.getActivePatterns();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return store.load().patterns;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Find patterns matching a command sequence
|
|
173
|
+
* @param {string[]} sequence - Command sequence to match
|
|
174
|
+
* @returns {Object[]} Matching patterns
|
|
175
|
+
*/
|
|
176
|
+
function findMatchingPatterns(sequence) {
|
|
177
|
+
const store = getDefaultStore();
|
|
178
|
+
return store.findSimilar(sequence);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Get pattern learning statistics
|
|
183
|
+
* @returns {Object} Statistics
|
|
184
|
+
*/
|
|
185
|
+
function getStats() {
|
|
186
|
+
return getDefaultStore().getStats();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Reset singleton instances (for testing)
|
|
191
|
+
*/
|
|
192
|
+
function reset() {
|
|
193
|
+
defaultCapture = null;
|
|
194
|
+
defaultValidator = null;
|
|
195
|
+
defaultStore = null;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
module.exports = {
|
|
199
|
+
// High-level API
|
|
200
|
+
captureAndStore,
|
|
201
|
+
getLearnedPatterns,
|
|
202
|
+
findMatchingPatterns,
|
|
203
|
+
getStats,
|
|
204
|
+
reset,
|
|
205
|
+
|
|
206
|
+
// Singleton accessors
|
|
207
|
+
getDefaultCapture,
|
|
208
|
+
getDefaultValidator,
|
|
209
|
+
getDefaultStore,
|
|
210
|
+
|
|
211
|
+
// Factory functions
|
|
212
|
+
createPatternCapture,
|
|
213
|
+
createPatternValidator,
|
|
214
|
+
createPatternStore,
|
|
215
|
+
|
|
216
|
+
// Classes (for advanced usage)
|
|
217
|
+
PatternCapture,
|
|
218
|
+
PatternValidator,
|
|
219
|
+
PatternStore,
|
|
220
|
+
|
|
221
|
+
// Constants
|
|
222
|
+
DEFAULT_MIN_SEQUENCE_LENGTH,
|
|
223
|
+
KEY_WORKFLOW_COMMANDS,
|
|
224
|
+
DEFAULT_VALIDATION_RULES,
|
|
225
|
+
KNOWN_COMMANDS,
|
|
226
|
+
DEFAULT_STORAGE_PATH,
|
|
227
|
+
DEFAULT_MAX_PATTERNS,
|
|
228
|
+
DEFAULT_PRUNE_THRESHOLD,
|
|
229
|
+
PATTERN_STATUS
|
|
230
|
+
};
|