noormme 1.1.0 → 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 +84 -65
- package/dist/cjs/agentic/ActionJournal.js +13 -9
- package/dist/cjs/agentic/CapabilityManager.js +35 -21
- package/dist/cjs/agentic/CognitiveRepository.js +19 -9
- package/dist/cjs/agentic/ContextBuffer.js +24 -12
- package/dist/cjs/agentic/Cortex.js +11 -4
- 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.js +30 -9
- package/dist/cjs/agentic/improvement/CuriosityEngine.js +27 -23
- package/dist/cjs/agentic/improvement/EvolutionRitual.js +4 -4
- package/dist/cjs/agentic/improvement/EvolutionaryPilot.js +16 -6
- 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.js +19 -11
- package/dist/cjs/agentic/improvement/HiveLink.js +22 -15
- package/dist/cjs/agentic/improvement/KnowledgeDistiller.js +48 -32
- package/dist/cjs/agentic/improvement/RecursiveReasoner.js +40 -17
- package/dist/cjs/agentic/improvement/ReflectionEngine.js +10 -8
- package/dist/cjs/agentic/improvement/RitualOrchestrator.js +28 -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.js +42 -27
- package/dist/cjs/agentic/improvement/SovereignMetrics.js +19 -17
- package/dist/cjs/agentic/improvement/StrategicPlanner.js +120 -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 +5 -2
- 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 +2 -0
- package/dist/cjs/helpers/postgresql.js +7 -4
- package/dist/cjs/helpers/schema-evolution.js +31 -6
- package/dist/cjs/index.d.ts +3 -3
- 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 +52 -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 +5 -2
- 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.js +35 -21
- package/dist/esm/agentic/CognitiveRepository.js +19 -9
- package/dist/esm/agentic/ContextBuffer.js +24 -12
- package/dist/esm/agentic/Cortex.js +11 -4
- 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.js +30 -9
- package/dist/esm/agentic/improvement/CuriosityEngine.js +27 -23
- package/dist/esm/agentic/improvement/EvolutionRitual.js +4 -4
- package/dist/esm/agentic/improvement/EvolutionaryPilot.js +16 -6
- 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.js +19 -11
- package/dist/esm/agentic/improvement/HiveLink.js +22 -15
- package/dist/esm/agentic/improvement/KnowledgeDistiller.js +48 -32
- package/dist/esm/agentic/improvement/RecursiveReasoner.js +40 -17
- package/dist/esm/agentic/improvement/ReflectionEngine.js +10 -8
- package/dist/esm/agentic/improvement/RitualOrchestrator.js +28 -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.js +42 -27
- package/dist/esm/agentic/improvement/SovereignMetrics.js +19 -17
- package/dist/esm/agentic/improvement/StrategicPlanner.js +120 -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 +5 -2
- 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 +2 -0
- package/dist/esm/helpers/postgresql.js +7 -4
- package/dist/esm/helpers/schema-evolution.js +31 -6
- package/dist/esm/index.d.ts +3 -3
- 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 +52 -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 +5 -2
- 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
|
@@ -27,12 +27,12 @@ class HiveLink {
|
|
|
27
27
|
async broadcastKnowledge(minConfidence = 0.9) {
|
|
28
28
|
console.log(`[HiveLink] Broadcasting knowledge with confidence >= ${minConfidence}`);
|
|
29
29
|
// Find high-confidence items that are "local" (have a source_session_id)
|
|
30
|
-
const items = await this.typedDb
|
|
30
|
+
const items = (await this.typedDb
|
|
31
31
|
.selectFrom(this.knowledgeTable)
|
|
32
32
|
.selectAll()
|
|
33
33
|
.where('confidence', '>=', minConfidence)
|
|
34
34
|
.where('source_session_id', 'is not', null) // Only local items
|
|
35
|
-
.execute();
|
|
35
|
+
.execute());
|
|
36
36
|
let promotedCount = 0;
|
|
37
37
|
for (const item of items) {
|
|
38
38
|
// Check if a global version already exists
|
|
@@ -51,7 +51,7 @@ class HiveLink {
|
|
|
51
51
|
.updateTable(this.knowledgeTable)
|
|
52
52
|
.set({
|
|
53
53
|
confidence: newConfidence,
|
|
54
|
-
updated_at: new Date()
|
|
54
|
+
updated_at: new Date(),
|
|
55
55
|
})
|
|
56
56
|
.where('id', '=', existingGlobal.id)
|
|
57
57
|
.execute();
|
|
@@ -72,10 +72,10 @@ class HiveLink {
|
|
|
72
72
|
metadata: JSON.stringify({
|
|
73
73
|
...item.metadata,
|
|
74
74
|
promoted_from: item.id,
|
|
75
|
-
promoted_at: new Date()
|
|
75
|
+
promoted_at: new Date(),
|
|
76
76
|
}),
|
|
77
77
|
created_at: new Date(),
|
|
78
|
-
updated_at: new Date()
|
|
78
|
+
updated_at: new Date(),
|
|
79
79
|
})
|
|
80
80
|
.execute();
|
|
81
81
|
promotedCount++;
|
|
@@ -94,7 +94,7 @@ class HiveLink {
|
|
|
94
94
|
.updateTable(this.knowledgeTable)
|
|
95
95
|
.set({
|
|
96
96
|
confidence: (0, sql_js_1.sql) `MIN(1.0, confidence + ${boostFactor})`,
|
|
97
|
-
updated_at: new Date()
|
|
97
|
+
updated_at: new Date(),
|
|
98
98
|
})
|
|
99
99
|
.where('tags', 'like', `%"${domainTag}"%`)
|
|
100
100
|
.where('confidence', '<', 1.0)
|
|
@@ -108,7 +108,8 @@ class HiveLink {
|
|
|
108
108
|
* High-Throughput Refactor: Batch updates and optimized set-based checks.
|
|
109
109
|
*/
|
|
110
110
|
async broadcastSkills() {
|
|
111
|
-
if (!this.config.evolution?.enableHiveLink &&
|
|
111
|
+
if (!this.config.evolution?.enableHiveLink &&
|
|
112
|
+
this.config.evolution !== undefined) {
|
|
112
113
|
console.log('[HiveLink] Skill broadcasting disabled by config.');
|
|
113
114
|
return 0;
|
|
114
115
|
}
|
|
@@ -119,7 +120,9 @@ class HiveLink {
|
|
|
119
120
|
// 1. Resolve Verified Skills with "Survival of the Fittest" logic
|
|
120
121
|
const verifiedSkills = await this.cortex.capabilities.getCapabilities('verified');
|
|
121
122
|
for (const skill of verifiedSkills) {
|
|
122
|
-
const meta = typeof skill.metadata === 'string'
|
|
123
|
+
const meta = typeof skill.metadata === 'string'
|
|
124
|
+
? JSON.parse(skill.metadata)
|
|
125
|
+
: skill.metadata || {};
|
|
123
126
|
if (meta.broadcasted)
|
|
124
127
|
continue;
|
|
125
128
|
// Check for competing global versions
|
|
@@ -146,15 +149,16 @@ class HiveLink {
|
|
|
146
149
|
}
|
|
147
150
|
}
|
|
148
151
|
if (shouldBroadcast) {
|
|
149
|
-
await trx
|
|
152
|
+
await trx
|
|
153
|
+
.updateTable(capTable)
|
|
150
154
|
.set({
|
|
151
155
|
metadata: JSON.stringify({
|
|
152
156
|
...meta,
|
|
153
157
|
broadcasted: true,
|
|
154
158
|
hive_verified: true,
|
|
155
159
|
broadcasted_at: new Date(),
|
|
156
|
-
conflict_resolved: !!competitor
|
|
157
|
-
})
|
|
160
|
+
conflict_resolved: !!competitor,
|
|
161
|
+
}),
|
|
158
162
|
})
|
|
159
163
|
.where('id', '=', skill.id)
|
|
160
164
|
.execute();
|
|
@@ -164,16 +168,19 @@ class HiveLink {
|
|
|
164
168
|
// 2. Broadcast Blacklisted Skills (Immediate Immune Propagations)
|
|
165
169
|
const blacklisted = await this.cortex.capabilities.getCapabilities('blacklisted');
|
|
166
170
|
for (const skill of blacklisted) {
|
|
167
|
-
const meta = typeof skill.metadata === 'string'
|
|
171
|
+
const meta = typeof skill.metadata === 'string'
|
|
172
|
+
? JSON.parse(skill.metadata)
|
|
173
|
+
: skill.metadata || {};
|
|
168
174
|
if (!meta.broadcasted) {
|
|
169
|
-
await trx
|
|
175
|
+
await trx
|
|
176
|
+
.updateTable(capTable)
|
|
170
177
|
.set({
|
|
171
178
|
metadata: JSON.stringify({
|
|
172
179
|
...meta,
|
|
173
180
|
broadcasted: true,
|
|
174
181
|
hive_blacklisted: true,
|
|
175
|
-
blocked_at: new Date()
|
|
176
|
-
})
|
|
182
|
+
blocked_at: new Date(),
|
|
183
|
+
}),
|
|
177
184
|
})
|
|
178
185
|
.where('id', '=', skill.id)
|
|
179
186
|
.execute();
|
|
@@ -42,8 +42,10 @@ class KnowledgeDistiller {
|
|
|
42
42
|
.where('entity', '=', entity)
|
|
43
43
|
.where('fact', '=', fact)
|
|
44
44
|
.executeTakeFirst();
|
|
45
|
-
if (quickMatch &&
|
|
46
|
-
|
|
45
|
+
if (quickMatch &&
|
|
46
|
+
quickMatch.status === 'verified' &&
|
|
47
|
+
source !== 'user') {
|
|
48
|
+
return (await this.getKnowledgeByEntity(entity)).find((k) => k.fact === fact);
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
51
|
this.bloomFilter.add(factHash);
|
|
@@ -59,10 +61,14 @@ class KnowledgeDistiller {
|
|
|
59
61
|
.executeTakeFirst();
|
|
60
62
|
if (existing) {
|
|
61
63
|
// Merge tags
|
|
62
|
-
const existingTags = existing.tags
|
|
64
|
+
const existingTags = existing.tags
|
|
65
|
+
? JSON.parse(existing.tags)
|
|
66
|
+
: [];
|
|
63
67
|
const mergedTags = Array.from(new Set([...existingTags, ...tags]));
|
|
64
68
|
// Merge metadata
|
|
65
|
-
const existingMeta = existing.metadata
|
|
69
|
+
const existingMeta = existing.metadata
|
|
70
|
+
? JSON.parse(existing.metadata)
|
|
71
|
+
: {};
|
|
66
72
|
// Hallucination Prevention: Tracking contributing sessions
|
|
67
73
|
const sessions = new Set(existingMeta.sessions || []);
|
|
68
74
|
if (sourceSessionId)
|
|
@@ -71,7 +77,7 @@ class KnowledgeDistiller {
|
|
|
71
77
|
...existingMeta,
|
|
72
78
|
...metadata,
|
|
73
79
|
sessions: Array.from(sessions),
|
|
74
|
-
session_count: sessions.size
|
|
80
|
+
session_count: sessions.size,
|
|
75
81
|
};
|
|
76
82
|
// Source weighting: User verification boosts confidence faster
|
|
77
83
|
const boost = source === 'user' ? 0.2 : 0.05;
|
|
@@ -89,7 +95,7 @@ class KnowledgeDistiller {
|
|
|
89
95
|
tags: JSON.stringify(mergedTags),
|
|
90
96
|
metadata: JSON.stringify(mergedMeta),
|
|
91
97
|
updated_at: new Date(),
|
|
92
|
-
source_session_id: sourceSessionId ?? existing.source_session_id
|
|
98
|
+
source_session_id: sourceSessionId ?? existing.source_session_id,
|
|
93
99
|
})
|
|
94
100
|
.where('id', '=', existing.id)
|
|
95
101
|
.returningAll()
|
|
@@ -103,7 +109,7 @@ class KnowledgeDistiller {
|
|
|
103
109
|
...metadata,
|
|
104
110
|
source,
|
|
105
111
|
sessions: sourceSessionId ? [sourceSessionId] : [],
|
|
106
|
-
session_count: sourceSessionId ? 1 : 0
|
|
112
|
+
session_count: sourceSessionId ? 1 : 0,
|
|
107
113
|
};
|
|
108
114
|
const created = await trx
|
|
109
115
|
.insertInto(this.knowledgeTable)
|
|
@@ -116,7 +122,7 @@ class KnowledgeDistiller {
|
|
|
116
122
|
tags: JSON.stringify(tags),
|
|
117
123
|
metadata: JSON.stringify(initialMeta),
|
|
118
124
|
created_at: new Date(),
|
|
119
|
-
updated_at: new Date()
|
|
125
|
+
updated_at: new Date(),
|
|
120
126
|
})
|
|
121
127
|
.returningAll()
|
|
122
128
|
.executeTakeFirstOrThrow();
|
|
@@ -138,7 +144,9 @@ class KnowledgeDistiller {
|
|
|
138
144
|
.executeTakeFirst();
|
|
139
145
|
if (!existing)
|
|
140
146
|
return null;
|
|
141
|
-
const metadata = typeof existing.metadata === 'string'
|
|
147
|
+
const metadata = typeof existing.metadata === 'string'
|
|
148
|
+
? JSON.parse(existing.metadata)
|
|
149
|
+
: existing.metadata || {};
|
|
142
150
|
// Hallucination Guard: Cap confidence for non-user sources until cross-session verification
|
|
143
151
|
let maxConfidence = 1.0;
|
|
144
152
|
if (metadata.source !== 'user' && (metadata.session_count || 0) < 3) {
|
|
@@ -156,7 +164,7 @@ class KnowledgeDistiller {
|
|
|
156
164
|
.set({
|
|
157
165
|
confidence: newConfidence,
|
|
158
166
|
status: newStatus,
|
|
159
|
-
updated_at: new Date()
|
|
167
|
+
updated_at: new Date(),
|
|
160
168
|
})
|
|
161
169
|
.where('id', '=', id)
|
|
162
170
|
.returningAll()
|
|
@@ -174,14 +182,14 @@ class KnowledgeDistiller {
|
|
|
174
182
|
.where('entity', '=', entity)
|
|
175
183
|
.orderBy('confidence', 'desc');
|
|
176
184
|
const items = (await query.execute());
|
|
177
|
-
const parsed = items.map(i => this.parseKnowledge(i));
|
|
185
|
+
const parsed = items.map((i) => this.parseKnowledge(i));
|
|
178
186
|
let filtered = parsed;
|
|
179
187
|
if (filterTags && filterTags.length > 0) {
|
|
180
|
-
filtered = parsed.filter(item => item.tags?.some(tag => filterTags.includes(tag)));
|
|
188
|
+
filtered = parsed.filter((item) => item.tags?.some((tag) => filterTags.includes(tag)));
|
|
181
189
|
}
|
|
182
190
|
// Record hits asynchronously
|
|
183
191
|
for (const item of filtered) {
|
|
184
|
-
this.recordHit(item.id).catch(err => console.error(`[KnowledgeDistiller] Failed to record hit for ${item.id}:`, err));
|
|
192
|
+
this.recordHit(item.id).catch((err) => console.error(`[KnowledgeDistiller] Failed to record hit for ${item.id}:`, err));
|
|
185
193
|
}
|
|
186
194
|
return filtered;
|
|
187
195
|
}
|
|
@@ -198,14 +206,14 @@ class KnowledgeDistiller {
|
|
|
198
206
|
return;
|
|
199
207
|
const metadata = typeof existing.metadata === 'string'
|
|
200
208
|
? JSON.parse(existing.metadata)
|
|
201
|
-
:
|
|
209
|
+
: existing.metadata || {};
|
|
202
210
|
metadata.hit_count = (metadata.hit_count || 0) + 1;
|
|
203
211
|
metadata.last_retrieved_at = new Date().toISOString();
|
|
204
212
|
await this.db
|
|
205
213
|
.updateTable(this.knowledgeTable)
|
|
206
214
|
.set({
|
|
207
215
|
metadata: JSON.stringify(metadata),
|
|
208
|
-
updated_at: new Date()
|
|
216
|
+
updated_at: new Date(),
|
|
209
217
|
})
|
|
210
218
|
.where('id', '=', id)
|
|
211
219
|
.execute();
|
|
@@ -215,7 +223,7 @@ class KnowledgeDistiller {
|
|
|
215
223
|
.values({
|
|
216
224
|
metric_name: `entity_hit_${existing.entity}`,
|
|
217
225
|
metric_value: 1,
|
|
218
|
-
created_at: new Date()
|
|
226
|
+
created_at: new Date(),
|
|
219
227
|
})
|
|
220
228
|
.execute();
|
|
221
229
|
}
|
|
@@ -232,7 +240,7 @@ class KnowledgeDistiller {
|
|
|
232
240
|
const stn = Math.min(1.0, hitCount / ageInDays);
|
|
233
241
|
// Source Multiplier: User verified facts get 1.0, Assistant-generated 0.7
|
|
234
242
|
const sourceMult = metadata.source === 'user' ? 1.0 : 0.7;
|
|
235
|
-
return
|
|
243
|
+
return item.confidence * 0.4 + stn * 0.4 + sourceMult * 0.2;
|
|
236
244
|
}
|
|
237
245
|
/**
|
|
238
246
|
* Challenge existing knowledge with new evidence.
|
|
@@ -259,12 +267,18 @@ class KnowledgeDistiller {
|
|
|
259
267
|
let newStatus = parsedItem.status;
|
|
260
268
|
if (parsedItem.confidence > 0.7) {
|
|
261
269
|
newStatus = 'disputed';
|
|
262
|
-
newMeta = {
|
|
270
|
+
newMeta = {
|
|
271
|
+
...newMeta,
|
|
272
|
+
status_reason: `Contradicted by: ${competingFact}`,
|
|
273
|
+
};
|
|
263
274
|
penalty = 0.1;
|
|
264
275
|
}
|
|
265
276
|
else {
|
|
266
277
|
newStatus = 'deprecated';
|
|
267
|
-
newMeta = {
|
|
278
|
+
newMeta = {
|
|
279
|
+
...newMeta,
|
|
280
|
+
status_reason: `Superseded by: ${competingFact}`,
|
|
281
|
+
};
|
|
268
282
|
penalty = 0.4;
|
|
269
283
|
}
|
|
270
284
|
const newConfidence = Math.max(0, parsedItem.confidence - penalty);
|
|
@@ -274,7 +288,7 @@ class KnowledgeDistiller {
|
|
|
274
288
|
confidence: newConfidence,
|
|
275
289
|
status: newStatus,
|
|
276
290
|
metadata: JSON.stringify(newMeta),
|
|
277
|
-
updated_at: new Date()
|
|
291
|
+
updated_at: new Date(),
|
|
278
292
|
})
|
|
279
293
|
.where('id', '=', parsedItem.id)
|
|
280
294
|
.execute();
|
|
@@ -290,7 +304,7 @@ class KnowledgeDistiller {
|
|
|
290
304
|
// 1. Structural/Syntactic Extraction (NER-style tokenization)
|
|
291
305
|
// Extract capitalized phrases (potential entities), quoted strings, and CamelCase identifiers
|
|
292
306
|
const tokens = item.fact.match(/([A-Z][a-z]+(?:\s[A-Z][a-z]+)*)|("[^"]+")|([a-z]+[A-Z][a-z]+)/g) || [];
|
|
293
|
-
const potentialEntities = Array.from(new Set(tokens.map(t => t.replace(/"/g, '').trim()))).filter(t => t.length > 2 && t !== item.entity);
|
|
307
|
+
const potentialEntities = Array.from(new Set(tokens.map((t) => t.replace(/"/g, '').trim()))).filter((t) => t.length > 2 && t !== item.entity);
|
|
294
308
|
if (potentialEntities.length > 0) {
|
|
295
309
|
const matches = await trx
|
|
296
310
|
.selectFrom(this.knowledgeTable)
|
|
@@ -344,7 +358,7 @@ class KnowledgeDistiller {
|
|
|
344
358
|
await trxOrDb
|
|
345
359
|
.updateTable(this.linksTable)
|
|
346
360
|
.set({
|
|
347
|
-
metadata: metadata ? JSON.stringify(metadata) : null
|
|
361
|
+
metadata: metadata ? JSON.stringify(metadata) : null,
|
|
348
362
|
})
|
|
349
363
|
.where('id', '=', existing.id)
|
|
350
364
|
.execute();
|
|
@@ -357,7 +371,7 @@ class KnowledgeDistiller {
|
|
|
357
371
|
target_id: targetId,
|
|
358
372
|
relationship,
|
|
359
373
|
metadata: metadata ? JSON.stringify(metadata) : null,
|
|
360
|
-
created_at: new Date()
|
|
374
|
+
created_at: new Date(),
|
|
361
375
|
})
|
|
362
376
|
.execute();
|
|
363
377
|
}
|
|
@@ -382,10 +396,10 @@ class KnowledgeDistiller {
|
|
|
382
396
|
.execute();
|
|
383
397
|
return {
|
|
384
398
|
item: this.parseKnowledge(center),
|
|
385
|
-
relations: links.map(l => ({
|
|
399
|
+
relations: links.map((l) => ({
|
|
386
400
|
relationship: l.link_rel,
|
|
387
|
-
target: this.parseKnowledge(l)
|
|
388
|
-
}))
|
|
401
|
+
target: this.parseKnowledge(l),
|
|
402
|
+
})),
|
|
389
403
|
};
|
|
390
404
|
}
|
|
391
405
|
/**
|
|
@@ -438,7 +452,7 @@ class KnowledgeDistiller {
|
|
|
438
452
|
...secondary.metadata,
|
|
439
453
|
...primary.metadata,
|
|
440
454
|
consolidated_from: secondary.id,
|
|
441
|
-
consolidated_at: new Date().toISOString()
|
|
455
|
+
consolidated_at: new Date().toISOString(),
|
|
442
456
|
};
|
|
443
457
|
const mergedTags = Array.from(new Set([...(primary.tags || []), ...(secondary.tags || [])]));
|
|
444
458
|
await this.db.transaction().execute(async (trx) => {
|
|
@@ -449,7 +463,7 @@ class KnowledgeDistiller {
|
|
|
449
463
|
confidence: Math.max(primary.confidence, secondary.confidence),
|
|
450
464
|
metadata: JSON.stringify(mergedMeta),
|
|
451
465
|
tags: JSON.stringify(mergedTags),
|
|
452
|
-
updated_at: new Date()
|
|
466
|
+
updated_at: new Date(),
|
|
453
467
|
})
|
|
454
468
|
.where('id', '=', primary.id)
|
|
455
469
|
.execute();
|
|
@@ -463,7 +477,7 @@ class KnowledgeDistiller {
|
|
|
463
477
|
bloomHash(str) {
|
|
464
478
|
let hash = 0;
|
|
465
479
|
for (let i = 0; i < str.length; i++) {
|
|
466
|
-
hash = (
|
|
480
|
+
hash = (hash << 5) - hash + str.charCodeAt(i);
|
|
467
481
|
hash |= 0; // Format to 32bit int
|
|
468
482
|
}
|
|
469
483
|
return hash;
|
|
@@ -476,10 +490,12 @@ class KnowledgeDistiller {
|
|
|
476
490
|
confidence: item.confidence,
|
|
477
491
|
status: item.status || 'proposed',
|
|
478
492
|
sourceSessionId: item.source_session_id,
|
|
479
|
-
tags: typeof item.tags === 'string' ? JSON.parse(item.tags) :
|
|
480
|
-
metadata: typeof item.metadata === 'string'
|
|
493
|
+
tags: typeof item.tags === 'string' ? JSON.parse(item.tags) : item.tags || [],
|
|
494
|
+
metadata: typeof item.metadata === 'string'
|
|
495
|
+
? JSON.parse(item.metadata)
|
|
496
|
+
: item.metadata || {},
|
|
481
497
|
createdAt: new Date(item.created_at),
|
|
482
|
-
updatedAt: new Date(item.updated_at)
|
|
498
|
+
updatedAt: new Date(item.updated_at),
|
|
483
499
|
};
|
|
484
500
|
}
|
|
485
501
|
}
|
|
@@ -16,9 +16,23 @@ class RecursiveReasoner {
|
|
|
16
16
|
['fast', 'slow'],
|
|
17
17
|
['short', 'long'],
|
|
18
18
|
['start', 'stop'],
|
|
19
|
-
['enable', 'disable']
|
|
19
|
+
['enable', 'disable'],
|
|
20
20
|
];
|
|
21
|
-
stopWords = new Set([
|
|
21
|
+
stopWords = new Set([
|
|
22
|
+
'the',
|
|
23
|
+
'a',
|
|
24
|
+
'an',
|
|
25
|
+
'and',
|
|
26
|
+
'or',
|
|
27
|
+
'but',
|
|
28
|
+
'in',
|
|
29
|
+
'on',
|
|
30
|
+
'at',
|
|
31
|
+
'to',
|
|
32
|
+
'for',
|
|
33
|
+
'with',
|
|
34
|
+
'from',
|
|
35
|
+
]);
|
|
22
36
|
constructor(db, config = {}) {
|
|
23
37
|
this.db = db;
|
|
24
38
|
this.config = config;
|
|
@@ -31,12 +45,12 @@ class RecursiveReasoner {
|
|
|
31
45
|
* Find goals matching a pattern across all sessions
|
|
32
46
|
*/
|
|
33
47
|
async analyzeGlobalProgress(pattern) {
|
|
34
|
-
const goals = await this.typedDb
|
|
48
|
+
const goals = (await this.typedDb
|
|
35
49
|
.selectFrom(this.goalsTable)
|
|
36
50
|
.selectAll()
|
|
37
51
|
.where('description', 'like', `%${pattern}%`)
|
|
38
52
|
.orderBy('created_at', 'desc')
|
|
39
|
-
.execute();
|
|
53
|
+
.execute());
|
|
40
54
|
return goals.map(this.parseGoal);
|
|
41
55
|
}
|
|
42
56
|
/**
|
|
@@ -46,12 +60,14 @@ class RecursiveReasoner {
|
|
|
46
60
|
async synthesizeLessons() {
|
|
47
61
|
console.log('[RecursiveReasoner] Performing high-throughput weighted token clustering...');
|
|
48
62
|
const reflectionsTable = this.config.reflectionsTable || 'agent_reflections';
|
|
49
|
-
const results = await this.typedDb
|
|
63
|
+
const results = (await this.typedDb
|
|
50
64
|
.selectFrom(reflectionsTable)
|
|
51
65
|
.select('lessons_learned')
|
|
52
66
|
.where('lessons_learned', 'is not', null)
|
|
53
|
-
.execute();
|
|
54
|
-
const rawLessons = results
|
|
67
|
+
.execute());
|
|
68
|
+
const rawLessons = results
|
|
69
|
+
.map((l) => l.lessons_learned)
|
|
70
|
+
.filter(Boolean);
|
|
55
71
|
const clusters = {};
|
|
56
72
|
// Global Token Frequency Pass
|
|
57
73
|
const globalTokenFreq = new Map();
|
|
@@ -114,9 +130,12 @@ class RecursiveReasoner {
|
|
|
114
130
|
description: `Systemic Best-Practice: ${reasoning}`,
|
|
115
131
|
status: 'pending',
|
|
116
132
|
priority: 5,
|
|
117
|
-
metadata: JSON.stringify({
|
|
133
|
+
metadata: JSON.stringify({
|
|
134
|
+
source_persona: persona.id,
|
|
135
|
+
cross_pollinated: true,
|
|
136
|
+
}),
|
|
118
137
|
created_at: new Date(),
|
|
119
|
-
updated_at: new Date()
|
|
138
|
+
updated_at: new Date(),
|
|
120
139
|
})
|
|
121
140
|
.execute();
|
|
122
141
|
goalsCreated++;
|
|
@@ -129,11 +148,11 @@ class RecursiveReasoner {
|
|
|
129
148
|
*/
|
|
130
149
|
async detectContradictions() {
|
|
131
150
|
console.log('[RecursiveReasoner] Detecting logical contradictions in systemic goals...');
|
|
132
|
-
const activeGoals = await this.typedDb
|
|
151
|
+
const activeGoals = (await this.typedDb
|
|
133
152
|
.selectFrom(this.goalsTable)
|
|
134
153
|
.selectAll()
|
|
135
154
|
.where('status', '=', 'active')
|
|
136
|
-
.execute();
|
|
155
|
+
.execute());
|
|
137
156
|
const contradictions = [];
|
|
138
157
|
for (let i = 0; i < activeGoals.length; i++) {
|
|
139
158
|
for (let j = i + 1; j < activeGoals.length; j++) {
|
|
@@ -158,7 +177,8 @@ class RecursiveReasoner {
|
|
|
158
177
|
const t2 = text2.toLowerCase();
|
|
159
178
|
// Check explicit opposites
|
|
160
179
|
for (const [op1, op2] of this.conflictPairs) {
|
|
161
|
-
if ((t1.includes(op1) && t2.includes(op2)) ||
|
|
180
|
+
if ((t1.includes(op1) && t2.includes(op2)) ||
|
|
181
|
+
(t1.includes(op2) && t2.includes(op1))) {
|
|
162
182
|
// Determine the subject of conflict (common words)
|
|
163
183
|
const intersection = this.intersect(this.tokenize(t1), this.tokenize(t2));
|
|
164
184
|
// If they share a subject (e.g. "latency"), it's a conflict
|
|
@@ -172,13 +192,14 @@ class RecursiveReasoner {
|
|
|
172
192
|
return null;
|
|
173
193
|
}
|
|
174
194
|
tokenize(text) {
|
|
175
|
-
return text
|
|
195
|
+
return text
|
|
196
|
+
.toLowerCase()
|
|
176
197
|
.split(/[\W_]+/)
|
|
177
|
-
.filter(w => w.length > 2 && !this.stopWords.has(w));
|
|
198
|
+
.filter((w) => w.length > 2 && !this.stopWords.has(w));
|
|
178
199
|
}
|
|
179
200
|
intersect(arr1, arr2) {
|
|
180
201
|
const s2 = new Set(arr2);
|
|
181
|
-
return arr1.filter(x => s2.has(x));
|
|
202
|
+
return arr1.filter((x) => s2.has(x));
|
|
182
203
|
}
|
|
183
204
|
parseGoal(g) {
|
|
184
205
|
return {
|
|
@@ -188,9 +209,11 @@ class RecursiveReasoner {
|
|
|
188
209
|
description: g.description,
|
|
189
210
|
status: g.status,
|
|
190
211
|
priority: g.priority,
|
|
191
|
-
metadata: typeof g.metadata === 'string'
|
|
212
|
+
metadata: typeof g.metadata === 'string'
|
|
213
|
+
? JSON.parse(g.metadata)
|
|
214
|
+
: g.metadata || {},
|
|
192
215
|
createdAt: new Date(g.created_at),
|
|
193
|
-
updatedAt: new Date(g.updated_at)
|
|
216
|
+
updatedAt: new Date(g.updated_at),
|
|
194
217
|
};
|
|
195
218
|
}
|
|
196
219
|
}
|
|
@@ -18,31 +18,33 @@ class ReflectionEngine {
|
|
|
18
18
|
* Record a reflection for a session
|
|
19
19
|
*/
|
|
20
20
|
async reflect(sessionId, outcome, lessonsLearned, suggestedActions, metadata) {
|
|
21
|
-
const reflection = await this.db
|
|
21
|
+
const reflection = (await this.db
|
|
22
22
|
.insertInto(this.reflectionsTable)
|
|
23
23
|
.values({
|
|
24
24
|
session_id: sessionId,
|
|
25
25
|
outcome,
|
|
26
26
|
lessons_learned: lessonsLearned,
|
|
27
|
-
suggested_actions: suggestedActions
|
|
27
|
+
suggested_actions: suggestedActions
|
|
28
|
+
? JSON.stringify(suggestedActions)
|
|
29
|
+
: null,
|
|
28
30
|
metadata: metadata ? JSON.stringify(metadata) : null,
|
|
29
|
-
created_at: new Date()
|
|
31
|
+
created_at: new Date(),
|
|
30
32
|
})
|
|
31
33
|
.returningAll()
|
|
32
|
-
.executeTakeFirstOrThrow();
|
|
34
|
+
.executeTakeFirstOrThrow());
|
|
33
35
|
return this.parseReflection(reflection);
|
|
34
36
|
}
|
|
35
37
|
/**
|
|
36
38
|
* Get reflections for a specific session
|
|
37
39
|
*/
|
|
38
40
|
async getSessionReflections(sessionId) {
|
|
39
|
-
const reflections = await this.db
|
|
41
|
+
const reflections = (await this.db
|
|
40
42
|
.selectFrom(this.reflectionsTable)
|
|
41
43
|
.selectAll()
|
|
42
44
|
.where('session_id', '=', sessionId)
|
|
43
45
|
.orderBy('created_at', 'desc')
|
|
44
|
-
.execute();
|
|
45
|
-
return reflections.map(r => this.parseReflection(r));
|
|
46
|
+
.execute());
|
|
47
|
+
return reflections.map((r) => this.parseReflection(r));
|
|
46
48
|
}
|
|
47
49
|
/**
|
|
48
50
|
* Get recent lessons learned across all sessions
|
|
@@ -67,7 +69,7 @@ class ReflectionEngine {
|
|
|
67
69
|
metadata: typeof reflection.metadata === 'string'
|
|
68
70
|
? JSON.parse(reflection.metadata)
|
|
69
71
|
: reflection.metadata,
|
|
70
|
-
createdAt: new Date(reflection.created_at)
|
|
72
|
+
createdAt: new Date(reflection.created_at),
|
|
71
73
|
};
|
|
72
74
|
}
|
|
73
75
|
}
|
|
@@ -21,7 +21,7 @@ class RitualOrchestrator {
|
|
|
21
21
|
*/
|
|
22
22
|
async scheduleRitual(name, type, frequency, definition, metadata) {
|
|
23
23
|
const nextRun = this.calculateNextRun(frequency);
|
|
24
|
-
const ritual = await this.db
|
|
24
|
+
const ritual = (await this.db
|
|
25
25
|
.insertInto(this.ritualsTable)
|
|
26
26
|
.values({
|
|
27
27
|
name,
|
|
@@ -30,10 +30,10 @@ class RitualOrchestrator {
|
|
|
30
30
|
definition,
|
|
31
31
|
next_run: nextRun,
|
|
32
32
|
status: 'pending',
|
|
33
|
-
metadata: metadata ? JSON.stringify(metadata) : null
|
|
33
|
+
metadata: metadata ? JSON.stringify(metadata) : null,
|
|
34
34
|
})
|
|
35
35
|
.returningAll()
|
|
36
|
-
.executeTakeFirstOrThrow();
|
|
36
|
+
.executeTakeFirstOrThrow());
|
|
37
37
|
return this.parseRitual(ritual);
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
@@ -42,41 +42,47 @@ class RitualOrchestrator {
|
|
|
42
42
|
async runPendingRituals() {
|
|
43
43
|
const now = new Date();
|
|
44
44
|
const lockTimeout = new Date(now.getTime() + 600000); // 10 min lock by default
|
|
45
|
-
|
|
46
|
-
const
|
|
45
|
+
const pending = await this.db.transaction().execute(async (trx) => {
|
|
46
|
+
const due = (await trx
|
|
47
47
|
.selectFrom(this.ritualsTable)
|
|
48
48
|
.selectAll()
|
|
49
49
|
.where('next_run', '<=', now)
|
|
50
50
|
.where('status', 'in', ['pending', 'success', 'failure'])
|
|
51
51
|
.where((eb) => eb.or([
|
|
52
52
|
eb('locked_until', '<=', now),
|
|
53
|
-
eb('locked_until', 'is', null)
|
|
53
|
+
eb('locked_until', 'is', null),
|
|
54
54
|
]))
|
|
55
|
-
.execute();
|
|
56
|
-
if (
|
|
57
|
-
return
|
|
58
|
-
|
|
59
|
-
for (const ritual of pending) {
|
|
55
|
+
.execute());
|
|
56
|
+
if (due.length === 0)
|
|
57
|
+
return [];
|
|
58
|
+
for (const ritual of due) {
|
|
60
59
|
// Production Hardening: Distributed Lock
|
|
61
60
|
await trx
|
|
62
61
|
.updateTable(this.ritualsTable)
|
|
63
62
|
.set({ locked_until: lockTimeout })
|
|
64
63
|
.where('id', '=', ritual.id)
|
|
65
64
|
.execute();
|
|
66
|
-
// Execute out-of-transaction to avoid long-held locks if sub-tasks are slow
|
|
67
|
-
// but we await it here for the summary count.
|
|
68
|
-
// In a highly parallel system, this might be sent to a worker queue.
|
|
69
|
-
await this.executeRitual(ritual);
|
|
70
65
|
}
|
|
71
|
-
return
|
|
66
|
+
return due;
|
|
72
67
|
});
|
|
68
|
+
if (pending.length === 0)
|
|
69
|
+
return 0;
|
|
70
|
+
console.log(`[RitualOrchestrator] Found ${pending.length} pending rituals due. Locking for execution...`);
|
|
71
|
+
for (const ritual of pending) {
|
|
72
|
+
// Execute out-of-transaction to avoid long-held locks if sub-tasks are slow
|
|
73
|
+
await this.executeRitual(ritual);
|
|
74
|
+
}
|
|
75
|
+
return pending.length;
|
|
73
76
|
}
|
|
74
77
|
/**
|
|
75
78
|
* Execute a specific ritual
|
|
76
79
|
*/
|
|
77
80
|
async executeRitual(ritual) {
|
|
78
81
|
console.log(`[RitualOrchestrator] Executing ritual: ${ritual.name} (${ritual.type})`);
|
|
79
|
-
const ritualMetadata = {
|
|
82
|
+
const ritualMetadata = {
|
|
83
|
+
...ritual.metadata,
|
|
84
|
+
startedAt: new Date(),
|
|
85
|
+
};
|
|
80
86
|
let success = false;
|
|
81
87
|
try {
|
|
82
88
|
switch (ritual.type) {
|
|
@@ -87,15 +93,15 @@ class RitualOrchestrator {
|
|
|
87
93
|
.select('id')
|
|
88
94
|
.where('status', '=', 'active')
|
|
89
95
|
.execute();
|
|
90
|
-
const compressionThreshold =
|
|
96
|
+
const compressionThreshold = this.config.contextWindowSize || 20;
|
|
91
97
|
let compressedCount = 0;
|
|
92
98
|
for (const session of activeSessions) {
|
|
93
99
|
const messagesTable = this.config.messagesTable || 'agent_messages';
|
|
94
|
-
const countResult = await this.db
|
|
100
|
+
const countResult = (await this.db
|
|
95
101
|
.selectFrom(messagesTable)
|
|
96
102
|
.select((eb) => eb.fn.countAll().as('count'))
|
|
97
103
|
.where('session_id', '=', session.id)
|
|
98
|
-
.executeTakeFirst();
|
|
104
|
+
.executeTakeFirst());
|
|
99
105
|
const count = Number(countResult?.count || 0);
|
|
100
106
|
if (count > compressionThreshold) {
|
|
101
107
|
await this.cortex.compressor.semanticPruning(session.id);
|
|
@@ -142,7 +148,7 @@ class RitualOrchestrator {
|
|
|
142
148
|
last_run: new Date(),
|
|
143
149
|
next_run: nextRun,
|
|
144
150
|
locked_until: null, // Unlock
|
|
145
|
-
metadata: JSON.stringify(ritualMetadata)
|
|
151
|
+
metadata: JSON.stringify(ritualMetadata),
|
|
146
152
|
})
|
|
147
153
|
.where('id', '=', ritual.id)
|
|
148
154
|
.execute();
|
|
@@ -176,7 +182,7 @@ class RitualOrchestrator {
|
|
|
176
182
|
lastRun: r.last_run ? new Date(r.last_run) : undefined,
|
|
177
183
|
nextRun: r.next_run ? new Date(r.next_run) : undefined,
|
|
178
184
|
lockedUntil: r.locked_until ? new Date(r.locked_until) : undefined,
|
|
179
|
-
metadata: typeof r.metadata === 'string' ? JSON.parse(r.metadata) : r.metadata
|
|
185
|
+
metadata: typeof r.metadata === 'string' ? JSON.parse(r.metadata) : r.metadata,
|
|
180
186
|
};
|
|
181
187
|
}
|
|
182
188
|
}
|