noormme 1.0.6 → 1.2.0
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 +92 -63
- package/dist/cjs/agentic/ActionJournal.js +13 -9
- package/dist/cjs/agentic/CapabilityManager.d.ts +9 -4
- package/dist/cjs/agentic/CapabilityManager.js +113 -17
- package/dist/cjs/agentic/CognitiveRepository.js +19 -9
- package/dist/cjs/agentic/ContextBuffer.js +24 -12
- package/dist/cjs/agentic/Cortex.d.ts +8 -1
- package/dist/cjs/agentic/Cortex.js +30 -7
- package/dist/cjs/agentic/EpisodicMemory.js +7 -5
- package/dist/cjs/agentic/PersonaManager.js +16 -8
- package/dist/cjs/agentic/PolicyEnforcer.js +31 -12
- package/dist/cjs/agentic/ResourceMonitor.js +4 -4
- package/dist/cjs/agentic/SessionCompressor.js +22 -14
- package/dist/cjs/agentic/SessionManager.js +36 -18
- package/dist/cjs/agentic/VectorIndexer.js +22 -18
- package/dist/cjs/agentic/improvement/AblationEngine.js +22 -15
- package/dist/cjs/agentic/improvement/ActionRefiner.js +12 -10
- package/dist/cjs/agentic/improvement/ConflictResolver.js +5 -5
- package/dist/cjs/agentic/improvement/CortexJanitor.d.ts +1 -1
- package/dist/cjs/agentic/improvement/CortexJanitor.js +64 -27
- package/dist/cjs/agentic/improvement/CuriosityEngine.d.ts +2 -2
- package/dist/cjs/agentic/improvement/CuriosityEngine.js +68 -59
- package/dist/cjs/agentic/improvement/EvolutionRitual.d.ts +24 -0
- package/dist/cjs/agentic/improvement/EvolutionRitual.js +91 -0
- package/dist/cjs/agentic/improvement/EvolutionaryPilot.d.ts +5 -0
- package/dist/cjs/agentic/improvement/EvolutionaryPilot.js +80 -7
- package/dist/cjs/agentic/improvement/GoalArchitect.d.ts +2 -2
- package/dist/cjs/agentic/improvement/GoalArchitect.js +20 -18
- package/dist/cjs/agentic/improvement/GovernanceManager.d.ts +1 -1
- package/dist/cjs/agentic/improvement/GovernanceManager.js +85 -49
- package/dist/cjs/agentic/improvement/HiveLink.d.ts +9 -0
- package/dist/cjs/agentic/improvement/HiveLink.js +120 -26
- package/dist/cjs/agentic/improvement/KnowledgeDistiller.d.ts +2 -0
- package/dist/cjs/agentic/improvement/KnowledgeDistiller.js +101 -47
- package/dist/cjs/agentic/improvement/RecursiveReasoner.d.ts +7 -1
- package/dist/cjs/agentic/improvement/RecursiveReasoner.js +106 -22
- package/dist/cjs/agentic/improvement/ReflectionEngine.js +10 -8
- package/dist/cjs/agentic/improvement/RitualOrchestrator.js +34 -22
- package/dist/cjs/agentic/improvement/RuleEngine.js +22 -17
- package/dist/cjs/agentic/improvement/SelfEvolution.js +24 -18
- package/dist/cjs/agentic/improvement/SelfTestRegistry.js +18 -15
- package/dist/cjs/agentic/improvement/SkillSynthesizer.d.ts +48 -0
- package/dist/cjs/agentic/improvement/SkillSynthesizer.js +288 -0
- package/dist/cjs/agentic/improvement/SovereignMetrics.js +19 -17
- package/dist/cjs/agentic/improvement/StrategicPlanner.d.ts +1 -1
- package/dist/cjs/agentic/improvement/StrategicPlanner.js +129 -55
- package/dist/cjs/agentic/telemetry/CognitiveSynthesizer.js +26 -12
- package/dist/cjs/agentic/telemetry/EventHarvester.js +3 -2
- package/dist/cjs/agentic/telemetry/ResearchAlchemist.js +13 -4
- package/dist/cjs/cache/cache-manager.js +7 -4
- package/dist/cjs/cli/commands/analyze.js +5 -4
- package/dist/cjs/cli/commands/generate.js +81 -44
- package/dist/cjs/cli/commands/init.js +7 -3
- package/dist/cjs/cli/commands/inspect.js +139 -36
- package/dist/cjs/cli/commands/migrate.js +5 -4
- package/dist/cjs/cli/commands/optimize.js +4 -4
- package/dist/cjs/cli/commands/status.js +9 -7
- package/dist/cjs/cli/commands/watch.js +7 -6
- package/dist/cjs/cli/index.js +2 -2
- package/dist/cjs/cli/ui/spinner.d.ts +15 -0
- package/dist/cjs/cli/ui/spinner.js +76 -0
- package/dist/cjs/dialect/database-introspector.js +3 -1
- package/dist/cjs/dialect/postgresql/postgresql-driver.js +3 -1
- package/dist/cjs/dialect/postgresql/postgresql-features.js +18 -8
- package/dist/cjs/dialect/postgresql/postgresql-introspector.js +2 -2
- package/dist/cjs/dialect/sqlite/sqlite-auto-indexer.js +47 -33
- package/dist/cjs/dialect/sqlite/sqlite-auto-optimizer.js +8 -7
- package/dist/cjs/dialect/sqlite/sqlite-driver.js +2 -2
- package/dist/cjs/dialect/sqlite/sqlite-introspector.js +15 -12
- package/dist/cjs/edge-runtime/edge-config.js +21 -19
- package/dist/cjs/errors/NoormError.js +22 -20
- package/dist/cjs/helpers/agent-schema.js +3 -0
- package/dist/cjs/helpers/postgresql.js +7 -4
- package/dist/cjs/helpers/schema-evolution.js +31 -6
- package/dist/cjs/index.d.ts +18 -16
- package/dist/cjs/logging/logger.js +8 -4
- package/dist/cjs/migration/data_migrator.js +12 -11
- package/dist/cjs/migration/database_migration_manager.js +17 -13
- package/dist/cjs/migration/schema_differ.js +22 -14
- package/dist/cjs/migration/schema_introspector.js +8 -8
- package/dist/cjs/migration/type_mapper.js +68 -67
- package/dist/cjs/noormme.js +54 -37
- package/dist/cjs/performance/index.js +5 -5
- package/dist/cjs/performance/query-optimizer.js +26 -21
- package/dist/cjs/performance/services/cache-service.js +26 -16
- package/dist/cjs/performance/services/connection-factory.js +28 -23
- package/dist/cjs/performance/services/metrics-collector.js +41 -36
- package/dist/cjs/performance/utils/query-parser.js +15 -16
- package/dist/cjs/relationships/relationship-engine.js +10 -8
- package/dist/cjs/repository/repository-factory.js +97 -38
- package/dist/cjs/schema/core/coordinators/schema-discovery.coordinator.js +1 -3
- package/dist/cjs/schema/core/discovery/relationship-discovery.js +16 -16
- package/dist/cjs/schema/core/discovery/table-metadata-discovery.js +9 -9
- package/dist/cjs/schema/core/discovery/view-discovery.js +5 -4
- package/dist/cjs/schema/core/factories/discovery-factory.js +4 -4
- package/dist/cjs/schema/core/utils/name-generator.js +14 -5
- package/dist/cjs/schema/core/utils/type-mapper.js +24 -24
- package/dist/cjs/schema/dialects/postgresql/postgresql-discovery.coordinator.js +8 -7
- package/dist/cjs/schema/dialects/sqlite/discovery/sqlite-constraint-discovery.js +17 -15
- package/dist/cjs/schema/dialects/sqlite/discovery/sqlite-index-discovery.js +8 -8
- package/dist/cjs/schema/dialects/sqlite/introspection/sqlite-schema-introspector.js +6 -11
- package/dist/cjs/schema/dialects/sqlite/sqlite-discovery.coordinator.js +14 -13
- package/dist/cjs/schema/test/basic-schema-test.js +11 -9
- package/dist/cjs/schema/test/dialect-capabilities.test.js +6 -6
- package/dist/cjs/schema/test/discovery-factory.test.js +2 -2
- package/dist/cjs/schema/test/error-handling.test.js +8 -6
- package/dist/cjs/schema/test/integration.test.js +24 -18
- package/dist/cjs/schema/test/schema-discovery-coordinator.test.js +9 -9
- package/dist/cjs/schema/test/simple-schema-test.js +9 -9
- package/dist/cjs/schema/test/sqlite-discovery-coordinator.test.js +64 -48
- package/dist/cjs/schema/test/test-runner.js +3 -3
- package/dist/cjs/sqlite-migration/index.d.ts +2 -2
- package/dist/cjs/sqlite-migration/sqlite-migration-manager.js +21 -17
- package/dist/cjs/sqlite-migration/sqlite-migration-provider.js +38 -34
- package/dist/cjs/testing/test-utils.js +36 -34
- package/dist/cjs/types/index.d.ts +61 -4
- package/dist/cjs/types/index.js +6 -3
- package/dist/cjs/types/type-generator.js +46 -42
- package/dist/cjs/util/safe-sql-helpers.js +1 -1
- package/dist/cjs/util/security-validator.js +20 -9
- package/dist/cjs/utils/errorHelpers.js +20 -10
- package/dist/cjs/watch/schema-watcher.js +22 -23
- package/dist/esm/agentic/ActionJournal.js +13 -9
- package/dist/esm/agentic/CapabilityManager.d.ts +9 -4
- package/dist/esm/agentic/CapabilityManager.js +113 -17
- package/dist/esm/agentic/CognitiveRepository.js +19 -9
- package/dist/esm/agentic/ContextBuffer.js +24 -12
- package/dist/esm/agentic/Cortex.d.ts +8 -1
- package/dist/esm/agentic/Cortex.js +30 -7
- package/dist/esm/agentic/EpisodicMemory.js +7 -5
- package/dist/esm/agentic/PersonaManager.js +16 -8
- package/dist/esm/agentic/PolicyEnforcer.js +31 -12
- package/dist/esm/agentic/ResourceMonitor.js +4 -4
- package/dist/esm/agentic/SessionCompressor.js +22 -14
- package/dist/esm/agentic/SessionManager.js +36 -18
- package/dist/esm/agentic/VectorIndexer.js +22 -18
- package/dist/esm/agentic/improvement/AblationEngine.js +22 -15
- package/dist/esm/agentic/improvement/ActionRefiner.js +12 -10
- package/dist/esm/agentic/improvement/ConflictResolver.js +5 -5
- package/dist/esm/agentic/improvement/CortexJanitor.d.ts +1 -1
- package/dist/esm/agentic/improvement/CortexJanitor.js +64 -27
- package/dist/esm/agentic/improvement/CuriosityEngine.d.ts +2 -2
- package/dist/esm/agentic/improvement/CuriosityEngine.js +68 -59
- package/dist/esm/agentic/improvement/EvolutionRitual.d.ts +24 -0
- package/dist/esm/agentic/improvement/EvolutionRitual.js +88 -0
- package/dist/esm/agentic/improvement/EvolutionaryPilot.d.ts +5 -0
- package/dist/esm/agentic/improvement/EvolutionaryPilot.js +80 -7
- package/dist/esm/agentic/improvement/GoalArchitect.d.ts +2 -2
- package/dist/esm/agentic/improvement/GoalArchitect.js +20 -18
- package/dist/esm/agentic/improvement/GovernanceManager.d.ts +1 -1
- package/dist/esm/agentic/improvement/GovernanceManager.js +85 -49
- package/dist/esm/agentic/improvement/HiveLink.d.ts +9 -0
- package/dist/esm/agentic/improvement/HiveLink.js +120 -26
- package/dist/esm/agentic/improvement/KnowledgeDistiller.d.ts +2 -0
- package/dist/esm/agentic/improvement/KnowledgeDistiller.js +101 -47
- package/dist/esm/agentic/improvement/RecursiveReasoner.d.ts +7 -1
- package/dist/esm/agentic/improvement/RecursiveReasoner.js +106 -22
- package/dist/esm/agentic/improvement/ReflectionEngine.js +10 -8
- package/dist/esm/agentic/improvement/RitualOrchestrator.js +34 -22
- package/dist/esm/agentic/improvement/RuleEngine.js +22 -17
- package/dist/esm/agentic/improvement/SelfEvolution.js +24 -18
- package/dist/esm/agentic/improvement/SelfTestRegistry.js +18 -15
- package/dist/esm/agentic/improvement/SkillSynthesizer.d.ts +48 -0
- package/dist/esm/agentic/improvement/SkillSynthesizer.js +285 -0
- package/dist/esm/agentic/improvement/SovereignMetrics.js +19 -17
- package/dist/esm/agentic/improvement/StrategicPlanner.d.ts +1 -1
- package/dist/esm/agentic/improvement/StrategicPlanner.js +129 -55
- package/dist/esm/agentic/telemetry/CognitiveSynthesizer.js +26 -12
- package/dist/esm/agentic/telemetry/EventHarvester.js +3 -2
- package/dist/esm/agentic/telemetry/ResearchAlchemist.js +13 -4
- package/dist/esm/cache/cache-manager.js +7 -4
- package/dist/esm/cli/commands/analyze.js +5 -4
- package/dist/esm/cli/commands/generate.js +82 -45
- package/dist/esm/cli/commands/init.js +8 -4
- package/dist/esm/cli/commands/inspect.js +140 -37
- package/dist/esm/cli/commands/migrate.js +5 -4
- package/dist/esm/cli/commands/optimize.js +4 -4
- package/dist/esm/cli/commands/status.js +9 -7
- package/dist/esm/cli/commands/watch.js +7 -6
- package/dist/esm/cli/index.js +2 -2
- package/dist/esm/cli/ui/spinner.d.ts +15 -0
- package/dist/esm/cli/ui/spinner.js +70 -0
- package/dist/esm/dialect/database-introspector.js +3 -1
- package/dist/esm/dialect/postgresql/postgresql-driver.js +3 -1
- package/dist/esm/dialect/postgresql/postgresql-features.js +18 -8
- package/dist/esm/dialect/postgresql/postgresql-introspector.js +2 -2
- package/dist/esm/dialect/sqlite/sqlite-auto-indexer.js +47 -33
- package/dist/esm/dialect/sqlite/sqlite-auto-optimizer.js +8 -7
- package/dist/esm/dialect/sqlite/sqlite-driver.js +2 -2
- package/dist/esm/dialect/sqlite/sqlite-introspector.js +15 -12
- package/dist/esm/dynamic/dynamic.js +1 -1
- package/dist/esm/edge-runtime/edge-config.js +21 -19
- package/dist/esm/errors/NoormError.js +22 -20
- package/dist/esm/helpers/agent-schema.js +3 -0
- package/dist/esm/helpers/postgresql.js +7 -4
- package/dist/esm/helpers/schema-evolution.js +31 -6
- package/dist/esm/index.d.ts +18 -16
- package/dist/esm/index.js +2 -2
- package/dist/esm/logging/logger.js +8 -4
- package/dist/esm/migration/data_migrator.js +12 -11
- package/dist/esm/migration/database_migration_manager.js +18 -14
- package/dist/esm/migration/schema_differ.js +22 -14
- package/dist/esm/migration/schema_introspector.js +8 -8
- package/dist/esm/migration/type_mapper.js +68 -67
- package/dist/esm/noormme.js +54 -37
- package/dist/esm/performance/index.js +5 -5
- package/dist/esm/performance/query-optimizer.js +26 -21
- package/dist/esm/performance/services/cache-service.js +26 -16
- package/dist/esm/performance/services/connection-factory.js +28 -23
- package/dist/esm/performance/services/metrics-collector.js +41 -36
- package/dist/esm/performance/utils/query-parser.js +15 -16
- package/dist/esm/raw-builder/sql.js +1 -1
- package/dist/esm/relationships/relationship-engine.js +10 -8
- package/dist/esm/repository/repository-factory.js +98 -39
- package/dist/esm/schema/builders/alter-table-add-index-builder.js +1 -1
- package/dist/esm/schema/builders/create-index-builder.js +2 -2
- package/dist/esm/schema/core/coordinators/schema-discovery.coordinator.js +1 -3
- package/dist/esm/schema/core/discovery/relationship-discovery.js +16 -16
- package/dist/esm/schema/core/discovery/table-metadata-discovery.js +9 -9
- package/dist/esm/schema/core/discovery/view-discovery.js +5 -4
- package/dist/esm/schema/core/factories/discovery-factory.js +4 -4
- package/dist/esm/schema/core/utils/name-generator.js +14 -5
- package/dist/esm/schema/core/utils/type-mapper.js +24 -24
- package/dist/esm/schema/dialects/postgresql/postgresql-discovery.coordinator.js +8 -7
- package/dist/esm/schema/dialects/sqlite/discovery/sqlite-constraint-discovery.js +17 -15
- package/dist/esm/schema/dialects/sqlite/discovery/sqlite-index-discovery.js +8 -8
- package/dist/esm/schema/dialects/sqlite/introspection/sqlite-schema-introspector.js +6 -11
- package/dist/esm/schema/dialects/sqlite/sqlite-discovery.coordinator.js +14 -13
- package/dist/esm/schema/test/basic-schema-test.js +11 -9
- package/dist/esm/schema/test/dialect-capabilities.test.js +6 -6
- package/dist/esm/schema/test/discovery-factory.test.js +2 -2
- package/dist/esm/schema/test/error-handling.test.js +8 -6
- package/dist/esm/schema/test/integration.test.js +24 -18
- package/dist/esm/schema/test/schema-discovery-coordinator.test.js +9 -9
- package/dist/esm/schema/test/simple-schema-test.js +9 -9
- package/dist/esm/schema/test/sqlite-discovery-coordinator.test.js +64 -48
- package/dist/esm/schema/test/test-runner.js +3 -3
- package/dist/esm/sqlite-migration/index.d.ts +2 -2
- package/dist/esm/sqlite-migration/sqlite-migration-manager.js +21 -17
- package/dist/esm/sqlite-migration/sqlite-migration-provider.js +38 -34
- package/dist/esm/testing/test-utils.js +36 -34
- package/dist/esm/types/index.d.ts +61 -4
- package/dist/esm/types/index.js +6 -3
- package/dist/esm/types/type-generator.js +46 -42
- package/dist/esm/util/safe-sql-helpers.js +1 -1
- package/dist/esm/util/security-validator.js +20 -9
- package/dist/esm/utils/errorHelpers.js +21 -11
- package/dist/esm/watch/schema-watcher.js +22 -23
- package/package.json +40 -44
|
@@ -62,7 +62,12 @@ function validateIdentifier(identifier, context = 'identifier') {
|
|
|
62
62
|
}
|
|
63
63
|
// Additional check: prevent reserved SQLite keywords that could be dangerous
|
|
64
64
|
const reservedKeywords = [
|
|
65
|
-
'PRAGMA',
|
|
65
|
+
'PRAGMA',
|
|
66
|
+
'ATTACH',
|
|
67
|
+
'DETACH',
|
|
68
|
+
'VACUUM',
|
|
69
|
+
'ANALYZE',
|
|
70
|
+
'REINDEX',
|
|
66
71
|
];
|
|
67
72
|
for (const keyword of reservedKeywords) {
|
|
68
73
|
if (identifier.toUpperCase() === keyword) {
|
|
@@ -83,7 +88,11 @@ function validateTableReference(tableRef) {
|
|
|
83
88
|
}
|
|
84
89
|
// Validate each part
|
|
85
90
|
parts.forEach((part, index) => {
|
|
86
|
-
const context = index === 0
|
|
91
|
+
const context = index === 0
|
|
92
|
+
? parts.length === 2
|
|
93
|
+
? 'schema name'
|
|
94
|
+
: 'table name'
|
|
95
|
+
: 'table name';
|
|
87
96
|
validateIdentifier(part, context);
|
|
88
97
|
});
|
|
89
98
|
}
|
|
@@ -108,7 +117,8 @@ function validateColumnReference(columnRef) {
|
|
|
108
117
|
context = index === 0 ? 'table name' : 'column name';
|
|
109
118
|
}
|
|
110
119
|
else {
|
|
111
|
-
context =
|
|
120
|
+
context =
|
|
121
|
+
index === 0 ? 'schema name' : index === 1 ? 'table name' : 'column name';
|
|
112
122
|
}
|
|
113
123
|
validateIdentifier(part, context);
|
|
114
124
|
});
|
|
@@ -140,7 +150,7 @@ function validateFilePath(filePath, allowedExtensions) {
|
|
|
140
150
|
}
|
|
141
151
|
// Validate file extension if specified
|
|
142
152
|
if (allowedExtensions && allowedExtensions.length > 0) {
|
|
143
|
-
const hasValidExtension = allowedExtensions.some(ext => filePath.toLowerCase().endsWith(ext.toLowerCase()));
|
|
153
|
+
const hasValidExtension = allowedExtensions.some((ext) => filePath.toLowerCase().endsWith(ext.toLowerCase()));
|
|
144
154
|
if (!hasValidExtension) {
|
|
145
155
|
throw new Error(`Invalid file extension for "${filePath}". ` +
|
|
146
156
|
`Allowed extensions: ${allowedExtensions.join(', ')}`);
|
|
@@ -164,7 +174,9 @@ function validateFilePath(filePath, allowedExtensions) {
|
|
|
164
174
|
function sanitizeDatabasePath(dbPath) {
|
|
165
175
|
validateFilePath(dbPath, ['.db', '.sqlite', '.sqlite3', '.db3']);
|
|
166
176
|
// Ensure the path doesn't escape current directory
|
|
167
|
-
if (dbPath.includes('..') ||
|
|
177
|
+
if (dbPath.includes('..') ||
|
|
178
|
+
dbPath.startsWith('/') ||
|
|
179
|
+
/^[a-zA-Z]:/.test(dbPath)) {
|
|
168
180
|
throw new Error(`Database path "${dbPath}" must be a relative path within the current directory`);
|
|
169
181
|
}
|
|
170
182
|
return dbPath;
|
|
@@ -221,8 +233,7 @@ class RateLimiter {
|
|
|
221
233
|
maxAttempts;
|
|
222
234
|
windowMs;
|
|
223
235
|
attempts = new Map();
|
|
224
|
-
constructor(maxAttempts = 10, windowMs = 60000
|
|
225
|
-
) {
|
|
236
|
+
constructor(maxAttempts = 10, windowMs = 60000) {
|
|
226
237
|
this.maxAttempts = maxAttempts;
|
|
227
238
|
this.windowMs = windowMs;
|
|
228
239
|
}
|
|
@@ -230,7 +241,7 @@ class RateLimiter {
|
|
|
230
241
|
const now = Date.now();
|
|
231
242
|
const attempts = this.attempts.get(key) || [];
|
|
232
243
|
// Remove old attempts outside the window
|
|
233
|
-
const recentAttempts = attempts.filter(time => now - time < this.windowMs);
|
|
244
|
+
const recentAttempts = attempts.filter((time) => now - time < this.windowMs);
|
|
234
245
|
if (recentAttempts.length >= this.maxAttempts) {
|
|
235
246
|
throw new Error(`Rate limit exceeded for ${key}. Please wait before trying again.`);
|
|
236
247
|
}
|
|
@@ -243,7 +254,7 @@ class RateLimiter {
|
|
|
243
254
|
}
|
|
244
255
|
cleanup(now) {
|
|
245
256
|
for (const [key, attempts] of this.attempts.entries()) {
|
|
246
|
-
const recentAttempts = attempts.filter(time => now - time < this.windowMs);
|
|
257
|
+
const recentAttempts = attempts.filter((time) => now - time < this.windowMs);
|
|
247
258
|
if (recentAttempts.length === 0) {
|
|
248
259
|
this.attempts.delete(key);
|
|
249
260
|
}
|
|
@@ -26,11 +26,15 @@ function wrapKyselyError(error, context) {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
// Handle connection errors
|
|
29
|
-
if (message.includes('connect') ||
|
|
29
|
+
if (message.includes('connect') ||
|
|
30
|
+
message.includes('ECONNREFUSED') ||
|
|
31
|
+
message.includes('ENOTFOUND')) {
|
|
30
32
|
return new NoormError_js_1.ConnectionError(message, error);
|
|
31
33
|
}
|
|
32
34
|
// Handle authentication errors
|
|
33
|
-
if (message.includes('authentication') ||
|
|
35
|
+
if (message.includes('authentication') ||
|
|
36
|
+
message.includes('password') ||
|
|
37
|
+
message.includes('SASL')) {
|
|
34
38
|
return new NoormError_js_1.ConnectionError('Authentication failed. Check your username and password.', error);
|
|
35
39
|
}
|
|
36
40
|
// Handle syntax errors
|
|
@@ -38,17 +42,19 @@ function wrapKyselyError(error, context) {
|
|
|
38
42
|
return new NoormError_js_1.NoormError(`SQL syntax error: ${message}`, {
|
|
39
43
|
table: context.table,
|
|
40
44
|
operation: context.operation,
|
|
41
|
-
suggestion:
|
|
42
|
-
originalError: error
|
|
45
|
+
suggestion: "Check your query syntax or report this as a bug if you're using NOORMME methods",
|
|
46
|
+
originalError: error,
|
|
43
47
|
});
|
|
44
48
|
}
|
|
45
49
|
// Handle constraint violations
|
|
46
|
-
if (message.includes('constraint') ||
|
|
50
|
+
if (message.includes('constraint') ||
|
|
51
|
+
message.includes('duplicate') ||
|
|
52
|
+
message.includes('unique')) {
|
|
47
53
|
return new NoormError_js_1.NoormError(`Database constraint violation: ${extractConstraintMessage(message)}`, {
|
|
48
54
|
table: context.table,
|
|
49
55
|
operation: context.operation,
|
|
50
56
|
suggestion: 'Check for duplicate values or foreign key violations',
|
|
51
|
-
originalError: error
|
|
57
|
+
originalError: error,
|
|
52
58
|
});
|
|
53
59
|
}
|
|
54
60
|
// Generic wrapper for other errors
|
|
@@ -56,7 +62,7 @@ function wrapKyselyError(error, context) {
|
|
|
56
62
|
table: context.table,
|
|
57
63
|
operation: context.operation,
|
|
58
64
|
suggestion: 'Check the database connection and query parameters',
|
|
59
|
-
originalError: error
|
|
65
|
+
originalError: error,
|
|
60
66
|
});
|
|
61
67
|
}
|
|
62
68
|
/**
|
|
@@ -121,14 +127,15 @@ function suggestCorrections(input, available, maxSuggestions = 3) {
|
|
|
121
127
|
const suggestions = [];
|
|
122
128
|
for (const option of available) {
|
|
123
129
|
const score = calculateSimilarity(input.toLowerCase(), option.toLowerCase());
|
|
124
|
-
if (score > 0.3) {
|
|
130
|
+
if (score > 0.3) {
|
|
131
|
+
// Only suggest if similarity > 30%
|
|
125
132
|
suggestions.push({ name: option, score });
|
|
126
133
|
}
|
|
127
134
|
}
|
|
128
135
|
return suggestions
|
|
129
136
|
.sort((a, b) => b.score - a.score)
|
|
130
137
|
.slice(0, maxSuggestions)
|
|
131
|
-
.map(s => s.name);
|
|
138
|
+
.map((s) => s.name);
|
|
132
139
|
}
|
|
133
140
|
/**
|
|
134
141
|
* Calculate string similarity using Jaro-Winkler algorithm (simplified)
|
|
@@ -173,7 +180,10 @@ function calculateSimilarity(str1, str2) {
|
|
|
173
180
|
transpositions++;
|
|
174
181
|
k++;
|
|
175
182
|
}
|
|
176
|
-
const jaro = (matches / len1 +
|
|
183
|
+
const jaro = (matches / len1 +
|
|
184
|
+
matches / len2 +
|
|
185
|
+
(matches - transpositions / 2) / matches) /
|
|
186
|
+
3;
|
|
177
187
|
// Jaro-Winkler bonus for common prefix
|
|
178
188
|
let prefix = 0;
|
|
179
189
|
for (let i = 0; i < Math.min(len1, len2, 4); i++) {
|
|
@@ -27,7 +27,7 @@ class SchemaWatcher {
|
|
|
27
27
|
ignoreViews: true,
|
|
28
28
|
ignoredTables: [],
|
|
29
29
|
enabled: options.enabled !== undefined ? options.enabled : defaultEnabled,
|
|
30
|
-
...options
|
|
30
|
+
...options,
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
@@ -57,7 +57,7 @@ class SchemaWatcher {
|
|
|
57
57
|
}
|
|
58
58
|
this.isWatching = true;
|
|
59
59
|
this.intervalId = setInterval(() => {
|
|
60
|
-
this.checkForChanges().catch(error => {
|
|
60
|
+
this.checkForChanges().catch((error) => {
|
|
61
61
|
this.logger.error('Error checking for schema changes:', error);
|
|
62
62
|
});
|
|
63
63
|
}, this.options.pollInterval);
|
|
@@ -141,23 +141,22 @@ class SchemaWatcher {
|
|
|
141
141
|
// Create a deterministic string representation of the schema
|
|
142
142
|
const schemaString = JSON.stringify({
|
|
143
143
|
tables: schema.tables
|
|
144
|
-
.filter(table => !this.options.ignoredTables?.includes(table.name))
|
|
145
|
-
.map(table => ({
|
|
144
|
+
.filter((table) => !this.options.ignoredTables?.includes(table.name))
|
|
145
|
+
.map((table) => ({
|
|
146
146
|
name: table.name,
|
|
147
|
-
columns: table.columns.map(col => ({
|
|
147
|
+
columns: table.columns.map((col) => ({
|
|
148
148
|
name: col.name,
|
|
149
149
|
type: col.type,
|
|
150
150
|
nullable: col.nullable,
|
|
151
151
|
isPrimaryKey: col.isPrimaryKey,
|
|
152
|
-
defaultValue: col.defaultValue
|
|
152
|
+
defaultValue: col.defaultValue,
|
|
153
153
|
})),
|
|
154
154
|
primaryKey: table.primaryKey,
|
|
155
155
|
foreignKeys: table.foreignKeys,
|
|
156
|
-
indexes: table.indexes
|
|
156
|
+
indexes: table.indexes,
|
|
157
157
|
}))
|
|
158
158
|
.sort((a, b) => a.name.localeCompare(b.name)),
|
|
159
|
-
relationships: schema.relationships
|
|
160
|
-
.sort((a, b) => `${a.fromTable}.${a.name}`.localeCompare(`${b.fromTable}.${b.name}`))
|
|
159
|
+
relationships: schema.relationships.sort((a, b) => `${a.fromTable}.${a.name}`.localeCompare(`${b.fromTable}.${b.name}`)),
|
|
161
160
|
});
|
|
162
161
|
return (0, node_crypto_1.createHash)('sha256').update(schemaString).digest('hex');
|
|
163
162
|
}
|
|
@@ -175,20 +174,20 @@ class SchemaWatcher {
|
|
|
175
174
|
changes.push({
|
|
176
175
|
type: 'table_added',
|
|
177
176
|
table: table.name,
|
|
178
|
-
details: { columns: table.columns.length }
|
|
177
|
+
details: { columns: table.columns.length },
|
|
179
178
|
});
|
|
180
179
|
}
|
|
181
180
|
return changes;
|
|
182
181
|
}
|
|
183
|
-
const oldTablesMap = new Map(oldSchema.tables.map(t => [t.name, t]));
|
|
184
|
-
const newTablesMap = new Map(newSchema.tables.map(t => [t.name, t]));
|
|
182
|
+
const oldTablesMap = new Map(oldSchema.tables.map((t) => [t.name, t]));
|
|
183
|
+
const newTablesMap = new Map(newSchema.tables.map((t) => [t.name, t]));
|
|
185
184
|
// Check for added tables
|
|
186
185
|
for (const table of newSchema.tables) {
|
|
187
186
|
if (!oldTablesMap.has(table.name)) {
|
|
188
187
|
changes.push({
|
|
189
188
|
type: 'table_added',
|
|
190
189
|
table: table.name,
|
|
191
|
-
details: { columns: table.columns.length }
|
|
190
|
+
details: { columns: table.columns.length },
|
|
192
191
|
});
|
|
193
192
|
}
|
|
194
193
|
}
|
|
@@ -197,7 +196,7 @@ class SchemaWatcher {
|
|
|
197
196
|
if (!newTablesMap.has(table.name)) {
|
|
198
197
|
changes.push({
|
|
199
198
|
type: 'table_removed',
|
|
200
|
-
table: table.name
|
|
199
|
+
table: table.name,
|
|
201
200
|
});
|
|
202
201
|
}
|
|
203
202
|
}
|
|
@@ -205,8 +204,8 @@ class SchemaWatcher {
|
|
|
205
204
|
for (const newTable of newSchema.tables) {
|
|
206
205
|
const oldTable = oldTablesMap.get(newTable.name);
|
|
207
206
|
if (oldTable) {
|
|
208
|
-
const oldColumnsMap = new Map(oldTable.columns.map(c => [c.name, c]));
|
|
209
|
-
const newColumnsMap = new Map(newTable.columns.map(c => [c.name, c]));
|
|
207
|
+
const oldColumnsMap = new Map(oldTable.columns.map((c) => [c.name, c]));
|
|
208
|
+
const newColumnsMap = new Map(newTable.columns.map((c) => [c.name, c]));
|
|
210
209
|
// Check for added columns
|
|
211
210
|
for (const column of newTable.columns) {
|
|
212
211
|
if (!oldColumnsMap.has(column.name)) {
|
|
@@ -214,7 +213,7 @@ class SchemaWatcher {
|
|
|
214
213
|
type: 'column_added',
|
|
215
214
|
table: newTable.name,
|
|
216
215
|
column: column.name,
|
|
217
|
-
details: { type: column.type }
|
|
216
|
+
details: { type: column.type },
|
|
218
217
|
});
|
|
219
218
|
}
|
|
220
219
|
}
|
|
@@ -224,7 +223,7 @@ class SchemaWatcher {
|
|
|
224
223
|
changes.push({
|
|
225
224
|
type: 'column_removed',
|
|
226
225
|
table: newTable.name,
|
|
227
|
-
column: column.name
|
|
226
|
+
column: column.name,
|
|
228
227
|
});
|
|
229
228
|
}
|
|
230
229
|
else {
|
|
@@ -237,8 +236,8 @@ class SchemaWatcher {
|
|
|
237
236
|
column: column.name,
|
|
238
237
|
details: {
|
|
239
238
|
old: { type: column.type, nullable: column.nullable },
|
|
240
|
-
new: { type: newColumn.type, nullable: newColumn.nullable }
|
|
241
|
-
}
|
|
239
|
+
new: { type: newColumn.type, nullable: newColumn.nullable },
|
|
240
|
+
},
|
|
242
241
|
});
|
|
243
242
|
}
|
|
244
243
|
}
|
|
@@ -248,15 +247,15 @@ class SchemaWatcher {
|
|
|
248
247
|
return changes;
|
|
249
248
|
}
|
|
250
249
|
isColumnModified(oldCol, newCol) {
|
|
251
|
-
return oldCol.type !== newCol.type ||
|
|
250
|
+
return (oldCol.type !== newCol.type ||
|
|
252
251
|
oldCol.nullable !== newCol.nullable ||
|
|
253
|
-
oldCol.isPrimaryKey !== newCol.isPrimaryKey;
|
|
252
|
+
oldCol.isPrimaryKey !== newCol.isPrimaryKey);
|
|
254
253
|
}
|
|
255
254
|
/**
|
|
256
255
|
* Notify all registered callbacks about schema changes
|
|
257
256
|
*/
|
|
258
257
|
notifyCallbacks(changes) {
|
|
259
|
-
this.callbacks.forEach(callback => {
|
|
258
|
+
this.callbacks.forEach((callback) => {
|
|
260
259
|
try {
|
|
261
260
|
callback(changes);
|
|
262
261
|
}
|
|
@@ -29,7 +29,7 @@ export class ActionJournal {
|
|
|
29
29
|
tool_name: toolName,
|
|
30
30
|
arguments: JSON.stringify(args),
|
|
31
31
|
status: 'pending',
|
|
32
|
-
created_at: new Date()
|
|
32
|
+
created_at: new Date(),
|
|
33
33
|
})
|
|
34
34
|
.returningAll()
|
|
35
35
|
.executeTakeFirstOrThrow();
|
|
@@ -50,7 +50,7 @@ export class ActionJournal {
|
|
|
50
50
|
status,
|
|
51
51
|
outcome,
|
|
52
52
|
duration_ms: durationMs || null,
|
|
53
|
-
metadata: metadata ? JSON.stringify(metadata) : null
|
|
53
|
+
metadata: metadata ? JSON.stringify(metadata) : null,
|
|
54
54
|
})
|
|
55
55
|
.where('id', '=', actionId)
|
|
56
56
|
.returningAll()
|
|
@@ -74,7 +74,7 @@ export class ActionJournal {
|
|
|
74
74
|
.where('session_id', '=', sessionId)
|
|
75
75
|
.orderBy('created_at', 'asc')
|
|
76
76
|
.execute();
|
|
77
|
-
return actions.map(a => this.parseAction(a));
|
|
77
|
+
return actions.map((a) => this.parseAction(a));
|
|
78
78
|
}
|
|
79
79
|
/**
|
|
80
80
|
* Get actions by tool name across all sessions.
|
|
@@ -87,7 +87,7 @@ export class ActionJournal {
|
|
|
87
87
|
.orderBy('created_at', 'desc')
|
|
88
88
|
.limit(limit)
|
|
89
89
|
.execute();
|
|
90
|
-
return actions.map(a => this.parseAction(a));
|
|
90
|
+
return actions.map((a) => this.parseAction(a));
|
|
91
91
|
}
|
|
92
92
|
/**
|
|
93
93
|
* Generate a report of tool failures.
|
|
@@ -98,7 +98,7 @@ export class ActionJournal {
|
|
|
98
98
|
.select([
|
|
99
99
|
'tool_name',
|
|
100
100
|
(eb) => eb.fn.count('id').as('failureCount'),
|
|
101
|
-
(eb) => eb.fn.max('created_at').as('lastFailure')
|
|
101
|
+
(eb) => eb.fn.max('created_at').as('lastFailure'),
|
|
102
102
|
])
|
|
103
103
|
.where('status', '=', 'failure')
|
|
104
104
|
.groupBy('tool_name')
|
|
@@ -107,7 +107,7 @@ export class ActionJournal {
|
|
|
107
107
|
return results.map((r) => ({
|
|
108
108
|
toolName: r.tool_name,
|
|
109
109
|
failureCount: Number(r.failureCount),
|
|
110
|
-
lastFailure: r.lastFailure
|
|
110
|
+
lastFailure: r.lastFailure,
|
|
111
111
|
}));
|
|
112
112
|
}
|
|
113
113
|
parseAction(action) {
|
|
@@ -116,12 +116,16 @@ export class ActionJournal {
|
|
|
116
116
|
sessionId: action.session_id,
|
|
117
117
|
messageId: action.message_id,
|
|
118
118
|
toolName: action.tool_name,
|
|
119
|
-
arguments: typeof action.arguments === 'string'
|
|
119
|
+
arguments: typeof action.arguments === 'string'
|
|
120
|
+
? JSON.parse(action.arguments)
|
|
121
|
+
: action.arguments || {},
|
|
120
122
|
status: action.status,
|
|
121
123
|
outcome: action.outcome,
|
|
122
124
|
durationMs: action.duration_ms,
|
|
123
|
-
metadata: typeof action.metadata === 'string'
|
|
124
|
-
|
|
125
|
+
metadata: typeof action.metadata === 'string'
|
|
126
|
+
? JSON.parse(action.metadata)
|
|
127
|
+
: action.metadata || {},
|
|
128
|
+
createdAt: new Date(action.created_at),
|
|
125
129
|
};
|
|
126
130
|
}
|
|
127
131
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { Kysely } from '../kysely.js';
|
|
2
|
-
import
|
|
2
|
+
import { AgenticConfig, AgentCapability } from '../types/index.js';
|
|
3
|
+
import type { Cortex } from './Cortex.js';
|
|
3
4
|
export interface CapabilityTable {
|
|
4
5
|
id: number | string;
|
|
5
6
|
name: string;
|
|
6
7
|
version: string;
|
|
7
8
|
description: string | null;
|
|
9
|
+
status: 'experimental' | 'verified' | 'blacklisted';
|
|
8
10
|
reliability: number;
|
|
9
11
|
metadata: string | null;
|
|
10
12
|
created_at: string | Date;
|
|
@@ -19,9 +21,11 @@ export interface CapabilityDatabase {
|
|
|
19
21
|
*/
|
|
20
22
|
export declare class CapabilityManager {
|
|
21
23
|
private db;
|
|
24
|
+
private cortex;
|
|
22
25
|
private config;
|
|
23
26
|
private capabilitiesTable;
|
|
24
|
-
|
|
27
|
+
private evolutionConfig;
|
|
28
|
+
constructor(db: Kysely<any>, cortex: Cortex, config?: AgenticConfig);
|
|
25
29
|
private get typedDb();
|
|
26
30
|
/**
|
|
27
31
|
* Register or update a capability (skill)
|
|
@@ -29,6 +33,7 @@ export declare class CapabilityManager {
|
|
|
29
33
|
registerCapability(name: string, version: string, description?: string, metadata?: Record<string, any>): Promise<AgentCapability>;
|
|
30
34
|
/**
|
|
31
35
|
* Update reliability based on action outcome using a damped moving average.
|
|
36
|
+
* Manages the lifecycle of emergent skills (sandbox -> verified / blacklisted).
|
|
32
37
|
*/
|
|
33
38
|
reportOutcome(name: string, success: boolean): Promise<void>;
|
|
34
39
|
/**
|
|
@@ -36,8 +41,8 @@ export declare class CapabilityManager {
|
|
|
36
41
|
*/
|
|
37
42
|
getReliability(name: string): Promise<number>;
|
|
38
43
|
/**
|
|
39
|
-
* Get all registered capabilities
|
|
44
|
+
* Get all registered capabilities, optionally filtered by status
|
|
40
45
|
*/
|
|
41
|
-
getCapabilities(): Promise<AgentCapability[]>;
|
|
46
|
+
getCapabilities(status?: AgentCapability['status']): Promise<AgentCapability[]>;
|
|
42
47
|
private parseCapability;
|
|
43
48
|
}
|
|
@@ -5,12 +5,22 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export class CapabilityManager {
|
|
7
7
|
db;
|
|
8
|
+
cortex;
|
|
8
9
|
config;
|
|
9
10
|
capabilitiesTable;
|
|
10
|
-
|
|
11
|
+
evolutionConfig;
|
|
12
|
+
constructor(db, cortex, config = {}) {
|
|
11
13
|
this.db = db;
|
|
14
|
+
this.cortex = cortex;
|
|
12
15
|
this.config = config;
|
|
13
16
|
this.capabilitiesTable = config.capabilitiesTable || 'agent_capabilities';
|
|
17
|
+
this.evolutionConfig = {
|
|
18
|
+
verificationWindow: config.evolution?.verificationWindow ?? 20,
|
|
19
|
+
rollbackThresholdZ: config.evolution?.rollbackThresholdZ ?? 2.5,
|
|
20
|
+
enableHiveLink: config.evolution?.enableHiveLink ?? true,
|
|
21
|
+
mutationAggressiveness: config.evolution?.mutationAggressiveness ?? 0.5,
|
|
22
|
+
maxSandboxSkills: config.evolution?.maxSandboxSkills ?? 5,
|
|
23
|
+
};
|
|
14
24
|
}
|
|
15
25
|
get typedDb() {
|
|
16
26
|
return this.db;
|
|
@@ -31,8 +41,12 @@ export class CapabilityManager {
|
|
|
31
41
|
.updateTable(this.capabilitiesTable)
|
|
32
42
|
.set({
|
|
33
43
|
description: description || existing.description,
|
|
34
|
-
|
|
35
|
-
|
|
44
|
+
status: existing.status || 'experimental',
|
|
45
|
+
metadata: JSON.stringify({
|
|
46
|
+
...JSON.parse(existing.metadata || '{}'),
|
|
47
|
+
...metadata,
|
|
48
|
+
}),
|
|
49
|
+
updated_at: new Date(),
|
|
36
50
|
})
|
|
37
51
|
.where('id', '=', existing.id)
|
|
38
52
|
.returningAll()
|
|
@@ -45,10 +59,15 @@ export class CapabilityManager {
|
|
|
45
59
|
name,
|
|
46
60
|
version,
|
|
47
61
|
description: description || null,
|
|
62
|
+
status: metadata.initialStatus || 'experimental',
|
|
48
63
|
reliability: 1.0,
|
|
49
|
-
metadata: JSON.stringify({
|
|
64
|
+
metadata: JSON.stringify({
|
|
65
|
+
...metadata,
|
|
66
|
+
successCount: 0,
|
|
67
|
+
totalCount: 0,
|
|
68
|
+
}),
|
|
50
69
|
created_at: new Date(),
|
|
51
|
-
updated_at: new Date()
|
|
70
|
+
updated_at: new Date(),
|
|
52
71
|
})
|
|
53
72
|
.returningAll()
|
|
54
73
|
.executeTakeFirstOrThrow();
|
|
@@ -57,6 +76,7 @@ export class CapabilityManager {
|
|
|
57
76
|
}
|
|
58
77
|
/**
|
|
59
78
|
* Update reliability based on action outcome using a damped moving average.
|
|
79
|
+
* Manages the lifecycle of emergent skills (sandbox -> verified / blacklisted).
|
|
60
80
|
*/
|
|
61
81
|
async reportOutcome(name, success) {
|
|
62
82
|
await this.db.transaction().execute(async (trx) => {
|
|
@@ -68,7 +88,9 @@ export class CapabilityManager {
|
|
|
68
88
|
.executeTakeFirst();
|
|
69
89
|
if (capability) {
|
|
70
90
|
const cap = capability;
|
|
71
|
-
const metadata = typeof cap.metadata === 'string'
|
|
91
|
+
const metadata = typeof cap.metadata === 'string'
|
|
92
|
+
? JSON.parse(cap.metadata)
|
|
93
|
+
: cap.metadata || {};
|
|
72
94
|
const totalCount = (metadata.totalCount || 0) + 1;
|
|
73
95
|
const successCount = (metadata.successCount || 0) + (success ? 1 : 0);
|
|
74
96
|
// Damped moving average: weight recent outcomes more but keep history
|
|
@@ -78,12 +100,81 @@ export class CapabilityManager {
|
|
|
78
100
|
const newReliability = success
|
|
79
101
|
? Math.min(1.0, currentReliability * (1 - alpha) + alpha)
|
|
80
102
|
: Math.max(0.0, currentReliability * (1 - alpha));
|
|
103
|
+
let newStatus = cap.status || 'experimental';
|
|
104
|
+
// --- Emergent Skill Evolution Optimization ---
|
|
105
|
+
const successStreak = (metadata.successStreak || 0) + (success ? 1 : 0);
|
|
106
|
+
const failureStreak = success ? 0 : (metadata.failureStreak || 0) + 1;
|
|
107
|
+
const streakSuccess = success ? successStreak : 0;
|
|
108
|
+
const winRate = successCount / totalCount;
|
|
109
|
+
const windowSize = this.evolutionConfig.verificationWindow || 20;
|
|
110
|
+
const minSampleSize = Math.ceil(windowSize * 0.75);
|
|
111
|
+
// Fast-Track Promotion: 5 consecutive successes bypasses sample size
|
|
112
|
+
const isPromotable = (totalCount >= minSampleSize && winRate >= 0.8) || streakSuccess >= 5;
|
|
113
|
+
// Early-Exit Rollback: 3 consecutive failures at the start immediately blacklists
|
|
114
|
+
const isCatastrophic = !success && failureStreak >= 3 && totalCount <= 5;
|
|
115
|
+
// Pass 6: Predictive Pre-warming Trigger
|
|
116
|
+
// If a skill is close to promotion, pre-warm its optimized description
|
|
117
|
+
const promoThreshold = Math.ceil(minSampleSize * 0.8);
|
|
118
|
+
const isNearingPromotion = (totalCount >= promoThreshold && winRate >= 0.8) ||
|
|
119
|
+
streakSuccess === 4;
|
|
120
|
+
if (isNearingPromotion &&
|
|
121
|
+
newStatus === 'experimental' &&
|
|
122
|
+
this.cortex.skillSynthesizer) {
|
|
123
|
+
// Trigger async background pre-warming
|
|
124
|
+
this.cortex.skillSynthesizer.preWarmSkill(name).catch(() => { });
|
|
125
|
+
}
|
|
126
|
+
// --- Production Hardening: Dynamic Performance Baselining ---
|
|
127
|
+
const historyAlpha = 0.05; // Slower moving average for baseline
|
|
128
|
+
const baseline = metadata.performanceBaseline ?? winRate;
|
|
129
|
+
const newBaseline = baseline * (1 - historyAlpha) + winRate * historyAlpha;
|
|
130
|
+
// Variance tracking for Z-score calculation
|
|
131
|
+
const variance = metadata.performanceVariance ?? 0.01;
|
|
132
|
+
const diff = winRate - baseline;
|
|
133
|
+
const newVariance = variance * (1 - historyAlpha) + Math.pow(diff, 2) * historyAlpha;
|
|
134
|
+
const stdDev = Math.sqrt(newVariance);
|
|
135
|
+
// Z-Score: How many standard deviations is current performance from baseline?
|
|
136
|
+
const zScore = stdDev > 0 ? (winRate - baseline) / stdDev : 0;
|
|
137
|
+
// Promotion/Demotion Logic
|
|
138
|
+
if (isCatastrophic &&
|
|
139
|
+
(newStatus === 'experimental' || newStatus === 'sandbox')) {
|
|
140
|
+
console.error(`[CapabilityManager] Skill '${name}' FAILED early-exit safety check (Streak: ${failureStreak}). Blacklisting immediately.`);
|
|
141
|
+
newStatus = 'blacklisted';
|
|
142
|
+
}
|
|
143
|
+
else if (isPromotable &&
|
|
144
|
+
(newStatus === 'experimental' || newStatus === 'sandbox')) {
|
|
145
|
+
console.log(`[CapabilityManager] Skill '${name}' PASSED fast-track verification (Streak: ${streakSuccess}, Rate: ${(winRate * 100).toFixed(1)}%). Promoting to Verified.`);
|
|
146
|
+
newStatus = 'verified';
|
|
147
|
+
}
|
|
148
|
+
else if (totalCount >= minSampleSize) {
|
|
149
|
+
if (winRate < 0.4) {
|
|
150
|
+
console.log(`[CapabilityManager] Skill '${name}' FAILED statistical verification (Rate: ${(winRate * 100).toFixed(1)}%). Blacklisting.`);
|
|
151
|
+
newStatus = 'blacklisted';
|
|
152
|
+
}
|
|
153
|
+
else if (newStatus === 'verified' && zScore < -2.0) {
|
|
154
|
+
// Performance Collapse: Z-score indicates current run is significantly below historical baseline
|
|
155
|
+
console.warn(`[CapabilityManager] Verified skill '${name}' PERFORMANCE COLLAPSE (Z: ${zScore.toFixed(2)}, Rate: ${(winRate * 100).toFixed(1)}%). Demoting to Experimental.`);
|
|
156
|
+
newStatus = 'experimental';
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (newStatus !== cap.status) {
|
|
160
|
+
console.log(`[CapabilityManager] EVOLVING STATUS: ${name} (${cap.status} -> ${newStatus})`);
|
|
161
|
+
}
|
|
81
162
|
await trx
|
|
82
163
|
.updateTable(this.capabilitiesTable)
|
|
83
164
|
.set({
|
|
84
165
|
reliability: newReliability,
|
|
85
|
-
|
|
86
|
-
|
|
166
|
+
status: newStatus,
|
|
167
|
+
metadata: JSON.stringify({
|
|
168
|
+
...metadata,
|
|
169
|
+
totalCount,
|
|
170
|
+
successCount,
|
|
171
|
+
successStreak: streakSuccess,
|
|
172
|
+
failureStreak,
|
|
173
|
+
performanceBaseline: newBaseline,
|
|
174
|
+
performanceVariance: newVariance,
|
|
175
|
+
lastOutcomeType: success ? 'success' : 'failure', // Categorization point
|
|
176
|
+
}),
|
|
177
|
+
updated_at: new Date(),
|
|
87
178
|
})
|
|
88
179
|
.where('id', '=', cap.id)
|
|
89
180
|
.execute();
|
|
@@ -103,15 +194,17 @@ export class CapabilityManager {
|
|
|
103
194
|
return cap ? cap.reliability : 0.0;
|
|
104
195
|
}
|
|
105
196
|
/**
|
|
106
|
-
* Get all registered capabilities
|
|
197
|
+
* Get all registered capabilities, optionally filtered by status
|
|
107
198
|
*/
|
|
108
|
-
async getCapabilities() {
|
|
109
|
-
|
|
199
|
+
async getCapabilities(status) {
|
|
200
|
+
let query = this.typedDb
|
|
110
201
|
.selectFrom(this.capabilitiesTable)
|
|
111
|
-
.selectAll()
|
|
112
|
-
|
|
113
|
-
.
|
|
114
|
-
|
|
202
|
+
.selectAll();
|
|
203
|
+
if (status) {
|
|
204
|
+
query = query.where('status', '=', status);
|
|
205
|
+
}
|
|
206
|
+
const list = await query.orderBy('name', 'asc').execute();
|
|
207
|
+
return list.map((c) => this.parseCapability(c));
|
|
115
208
|
}
|
|
116
209
|
parseCapability(cap) {
|
|
117
210
|
return {
|
|
@@ -119,10 +212,13 @@ export class CapabilityManager {
|
|
|
119
212
|
name: cap.name,
|
|
120
213
|
version: cap.version,
|
|
121
214
|
description: cap.description,
|
|
215
|
+
status: cap.status || 'experimental',
|
|
122
216
|
reliability: cap.reliability,
|
|
123
|
-
metadata: typeof cap.metadata === 'string'
|
|
217
|
+
metadata: typeof cap.metadata === 'string'
|
|
218
|
+
? JSON.parse(cap.metadata)
|
|
219
|
+
: cap.metadata || {},
|
|
124
220
|
createdAt: new Date(cap.created_at),
|
|
125
|
-
updatedAt: new Date(cap.updated_at)
|
|
221
|
+
updatedAt: new Date(cap.updated_at),
|
|
126
222
|
};
|
|
127
223
|
}
|
|
128
224
|
}
|