@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.
- package/CHANGELOG.md +1 -2
- package/ROADMAP.md +68 -66
- package/dist/{InvisibleWallet-BB6tFvRA.d.cts → InvisibleWallet-EFiuaLn3.d.cts} +1 -1
- package/dist/{OrchestratorAgent-BvWgf9uw.d.cts → OrchestratorAgent-CrLDGNL6.d.cts} +1 -1
- package/dist/agents/index.cjs +11 -10
- package/dist/agents/index.d.cts +4 -16
- package/dist/ai/index.cjs +2 -2
- package/dist/behavior.cjs +10 -0
- package/dist/economy/index.cjs +4 -4
- package/dist/economy/index.d.cts +2 -2
- package/dist/index.cjs +33 -11
- package/dist/index.d.cts +3 -3
- package/dist/swarm/index.cjs +3 -0
- package/package.json +14 -9
- package/src/__tests__/bounty-marketplace.test.ts +53 -21
- package/src/__tests__/delegation.test.ts +1 -4
- package/src/__tests__/done-log-audit.test.ts +38 -46
- package/src/__tests__/framework.test.ts +172 -53
- package/src/__tests__/goal-synthesizer.test.ts +9 -6
- package/src/__tests__/presence.test.ts +1 -1
- package/src/__tests__/protocol-agent.test.ts +12 -11
- package/src/__tests__/revenue-splitter.test.ts +22 -15
- package/src/__tests__/scenario-driven-todo.test.ts +55 -35
- package/src/__tests__/self-improve.test.ts +28 -9
- package/src/__tests__/service-lifecycle.test.ts +9 -3
- package/src/__tests__/skill-router.test.ts +3 -3
- package/src/agents/CulturalMemory.ts +6 -6
- package/src/agents/DelegationTraceHooks.ts +560 -0
- package/src/agents/FederatedRegistryAdapter.ts +1 -1
- package/src/agents/NormEngine.ts +3 -8
- package/src/agents/OrchestratorAgent.ts +1 -1
- package/src/agents/TaskDelegationService.ts +5 -9
- package/src/agents/__tests__/AgentWalletRegistry.test.ts +5 -4
- package/src/agents/__tests__/CrossRealityHandoff.test.ts +9 -3
- package/src/agents/__tests__/DelegationTraceHooks.test.ts +390 -0
- package/src/agents/__tests__/TaskDelegationService.test.ts +4 -2
- package/src/agents/spatial-comms/Layer1RealTime.ts +36 -19
- package/src/agents/spatial-comms/Layer2A2A.ts +1 -3
- package/src/agents/spatial-comms/Layer3MCP.ts +13 -4
- package/src/agents/spatial-comms/ProtocolTypes.ts +5 -2
- package/src/agents/spatial-comms/examples/multi-agent-world-creation.ts +2 -2
- package/src/ai/HoloScriptGenerator.ts +2 -2
- package/src/ai/__tests__/PerceptionSystem.prod.test.ts +1 -1
- package/src/ai/__tests__/PerceptionSystem.test.ts +14 -14
- package/src/ai/__tests__/SteeringBehaviors.prod.test.ts +1 -1
- package/src/ai/index.ts +5 -1
- package/src/board/audit.ts +17 -6
- package/src/board/board-ops.ts +45 -15
- package/src/board/board-types.ts +94 -20
- package/src/delegation.ts +5 -3
- package/src/distributed-claimer.ts +13 -2
- package/src/economy/BountyManager.ts +40 -18
- package/src/economy/KnowledgeMarketplace.ts +27 -8
- package/src/economy/PaymentWebhookService.ts +0 -1
- package/src/economy/RevenueSplitter.ts +2 -4
- package/src/economy/UnifiedBudgetOptimizer.ts +8 -9
- package/src/economy/_core-stubs.ts +1 -1
- package/src/economy/x402-facilitator.ts +17 -8
- package/src/index.ts +16 -12
- package/src/knowledge/__tests__/knowledge-consolidator.test.ts +138 -89
- package/src/knowledge/__tests__/knowledge-store-vector.test.ts +59 -16
- package/src/knowledge/brain.ts +7 -7
- package/src/knowledge/consolidation.ts +16 -16
- package/src/knowledge/knowledge-consolidator.ts +60 -30
- package/src/knowledge/knowledge-store.ts +83 -45
- package/src/learning/ProceduralCompiler.ts +6 -1
- package/src/learning/learning/MemoryConsolidator.ts +102 -0
- package/src/learning/learning/MemoryScorer.ts +69 -0
- package/src/learning/learning/ProceduralCompiler.ts +45 -0
- package/src/learning/learning/SemanticClusterer.ts +66 -0
- package/src/llm/llm-adapter.ts +24 -10
- package/src/mesh/index.ts +37 -17
- package/src/protocol/goal-synthesizer.ts +24 -34
- package/src/protocol/implementations.ts +91 -22
- package/src/protocol/micro-phase-decomposer.ts +25 -17
- package/src/protocol/micro-step-decomposer.test.ts +104 -39
- package/src/protocol-agent.test.ts +17 -7
- package/src/protocol-agent.ts +45 -42
- package/src/self-improve/absorb-scanner.ts +9 -6
- package/src/self-improve/evolution-engine.ts +36 -18
- package/src/self-improve/framework-absorber.ts +21 -16
- package/src/self-improve/index.ts +2 -10
- package/src/self-improve/prompt-optimizer.ts +31 -19
- package/src/self-improve/test-generator.ts +16 -12
- package/src/skill-router.ts +7 -6
- package/src/swarm/messaging/GossipProtocol.ts +1 -1
- package/src/swarm/messaging/__tests__/BroadcastChannel.prod.test.ts +31 -9
- package/src/swarm/messaging/__tests__/GossipProtocol.prod.test.ts +21 -7
- package/src/swarm/messaging/__tests__/SwarmEventBus.prod.test.ts +24 -8
- package/src/swarm/messaging/__tests__/SwarmEventBus.test.ts +6 -2
- package/src/team.ts +277 -122
- package/src/training/scripts/generate-spatial-dataset.ts +1 -1
- package/src/training/training/LRScheduler.ts +377 -0
- package/src/training/training/QualityScoringPipeline.ts +139 -0
- package/src/training/training/SoftDedup.ts +461 -0
- package/src/training/training/SparsityMonitor.ts +685 -0
- package/src/training/training/SparsityMonitorTypes.ts +209 -0
- package/src/training/training/SpatialTrainingDataGenerator.ts +1526 -0
- package/src/training/training/SpatialTrainingDataTypes.ts +216 -0
- package/src/training/training/TrainingPipelineConfig.ts +215 -0
- package/src/training/training/__tests__/CorpusValidation.test.ts +87 -0
- package/src/training/training/__tests__/LRScheduler.test.ts +592 -0
- package/src/training/training/__tests__/SoftDedup.test.ts +415 -0
- package/src/training/training/__tests__/SparsityMonitor.test.ts +1623 -0
- package/src/training/training/__tests__/SpatialCorpusValidation.test.ts +72 -0
- package/src/training/training/__tests__/SpatialTrainingDataGenerator.test.ts +1244 -0
- package/src/training/training/__tests__/TrainingMonkeyIntegration.test.ts +897 -0
- package/src/training/training/__tests__/TrainingPipelineConfig.test.ts +202 -0
- package/src/training/training/__tests__/schema.test.ts +72 -0
- package/src/training/training/__tests__/training-constants.test.ts +106 -0
- package/src/training/training/__tests__/trait-mappings.test.ts +81 -0
- package/src/training/training/constants.ts +94 -0
- package/src/training/training/index.ts +17 -0
- package/src/training/training/schema.ts +147 -0
- package/src/training/training/scripts/generate-novel-use-cases-dataset.ts +272 -0
- package/src/training/training/scripts/generate-spatial-dataset.ts +521 -0
- package/src/training/training/trainingmonkey/TrainingMonkeyIntegration.ts +477 -0
- package/src/training/training/trainingmonkey/TrainingMonkeyTypes.ts +230 -0
- package/src/training/training/trainingmonkey/index.ts +26 -0
- package/src/training/training/trait-mappings.ts +157 -0
- package/src/types.ts +2 -7
- package/ALL-test-results.json +0 -1
- package/LICENSE +0 -21
- package/dist/AgentManifest-CB4xM-Ma.d.ts +0 -704
- package/dist/BehaviorTree-BrBFECv5.d.ts +0 -103
- package/dist/InvisibleWallet-rtRrBOA8.d.ts +0 -1732
- package/dist/OrchestratorAgent-Q_CbVTmO.d.ts +0 -798
- package/dist/agents/index.d.ts +0 -1788
- package/dist/agents/index.js +0 -4695
- package/dist/ai/index.d.ts +0 -1753
- package/dist/ai/index.js +0 -5244
- package/dist/behavior.d.ts +0 -130
- package/dist/behavior.js +0 -407
- package/dist/economy/index.d.ts +0 -747
- package/dist/economy/index.js +0 -3617
- package/dist/implementations-D9T3un9D.d.ts +0 -236
- package/dist/index.d.ts +0 -1729
- package/dist/index.js +0 -24277
- package/dist/learning/index.d.ts +0 -104
- package/dist/learning/index.js +0 -189
- package/dist/negotiation/index.d.ts +0 -610
- package/dist/negotiation/index.js +0 -931
- package/dist/skills/index.d.ts +0 -289
- package/dist/skills/index.js +0 -1079
- package/dist/swarm/index.d.ts +0 -2433
- package/dist/swarm/index.js +0 -5221
- package/dist/training/index.d.ts +0 -1734
- package/dist/training/index.js +0 -2687
- package/extract-failures.js +0 -10
- package/src/training/training/data/novel-use-cases.jsonl +0 -153
- package/src/training/training/data/spatial-reasoning-10k.jsonl +0 -9354
- package/src/types/core-stubs.d.ts +0 -113
- package/test-output.txt +0 -0
- package/test-result.json +0 -1
- package/tsc-errors.txt +0 -4
- package/tsc_output.txt +0 -0
- package/typescript-errors-2.txt +0 -0
- package/typescript-errors.txt +0 -22
- package/vitest-log-utf8.txt +0 -268
- 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,
|
|
98
|
-
coldDemoteAfterMs: 48 * 60 * 60 * 1000,
|
|
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
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
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',
|
|
305
|
-
'
|
|
306
|
-
'
|
|
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,
|
|
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 {
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
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(
|
|
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) :
|
|
366
|
-
cycleId: e.cycleId ? String(e.cycleId) :
|
|
367
|
-
verifierId: e.verifierId
|
|
368
|
-
|
|
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
|
|
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,
|
|
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(
|
|
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);
|
|
@@ -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
|
+
}
|