@sparkleideas/neural 3.5.2-patch.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.md +260 -0
- package/__tests__/README.md +235 -0
- package/__tests__/algorithms.test.ts +582 -0
- package/__tests__/patterns.test.ts +549 -0
- package/__tests__/sona.test.ts +445 -0
- package/docs/SONA_INTEGRATION.md +460 -0
- package/docs/SONA_QUICKSTART.md +168 -0
- package/examples/sona-usage.ts +318 -0
- package/package.json +23 -0
- package/src/algorithms/a2c.d.ts +86 -0
- package/src/algorithms/a2c.d.ts.map +1 -0
- package/src/algorithms/a2c.js +361 -0
- package/src/algorithms/a2c.js.map +1 -0
- package/src/algorithms/a2c.ts +478 -0
- package/src/algorithms/curiosity.d.ts +82 -0
- package/src/algorithms/curiosity.d.ts.map +1 -0
- package/src/algorithms/curiosity.js +392 -0
- package/src/algorithms/curiosity.js.map +1 -0
- package/src/algorithms/curiosity.ts +509 -0
- package/src/algorithms/decision-transformer.d.ts +82 -0
- package/src/algorithms/decision-transformer.d.ts.map +1 -0
- package/src/algorithms/decision-transformer.js +415 -0
- package/src/algorithms/decision-transformer.js.map +1 -0
- package/src/algorithms/decision-transformer.ts +521 -0
- package/src/algorithms/dqn.d.ts +72 -0
- package/src/algorithms/dqn.d.ts.map +1 -0
- package/src/algorithms/dqn.js +303 -0
- package/src/algorithms/dqn.js.map +1 -0
- package/src/algorithms/dqn.ts +382 -0
- package/src/algorithms/index.d.ts +32 -0
- package/src/algorithms/index.d.ts.map +1 -0
- package/src/algorithms/index.js +74 -0
- package/src/algorithms/index.js.map +1 -0
- package/src/algorithms/index.ts +122 -0
- package/src/algorithms/ppo.d.ts +72 -0
- package/src/algorithms/ppo.d.ts.map +1 -0
- package/src/algorithms/ppo.js +331 -0
- package/src/algorithms/ppo.js.map +1 -0
- package/src/algorithms/ppo.ts +429 -0
- package/src/algorithms/q-learning.d.ts +77 -0
- package/src/algorithms/q-learning.d.ts.map +1 -0
- package/src/algorithms/q-learning.js +259 -0
- package/src/algorithms/q-learning.js.map +1 -0
- package/src/algorithms/q-learning.ts +333 -0
- package/src/algorithms/sarsa.d.ts +82 -0
- package/src/algorithms/sarsa.d.ts.map +1 -0
- package/src/algorithms/sarsa.js +297 -0
- package/src/algorithms/sarsa.js.map +1 -0
- package/src/algorithms/sarsa.ts +383 -0
- package/src/algorithms/tmp.json +0 -0
- package/src/application/index.ts +11 -0
- package/src/application/services/neural-application-service.ts +217 -0
- package/src/domain/entities/pattern.ts +169 -0
- package/src/domain/index.ts +18 -0
- package/src/domain/services/learning-service.ts +256 -0
- package/src/index.d.ts +118 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +201 -0
- package/src/index.js.map +1 -0
- package/src/index.ts +363 -0
- package/src/modes/balanced.d.ts +60 -0
- package/src/modes/balanced.d.ts.map +1 -0
- package/src/modes/balanced.js +234 -0
- package/src/modes/balanced.js.map +1 -0
- package/src/modes/balanced.ts +299 -0
- package/src/modes/base.ts +163 -0
- package/src/modes/batch.d.ts +82 -0
- package/src/modes/batch.d.ts.map +1 -0
- package/src/modes/batch.js +316 -0
- package/src/modes/batch.js.map +1 -0
- package/src/modes/batch.ts +434 -0
- package/src/modes/edge.d.ts +85 -0
- package/src/modes/edge.d.ts.map +1 -0
- package/src/modes/edge.js +310 -0
- package/src/modes/edge.js.map +1 -0
- package/src/modes/edge.ts +409 -0
- package/src/modes/index.d.ts +55 -0
- package/src/modes/index.d.ts.map +1 -0
- package/src/modes/index.js +83 -0
- package/src/modes/index.js.map +1 -0
- package/src/modes/index.ts +16 -0
- package/src/modes/real-time.d.ts +58 -0
- package/src/modes/real-time.d.ts.map +1 -0
- package/src/modes/real-time.js +196 -0
- package/src/modes/real-time.js.map +1 -0
- package/src/modes/real-time.ts +257 -0
- package/src/modes/research.d.ts +79 -0
- package/src/modes/research.d.ts.map +1 -0
- package/src/modes/research.js +389 -0
- package/src/modes/research.js.map +1 -0
- package/src/modes/research.ts +486 -0
- package/src/modes/tmp.json +0 -0
- package/src/pattern-learner.d.ts +117 -0
- package/src/pattern-learner.d.ts.map +1 -0
- package/src/pattern-learner.js +603 -0
- package/src/pattern-learner.js.map +1 -0
- package/src/pattern-learner.ts +757 -0
- package/src/reasoning-bank.d.ts +259 -0
- package/src/reasoning-bank.d.ts.map +1 -0
- package/src/reasoning-bank.js +993 -0
- package/src/reasoning-bank.js.map +1 -0
- package/src/reasoning-bank.ts +1279 -0
- package/src/reasoningbank-adapter.ts +697 -0
- package/src/sona-integration.d.ts +168 -0
- package/src/sona-integration.d.ts.map +1 -0
- package/src/sona-integration.js +316 -0
- package/src/sona-integration.js.map +1 -0
- package/src/sona-integration.ts +432 -0
- package/src/sona-manager.d.ts +147 -0
- package/src/sona-manager.d.ts.map +1 -0
- package/src/sona-manager.js +695 -0
- package/src/sona-manager.js.map +1 -0
- package/src/sona-manager.ts +835 -0
- package/src/tmp.json +0 -0
- package/src/types.d.ts +431 -0
- package/src/types.d.ts.map +1 -0
- package/src/types.js +11 -0
- package/src/types.js.map +1 -0
- package/src/types.ts +590 -0
- package/tmp.json +0 -0
- package/tsconfig.json +9 -0
- package/vitest.config.ts +19 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Neural Application Service - Application Layer
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates neural learning operations.
|
|
5
|
+
*
|
|
6
|
+
* @module v3/neural/application/services
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { Pattern, PatternType } from '../../domain/entities/pattern.js';
|
|
10
|
+
import { LearningDomainService, Trajectory, LearningResult, RouteRecommendation } from '../../domain/services/learning-service.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Training session result
|
|
14
|
+
*/
|
|
15
|
+
export interface TrainingSessionResult {
|
|
16
|
+
trajectoriesProcessed: number;
|
|
17
|
+
patternsExtracted: number;
|
|
18
|
+
patternsUpdated: number;
|
|
19
|
+
averageConfidenceChange: number;
|
|
20
|
+
duration: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Neural metrics
|
|
25
|
+
*/
|
|
26
|
+
export interface NeuralMetrics {
|
|
27
|
+
totalPatterns: number;
|
|
28
|
+
patternsByType: Record<PatternType, number>;
|
|
29
|
+
averageConfidence: number;
|
|
30
|
+
reliablePatterns: number;
|
|
31
|
+
totalSuccesses: number;
|
|
32
|
+
totalFailures: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Neural Application Service
|
|
37
|
+
*/
|
|
38
|
+
export class NeuralApplicationService {
|
|
39
|
+
private readonly learningService: LearningDomainService;
|
|
40
|
+
|
|
41
|
+
constructor() {
|
|
42
|
+
this.learningService = new LearningDomainService();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ============================================================================
|
|
46
|
+
// Learning Operations
|
|
47
|
+
// ============================================================================
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Learn from a single trajectory
|
|
51
|
+
*/
|
|
52
|
+
learn(trajectory: Trajectory): LearningResult {
|
|
53
|
+
return this.learningService.updatePatterns(trajectory);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Train on batch of trajectories
|
|
58
|
+
*/
|
|
59
|
+
train(trajectories: Trajectory[]): TrainingSessionResult {
|
|
60
|
+
const start = Date.now();
|
|
61
|
+
let totalPatternsExtracted = 0;
|
|
62
|
+
let totalPatternsUpdated = 0;
|
|
63
|
+
let totalConfidenceChange = 0;
|
|
64
|
+
|
|
65
|
+
for (const trajectory of trajectories) {
|
|
66
|
+
const result = this.learningService.updatePatterns(trajectory);
|
|
67
|
+
totalPatternsExtracted += result.patternsExtracted;
|
|
68
|
+
totalPatternsUpdated += result.patternsUpdated;
|
|
69
|
+
totalConfidenceChange += result.confidenceChange;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
trajectoriesProcessed: trajectories.length,
|
|
74
|
+
patternsExtracted: totalPatternsExtracted,
|
|
75
|
+
patternsUpdated: totalPatternsUpdated,
|
|
76
|
+
averageConfidenceChange: trajectories.length > 0 ? totalConfidenceChange / trajectories.length : 0,
|
|
77
|
+
duration: Date.now() - start,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ============================================================================
|
|
82
|
+
// Routing
|
|
83
|
+
// ============================================================================
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Get route recommendation for task
|
|
87
|
+
*/
|
|
88
|
+
route(taskDescription: string): RouteRecommendation {
|
|
89
|
+
return this.learningService.getRouteRecommendation(taskDescription);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Explain routing decision
|
|
94
|
+
*/
|
|
95
|
+
explain(taskDescription: string): {
|
|
96
|
+
recommendation: RouteRecommendation;
|
|
97
|
+
matchingPatterns: Pattern[];
|
|
98
|
+
reasoning: string[];
|
|
99
|
+
} {
|
|
100
|
+
const recommendation = this.route(taskDescription);
|
|
101
|
+
const matchingPatterns = this.learningService
|
|
102
|
+
.getPatternsByType('task-routing')
|
|
103
|
+
.filter((p) => p.matches(taskDescription));
|
|
104
|
+
|
|
105
|
+
const reasoning: string[] = [];
|
|
106
|
+
if (matchingPatterns.length > 0) {
|
|
107
|
+
reasoning.push(`Found ${matchingPatterns.length} matching patterns`);
|
|
108
|
+
for (const p of matchingPatterns.slice(0, 3)) {
|
|
109
|
+
reasoning.push(`- Pattern "${p.name}": ${p.successRate.toFixed(2)} success rate, ${p.confidence.toFixed(2)} confidence`);
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
reasoning.push('No matching patterns found, using keyword-based routing');
|
|
113
|
+
}
|
|
114
|
+
reasoning.push(`Recommended: ${recommendation.agentRole} (${(recommendation.confidence * 100).toFixed(0)}% confidence)`);
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
recommendation,
|
|
118
|
+
matchingPatterns,
|
|
119
|
+
reasoning,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ============================================================================
|
|
124
|
+
// Pattern Management
|
|
125
|
+
// ============================================================================
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get all patterns
|
|
129
|
+
*/
|
|
130
|
+
getPatterns(): Pattern[] {
|
|
131
|
+
return this.learningService.getPatterns();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Get patterns by type
|
|
136
|
+
*/
|
|
137
|
+
getPatternsByType(type: PatternType): Pattern[] {
|
|
138
|
+
return this.learningService.getPatternsByType(type);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Add custom pattern
|
|
143
|
+
*/
|
|
144
|
+
addPattern(props: {
|
|
145
|
+
type: PatternType;
|
|
146
|
+
name: string;
|
|
147
|
+
description: string;
|
|
148
|
+
condition: string;
|
|
149
|
+
action: string;
|
|
150
|
+
confidence?: number;
|
|
151
|
+
}): Pattern {
|
|
152
|
+
const pattern = Pattern.create({
|
|
153
|
+
type: props.type,
|
|
154
|
+
name: props.name,
|
|
155
|
+
description: props.description,
|
|
156
|
+
condition: props.condition,
|
|
157
|
+
action: props.action,
|
|
158
|
+
confidence: props.confidence ?? 0.5,
|
|
159
|
+
});
|
|
160
|
+
this.learningService.addPattern(pattern);
|
|
161
|
+
return pattern;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Remove pattern
|
|
166
|
+
*/
|
|
167
|
+
removePattern(id: string): boolean {
|
|
168
|
+
return this.learningService.removePattern(id);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Consolidate patterns
|
|
173
|
+
*/
|
|
174
|
+
consolidate(minConfidence?: number): { merged: number; pruned: number } {
|
|
175
|
+
return this.learningService.consolidate(minConfidence);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ============================================================================
|
|
179
|
+
// Metrics
|
|
180
|
+
// ============================================================================
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Get neural metrics
|
|
184
|
+
*/
|
|
185
|
+
getMetrics(): NeuralMetrics {
|
|
186
|
+
const patterns = this.learningService.getPatterns();
|
|
187
|
+
|
|
188
|
+
const patternsByType: Record<PatternType, number> = {
|
|
189
|
+
'task-routing': 0,
|
|
190
|
+
'error-recovery': 0,
|
|
191
|
+
optimization: 0,
|
|
192
|
+
learning: 0,
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
let totalConfidence = 0;
|
|
196
|
+
let reliablePatterns = 0;
|
|
197
|
+
let totalSuccesses = 0;
|
|
198
|
+
let totalFailures = 0;
|
|
199
|
+
|
|
200
|
+
for (const pattern of patterns) {
|
|
201
|
+
patternsByType[pattern.type]++;
|
|
202
|
+
totalConfidence += pattern.confidence;
|
|
203
|
+
if (pattern.isReliable()) reliablePatterns++;
|
|
204
|
+
totalSuccesses += pattern.successCount;
|
|
205
|
+
totalFailures += pattern.failureCount;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
totalPatterns: patterns.length,
|
|
210
|
+
patternsByType,
|
|
211
|
+
averageConfidence: patterns.length > 0 ? totalConfidence / patterns.length : 0,
|
|
212
|
+
reliablePatterns,
|
|
213
|
+
totalSuccesses,
|
|
214
|
+
totalFailures,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pattern Entity - Domain Layer
|
|
3
|
+
*
|
|
4
|
+
* Represents a learned pattern for intelligent routing and optimization.
|
|
5
|
+
*
|
|
6
|
+
* @module v3/neural/domain/entities
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { randomUUID } from 'crypto';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Pattern type
|
|
13
|
+
*/
|
|
14
|
+
export type PatternType = 'task-routing' | 'error-recovery' | 'optimization' | 'learning';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Pattern properties
|
|
18
|
+
*/
|
|
19
|
+
export interface PatternProps {
|
|
20
|
+
id?: string;
|
|
21
|
+
type: PatternType;
|
|
22
|
+
name: string;
|
|
23
|
+
description: string;
|
|
24
|
+
condition: string;
|
|
25
|
+
action: string;
|
|
26
|
+
confidence: number;
|
|
27
|
+
successCount?: number;
|
|
28
|
+
failureCount?: number;
|
|
29
|
+
metadata?: Record<string, unknown>;
|
|
30
|
+
createdAt?: Date;
|
|
31
|
+
updatedAt?: Date;
|
|
32
|
+
lastMatchedAt?: Date;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Pattern Entity
|
|
37
|
+
*/
|
|
38
|
+
export class Pattern {
|
|
39
|
+
private _id: string;
|
|
40
|
+
private _type: PatternType;
|
|
41
|
+
private _name: string;
|
|
42
|
+
private _description: string;
|
|
43
|
+
private _condition: string;
|
|
44
|
+
private _action: string;
|
|
45
|
+
private _confidence: number;
|
|
46
|
+
private _successCount: number;
|
|
47
|
+
private _failureCount: number;
|
|
48
|
+
private _metadata: Record<string, unknown>;
|
|
49
|
+
private _createdAt: Date;
|
|
50
|
+
private _updatedAt: Date;
|
|
51
|
+
private _lastMatchedAt?: Date;
|
|
52
|
+
|
|
53
|
+
private constructor(props: PatternProps) {
|
|
54
|
+
const now = new Date();
|
|
55
|
+
this._id = props.id ?? randomUUID();
|
|
56
|
+
this._type = props.type;
|
|
57
|
+
this._name = props.name;
|
|
58
|
+
this._description = props.description;
|
|
59
|
+
this._condition = props.condition;
|
|
60
|
+
this._action = props.action;
|
|
61
|
+
this._confidence = props.confidence;
|
|
62
|
+
this._successCount = props.successCount ?? 0;
|
|
63
|
+
this._failureCount = props.failureCount ?? 0;
|
|
64
|
+
this._metadata = props.metadata ?? {};
|
|
65
|
+
this._createdAt = props.createdAt ?? now;
|
|
66
|
+
this._updatedAt = props.updatedAt ?? now;
|
|
67
|
+
this._lastMatchedAt = props.lastMatchedAt;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static create(props: PatternProps): Pattern {
|
|
71
|
+
return new Pattern(props);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static fromPersistence(props: PatternProps): Pattern {
|
|
75
|
+
return new Pattern(props);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
get id(): string { return this._id; }
|
|
79
|
+
get type(): PatternType { return this._type; }
|
|
80
|
+
get name(): string { return this._name; }
|
|
81
|
+
get description(): string { return this._description; }
|
|
82
|
+
get condition(): string { return this._condition; }
|
|
83
|
+
get action(): string { return this._action; }
|
|
84
|
+
get confidence(): number { return this._confidence; }
|
|
85
|
+
get successCount(): number { return this._successCount; }
|
|
86
|
+
get failureCount(): number { return this._failureCount; }
|
|
87
|
+
get metadata(): Record<string, unknown> { return { ...this._metadata }; }
|
|
88
|
+
get createdAt(): Date { return new Date(this._createdAt); }
|
|
89
|
+
get updatedAt(): Date { return new Date(this._updatedAt); }
|
|
90
|
+
get lastMatchedAt(): Date | undefined { return this._lastMatchedAt ? new Date(this._lastMatchedAt) : undefined; }
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Calculate success rate
|
|
94
|
+
*/
|
|
95
|
+
get successRate(): number {
|
|
96
|
+
const total = this._successCount + this._failureCount;
|
|
97
|
+
return total > 0 ? this._successCount / total : 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Record successful match
|
|
102
|
+
*/
|
|
103
|
+
recordSuccess(): void {
|
|
104
|
+
this._successCount++;
|
|
105
|
+
this._confidence = this.calculateConfidence();
|
|
106
|
+
this._lastMatchedAt = new Date();
|
|
107
|
+
this._updatedAt = new Date();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Record failed match
|
|
112
|
+
*/
|
|
113
|
+
recordFailure(): void {
|
|
114
|
+
this._failureCount++;
|
|
115
|
+
this._confidence = this.calculateConfidence();
|
|
116
|
+
this._lastMatchedAt = new Date();
|
|
117
|
+
this._updatedAt = new Date();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Calculate confidence based on success rate
|
|
122
|
+
*/
|
|
123
|
+
private calculateConfidence(): number {
|
|
124
|
+
const total = this._successCount + this._failureCount;
|
|
125
|
+
if (total < 5) return this._confidence; // Not enough data
|
|
126
|
+
|
|
127
|
+
const newConfidence = this.successRate;
|
|
128
|
+
// Weighted average with existing confidence
|
|
129
|
+
return this._confidence * 0.3 + newConfidence * 0.7;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Check if pattern matches input
|
|
134
|
+
*/
|
|
135
|
+
matches(input: string): boolean {
|
|
136
|
+
try {
|
|
137
|
+
const regex = new RegExp(this._condition, 'i');
|
|
138
|
+
return regex.test(input);
|
|
139
|
+
} catch {
|
|
140
|
+
return input.toLowerCase().includes(this._condition.toLowerCase());
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Check if pattern is reliable (high confidence, sufficient data)
|
|
146
|
+
*/
|
|
147
|
+
isReliable(): boolean {
|
|
148
|
+
const total = this._successCount + this._failureCount;
|
|
149
|
+
return total >= 10 && this._confidence >= 0.7;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
toPersistence(): Record<string, unknown> {
|
|
153
|
+
return {
|
|
154
|
+
id: this._id,
|
|
155
|
+
type: this._type,
|
|
156
|
+
name: this._name,
|
|
157
|
+
description: this._description,
|
|
158
|
+
condition: this._condition,
|
|
159
|
+
action: this._action,
|
|
160
|
+
confidence: this._confidence,
|
|
161
|
+
successCount: this._successCount,
|
|
162
|
+
failureCount: this._failureCount,
|
|
163
|
+
metadata: this._metadata,
|
|
164
|
+
createdAt: this._createdAt.toISOString(),
|
|
165
|
+
updatedAt: this._updatedAt.toISOString(),
|
|
166
|
+
lastMatchedAt: this._lastMatchedAt?.toISOString(),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Neural Domain Layer - Public Exports
|
|
3
|
+
*
|
|
4
|
+
* @module v3/neural/domain
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
Pattern,
|
|
9
|
+
type PatternType,
|
|
10
|
+
type PatternProps,
|
|
11
|
+
} from './entities/pattern.js';
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
LearningDomainService,
|
|
15
|
+
type Trajectory,
|
|
16
|
+
type LearningResult,
|
|
17
|
+
type RouteRecommendation,
|
|
18
|
+
} from './services/learning-service.js';
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Learning Domain Service - Domain Layer
|
|
3
|
+
*
|
|
4
|
+
* Contains learning logic for pattern recognition and optimization.
|
|
5
|
+
*
|
|
6
|
+
* @module v3/neural/domain/services
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { Pattern, PatternType } from '../entities/pattern.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Learning trajectory
|
|
13
|
+
*/
|
|
14
|
+
export interface Trajectory {
|
|
15
|
+
id: string;
|
|
16
|
+
input: string;
|
|
17
|
+
actions: string[];
|
|
18
|
+
outcome: 'success' | 'failure' | 'partial';
|
|
19
|
+
reward: number;
|
|
20
|
+
metadata?: Record<string, unknown>;
|
|
21
|
+
timestamp: Date;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Learning result
|
|
26
|
+
*/
|
|
27
|
+
export interface LearningResult {
|
|
28
|
+
patternsExtracted: number;
|
|
29
|
+
patternsUpdated: number;
|
|
30
|
+
confidenceChange: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Route recommendation
|
|
35
|
+
*/
|
|
36
|
+
export interface RouteRecommendation {
|
|
37
|
+
agentRole: string;
|
|
38
|
+
confidence: number;
|
|
39
|
+
reasoning: string;
|
|
40
|
+
alternates: Array<{ role: string; confidence: number }>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Learning Domain Service
|
|
45
|
+
*/
|
|
46
|
+
export class LearningDomainService {
|
|
47
|
+
private patterns: Map<string, Pattern> = new Map();
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Extract patterns from trajectory
|
|
51
|
+
*/
|
|
52
|
+
extractPatterns(trajectory: Trajectory): Pattern[] {
|
|
53
|
+
const extracted: Pattern[] = [];
|
|
54
|
+
|
|
55
|
+
// Extract task-routing pattern
|
|
56
|
+
if (trajectory.outcome === 'success') {
|
|
57
|
+
const taskPattern = Pattern.create({
|
|
58
|
+
type: 'task-routing',
|
|
59
|
+
name: `route_${trajectory.id}`,
|
|
60
|
+
description: `Learned from successful trajectory`,
|
|
61
|
+
condition: this.extractCondition(trajectory.input),
|
|
62
|
+
action: trajectory.actions[0] ?? 'default',
|
|
63
|
+
confidence: 0.6 + trajectory.reward * 0.2,
|
|
64
|
+
metadata: { source: trajectory.id },
|
|
65
|
+
});
|
|
66
|
+
extracted.push(taskPattern);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Extract error recovery pattern if failure
|
|
70
|
+
if (trajectory.outcome === 'failure' && trajectory.actions.length > 1) {
|
|
71
|
+
const lastAction = trajectory.actions[trajectory.actions.length - 1];
|
|
72
|
+
const recoveryPattern = Pattern.create({
|
|
73
|
+
type: 'error-recovery',
|
|
74
|
+
name: `recovery_${trajectory.id}`,
|
|
75
|
+
description: `Recovery action from failure`,
|
|
76
|
+
condition: `error:${trajectory.actions[0]}`,
|
|
77
|
+
action: lastAction,
|
|
78
|
+
confidence: 0.5,
|
|
79
|
+
metadata: { source: trajectory.id },
|
|
80
|
+
});
|
|
81
|
+
extracted.push(recoveryPattern);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return extracted;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Update patterns based on trajectory outcome
|
|
89
|
+
*/
|
|
90
|
+
updatePatterns(trajectory: Trajectory): LearningResult {
|
|
91
|
+
let patternsUpdated = 0;
|
|
92
|
+
let totalConfidenceChange = 0;
|
|
93
|
+
|
|
94
|
+
for (const pattern of this.patterns.values()) {
|
|
95
|
+
if (pattern.matches(trajectory.input)) {
|
|
96
|
+
const oldConfidence = pattern.confidence;
|
|
97
|
+
|
|
98
|
+
if (trajectory.outcome === 'success') {
|
|
99
|
+
pattern.recordSuccess();
|
|
100
|
+
} else {
|
|
101
|
+
pattern.recordFailure();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
totalConfidenceChange += pattern.confidence - oldConfidence;
|
|
105
|
+
patternsUpdated++;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Extract and add new patterns
|
|
110
|
+
const newPatterns = this.extractPatterns(trajectory);
|
|
111
|
+
for (const pattern of newPatterns) {
|
|
112
|
+
this.patterns.set(pattern.id, pattern);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
patternsExtracted: newPatterns.length,
|
|
117
|
+
patternsUpdated,
|
|
118
|
+
confidenceChange: totalConfidenceChange,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Get route recommendation for task
|
|
124
|
+
*/
|
|
125
|
+
getRouteRecommendation(taskDescription: string): RouteRecommendation {
|
|
126
|
+
const matchingPatterns: Array<{ pattern: Pattern; score: number }> = [];
|
|
127
|
+
|
|
128
|
+
for (const pattern of this.patterns.values()) {
|
|
129
|
+
if (pattern.type !== 'task-routing') continue;
|
|
130
|
+
|
|
131
|
+
if (pattern.matches(taskDescription)) {
|
|
132
|
+
const score = pattern.confidence * (pattern.isReliable() ? 1.2 : 1.0);
|
|
133
|
+
matchingPatterns.push({ pattern, score });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Sort by score
|
|
138
|
+
matchingPatterns.sort((a, b) => b.score - a.score);
|
|
139
|
+
|
|
140
|
+
if (matchingPatterns.length === 0) {
|
|
141
|
+
return this.getDefaultRecommendation(taskDescription);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const best = matchingPatterns[0];
|
|
145
|
+
const alternates = matchingPatterns.slice(1, 4).map((m) => ({
|
|
146
|
+
role: m.pattern.action,
|
|
147
|
+
confidence: m.score,
|
|
148
|
+
}));
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
agentRole: best.pattern.action,
|
|
152
|
+
confidence: best.score,
|
|
153
|
+
reasoning: `Based on pattern "${best.pattern.name}" with ${best.pattern.successCount} successes`,
|
|
154
|
+
alternates,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Get default recommendation based on keywords
|
|
160
|
+
*/
|
|
161
|
+
private getDefaultRecommendation(task: string): RouteRecommendation {
|
|
162
|
+
const taskLower = task.toLowerCase();
|
|
163
|
+
const keywordMap: Record<string, string> = {
|
|
164
|
+
code: 'coder',
|
|
165
|
+
implement: 'coder',
|
|
166
|
+
write: 'coder',
|
|
167
|
+
test: 'tester',
|
|
168
|
+
review: 'reviewer',
|
|
169
|
+
plan: 'planner',
|
|
170
|
+
research: 'researcher',
|
|
171
|
+
security: 'security-architect',
|
|
172
|
+
performance: 'performance-engineer',
|
|
173
|
+
memory: 'memory-specialist',
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
for (const [keyword, role] of Object.entries(keywordMap)) {
|
|
177
|
+
if (taskLower.includes(keyword)) {
|
|
178
|
+
return {
|
|
179
|
+
agentRole: role,
|
|
180
|
+
confidence: 0.5,
|
|
181
|
+
reasoning: `Keyword match: "${keyword}"`,
|
|
182
|
+
alternates: [],
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return {
|
|
188
|
+
agentRole: 'coder',
|
|
189
|
+
confidence: 0.3,
|
|
190
|
+
reasoning: 'Default fallback',
|
|
191
|
+
alternates: [],
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Extract condition from input
|
|
197
|
+
*/
|
|
198
|
+
private extractCondition(input: string): string {
|
|
199
|
+
// Extract key terms from input
|
|
200
|
+
const words = input.toLowerCase().split(/\s+/);
|
|
201
|
+
const keyWords = words.filter((w) => w.length > 4).slice(0, 5);
|
|
202
|
+
return keyWords.join('|');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Consolidate patterns (merge duplicates, prune low-confidence)
|
|
207
|
+
*/
|
|
208
|
+
consolidate(minConfidence: number = 0.3): { merged: number; pruned: number } {
|
|
209
|
+
let merged = 0;
|
|
210
|
+
let pruned = 0;
|
|
211
|
+
|
|
212
|
+
const toRemove: string[] = [];
|
|
213
|
+
|
|
214
|
+
for (const [id, pattern] of this.patterns) {
|
|
215
|
+
// Prune low confidence patterns with enough data
|
|
216
|
+
if (pattern.confidence < minConfidence && pattern.successCount + pattern.failureCount > 20) {
|
|
217
|
+
toRemove.push(id);
|
|
218
|
+
pruned++;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
for (const id of toRemove) {
|
|
223
|
+
this.patterns.delete(id);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return { merged, pruned };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Get all patterns
|
|
231
|
+
*/
|
|
232
|
+
getPatterns(): Pattern[] {
|
|
233
|
+
return Array.from(this.patterns.values());
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Get patterns by type
|
|
238
|
+
*/
|
|
239
|
+
getPatternsByType(type: PatternType): Pattern[] {
|
|
240
|
+
return Array.from(this.patterns.values()).filter((p) => p.type === type);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Add pattern
|
|
245
|
+
*/
|
|
246
|
+
addPattern(pattern: Pattern): void {
|
|
247
|
+
this.patterns.set(pattern.id, pattern);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Remove pattern
|
|
252
|
+
*/
|
|
253
|
+
removePattern(id: string): boolean {
|
|
254
|
+
return this.patterns.delete(id);
|
|
255
|
+
}
|
|
256
|
+
}
|