@holoscript/framework 6.0.3
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/ALL-test-results.json +1 -0
- package/CHANGELOG.md +8 -0
- package/LICENSE +21 -0
- package/ROADMAP.md +175 -0
- package/dist/AgentManifest-CB4xM-Ma.d.cts +704 -0
- package/dist/AgentManifest-CB4xM-Ma.d.ts +704 -0
- package/dist/BehaviorTree-BrBFECv5.d.cts +103 -0
- package/dist/BehaviorTree-BrBFECv5.d.ts +103 -0
- package/dist/InvisibleWallet-BB6tFvRA.d.cts +1732 -0
- package/dist/InvisibleWallet-rtRrBOA8.d.ts +1732 -0
- package/dist/OrchestratorAgent-BvWgf9uw.d.cts +798 -0
- package/dist/OrchestratorAgent-Q_CbVTmO.d.ts +798 -0
- package/dist/agents/index.cjs +4790 -0
- package/dist/agents/index.d.cts +1788 -0
- package/dist/agents/index.d.ts +1788 -0
- package/dist/agents/index.js +4695 -0
- package/dist/ai/index.cjs +5347 -0
- package/dist/ai/index.d.cts +1753 -0
- package/dist/ai/index.d.ts +1753 -0
- package/dist/ai/index.js +5244 -0
- package/dist/behavior.cjs +449 -0
- package/dist/behavior.d.cts +130 -0
- package/dist/behavior.d.ts +130 -0
- package/dist/behavior.js +407 -0
- package/dist/economy/index.cjs +3659 -0
- package/dist/economy/index.d.cts +747 -0
- package/dist/economy/index.d.ts +747 -0
- package/dist/economy/index.js +3617 -0
- package/dist/implementations-D9T3un9D.d.cts +236 -0
- package/dist/implementations-D9T3un9D.d.ts +236 -0
- package/dist/index.cjs +24550 -0
- package/dist/index.d.cts +1729 -0
- package/dist/index.d.ts +1729 -0
- package/dist/index.js +24277 -0
- package/dist/learning/index.cjs +219 -0
- package/dist/learning/index.d.cts +104 -0
- package/dist/learning/index.d.ts +104 -0
- package/dist/learning/index.js +189 -0
- package/dist/negotiation/index.cjs +970 -0
- package/dist/negotiation/index.d.cts +610 -0
- package/dist/negotiation/index.d.ts +610 -0
- package/dist/negotiation/index.js +931 -0
- package/dist/skills/index.cjs +1118 -0
- package/dist/skills/index.d.cts +289 -0
- package/dist/skills/index.d.ts +289 -0
- package/dist/skills/index.js +1079 -0
- package/dist/swarm/index.cjs +5268 -0
- package/dist/swarm/index.d.cts +2433 -0
- package/dist/swarm/index.d.ts +2433 -0
- package/dist/swarm/index.js +5221 -0
- package/dist/training/index.cjs +2745 -0
- package/dist/training/index.d.cts +1734 -0
- package/dist/training/index.d.ts +1734 -0
- package/dist/training/index.js +2687 -0
- package/extract-failures.js +10 -0
- package/package.json +82 -0
- package/src/__tests__/bounty-marketplace.test.ts +374 -0
- package/src/__tests__/delegation.test.ts +144 -0
- package/src/__tests__/distributed-claimer.test.ts +147 -0
- package/src/__tests__/done-log-audit.test.ts +342 -0
- package/src/__tests__/framework.test.ts +865 -0
- package/src/__tests__/goal-synthesizer.test.ts +236 -0
- package/src/__tests__/presence.test.ts +223 -0
- package/src/__tests__/protocol-agent.test.ts +254 -0
- package/src/__tests__/revenue-splitter.test.ts +114 -0
- package/src/__tests__/scenario-driven-todo.test.ts +197 -0
- package/src/__tests__/self-improve.test.ts +349 -0
- package/src/__tests__/service-lifecycle.test.ts +237 -0
- package/src/__tests__/skill-router.test.ts +121 -0
- package/src/agents/AgentManifest.ts +493 -0
- package/src/agents/AgentRegistry.ts +475 -0
- package/src/agents/AgentTypes.ts +585 -0
- package/src/agents/AgentWalletRegistry.ts +83 -0
- package/src/agents/AuthenticatedCRDT.ts +388 -0
- package/src/agents/CapabilityMatcher.ts +453 -0
- package/src/agents/CrossRealityHandoff.ts +305 -0
- package/src/agents/CulturalMemory.ts +454 -0
- package/src/agents/FederatedRegistryAdapter.ts +429 -0
- package/src/agents/NormEngine.ts +450 -0
- package/src/agents/OrchestratorAgent.ts +414 -0
- package/src/agents/SkillWorkflowEngine.ts +472 -0
- package/src/agents/TaskDelegationService.ts +551 -0
- package/src/agents/__tests__/AgentManifest.prod.test.ts +134 -0
- package/src/agents/__tests__/AgentManifest.test.ts +182 -0
- package/src/agents/__tests__/AgentModule.test.ts +864 -0
- package/src/agents/__tests__/AgentRegistry.prod.test.ts +125 -0
- package/src/agents/__tests__/AgentRegistry.test.ts +148 -0
- package/src/agents/__tests__/AgentTypes.test.ts +534 -0
- package/src/agents/__tests__/AgentWalletRegistry.test.ts +152 -0
- package/src/agents/__tests__/AuthenticatedCRDT.test.ts +558 -0
- package/src/agents/__tests__/CapabilityMatcher.prod.test.ts +117 -0
- package/src/agents/__tests__/CapabilityMatcher.test.ts +178 -0
- package/src/agents/__tests__/CrossRealityHandoff.test.ts +402 -0
- package/src/agents/__tests__/CulturalMemory.test.ts +200 -0
- package/src/agents/__tests__/FederatedRegistryAdapter.test.ts +409 -0
- package/src/agents/__tests__/NormEngine.test.ts +276 -0
- package/src/agents/__tests__/OrchestratorAgent.test.ts +182 -0
- package/src/agents/__tests__/SkillWorkflowEngine.test.ts +357 -0
- package/src/agents/__tests__/TaskDelegationService.test.ts +446 -0
- package/src/agents/index.ts +107 -0
- package/src/agents/spatial-comms/Layer1RealTime.ts +621 -0
- package/src/agents/spatial-comms/Layer2A2A.ts +661 -0
- package/src/agents/spatial-comms/Layer3MCP.ts +651 -0
- package/src/agents/spatial-comms/ProtocolTypes.ts +543 -0
- package/src/agents/spatial-comms/SpatialCommClient.ts +483 -0
- package/src/agents/spatial-comms/__tests__/performance-benchmark.test.ts +465 -0
- package/src/agents/spatial-comms/examples/multi-agent-world-creation.ts +409 -0
- package/src/agents/spatial-comms/index.ts +66 -0
- package/src/ai/AIAdapter.ts +313 -0
- package/src/ai/AICopilot.ts +331 -0
- package/src/ai/AIOutputValidator.ts +203 -0
- package/src/ai/BTNodes.ts +239 -0
- package/src/ai/BehaviorSelector.ts +135 -0
- package/src/ai/BehaviorTree.ts +153 -0
- package/src/ai/Blackboard.ts +165 -0
- package/src/ai/GenerationAnalytics.ts +461 -0
- package/src/ai/GenerationCache.ts +265 -0
- package/src/ai/GoalPlanner.ts +165 -0
- package/src/ai/HoloScriptGenerator.ts +580 -0
- package/src/ai/InfluenceMap.ts +180 -0
- package/src/ai/NavMesh.ts +168 -0
- package/src/ai/PerceptionSystem.ts +178 -0
- package/src/ai/PromptTemplates.ts +453 -0
- package/src/ai/SemanticSearchService.ts +80 -0
- package/src/ai/StateMachine.ts +196 -0
- package/src/ai/SteeringBehavior.ts +150 -0
- package/src/ai/SteeringBehaviors.ts +244 -0
- package/src/ai/TrainingDataGenerator.ts +1082 -0
- package/src/ai/UtilityAI.ts +145 -0
- package/src/ai/__tests__/AIAdapter.prod.test.ts +259 -0
- package/src/ai/__tests__/AIAdapter.test.ts +109 -0
- package/src/ai/__tests__/AICopilot.prod.test.ts +341 -0
- package/src/ai/__tests__/AICopilot.test.ts +178 -0
- package/src/ai/__tests__/AIOutputValidator.prod.test.ts +226 -0
- package/src/ai/__tests__/AIOutputValidator.test.ts +138 -0
- package/src/ai/__tests__/BTNodes.prod.test.ts +391 -0
- package/src/ai/__tests__/BTNodes.test.ts +263 -0
- package/src/ai/__tests__/BehaviorSelector.prod.test.ts +129 -0
- package/src/ai/__tests__/BehaviorSelector.test.ts +132 -0
- package/src/ai/__tests__/BehaviorTree.prod.test.ts +266 -0
- package/src/ai/__tests__/BehaviorTree.test.ts +216 -0
- package/src/ai/__tests__/Blackboard.prod.test.ts +339 -0
- package/src/ai/__tests__/Blackboard.test.ts +183 -0
- package/src/ai/__tests__/GenerationAnalytics.prod.test.ts +141 -0
- package/src/ai/__tests__/GenerationAnalytics.test.ts +165 -0
- package/src/ai/__tests__/GenerationCache.prod.test.ts +144 -0
- package/src/ai/__tests__/GenerationCache.test.ts +171 -0
- package/src/ai/__tests__/GoalPlanner.prod.test.ts +189 -0
- package/src/ai/__tests__/GoalPlanner.test.ts +137 -0
- package/src/ai/__tests__/GoalPlannerDepth.prod.test.ts +217 -0
- package/src/ai/__tests__/HoloScriptGenerator.test.ts +125 -0
- package/src/ai/__tests__/InfluenceMap.prod.test.ts +146 -0
- package/src/ai/__tests__/InfluenceMap.test.ts +149 -0
- package/src/ai/__tests__/NavMesh.prod.test.ts +141 -0
- package/src/ai/__tests__/NavMesh.test.ts +159 -0
- package/src/ai/__tests__/PerceptionSystem.prod.test.ts +135 -0
- package/src/ai/__tests__/PerceptionSystem.test.ts +250 -0
- package/src/ai/__tests__/PromptTemplates.prod.test.ts +313 -0
- package/src/ai/__tests__/PromptTemplates.test.ts +146 -0
- package/src/ai/__tests__/SemanticSearch.test.ts +37 -0
- package/src/ai/__tests__/StateMachine.prod.test.ts +162 -0
- package/src/ai/__tests__/StateMachine.test.ts +163 -0
- package/src/ai/__tests__/SteeringBehavior.prod.test.ts +251 -0
- package/src/ai/__tests__/SteeringBehavior.test.ts +135 -0
- package/src/ai/__tests__/SteeringBehaviors.prod.test.ts +133 -0
- package/src/ai/__tests__/SteeringBehaviors.test.ts +151 -0
- package/src/ai/__tests__/TrainingDataGenerator.prod.test.ts +286 -0
- package/src/ai/__tests__/TrainingDataGenerator.test.ts +286 -0
- package/src/ai/__tests__/UtilityAI.prod.test.ts +207 -0
- package/src/ai/__tests__/UtilityAI.test.ts +155 -0
- package/src/ai/__tests__/adapters.prod.test.ts +263 -0
- package/src/ai/__tests__/adapters.test.ts +320 -0
- package/src/ai/adapters.ts +1585 -0
- package/src/ai/index.ts +130 -0
- package/src/behavior/BehaviorPresets.ts +140 -0
- package/src/behavior/BehaviorTree.ts +236 -0
- package/src/behavior/StateMachine.ts +176 -0
- package/src/behavior/StateTrait.ts +67 -0
- package/src/behavior/index.ts +8 -0
- package/src/behavior.ts +8 -0
- package/src/board/audit.ts +284 -0
- package/src/board/board-ops.ts +336 -0
- package/src/board/board-types.ts +302 -0
- package/src/board/index.ts +69 -0
- package/src/define-agent.ts +46 -0
- package/src/define-team.ts +33 -0
- package/src/delegation.ts +265 -0
- package/src/distributed-claimer.ts +228 -0
- package/src/economy/AgentBudgetEnforcer.ts +464 -0
- package/src/economy/BountyManager.ts +185 -0
- package/src/economy/CreatorRevenueAggregator.ts +460 -0
- package/src/economy/InvisibleWallet.ts +82 -0
- package/src/economy/KnowledgeMarketplace.ts +193 -0
- package/src/economy/PaymentWebhookService.ts +512 -0
- package/src/economy/RevenueSplitter.ts +156 -0
- package/src/economy/SubscriptionManager.ts +546 -0
- package/src/economy/UnifiedBudgetOptimizer.ts +635 -0
- package/src/economy/UsageMeter.ts +440 -0
- package/src/economy/_core-stubs.ts +219 -0
- package/src/economy/index.ts +100 -0
- package/src/economy/x402-facilitator.ts +1978 -0
- package/src/index.ts +348 -0
- package/src/knowledge/__tests__/knowledge-consolidator.test.ts +444 -0
- package/src/knowledge/__tests__/knowledge-store-vector.test.ts +291 -0
- package/src/knowledge/brain.ts +167 -0
- package/src/knowledge/consolidation.ts +581 -0
- package/src/knowledge/knowledge-consolidator.ts +510 -0
- package/src/knowledge/knowledge-store.ts +616 -0
- package/src/learning/MemoryConsolidator.ts +102 -0
- package/src/learning/MemoryScorer.ts +69 -0
- package/src/learning/ProceduralCompiler.ts +45 -0
- package/src/learning/SemanticClusterer.ts +66 -0
- package/src/learning/index.ts +8 -0
- package/src/llm/llm-adapter.ts +159 -0
- package/src/mesh/index.ts +309 -0
- package/src/negotiation/NegotiationProtocol.ts +694 -0
- package/src/negotiation/NegotiationTypes.ts +473 -0
- package/src/negotiation/VotingMechanisms.ts +691 -0
- package/src/negotiation/index.ts +49 -0
- package/src/protocol/goal-synthesizer.ts +317 -0
- package/src/protocol/implementations.ts +474 -0
- package/src/protocol/micro-phase-decomposer.ts +299 -0
- package/src/protocol/micro-step-decomposer.test.ts +306 -0
- package/src/protocol-agent.test.ts +353 -0
- package/src/protocol-agent.ts +670 -0
- package/src/self-improve/absorb-scanner.ts +252 -0
- package/src/self-improve/evolution-engine.ts +149 -0
- package/src/self-improve/framework-absorber.ts +214 -0
- package/src/self-improve/index.ts +50 -0
- package/src/self-improve/prompt-optimizer.ts +212 -0
- package/src/self-improve/test-generator.ts +175 -0
- package/src/skill-router.ts +186 -0
- package/src/skills/index.ts +5 -0
- package/src/skills/skill-md-bridge.ts +1699 -0
- package/src/swarm/ACOEngine.ts +261 -0
- package/src/swarm/CollectiveIntelligence.ts +383 -0
- package/src/swarm/ContributionSynthesizer.ts +481 -0
- package/src/swarm/LeaderElection.ts +393 -0
- package/src/swarm/PSOEngine.ts +206 -0
- package/src/swarm/QuorumPolicy.ts +173 -0
- package/src/swarm/SwarmCoordinator.ts +335 -0
- package/src/swarm/SwarmManager.ts +442 -0
- package/src/swarm/SwarmMembership.ts +456 -0
- package/src/swarm/VotingRound.ts +255 -0
- package/src/swarm/__tests__/ACOEngine.prod.test.ts +164 -0
- package/src/swarm/__tests__/ACOEngine.test.ts +117 -0
- package/src/swarm/__tests__/CollectiveIntelligence.prod.test.ts +296 -0
- package/src/swarm/__tests__/CollectiveIntelligence.test.ts +457 -0
- package/src/swarm/__tests__/ContributionSynthesizer.prod.test.ts +269 -0
- package/src/swarm/__tests__/ContributionSynthesizer.test.ts +254 -0
- package/src/swarm/__tests__/LeaderElection.prod.test.ts +196 -0
- package/src/swarm/__tests__/LeaderElection.test.ts +151 -0
- package/src/swarm/__tests__/PSOEngine.prod.test.ts +162 -0
- package/src/swarm/__tests__/PSOEngine.test.ts +106 -0
- package/src/swarm/__tests__/QuorumPolicy.prod.test.ts +216 -0
- package/src/swarm/__tests__/QuorumPolicy.test.ts +177 -0
- package/src/swarm/__tests__/SwarmCoordinator.prod.test.ts +186 -0
- package/src/swarm/__tests__/SwarmCoordinator.test.ts +167 -0
- package/src/swarm/__tests__/SwarmManager.prod.test.ts +308 -0
- package/src/swarm/__tests__/SwarmManager.test.ts +373 -0
- package/src/swarm/__tests__/SwarmMembership.prod.test.ts +273 -0
- package/src/swarm/__tests__/SwarmMembership.test.ts +264 -0
- package/src/swarm/__tests__/VotingRound.prod.test.ts +233 -0
- package/src/swarm/__tests__/VotingRound.test.ts +174 -0
- package/src/swarm/analytics/SwarmInspector.ts +476 -0
- package/src/swarm/analytics/SwarmMetrics.ts +449 -0
- package/src/swarm/analytics/__tests__/SwarmInspector.prod.test.ts +366 -0
- package/src/swarm/analytics/__tests__/SwarmInspector.test.ts +454 -0
- package/src/swarm/analytics/__tests__/SwarmMetrics.prod.test.ts +254 -0
- package/src/swarm/analytics/__tests__/SwarmMetrics.test.ts +370 -0
- package/src/swarm/analytics/index.ts +7 -0
- package/src/swarm/index.ts +69 -0
- package/src/swarm/messaging/BroadcastChannel.ts +509 -0
- package/src/swarm/messaging/GossipProtocol.ts +565 -0
- package/src/swarm/messaging/SwarmEventBus.ts +443 -0
- package/src/swarm/messaging/__tests__/BroadcastChannel.prod.test.ts +331 -0
- package/src/swarm/messaging/__tests__/BroadcastChannel.test.ts +333 -0
- package/src/swarm/messaging/__tests__/GossipProtocol.prod.test.ts +356 -0
- package/src/swarm/messaging/__tests__/GossipProtocol.test.ts +437 -0
- package/src/swarm/messaging/__tests__/SwarmEventBus.prod.test.ts +191 -0
- package/src/swarm/messaging/__tests__/SwarmEventBus.test.ts +247 -0
- package/src/swarm/messaging/index.ts +8 -0
- package/src/swarm/spatial/FlockingBehavior.ts +462 -0
- package/src/swarm/spatial/FormationController.ts +500 -0
- package/src/swarm/spatial/Vector3.ts +170 -0
- package/src/swarm/spatial/ZoneClaiming.ts +509 -0
- package/src/swarm/spatial/__tests__/FlockingBehavior.prod.test.ts +239 -0
- package/src/swarm/spatial/__tests__/FlockingBehavior.test.ts +298 -0
- package/src/swarm/spatial/__tests__/FormationController.prod.test.ts +240 -0
- package/src/swarm/spatial/__tests__/FormationController.test.ts +297 -0
- package/src/swarm/spatial/__tests__/Vector3.prod.test.ts +283 -0
- package/src/swarm/spatial/__tests__/Vector3.test.ts +224 -0
- package/src/swarm/spatial/__tests__/ZoneClaiming.prod.test.ts +246 -0
- package/src/swarm/spatial/__tests__/ZoneClaiming.test.ts +374 -0
- package/src/swarm/spatial/index.ts +28 -0
- package/src/team.ts +1245 -0
- package/src/training/LRScheduler.ts +377 -0
- package/src/training/QualityScoringPipeline.ts +139 -0
- package/src/training/SoftDedup.ts +461 -0
- package/src/training/SparsityMonitor.ts +685 -0
- package/src/training/SparsityMonitorTypes.ts +209 -0
- package/src/training/SpatialTrainingDataGenerator.ts +1526 -0
- package/src/training/SpatialTrainingDataTypes.ts +216 -0
- package/src/training/TrainingPipelineConfig.ts +215 -0
- package/src/training/constants.ts +94 -0
- package/src/training/index.ts +138 -0
- package/src/training/schema.ts +147 -0
- package/src/training/scripts/generate-novel-use-cases-dataset.ts +272 -0
- package/src/training/scripts/generate-spatial-dataset.ts +521 -0
- package/src/training/training/data/novel-use-cases.jsonl +153 -0
- package/src/training/training/data/spatial-reasoning-10k.jsonl +9354 -0
- package/src/training/trainingmonkey/TrainingMonkeyIntegration.ts +477 -0
- package/src/training/trainingmonkey/TrainingMonkeyTypes.ts +230 -0
- package/src/training/trainingmonkey/index.ts +26 -0
- package/src/training/trait-mappings.ts +157 -0
- package/src/types/core-stubs.d.ts +113 -0
- package/src/types.ts +304 -0
- package/test-output.txt +0 -0
- package/test-result.json +1 -0
- package/tsc-errors.txt +4 -0
- package/tsc_output.txt +0 -0
- package/tsconfig.json +14 -0
- package/tsup-learning-esm.config.ts +12 -0
- package/tsup.config.ts +21 -0
- package/typescript-errors-2.txt +0 -0
- package/typescript-errors.txt +22 -0
- package/vitest-log-utf8.txt +268 -0
- package/vitest-log.txt +0 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Consolidator — FW-0.5
|
|
3
|
+
*
|
|
4
|
+
* Higher-level orchestrator that adds:
|
|
5
|
+
* - Tiered sleep/wake consolidation (hot → warm → cold)
|
|
6
|
+
* - Cross-domain pattern surfacing
|
|
7
|
+
* - Contradiction detection (content-based, not just peer-flagged)
|
|
8
|
+
* - Provenance chain tracking
|
|
9
|
+
*
|
|
10
|
+
* Builds on KnowledgeStore (local persistence) and ConsolidationEngine (pure state machine).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { StoredEntry } from './knowledge-store';
|
|
14
|
+
import { KnowledgeStore } from './knowledge-store';
|
|
15
|
+
import type { KnowledgeDomain, ExcitabilityMetadata } from './brain';
|
|
16
|
+
import { DOMAIN_HALF_LIVES, computeExcitability, applyHalfLifeDecay } from './brain';
|
|
17
|
+
|
|
18
|
+
// ── Tier Definitions ──
|
|
19
|
+
|
|
20
|
+
export type KnowledgeTier = 'hot' | 'warm' | 'cold';
|
|
21
|
+
|
|
22
|
+
export interface TieredEntry extends StoredEntry {
|
|
23
|
+
tier: KnowledgeTier;
|
|
24
|
+
/** Last tier transition timestamp */
|
|
25
|
+
tierChangedAt: number;
|
|
26
|
+
/** Full provenance chain (newest first) */
|
|
27
|
+
provenanceChain: ProvenanceNode[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ── Provenance ──
|
|
31
|
+
|
|
32
|
+
export interface ProvenanceNode {
|
|
33
|
+
/** Entry ID at this point */
|
|
34
|
+
entryId: string;
|
|
35
|
+
/** Agent that created or modified */
|
|
36
|
+
agentId: string;
|
|
37
|
+
/** Timestamp of action */
|
|
38
|
+
timestamp: number;
|
|
39
|
+
/** What happened */
|
|
40
|
+
action: 'created' | 'promoted' | 'demoted' | 'merged' | 'corrected' | 'cited';
|
|
41
|
+
/** Optional parent entry (what was this derived from) */
|
|
42
|
+
parentEntryId?: string;
|
|
43
|
+
/** Optional hash for integrity verification */
|
|
44
|
+
hash?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ── Cross-Domain Patterns ──
|
|
48
|
+
|
|
49
|
+
export interface CrossDomainPattern {
|
|
50
|
+
/** Shared keywords or concepts across domains */
|
|
51
|
+
pattern: string;
|
|
52
|
+
/** Domains where the pattern appears */
|
|
53
|
+
domains: string[];
|
|
54
|
+
/** Entries contributing to this pattern */
|
|
55
|
+
entries: Array<{ id: string; domain: string; snippet: string }>;
|
|
56
|
+
/** Strength: how many entries corroborate */
|
|
57
|
+
strength: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ── Contradiction Detection ──
|
|
61
|
+
|
|
62
|
+
export interface Contradiction {
|
|
63
|
+
/** First entry */
|
|
64
|
+
entryA: { id: string; content: string; domain: string };
|
|
65
|
+
/** Conflicting entry */
|
|
66
|
+
entryB: { id: string; content: string; domain: string };
|
|
67
|
+
/** Why they conflict */
|
|
68
|
+
reason: string;
|
|
69
|
+
/** Confidence that this is a real contradiction (0-1) */
|
|
70
|
+
confidence: number;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ── Consolidation Stats ──
|
|
74
|
+
|
|
75
|
+
export interface ConsolidationStats {
|
|
76
|
+
demoted: number;
|
|
77
|
+
promoted: number;
|
|
78
|
+
evicted: number;
|
|
79
|
+
timestamp: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ── Consolidator ──
|
|
83
|
+
|
|
84
|
+
/** Thresholds for tier transitions */
|
|
85
|
+
export interface ConsolidatorConfig {
|
|
86
|
+
/** Entries with no queries in this many ms get demoted hot→warm (default: 6h) */
|
|
87
|
+
warmDemoteAfterMs: number;
|
|
88
|
+
/** Entries with no queries in this many ms get demoted warm→cold (default: 48h) */
|
|
89
|
+
coldDemoteAfterMs: number;
|
|
90
|
+
/** Max entries in hot tier before forced demotion (default: 100) */
|
|
91
|
+
hotCapacity: number;
|
|
92
|
+
/** Max entries in warm tier before forced demotion (default: 500) */
|
|
93
|
+
warmCapacity: number;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const DEFAULT_CONFIG: ConsolidatorConfig = {
|
|
97
|
+
warmDemoteAfterMs: 6 * 60 * 60 * 1000, // 6 hours
|
|
98
|
+
coldDemoteAfterMs: 48 * 60 * 60 * 1000, // 48 hours
|
|
99
|
+
hotCapacity: 100,
|
|
100
|
+
warmCapacity: 500,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Orchestrates tiered consolidation, cross-domain surfacing,
|
|
105
|
+
* contradiction detection, and provenance chain tracking.
|
|
106
|
+
*/
|
|
107
|
+
export class KnowledgeConsolidator {
|
|
108
|
+
private tiers: Map<string, TieredEntry> = new Map();
|
|
109
|
+
private config: ConsolidatorConfig;
|
|
110
|
+
|
|
111
|
+
constructor(config: Partial<ConsolidatorConfig> = {}) {
|
|
112
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ── Import from KnowledgeStore ──
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Import entries from a KnowledgeStore into the tiered system.
|
|
119
|
+
* All imported entries start in the hot tier.
|
|
120
|
+
*/
|
|
121
|
+
importFromStore(store: KnowledgeStore): number {
|
|
122
|
+
const entries = store.all();
|
|
123
|
+
let imported = 0;
|
|
124
|
+
for (const entry of entries) {
|
|
125
|
+
if (this.tiers.has(entry.id)) continue;
|
|
126
|
+
const tiered: TieredEntry = {
|
|
127
|
+
...entry,
|
|
128
|
+
tier: 'hot',
|
|
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
|
+
}],
|
|
138
|
+
};
|
|
139
|
+
this.tiers.set(entry.id, tiered);
|
|
140
|
+
imported++;
|
|
141
|
+
}
|
|
142
|
+
return imported;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Add a single entry directly.
|
|
147
|
+
*/
|
|
148
|
+
addEntry(entry: StoredEntry, parentEntryId?: string): TieredEntry {
|
|
149
|
+
const existing = this.tiers.get(entry.id);
|
|
150
|
+
if (existing) return existing;
|
|
151
|
+
|
|
152
|
+
const tiered: TieredEntry = {
|
|
153
|
+
...entry,
|
|
154
|
+
tier: 'hot',
|
|
155
|
+
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
|
+
}],
|
|
164
|
+
};
|
|
165
|
+
this.tiers.set(entry.id, tiered);
|
|
166
|
+
return tiered;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ── Sleep/Wake Consolidation ──
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Sleep cycle: demote stale entries down tiers.
|
|
173
|
+
* hot → warm if no access within warmDemoteAfterMs
|
|
174
|
+
* warm → cold if no access within coldDemoteAfterMs
|
|
175
|
+
*/
|
|
176
|
+
sleepCycle(): ConsolidationStats {
|
|
177
|
+
const now = Date.now();
|
|
178
|
+
let demoted = 0;
|
|
179
|
+
let evicted = 0;
|
|
180
|
+
|
|
181
|
+
for (const entry of this.tiers.values()) {
|
|
182
|
+
const lastActivity = Math.max(
|
|
183
|
+
entry.queryCount > 0 ? new Date(entry.createdAt).getTime() : 0,
|
|
184
|
+
entry.excitability?.lastRetrievedAt ?? 0,
|
|
185
|
+
entry.tierChangedAt
|
|
186
|
+
);
|
|
187
|
+
const idle = now - lastActivity;
|
|
188
|
+
|
|
189
|
+
if (entry.tier === 'hot' && idle > this.config.warmDemoteAfterMs) {
|
|
190
|
+
entry.tier = 'warm';
|
|
191
|
+
entry.tierChangedAt = now;
|
|
192
|
+
this.appendProvenance(entry.id, entry.authorAgent, 'demoted');
|
|
193
|
+
demoted++;
|
|
194
|
+
} else if (entry.tier === 'warm' && idle > this.config.coldDemoteAfterMs) {
|
|
195
|
+
entry.tier = 'cold';
|
|
196
|
+
entry.tierChangedAt = now;
|
|
197
|
+
this.appendProvenance(entry.id, entry.authorAgent, 'demoted');
|
|
198
|
+
demoted++;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Capacity enforcement: force-demote oldest hot entries if over capacity
|
|
203
|
+
const hotEntries = this.getByTier('hot');
|
|
204
|
+
if (hotEntries.length > this.config.hotCapacity) {
|
|
205
|
+
const sorted = hotEntries.sort((a, b) => a.tierChangedAt - b.tierChangedAt);
|
|
206
|
+
const excess = sorted.slice(0, hotEntries.length - this.config.hotCapacity);
|
|
207
|
+
for (const entry of excess) {
|
|
208
|
+
entry.tier = 'warm';
|
|
209
|
+
entry.tierChangedAt = now;
|
|
210
|
+
this.appendProvenance(entry.id, entry.authorAgent, 'demoted');
|
|
211
|
+
demoted++;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const warmEntries = this.getByTier('warm');
|
|
216
|
+
if (warmEntries.length > this.config.warmCapacity) {
|
|
217
|
+
const sorted = warmEntries.sort((a, b) => a.tierChangedAt - b.tierChangedAt);
|
|
218
|
+
const excess = sorted.slice(0, warmEntries.length - this.config.warmCapacity);
|
|
219
|
+
for (const entry of excess) {
|
|
220
|
+
entry.tier = 'cold';
|
|
221
|
+
entry.tierChangedAt = now;
|
|
222
|
+
this.appendProvenance(entry.id, entry.authorAgent, 'demoted');
|
|
223
|
+
demoted++;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return { demoted, promoted: 0, evicted, timestamp: now };
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Wake cycle: promote entries that were recently accessed back up tiers.
|
|
232
|
+
* cold → warm if accessed since last sleep
|
|
233
|
+
* warm → hot if access count > 3 since demotion
|
|
234
|
+
*/
|
|
235
|
+
wakeCycle(): ConsolidationStats {
|
|
236
|
+
const now = Date.now();
|
|
237
|
+
let promoted = 0;
|
|
238
|
+
|
|
239
|
+
for (const entry of this.tiers.values()) {
|
|
240
|
+
const lastAccess = entry.excitability?.lastRetrievedAt ?? 0;
|
|
241
|
+
if (lastAccess <= entry.tierChangedAt) continue; // No access since tier change
|
|
242
|
+
|
|
243
|
+
if (entry.tier === 'cold') {
|
|
244
|
+
entry.tier = 'warm';
|
|
245
|
+
entry.tierChangedAt = now;
|
|
246
|
+
this.appendProvenance(entry.id, entry.authorAgent, 'promoted');
|
|
247
|
+
promoted++;
|
|
248
|
+
} else if (entry.tier === 'warm') {
|
|
249
|
+
// Promote to hot only if enough recent activity
|
|
250
|
+
const recentQueries = entry.excitability?.queryCount ?? 0;
|
|
251
|
+
if (recentQueries >= 3) {
|
|
252
|
+
entry.tier = 'hot';
|
|
253
|
+
entry.tierChangedAt = now;
|
|
254
|
+
this.appendProvenance(entry.id, entry.authorAgent, 'promoted');
|
|
255
|
+
promoted++;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return { demoted: 0, promoted, evicted: 0, timestamp: now };
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Promote a specific entry to a higher tier.
|
|
265
|
+
*/
|
|
266
|
+
promote(entryId: string): boolean {
|
|
267
|
+
const entry = this.tiers.get(entryId);
|
|
268
|
+
if (!entry) return false;
|
|
269
|
+
|
|
270
|
+
if (entry.tier === 'cold') {
|
|
271
|
+
entry.tier = 'warm';
|
|
272
|
+
} else if (entry.tier === 'warm') {
|
|
273
|
+
entry.tier = 'hot';
|
|
274
|
+
} else {
|
|
275
|
+
return false; // Already hot
|
|
276
|
+
}
|
|
277
|
+
entry.tierChangedAt = Date.now();
|
|
278
|
+
this.appendProvenance(entryId, entry.authorAgent, 'promoted');
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Evict an entry from all tiers.
|
|
284
|
+
*/
|
|
285
|
+
evict(entryId: string): boolean {
|
|
286
|
+
return this.tiers.delete(entryId);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// ── Cross-Domain Pattern Surfacing ──
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Find entries that share concepts across multiple domains.
|
|
293
|
+
* Extracts significant keywords from each entry and groups
|
|
294
|
+
* entries that share keywords across different domains.
|
|
295
|
+
*/
|
|
296
|
+
surfaceCrossDomainPatterns(domains?: string[]): CrossDomainPattern[] {
|
|
297
|
+
const entries = domains
|
|
298
|
+
? Array.from(this.tiers.values()).filter(e => domains.includes(e.domain))
|
|
299
|
+
: Array.from(this.tiers.values());
|
|
300
|
+
|
|
301
|
+
// Extract keyword → domain+entry mapping
|
|
302
|
+
const keywordMap = new Map<string, Array<{ id: string; domain: string; snippet: string }>>();
|
|
303
|
+
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',
|
|
307
|
+
]);
|
|
308
|
+
|
|
309
|
+
for (const entry of entries) {
|
|
310
|
+
const words = entry.content
|
|
311
|
+
.toLowerCase()
|
|
312
|
+
.replace(/[^a-z0-9\s-]/g, '')
|
|
313
|
+
.split(/\s+/)
|
|
314
|
+
.filter(w => w.length > 3 && !STOP_WORDS.has(w));
|
|
315
|
+
|
|
316
|
+
// Use unique words per entry
|
|
317
|
+
const unique = [...new Set(words)];
|
|
318
|
+
for (const word of unique) {
|
|
319
|
+
if (!keywordMap.has(word)) keywordMap.set(word, []);
|
|
320
|
+
keywordMap.get(word)!.push({
|
|
321
|
+
id: entry.id,
|
|
322
|
+
domain: entry.domain,
|
|
323
|
+
snippet: entry.content.slice(0, 80),
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Find keywords that span multiple domains
|
|
329
|
+
const patterns: CrossDomainPattern[] = [];
|
|
330
|
+
for (const [keyword, refs] of keywordMap) {
|
|
331
|
+
const uniqueDomains = [...new Set(refs.map(r => r.domain))];
|
|
332
|
+
if (uniqueDomains.length >= 2) {
|
|
333
|
+
patterns.push({
|
|
334
|
+
pattern: keyword,
|
|
335
|
+
domains: uniqueDomains,
|
|
336
|
+
entries: refs,
|
|
337
|
+
strength: refs.length,
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// 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);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// ── Contradiction Detection ──
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Detect contradictions between entries.
|
|
351
|
+
*
|
|
352
|
+
* Strategy: find entry pairs in the same or related domains where:
|
|
353
|
+
* 1. They share significant keywords (about the same topic)
|
|
354
|
+
* 2. One contains negation patterns relative to the other
|
|
355
|
+
*
|
|
356
|
+
* This is a heuristic — not an LLM call. False positives are expected
|
|
357
|
+
* and should be reviewed by agents.
|
|
358
|
+
*/
|
|
359
|
+
detectContradictions(entries?: StoredEntry[]): Contradiction[] {
|
|
360
|
+
const pool = entries ?? Array.from(this.tiers.values());
|
|
361
|
+
if (pool.length < 2) return [];
|
|
362
|
+
|
|
363
|
+
const contradictions: Contradiction[] = [];
|
|
364
|
+
const NEGATION_PAIRS = [
|
|
365
|
+
['never', 'always'],
|
|
366
|
+
['should not', 'should'],
|
|
367
|
+
['must not', 'must'],
|
|
368
|
+
['do not', 'do'],
|
|
369
|
+
['avoid', 'prefer'],
|
|
370
|
+
['disable', 'enable'],
|
|
371
|
+
['deprecated', 'recommended'],
|
|
372
|
+
['broken', 'working'],
|
|
373
|
+
['false', 'true'],
|
|
374
|
+
['removed', 'added'],
|
|
375
|
+
];
|
|
376
|
+
|
|
377
|
+
// Index entries by significant keywords for O(n*k) instead of O(n^2)
|
|
378
|
+
const keywordIndex = new Map<string, StoredEntry[]>();
|
|
379
|
+
for (const entry of pool) {
|
|
380
|
+
const words = entry.content
|
|
381
|
+
.toLowerCase()
|
|
382
|
+
.replace(/[^a-z0-9\s]/g, '')
|
|
383
|
+
.split(/\s+/)
|
|
384
|
+
.filter(w => w.length > 4);
|
|
385
|
+
const unique = [...new Set(words)];
|
|
386
|
+
for (const w of unique) {
|
|
387
|
+
if (!keywordIndex.has(w)) keywordIndex.set(w, []);
|
|
388
|
+
keywordIndex.get(w)!.push(entry);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Check pairs that share keywords
|
|
393
|
+
const checked = new Set<string>();
|
|
394
|
+
for (const [, group] of keywordIndex) {
|
|
395
|
+
if (group.length < 2 || group.length > 20) continue; // Skip too-common keywords
|
|
396
|
+
for (let i = 0; i < group.length; i++) {
|
|
397
|
+
for (let j = i + 1; j < group.length; j++) {
|
|
398
|
+
const a = group[i];
|
|
399
|
+
const b = group[j];
|
|
400
|
+
const pairKey = [a.id, b.id].sort().join('|');
|
|
401
|
+
if (checked.has(pairKey)) continue;
|
|
402
|
+
checked.add(pairKey);
|
|
403
|
+
|
|
404
|
+
const contentA = a.content.toLowerCase();
|
|
405
|
+
const contentB = b.content.toLowerCase();
|
|
406
|
+
|
|
407
|
+
for (const [neg, pos] of NEGATION_PAIRS) {
|
|
408
|
+
const aHasNeg = contentA.includes(neg);
|
|
409
|
+
const bHasPos = contentB.includes(pos) && !contentB.includes(neg);
|
|
410
|
+
const aHasPos = contentA.includes(pos) && !contentA.includes(neg);
|
|
411
|
+
const bHasNeg = contentB.includes(neg);
|
|
412
|
+
|
|
413
|
+
if ((aHasNeg && bHasPos) || (aHasPos && bHasNeg)) {
|
|
414
|
+
// Calculate confidence based on domain similarity and keyword overlap
|
|
415
|
+
const sameDomain = a.domain === b.domain;
|
|
416
|
+
const confidence = sameDomain ? 0.7 : 0.4;
|
|
417
|
+
|
|
418
|
+
contradictions.push({
|
|
419
|
+
entryA: { id: a.id, content: a.content, domain: a.domain },
|
|
420
|
+
entryB: { id: b.id, content: b.content, domain: b.domain },
|
|
421
|
+
reason: `Opposing claims: "${neg}" vs "${pos}"`,
|
|
422
|
+
confidence,
|
|
423
|
+
});
|
|
424
|
+
break; // One contradiction per pair is enough
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
return contradictions.sort((a, b) => b.confidence - a.confidence);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// ── Provenance Chain ──
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Get the full provenance chain for an entry.
|
|
438
|
+
* Returns nodes from most recent to oldest.
|
|
439
|
+
*/
|
|
440
|
+
getProvenanceChain(entryId: string): ProvenanceNode[] {
|
|
441
|
+
const entry = this.tiers.get(entryId);
|
|
442
|
+
if (!entry) return [];
|
|
443
|
+
return [...entry.provenanceChain];
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Record a citation: entry B cites entry A.
|
|
448
|
+
*/
|
|
449
|
+
recordCitation(citedEntryId: string, citingAgentId: string): boolean {
|
|
450
|
+
const entry = this.tiers.get(citedEntryId);
|
|
451
|
+
if (!entry) return false;
|
|
452
|
+
|
|
453
|
+
this.appendProvenance(citedEntryId, citingAgentId, 'cited');
|
|
454
|
+
|
|
455
|
+
// Boost excitability on citation
|
|
456
|
+
if (entry.excitability) {
|
|
457
|
+
entry.excitability.citationCount++;
|
|
458
|
+
entry.excitability.excitability = computeExcitability(entry.excitability);
|
|
459
|
+
}
|
|
460
|
+
entry.reuseCount++;
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// ── Inspection ──
|
|
465
|
+
|
|
466
|
+
getByTier(tier: KnowledgeTier): TieredEntry[] {
|
|
467
|
+
return Array.from(this.tiers.values()).filter(e => e.tier === tier);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
getEntry(id: string): TieredEntry | undefined {
|
|
471
|
+
return this.tiers.get(id);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
get size(): number {
|
|
475
|
+
return this.tiers.size;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
stats(): { hot: number; warm: number; cold: number; total: number } {
|
|
479
|
+
let hot = 0, warm = 0, cold = 0;
|
|
480
|
+
for (const entry of this.tiers.values()) {
|
|
481
|
+
if (entry.tier === 'hot') hot++;
|
|
482
|
+
else if (entry.tier === 'warm') warm++;
|
|
483
|
+
else cold++;
|
|
484
|
+
}
|
|
485
|
+
return { hot, warm, cold, total: this.tiers.size };
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
all(): TieredEntry[] {
|
|
489
|
+
return Array.from(this.tiers.values());
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// ── Internal ──
|
|
493
|
+
|
|
494
|
+
private appendProvenance(
|
|
495
|
+
entryId: string,
|
|
496
|
+
agentId: string,
|
|
497
|
+
action: ProvenanceNode['action'],
|
|
498
|
+
parentEntryId?: string
|
|
499
|
+
): void {
|
|
500
|
+
const entry = this.tiers.get(entryId);
|
|
501
|
+
if (!entry) return;
|
|
502
|
+
entry.provenanceChain.unshift({
|
|
503
|
+
entryId,
|
|
504
|
+
agentId,
|
|
505
|
+
timestamp: Date.now(),
|
|
506
|
+
action,
|
|
507
|
+
parentEntryId,
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
}
|