@holoscript/framework 6.0.3 → 6.0.4

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.
Files changed (160) hide show
  1. package/CHANGELOG.md +1 -2
  2. package/ROADMAP.md +68 -66
  3. package/dist/{InvisibleWallet-BB6tFvRA.d.cts → InvisibleWallet-EFiuaLn3.d.cts} +1 -1
  4. package/dist/{OrchestratorAgent-BvWgf9uw.d.cts → OrchestratorAgent-CrLDGNL6.d.cts} +1 -1
  5. package/dist/agents/index.cjs +11 -10
  6. package/dist/agents/index.d.cts +4 -16
  7. package/dist/ai/index.cjs +2 -2
  8. package/dist/behavior.cjs +10 -0
  9. package/dist/economy/index.cjs +4 -4
  10. package/dist/economy/index.d.cts +2 -2
  11. package/dist/index.cjs +33 -11
  12. package/dist/index.d.cts +3 -3
  13. package/dist/swarm/index.cjs +3 -0
  14. package/package.json +14 -9
  15. package/src/__tests__/bounty-marketplace.test.ts +53 -21
  16. package/src/__tests__/delegation.test.ts +1 -4
  17. package/src/__tests__/done-log-audit.test.ts +38 -46
  18. package/src/__tests__/framework.test.ts +172 -53
  19. package/src/__tests__/goal-synthesizer.test.ts +9 -6
  20. package/src/__tests__/presence.test.ts +1 -1
  21. package/src/__tests__/protocol-agent.test.ts +12 -11
  22. package/src/__tests__/revenue-splitter.test.ts +22 -15
  23. package/src/__tests__/scenario-driven-todo.test.ts +55 -35
  24. package/src/__tests__/self-improve.test.ts +28 -9
  25. package/src/__tests__/service-lifecycle.test.ts +9 -3
  26. package/src/__tests__/skill-router.test.ts +3 -3
  27. package/src/agents/CulturalMemory.ts +6 -6
  28. package/src/agents/DelegationTraceHooks.ts +560 -0
  29. package/src/agents/FederatedRegistryAdapter.ts +1 -1
  30. package/src/agents/NormEngine.ts +3 -8
  31. package/src/agents/OrchestratorAgent.ts +1 -1
  32. package/src/agents/TaskDelegationService.ts +5 -9
  33. package/src/agents/__tests__/AgentWalletRegistry.test.ts +5 -4
  34. package/src/agents/__tests__/CrossRealityHandoff.test.ts +9 -3
  35. package/src/agents/__tests__/DelegationTraceHooks.test.ts +390 -0
  36. package/src/agents/__tests__/TaskDelegationService.test.ts +4 -2
  37. package/src/agents/spatial-comms/Layer1RealTime.ts +36 -19
  38. package/src/agents/spatial-comms/Layer2A2A.ts +1 -3
  39. package/src/agents/spatial-comms/Layer3MCP.ts +13 -4
  40. package/src/agents/spatial-comms/ProtocolTypes.ts +5 -2
  41. package/src/agents/spatial-comms/examples/multi-agent-world-creation.ts +2 -2
  42. package/src/ai/HoloScriptGenerator.ts +2 -2
  43. package/src/ai/__tests__/PerceptionSystem.prod.test.ts +1 -1
  44. package/src/ai/__tests__/PerceptionSystem.test.ts +14 -14
  45. package/src/ai/__tests__/SteeringBehaviors.prod.test.ts +1 -1
  46. package/src/ai/index.ts +5 -1
  47. package/src/board/audit.ts +17 -6
  48. package/src/board/board-ops.ts +45 -15
  49. package/src/board/board-types.ts +94 -20
  50. package/src/delegation.ts +5 -3
  51. package/src/distributed-claimer.ts +13 -2
  52. package/src/economy/BountyManager.ts +40 -18
  53. package/src/economy/KnowledgeMarketplace.ts +27 -8
  54. package/src/economy/PaymentWebhookService.ts +0 -1
  55. package/src/economy/RevenueSplitter.ts +2 -4
  56. package/src/economy/UnifiedBudgetOptimizer.ts +8 -9
  57. package/src/economy/_core-stubs.ts +1 -1
  58. package/src/economy/x402-facilitator.ts +17 -8
  59. package/src/index.ts +16 -12
  60. package/src/knowledge/__tests__/knowledge-consolidator.test.ts +138 -89
  61. package/src/knowledge/__tests__/knowledge-store-vector.test.ts +59 -16
  62. package/src/knowledge/brain.ts +7 -7
  63. package/src/knowledge/consolidation.ts +16 -16
  64. package/src/knowledge/knowledge-consolidator.ts +60 -30
  65. package/src/knowledge/knowledge-store.ts +83 -45
  66. package/src/learning/ProceduralCompiler.ts +6 -1
  67. package/src/learning/learning/MemoryConsolidator.ts +102 -0
  68. package/src/learning/learning/MemoryScorer.ts +69 -0
  69. package/src/learning/learning/ProceduralCompiler.ts +45 -0
  70. package/src/learning/learning/SemanticClusterer.ts +66 -0
  71. package/src/llm/llm-adapter.ts +24 -10
  72. package/src/mesh/index.ts +37 -17
  73. package/src/protocol/goal-synthesizer.ts +24 -34
  74. package/src/protocol/implementations.ts +91 -22
  75. package/src/protocol/micro-phase-decomposer.ts +25 -17
  76. package/src/protocol/micro-step-decomposer.test.ts +104 -39
  77. package/src/protocol-agent.test.ts +17 -7
  78. package/src/protocol-agent.ts +45 -42
  79. package/src/self-improve/absorb-scanner.ts +9 -6
  80. package/src/self-improve/evolution-engine.ts +36 -18
  81. package/src/self-improve/framework-absorber.ts +21 -16
  82. package/src/self-improve/index.ts +2 -10
  83. package/src/self-improve/prompt-optimizer.ts +31 -19
  84. package/src/self-improve/test-generator.ts +16 -12
  85. package/src/skill-router.ts +7 -6
  86. package/src/swarm/messaging/GossipProtocol.ts +1 -1
  87. package/src/swarm/messaging/__tests__/BroadcastChannel.prod.test.ts +31 -9
  88. package/src/swarm/messaging/__tests__/GossipProtocol.prod.test.ts +21 -7
  89. package/src/swarm/messaging/__tests__/SwarmEventBus.prod.test.ts +24 -8
  90. package/src/swarm/messaging/__tests__/SwarmEventBus.test.ts +6 -2
  91. package/src/team.ts +277 -122
  92. package/src/training/scripts/generate-spatial-dataset.ts +1 -1
  93. package/src/training/training/LRScheduler.ts +377 -0
  94. package/src/training/training/QualityScoringPipeline.ts +139 -0
  95. package/src/training/training/SoftDedup.ts +461 -0
  96. package/src/training/training/SparsityMonitor.ts +685 -0
  97. package/src/training/training/SparsityMonitorTypes.ts +209 -0
  98. package/src/training/training/SpatialTrainingDataGenerator.ts +1526 -0
  99. package/src/training/training/SpatialTrainingDataTypes.ts +216 -0
  100. package/src/training/training/TrainingPipelineConfig.ts +215 -0
  101. package/src/training/training/__tests__/CorpusValidation.test.ts +87 -0
  102. package/src/training/training/__tests__/LRScheduler.test.ts +592 -0
  103. package/src/training/training/__tests__/SoftDedup.test.ts +415 -0
  104. package/src/training/training/__tests__/SparsityMonitor.test.ts +1623 -0
  105. package/src/training/training/__tests__/SpatialCorpusValidation.test.ts +72 -0
  106. package/src/training/training/__tests__/SpatialTrainingDataGenerator.test.ts +1244 -0
  107. package/src/training/training/__tests__/TrainingMonkeyIntegration.test.ts +897 -0
  108. package/src/training/training/__tests__/TrainingPipelineConfig.test.ts +202 -0
  109. package/src/training/training/__tests__/schema.test.ts +72 -0
  110. package/src/training/training/__tests__/training-constants.test.ts +106 -0
  111. package/src/training/training/__tests__/trait-mappings.test.ts +81 -0
  112. package/src/training/training/constants.ts +94 -0
  113. package/src/training/training/index.ts +17 -0
  114. package/src/training/training/schema.ts +147 -0
  115. package/src/training/training/scripts/generate-novel-use-cases-dataset.ts +272 -0
  116. package/src/training/training/scripts/generate-spatial-dataset.ts +521 -0
  117. package/src/training/training/trainingmonkey/TrainingMonkeyIntegration.ts +477 -0
  118. package/src/training/training/trainingmonkey/TrainingMonkeyTypes.ts +230 -0
  119. package/src/training/training/trainingmonkey/index.ts +26 -0
  120. package/src/training/training/trait-mappings.ts +157 -0
  121. package/src/types.ts +2 -7
  122. package/ALL-test-results.json +0 -1
  123. package/LICENSE +0 -21
  124. package/dist/AgentManifest-CB4xM-Ma.d.ts +0 -704
  125. package/dist/BehaviorTree-BrBFECv5.d.ts +0 -103
  126. package/dist/InvisibleWallet-rtRrBOA8.d.ts +0 -1732
  127. package/dist/OrchestratorAgent-Q_CbVTmO.d.ts +0 -798
  128. package/dist/agents/index.d.ts +0 -1788
  129. package/dist/agents/index.js +0 -4695
  130. package/dist/ai/index.d.ts +0 -1753
  131. package/dist/ai/index.js +0 -5244
  132. package/dist/behavior.d.ts +0 -130
  133. package/dist/behavior.js +0 -407
  134. package/dist/economy/index.d.ts +0 -747
  135. package/dist/economy/index.js +0 -3617
  136. package/dist/implementations-D9T3un9D.d.ts +0 -236
  137. package/dist/index.d.ts +0 -1729
  138. package/dist/index.js +0 -24277
  139. package/dist/learning/index.d.ts +0 -104
  140. package/dist/learning/index.js +0 -189
  141. package/dist/negotiation/index.d.ts +0 -610
  142. package/dist/negotiation/index.js +0 -931
  143. package/dist/skills/index.d.ts +0 -289
  144. package/dist/skills/index.js +0 -1079
  145. package/dist/swarm/index.d.ts +0 -2433
  146. package/dist/swarm/index.js +0 -5221
  147. package/dist/training/index.d.ts +0 -1734
  148. package/dist/training/index.js +0 -2687
  149. package/extract-failures.js +0 -10
  150. package/src/training/training/data/novel-use-cases.jsonl +0 -153
  151. package/src/training/training/data/spatial-reasoning-10k.jsonl +0 -9354
  152. package/src/types/core-stubs.d.ts +0 -113
  153. package/test-output.txt +0 -0
  154. package/test-result.json +0 -1
  155. package/tsc-errors.txt +0 -4
  156. package/tsc_output.txt +0 -0
  157. package/typescript-errors-2.txt +0 -0
  158. package/typescript-errors.txt +0 -22
  159. package/vitest-log-utf8.txt +0 -268
  160. package/vitest-log.txt +0 -0
@@ -94,8 +94,8 @@ export interface ConsolidatorConfig {
94
94
  }
95
95
 
96
96
  const DEFAULT_CONFIG: ConsolidatorConfig = {
97
- warmDemoteAfterMs: 6 * 60 * 60 * 1000, // 6 hours
98
- coldDemoteAfterMs: 48 * 60 * 60 * 1000, // 48 hours
97
+ warmDemoteAfterMs: 6 * 60 * 60 * 1000, // 6 hours
98
+ coldDemoteAfterMs: 48 * 60 * 60 * 1000, // 48 hours
99
99
  hotCapacity: 100,
100
100
  warmCapacity: 500,
101
101
  };
@@ -127,14 +127,16 @@ export class KnowledgeConsolidator {
127
127
  ...entry,
128
128
  tier: 'hot',
129
129
  tierChangedAt: Date.now(),
130
- provenanceChain: [{
131
- entryId: entry.id,
132
- agentId: entry.authorAgent,
133
- timestamp: new Date(entry.createdAt).getTime(),
134
- action: 'created',
135
- parentEntryId: undefined,
136
- hash: entry.provenanceHash,
137
- }],
130
+ provenanceChain: [
131
+ {
132
+ entryId: entry.id,
133
+ agentId: entry.authorAgent,
134
+ timestamp: new Date(entry.createdAt).getTime(),
135
+ action: 'created',
136
+ parentEntryId: undefined,
137
+ hash: entry.provenanceHash,
138
+ },
139
+ ],
138
140
  };
139
141
  this.tiers.set(entry.id, tiered);
140
142
  imported++;
@@ -153,14 +155,16 @@ export class KnowledgeConsolidator {
153
155
  ...entry,
154
156
  tier: 'hot',
155
157
  tierChangedAt: Date.now(),
156
- provenanceChain: [{
157
- entryId: entry.id,
158
- agentId: entry.authorAgent,
159
- timestamp: new Date(entry.createdAt).getTime(),
160
- action: 'created',
161
- parentEntryId,
162
- hash: entry.provenanceHash,
163
- }],
158
+ provenanceChain: [
159
+ {
160
+ entryId: entry.id,
161
+ agentId: entry.authorAgent,
162
+ timestamp: new Date(entry.createdAt).getTime(),
163
+ action: 'created',
164
+ parentEntryId,
165
+ hash: entry.provenanceHash,
166
+ },
167
+ ],
164
168
  };
165
169
  this.tiers.set(entry.id, tiered);
166
170
  return tiered;
@@ -176,7 +180,7 @@ export class KnowledgeConsolidator {
176
180
  sleepCycle(): ConsolidationStats {
177
181
  const now = Date.now();
178
182
  let demoted = 0;
179
- let evicted = 0;
183
+ const evicted = 0;
180
184
 
181
185
  for (const entry of this.tiers.values()) {
182
186
  const lastActivity = Math.max(
@@ -295,15 +299,40 @@ export class KnowledgeConsolidator {
295
299
  */
296
300
  surfaceCrossDomainPatterns(domains?: string[]): CrossDomainPattern[] {
297
301
  const entries = domains
298
- ? Array.from(this.tiers.values()).filter(e => domains.includes(e.domain))
302
+ ? Array.from(this.tiers.values()).filter((e) => domains.includes(e.domain))
299
303
  : Array.from(this.tiers.values());
300
304
 
301
305
  // Extract keyword → domain+entry mapping
302
306
  const keywordMap = new Map<string, Array<{ id: string; domain: string; snippet: string }>>();
303
307
  const STOP_WORDS = new Set([
304
- 'the', 'and', 'for', 'that', 'this', 'with', 'from', 'are', 'was', 'were',
305
- 'not', 'but', 'have', 'has', 'had', 'will', 'would', 'could', 'should',
306
- 'can', 'may', 'its', 'all', 'each', 'any', 'use', 'used', 'using',
308
+ 'the',
309
+ 'and',
310
+ 'for',
311
+ 'that',
312
+ 'this',
313
+ 'with',
314
+ 'from',
315
+ 'are',
316
+ 'was',
317
+ 'were',
318
+ 'not',
319
+ 'but',
320
+ 'have',
321
+ 'has',
322
+ 'had',
323
+ 'will',
324
+ 'would',
325
+ 'could',
326
+ 'should',
327
+ 'can',
328
+ 'may',
329
+ 'its',
330
+ 'all',
331
+ 'each',
332
+ 'any',
333
+ 'use',
334
+ 'used',
335
+ 'using',
307
336
  ]);
308
337
 
309
338
  for (const entry of entries) {
@@ -311,7 +340,7 @@ export class KnowledgeConsolidator {
311
340
  .toLowerCase()
312
341
  .replace(/[^a-z0-9\s-]/g, '')
313
342
  .split(/\s+/)
314
- .filter(w => w.length > 3 && !STOP_WORDS.has(w));
343
+ .filter((w) => w.length > 3 && !STOP_WORDS.has(w));
315
344
 
316
345
  // Use unique words per entry
317
346
  const unique = [...new Set(words)];
@@ -328,7 +357,7 @@ export class KnowledgeConsolidator {
328
357
  // Find keywords that span multiple domains
329
358
  const patterns: CrossDomainPattern[] = [];
330
359
  for (const [keyword, refs] of keywordMap) {
331
- const uniqueDomains = [...new Set(refs.map(r => r.domain))];
360
+ const uniqueDomains = [...new Set(refs.map((r) => r.domain))];
332
361
  if (uniqueDomains.length >= 2) {
333
362
  patterns.push({
334
363
  pattern: keyword,
@@ -340,8 +369,7 @@ export class KnowledgeConsolidator {
340
369
  }
341
370
 
342
371
  // Sort by strength (most entries), then by domain count
343
- return patterns
344
- .sort((a, b) => b.domains.length - a.domains.length || b.strength - a.strength);
372
+ return patterns.sort((a, b) => b.domains.length - a.domains.length || b.strength - a.strength);
345
373
  }
346
374
 
347
375
  // ── Contradiction Detection ──
@@ -381,7 +409,7 @@ export class KnowledgeConsolidator {
381
409
  .toLowerCase()
382
410
  .replace(/[^a-z0-9\s]/g, '')
383
411
  .split(/\s+/)
384
- .filter(w => w.length > 4);
412
+ .filter((w) => w.length > 4);
385
413
  const unique = [...new Set(words)];
386
414
  for (const w of unique) {
387
415
  if (!keywordIndex.has(w)) keywordIndex.set(w, []);
@@ -464,7 +492,7 @@ export class KnowledgeConsolidator {
464
492
  // ── Inspection ──
465
493
 
466
494
  getByTier(tier: KnowledgeTier): TieredEntry[] {
467
- return Array.from(this.tiers.values()).filter(e => e.tier === tier);
495
+ return Array.from(this.tiers.values()).filter((e) => e.tier === tier);
468
496
  }
469
497
 
470
498
  getEntry(id: string): TieredEntry | undefined {
@@ -476,7 +504,9 @@ export class KnowledgeConsolidator {
476
504
  }
477
505
 
478
506
  stats(): { hot: number; warm: number; cold: number; total: number } {
479
- let hot = 0, warm = 0, cold = 0;
507
+ let hot = 0,
508
+ warm = 0,
509
+ cold = 0;
480
510
  for (const entry of this.tiers.values()) {
481
511
  if (entry.tier === 'hot') hot++;
482
512
  else if (entry.tier === 'warm') warm++;
@@ -12,7 +12,11 @@ import type { KnowledgeConfig, KnowledgeInsight } from '../types';
12
12
  import { applyHalfLifeDecay, computeExcitability } from './brain';
13
13
  import type { KnowledgeDomain, ExcitabilityMetadata } from './brain';
14
14
  import { KnowledgeMarketplace } from '../economy/KnowledgeMarketplace';
15
- import type { KnowledgeListing, PurchaseResult, ListingResult } from '../economy/KnowledgeMarketplace';
15
+ import type {
16
+ KnowledgeListing,
17
+ PurchaseResult,
18
+ ListingResult,
19
+ } from '../economy/KnowledgeMarketplace';
16
20
 
17
21
  export interface StoredEntry extends KnowledgeInsight {
18
22
  id: string;
@@ -61,17 +65,28 @@ export class KnowledgeStore {
61
65
 
62
66
  /** Publish a knowledge entry. Deduplicates by normalized content. */
63
67
  publish(
64
- insight: KnowledgeInsight,
65
- authorAgent: string,
68
+ insight: KnowledgeInsight,
69
+ authorAgent: string,
66
70
  provenance?: { taskId?: string; cycleId?: string; verifierId?: string; provenanceHash?: string }
67
71
  ): StoredEntry {
68
72
  const prefix = insight.type === 'wisdom' ? 'W' : insight.type === 'pattern' ? 'P' : 'G';
69
- const domain = insight.domain.toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 8);
73
+ const domain = insight.domain
74
+ .toUpperCase()
75
+ .replace(/[^A-Z0-9]/g, '')
76
+ .slice(0, 8);
70
77
  const id = `${prefix}.${domain}.${String(this.nextId++).padStart(3, '0')}`;
71
78
 
72
- const norm = insight.content.toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim().slice(0, 100);
79
+ const norm = insight.content
80
+ .toLowerCase()
81
+ .replace(/[^a-z0-9]+/g, ' ')
82
+ .trim()
83
+ .slice(0, 100);
73
84
  for (const existing of this.entries.values()) {
74
- const existingNorm = existing.content.toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim().slice(0, 100);
85
+ const existingNorm = existing.content
86
+ .toLowerCase()
87
+ .replace(/[^a-z0-9]+/g, ' ')
88
+ .trim()
89
+ .slice(0, 100);
75
90
  if (existingNorm === norm) return existing;
76
91
  }
77
92
 
@@ -94,7 +109,10 @@ export class KnowledgeStore {
94
109
 
95
110
  /** Search entries by keyword with excitability + half-life decay ranking. */
96
111
  search(query: string, limit = 10): StoredEntry[] {
97
- const keywords = query.toLowerCase().split(/\s+/).filter(w => w.length > 2);
112
+ const keywords = query
113
+ .toLowerCase()
114
+ .split(/\s+/)
115
+ .filter((w) => w.length > 2);
98
116
  if (keywords.length === 0) return this.recent(limit);
99
117
 
100
118
  const now = Date.now();
@@ -136,7 +154,7 @@ export class KnowledgeStore {
136
154
  return scored
137
155
  .sort((a, b) => b.score - a.score)
138
156
  .slice(0, limit)
139
- .map(s => s.entry);
157
+ .map((s) => s.entry);
140
158
  }
141
159
 
142
160
  /** Search remote knowledge store (MCP Orchestrator). */
@@ -153,8 +171,8 @@ export class KnowledgeStore {
153
171
  signal: AbortSignal.timeout(10_000),
154
172
  });
155
173
  if (!res.ok) return [];
156
- const data = await res.json() as Array<Record<string, unknown>>;
157
- return (Array.isArray(data) ? data : []).map(e => this.mapRemoteEntry(e));
174
+ const data = (await res.json()) as Array<Record<string, unknown>>;
175
+ return (Array.isArray(data) ? data : []).map((e) => this.mapRemoteEntry(e));
158
176
  } catch {
159
177
  return [];
160
178
  }
@@ -163,19 +181,19 @@ export class KnowledgeStore {
163
181
  /** Sync local entries to remote knowledge store. */
164
182
  async syncToRemote(): Promise<number> {
165
183
  if (!this.config.remoteUrl || !this.config.remoteApiKey) return 0;
166
- const entries = this.all().map(e => ({
184
+ const entries = this.all().map((e) => ({
167
185
  id: e.id,
168
186
  workspace_id: 'ai-ecosystem',
169
187
  type: e.type,
170
188
  content: e.content,
171
189
  provenanceHash: e.provenanceHash || '',
172
- metadata: {
173
- domain: e.domain,
174
- confidence: e.confidence,
190
+ metadata: {
191
+ domain: e.domain,
192
+ confidence: e.confidence,
175
193
  source: e.authorAgent,
176
194
  taskId: e.taskId,
177
195
  cycleId: e.cycleId,
178
- verifierId: e.verifierId
196
+ verifierId: e.verifierId,
179
197
  },
180
198
  }));
181
199
  if (entries.length === 0) return 0;
@@ -190,7 +208,7 @@ export class KnowledgeStore {
190
208
  signal: AbortSignal.timeout(15_000),
191
209
  });
192
210
  if (!res.ok) return 0;
193
- const data = await res.json() as { synced?: number };
211
+ const data = (await res.json()) as { synced?: number };
194
212
  return data.synced ?? entries.length;
195
213
  } catch {
196
214
  return 0;
@@ -224,21 +242,23 @@ export class KnowledgeStore {
224
242
  try {
225
243
  const payload = {
226
244
  workspace_id: 'ai-ecosystem',
227
- entries: [{
228
- id: entry.id,
229
- workspace_id: 'ai-ecosystem',
230
- type: entry.type,
231
- content: entry.content,
232
- provenanceHash: entry.provenanceHash || '',
233
- metadata: {
234
- domain: entry.domain,
235
- confidence: entry.confidence,
236
- source: entry.authorAgent,
237
- taskId: entry.taskId,
238
- cycleId: entry.cycleId,
239
- verifierId: entry.verifierId,
245
+ entries: [
246
+ {
247
+ id: entry.id,
248
+ workspace_id: 'ai-ecosystem',
249
+ type: entry.type,
250
+ content: entry.content,
251
+ provenanceHash: entry.provenanceHash || '',
252
+ metadata: {
253
+ domain: entry.domain,
254
+ confidence: entry.confidence,
255
+ source: entry.authorAgent,
256
+ taskId: entry.taskId,
257
+ cycleId: entry.cycleId,
258
+ verifierId: entry.verifierId,
259
+ },
240
260
  },
241
- }],
261
+ ],
242
262
  };
243
263
 
244
264
  const res = await fetch(`${this.config.remoteUrl}/knowledge/sync`, {
@@ -255,7 +275,7 @@ export class KnowledgeStore {
255
275
  return { entryId: entry.id, synced: false };
256
276
  }
257
277
 
258
- const data = await res.json() as { synced?: number; ids?: string[] };
278
+ const data = (await res.json()) as { synced?: number; ids?: string[] };
259
279
  return {
260
280
  entryId: entry.id,
261
281
  synced: (data.synced ?? 0) > 0,
@@ -302,12 +322,14 @@ export class KnowledgeStore {
302
322
  });
303
323
 
304
324
  if (res.ok) {
305
- const data = await res.json() as Array<Record<string, unknown>>;
306
- remoteResults = (Array.isArray(data) ? data : []).map(e => this.mapRemoteEntry(e));
325
+ const data = (await res.json()) as Array<Record<string, unknown>>;
326
+ remoteResults = (Array.isArray(data) ? data : []).map((e) => this.mapRemoteEntry(e));
307
327
 
308
328
  // Apply confidence filter
309
329
  if (options?.minConfidence !== undefined) {
310
- remoteResults = remoteResults.filter(e => e.confidence >= (options.minConfidence ?? 0));
330
+ remoteResults = remoteResults.filter(
331
+ (e) => e.confidence >= (options.minConfidence ?? 0)
332
+ );
311
333
  }
312
334
  }
313
335
  } catch {
@@ -362,10 +384,18 @@ export class KnowledgeStore {
362
384
  reuseCount: Number(e.reuseCount || 0),
363
385
  createdAt: String(e.createdAt || new Date().toISOString()),
364
386
  authorAgent: String(e.authorName || meta.source || 'remote'),
365
- taskId: e.taskId ? String(e.taskId) : (meta.taskId ? String(meta.taskId) : undefined),
366
- cycleId: e.cycleId ? String(e.cycleId) : (meta.cycleId ? String(meta.cycleId) : undefined),
367
- verifierId: e.verifierId ? String(e.verifierId) : (meta.verifierId ? String(meta.verifierId) : undefined),
368
- provenanceHash: e.provenanceHash ? String(e.provenanceHash) : (meta.provenanceHash ? String(meta.provenanceHash) : undefined),
387
+ taskId: e.taskId ? String(e.taskId) : meta.taskId ? String(meta.taskId) : undefined,
388
+ cycleId: e.cycleId ? String(e.cycleId) : meta.cycleId ? String(meta.cycleId) : undefined,
389
+ verifierId: e.verifierId
390
+ ? String(e.verifierId)
391
+ : meta.verifierId
392
+ ? String(meta.verifierId)
393
+ : undefined,
394
+ provenanceHash: e.provenanceHash
395
+ ? String(e.provenanceHash)
396
+ : meta.provenanceHash
397
+ ? String(meta.provenanceHash)
398
+ : undefined,
369
399
  };
370
400
  }
371
401
 
@@ -376,12 +406,12 @@ export class KnowledgeStore {
376
406
  }
377
407
 
378
408
  byType(type: 'wisdom' | 'pattern' | 'gotcha'): StoredEntry[] {
379
- return Array.from(this.entries.values()).filter(e => e.type === type);
409
+ return Array.from(this.entries.values()).filter((e) => e.type === type);
380
410
  }
381
411
 
382
412
  byDomain(domain: string): StoredEntry[] {
383
413
  const d = domain.toLowerCase();
384
- return Array.from(this.entries.values()).filter(e => e.domain.toLowerCase() === d);
414
+ return Array.from(this.entries.values()).filter((e) => e.domain.toLowerCase() === d);
385
415
  }
386
416
 
387
417
  markReused(id: string): void {
@@ -489,7 +519,7 @@ export class KnowledgeStore {
489
519
  const updated = [...existing, ...archived];
490
520
  fs.writeFileSync(archivePath, JSON.stringify(updated, null, 2), 'utf8');
491
521
  // Remove from hot buffer
492
- archived.forEach(e => this.entries.delete(e.id));
522
+ archived.forEach((e) => this.entries.delete(e.id));
493
523
  } catch {
494
524
  // Cold store unavailable; keep in hot buffer
495
525
  }
@@ -508,7 +538,10 @@ export class KnowledgeStore {
508
538
  const fs = require('fs') as typeof import('fs');
509
539
  if (!fs.existsSync(archivePath)) return [];
510
540
  const archived = JSON.parse(fs.readFileSync(archivePath, 'utf8')) as StoredEntry[];
511
- const keywords = query.toLowerCase().split(/\s+/).filter(w => w.length > 2);
541
+ const keywords = query
542
+ .toLowerCase()
543
+ .split(/\s+/)
544
+ .filter((w) => w.length > 2);
512
545
 
513
546
  const restored: StoredEntry[] = [];
514
547
  for (const entry of archived) {
@@ -525,7 +558,7 @@ export class KnowledgeStore {
525
558
 
526
559
  // Update cold store (remove restored)
527
560
  if (restored.length > 0) {
528
- const remaining = archived.filter(e => !restored.find(r => r.id === e.id));
561
+ const remaining = archived.filter((e) => !restored.find((r) => r.id === e.id));
529
562
  fs.writeFileSync(archivePath, JSON.stringify(remaining, null, 2), 'utf8');
530
563
  }
531
564
 
@@ -554,7 +587,7 @@ export class KnowledgeStore {
554
587
  * Evict: Permanently remove an entry from both hot and cold stores.
555
588
  * Called during cleanup or when an entry is marked as stale/wrong.
556
589
  */
557
- evict(id: string, archivePath?: string): boolean {
590
+ evict(id: string, _archivePath?: string): boolean {
558
591
  const existed = this.entries.delete(id);
559
592
  if (existed) {
560
593
  this.persistIfEnabled();
@@ -593,7 +626,12 @@ export class KnowledgeStore {
593
626
  }
594
627
 
595
628
  /** List a knowledge entry for sale on the marketplace. */
596
- listForSale(id: string, seller: string, price?: number, currency?: 'USDC' | 'credits'): ListingResult {
629
+ listForSale(
630
+ id: string,
631
+ seller: string,
632
+ price?: number,
633
+ currency?: 'USDC' | 'credits'
634
+ ): ListingResult {
597
635
  const entry = this.entries.get(id);
598
636
  if (!entry) return { success: false, listingId: '', error: 'Entry not found' };
599
637
  const finalPrice = price ?? this.marketplace.priceKnowledge(entry);
@@ -1,4 +1,9 @@
1
- export interface ProceduralSkill { id: string; name: string; description?: string; code?: string; }
1
+ export interface ProceduralSkill {
2
+ id: string;
3
+ name: string;
4
+ description?: string;
5
+ code?: string;
6
+ }
2
7
 
3
8
  /**
4
9
  * ProceduralCompiler
@@ -0,0 +1,102 @@
1
+ import { logger } from '../logger';
2
+
3
+ export interface EpisodicMemory {
4
+ id: string;
5
+ timestamp: number;
6
+ action: string;
7
+ outcome: string;
8
+ entitiesInvolved: string[];
9
+ semanticVector?: number[]; // Mock embedding
10
+ }
11
+
12
+ export interface SemanticFact {
13
+ id: string;
14
+ fact: string;
15
+ confidence: number;
16
+ sourceEpisodes: string[];
17
+ }
18
+
19
+ /**
20
+ * MemoryConsolidator
21
+ *
22
+ * Compresses raw episodic events into structured semantic facts
23
+ * via idle background cycles, mirroring human sleep consolidation.
24
+ */
25
+ export class MemoryConsolidator {
26
+ /**
27
+ * Identifies conceptually similar episodic memories based on shared entities and actions.
28
+ */
29
+ private static clusterEpisodes(episodes: EpisodicMemory[]): EpisodicMemory[][] {
30
+ const clusters: Record<string, EpisodicMemory[]> = {};
31
+
32
+ // Basic heuristic: Cluster by primary action and first entity
33
+ for (const ep of episodes) {
34
+ const key = `${ep.action}_${ep.entitiesInvolved[0] || 'generic'}`;
35
+ if (!clusters[key]) clusters[key] = [];
36
+ clusters[key].push(ep);
37
+ }
38
+
39
+ return Object.values(clusters);
40
+ }
41
+
42
+ /**
43
+ * Mocks an LLM-based summarization pass converting a cluster of raw events
44
+ * into a single concrete semantic truth.
45
+ */
46
+ private static summarizeCluster(cluster: EpisodicMemory[]): SemanticFact | null {
47
+ if (cluster.length < 3) return null; // Only consolidate recurring patterns
48
+
49
+ const sample = cluster[0];
50
+ const successCount = cluster.filter((ep) => ep.outcome.includes('success')).length;
51
+ const successRate = successCount / cluster.length;
52
+
53
+ let rule = '';
54
+ if (successRate > 0.7) {
55
+ rule = `${sample.action} applied to ${sample.entitiesInvolved[0]} is generally effective.`;
56
+ } else {
57
+ rule = `${sample.action} applied to ${sample.entitiesInvolved[0]} has high failure risk.`;
58
+ }
59
+
60
+ return {
61
+ id: `fact_${Date.now()}_${Math.random().toString(36).substring(7)}`,
62
+ fact: rule,
63
+ confidence: successRate,
64
+ sourceEpisodes: cluster.map((c) => c.id),
65
+ };
66
+ }
67
+
68
+ /**
69
+ * Executes the background consolidation pass.
70
+ * Takes raw episodes, clusters them, extracts truths, and returns the facts
71
+ * while reporting which raw episodes can be safely garbage collected.
72
+ */
73
+ static compressEpisodes(rawEpisodes: EpisodicMemory[]): {
74
+ newFacts: SemanticFact[];
75
+ prunedEpisodes: string[];
76
+ } {
77
+ if (rawEpisodes.length < 5) return { newFacts: [], prunedEpisodes: [] };
78
+
79
+ logger.info(
80
+ `[Consolidation] Running idle memory compression on ${rawEpisodes.length} episodes.`
81
+ );
82
+
83
+ const clusters = this.clusterEpisodes(rawEpisodes);
84
+ const newFacts: SemanticFact[] = [];
85
+ const prunedEpisodes: string[] = [];
86
+
87
+ for (const cluster of clusters) {
88
+ const fact = this.summarizeCluster(cluster);
89
+ if (fact) {
90
+ newFacts.push(fact);
91
+ // Mark these source episodes for pruning since we extracted the semantic truth
92
+ prunedEpisodes.push(...fact.sourceEpisodes);
93
+ }
94
+ }
95
+
96
+ logger.info(
97
+ `[Consolidation] Distilled ${prunedEpisodes.length} raw episodes into ${newFacts.length} semantic facts.`
98
+ );
99
+
100
+ return { newFacts, prunedEpisodes };
101
+ }
102
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * MemoryScorer
3
+ *
4
+ * Generates an 'importance' dimensional scalar for Episodic memories.
5
+ * Allows the aggregation engine to aggressively prune trivial loops (like 'Idle')
6
+ * and permanently archive high-value bounds (like 'Combat' or 'Crafting').
7
+ */
8
+
9
+ export interface EpisodicEvent {
10
+ agentId: string;
11
+ timestamp: number;
12
+ action: string;
13
+ context: Record<string, any>;
14
+ outcome: string;
15
+ }
16
+
17
+ export class MemoryScorer {
18
+ /**
19
+ * Scores an event from -100 (Absolute Noise) to 100 (Critical Experience).
20
+ */
21
+ static computeImportance(event: EpisodicEvent): number {
22
+ let score = 0;
23
+
24
+ // 1. Action Density Weighting
25
+ const action = event.action.toLowerCase();
26
+ if (action.includes('idle') || action.includes('wait') || action.includes('sleep')) {
27
+ score -= 50;
28
+ } else if (action.includes('move') || action.includes('look') || action.includes('walk')) {
29
+ score -= 10;
30
+ } else if (action.includes('craft') || action.includes('build') || action.includes('analyze')) {
31
+ score += 30;
32
+ } else if (
33
+ action.includes('combat') ||
34
+ action.includes('attack') ||
35
+ action.includes('defense') ||
36
+ action.includes('damage')
37
+ ) {
38
+ score += 50;
39
+ }
40
+
41
+ // 2. Context Entropy (More complex context = higher density value)
42
+ const contextKeys = Object.keys(event.context || {}).length;
43
+ score += Math.min(20, contextKeys * 2);
44
+
45
+ // 3. Outcome Variance (Is the outcome signifying a concrete change?)
46
+ const outcome = event.outcome.toLowerCase();
47
+ if (outcome.includes('failed') || outcome.includes('error')) {
48
+ score += 25; // Agent failures are important for negative reinforcement
49
+ } else if (
50
+ outcome.includes('success') ||
51
+ outcome.includes('crafted') ||
52
+ outcome.includes('killed')
53
+ ) {
54
+ score += 25; // Major achievements are important for positive reinforcement
55
+ } else if (outcome.includes('nothing') || outcome.includes('none')) {
56
+ score -= 20; // Zero variance
57
+ }
58
+
59
+ // Clamp between -100 and 100
60
+ return Math.max(-100, Math.min(100, score));
61
+ }
62
+
63
+ /**
64
+ * Filters arrays natively discarding negative arrays
65
+ */
66
+ static cullLowImportance(events: EpisodicEvent[], threshold: number = 0): EpisodicEvent[] {
67
+ return events.filter((e) => this.computeImportance(e) >= threshold);
68
+ }
69
+ }
@@ -0,0 +1,45 @@
1
+ import { ProceduralSkill } from '../types';
2
+
3
+ /**
4
+ * ProceduralCompiler
5
+ *
6
+ * Takes JSON-based AI logic trees extracted from temporal LLM generation natively
7
+ * and compiles them strictly down into raw executable `.holo` syntax bounds.
8
+ */
9
+ export class ProceduralCompiler {
10
+ /**
11
+ * Translates an Abstract Skill representation into native text executing within the VM.
12
+ */
13
+ static compile(skill: ProceduralSkill): string {
14
+ let compiled = `// Auto-generated skill: ${skill.name}\n`;
15
+ compiled += `// Desc: ${(skill as unknown as { description?: string }).description || 'N/A'}\n\n`;
16
+
17
+ compiled += `agent ${skill.id.replace(/-/g, '_')} {\n`;
18
+
19
+ // Generate behavior node
20
+ compiled += ` behavior execute() {\n`;
21
+
22
+ const codeBlock = (skill as unknown as { code?: string }).code || '';
23
+
24
+ // MVP: The LLM outputs pseudo-code or raw JS/HoloScript lines directly in string
25
+ // The procedural compiler validates and formats the raw string cleanly
26
+ const parsedLines = codeBlock.split('\n');
27
+
28
+ for (let line of parsedLines) {
29
+ line = line.trim();
30
+ if (!line) continue;
31
+
32
+ // Map some logical conversions if needed, here we just enforce safety wrappers
33
+ if (line.includes('move(') || line.includes('attack(') || line.includes('craft(')) {
34
+ compiled += ` ensure_safety() {\n ${line}\n }\n`;
35
+ } else {
36
+ compiled += ` ${line}\n`;
37
+ }
38
+ }
39
+
40
+ compiled += ` }\n`;
41
+ compiled += `}\n`;
42
+
43
+ return compiled;
44
+ }
45
+ }