@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,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for KnowledgeStore vector embedding pipeline (FW-0.5).
|
|
3
|
+
*
|
|
4
|
+
* Covers: embedAndStore(), semanticSearch(), hybrid search, error fallback.
|
|
5
|
+
* Uses vi.fn() to mock global fetch — no real network calls.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
9
|
+
import { KnowledgeStore } from '../knowledge-store';
|
|
10
|
+
import type { KnowledgeConfig, KnowledgeInsight } from '../../types';
|
|
11
|
+
|
|
12
|
+
// ── Helpers ──
|
|
13
|
+
|
|
14
|
+
function makeConfig(remote = true): KnowledgeConfig {
|
|
15
|
+
return {
|
|
16
|
+
persist: false,
|
|
17
|
+
...(remote ? {
|
|
18
|
+
remoteUrl: 'https://mcp-orchestrator-production-45f9.up.railway.app',
|
|
19
|
+
remoteApiKey: 'test-api-key',
|
|
20
|
+
} : {}),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function makeInsight(overrides?: Partial<KnowledgeInsight>): KnowledgeInsight {
|
|
25
|
+
return {
|
|
26
|
+
type: 'wisdom',
|
|
27
|
+
content: 'Always use strict TypeScript',
|
|
28
|
+
domain: 'compilation',
|
|
29
|
+
confidence: 0.9,
|
|
30
|
+
source: 'test-agent',
|
|
31
|
+
...overrides,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function mockFetchOk(data: unknown) {
|
|
36
|
+
return vi.fn().mockResolvedValue({
|
|
37
|
+
ok: true,
|
|
38
|
+
json: () => Promise.resolve(data),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function mockFetchFail() {
|
|
43
|
+
return vi.fn().mockResolvedValue({ ok: false, status: 500 });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function mockFetchThrow() {
|
|
47
|
+
return vi.fn().mockRejectedValue(new Error('Network error'));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ── Tests ──
|
|
51
|
+
|
|
52
|
+
describe('KnowledgeStore — Vector Embedding Pipeline', () => {
|
|
53
|
+
let originalFetch: typeof globalThis.fetch;
|
|
54
|
+
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
originalFetch = globalThis.fetch;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
afterEach(() => {
|
|
60
|
+
globalThis.fetch = originalFetch;
|
|
61
|
+
vi.restoreAllMocks();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// ── embedAndStore ──
|
|
65
|
+
|
|
66
|
+
describe('embedAndStore', () => {
|
|
67
|
+
it('publishes locally and syncs to remote', async () => {
|
|
68
|
+
const fetchMock = mockFetchOk({ synced: 1, ids: ['remote-001'] });
|
|
69
|
+
globalThis.fetch = fetchMock;
|
|
70
|
+
|
|
71
|
+
const store = new KnowledgeStore(makeConfig());
|
|
72
|
+
const result = await store.embedAndStore(makeInsight(), 'agent-a');
|
|
73
|
+
|
|
74
|
+
expect(result.entryId).toMatch(/^W\./);
|
|
75
|
+
expect(result.synced).toBe(true);
|
|
76
|
+
expect(result.remoteId).toBe('remote-001');
|
|
77
|
+
expect(store.size).toBe(1);
|
|
78
|
+
|
|
79
|
+
// Verify fetch was called with correct endpoint and payload
|
|
80
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
81
|
+
const [url, opts] = fetchMock.mock.calls[0];
|
|
82
|
+
expect(url).toContain('/knowledge/sync');
|
|
83
|
+
expect(opts.headers['x-mcp-api-key']).toBe('test-api-key');
|
|
84
|
+
|
|
85
|
+
const body = JSON.parse(opts.body);
|
|
86
|
+
expect(body.workspace_id).toBe('ai-ecosystem');
|
|
87
|
+
expect(body.entries).toHaveLength(1);
|
|
88
|
+
expect(body.entries[0].content).toBe('Always use strict TypeScript');
|
|
89
|
+
expect(body.entries[0].metadata.domain).toBe('compilation');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('publishes locally even when remote fails', async () => {
|
|
93
|
+
globalThis.fetch = mockFetchFail();
|
|
94
|
+
|
|
95
|
+
const store = new KnowledgeStore(makeConfig());
|
|
96
|
+
const result = await store.embedAndStore(makeInsight(), 'agent-a');
|
|
97
|
+
|
|
98
|
+
expect(result.entryId).toMatch(/^W\./);
|
|
99
|
+
expect(result.synced).toBe(false);
|
|
100
|
+
expect(result.remoteId).toBeUndefined();
|
|
101
|
+
expect(store.size).toBe(1);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('publishes locally even when fetch throws', async () => {
|
|
105
|
+
globalThis.fetch = mockFetchThrow();
|
|
106
|
+
|
|
107
|
+
const store = new KnowledgeStore(makeConfig());
|
|
108
|
+
const result = await store.embedAndStore(makeInsight(), 'agent-a');
|
|
109
|
+
|
|
110
|
+
expect(result.entryId).toMatch(/^W\./);
|
|
111
|
+
expect(result.synced).toBe(false);
|
|
112
|
+
expect(store.size).toBe(1);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('skips remote when no remoteUrl configured', async () => {
|
|
116
|
+
const fetchMock = vi.fn();
|
|
117
|
+
globalThis.fetch = fetchMock;
|
|
118
|
+
|
|
119
|
+
const store = new KnowledgeStore(makeConfig(false));
|
|
120
|
+
const result = await store.embedAndStore(makeInsight(), 'agent-a');
|
|
121
|
+
|
|
122
|
+
expect(result.entryId).toMatch(/^W\./);
|
|
123
|
+
expect(result.synced).toBe(false);
|
|
124
|
+
expect(fetchMock).not.toHaveBeenCalled();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('deduplicates on repeated embed of same content', async () => {
|
|
128
|
+
globalThis.fetch = mockFetchOk({ synced: 1 });
|
|
129
|
+
|
|
130
|
+
const store = new KnowledgeStore(makeConfig());
|
|
131
|
+
const r1 = await store.embedAndStore(makeInsight(), 'agent-a');
|
|
132
|
+
const r2 = await store.embedAndStore(makeInsight(), 'agent-b');
|
|
133
|
+
|
|
134
|
+
// Same content = same entry (dedup)
|
|
135
|
+
expect(r1.entryId).toBe(r2.entryId);
|
|
136
|
+
expect(store.size).toBe(1);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('includes provenance metadata in remote sync', async () => {
|
|
140
|
+
const fetchMock = mockFetchOk({ synced: 1 });
|
|
141
|
+
globalThis.fetch = fetchMock;
|
|
142
|
+
|
|
143
|
+
const store = new KnowledgeStore(makeConfig());
|
|
144
|
+
await store.embedAndStore(makeInsight(), 'agent-a', {
|
|
145
|
+
taskId: 'task-42',
|
|
146
|
+
cycleId: 'cycle-7',
|
|
147
|
+
provenanceHash: 'abc123',
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
151
|
+
expect(body.entries[0].metadata.taskId).toBe('task-42');
|
|
152
|
+
expect(body.entries[0].metadata.cycleId).toBe('cycle-7');
|
|
153
|
+
expect(body.entries[0].provenanceHash).toBe('abc123');
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// ── semanticSearch ──
|
|
158
|
+
|
|
159
|
+
describe('semanticSearch', () => {
|
|
160
|
+
it('returns remote results when available', async () => {
|
|
161
|
+
const remoteEntries = [
|
|
162
|
+
{ id: 'r1', type: 'wisdom', content: 'Use strict mode', metadata: { domain: 'compilation', confidence: 0.8 } },
|
|
163
|
+
{ id: 'r2', type: 'pattern', content: 'Pattern matching', metadata: { domain: 'compilation', confidence: 0.7 } },
|
|
164
|
+
];
|
|
165
|
+
globalThis.fetch = mockFetchOk(remoteEntries);
|
|
166
|
+
|
|
167
|
+
const store = new KnowledgeStore(makeConfig());
|
|
168
|
+
const results = await store.semanticSearch('strict typescript');
|
|
169
|
+
|
|
170
|
+
expect(results).toHaveLength(2);
|
|
171
|
+
expect(results[0].id).toBe('r1');
|
|
172
|
+
expect(results[0].content).toBe('Use strict mode');
|
|
173
|
+
expect(results[1].id).toBe('r2');
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('falls back to local keyword search when remote fails', async () => {
|
|
177
|
+
globalThis.fetch = mockFetchFail();
|
|
178
|
+
|
|
179
|
+
const store = new KnowledgeStore(makeConfig());
|
|
180
|
+
store.publish(makeInsight({ content: 'TypeScript strict mode is essential' }), 'agent-a');
|
|
181
|
+
store.publish(makeInsight({ content: 'Python type hints are optional' }), 'agent-b');
|
|
182
|
+
|
|
183
|
+
const results = await store.semanticSearch('strict typescript');
|
|
184
|
+
|
|
185
|
+
// Should find the local entry with matching keywords
|
|
186
|
+
expect(results.length).toBeGreaterThanOrEqual(1);
|
|
187
|
+
expect(results[0].content).toContain('strict');
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('falls back to local when fetch throws', async () => {
|
|
191
|
+
globalThis.fetch = mockFetchThrow();
|
|
192
|
+
|
|
193
|
+
const store = new KnowledgeStore(makeConfig());
|
|
194
|
+
store.publish(makeInsight({ content: 'TypeScript strict mode rocks' }), 'agent-a');
|
|
195
|
+
|
|
196
|
+
const results = await store.semanticSearch('strict typescript');
|
|
197
|
+
expect(results.length).toBeGreaterThanOrEqual(1);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('falls back to local when no remote configured', async () => {
|
|
201
|
+
const store = new KnowledgeStore(makeConfig(false));
|
|
202
|
+
store.publish(makeInsight({ content: 'TypeScript strict mode rocks' }), 'agent-a');
|
|
203
|
+
|
|
204
|
+
const results = await store.semanticSearch('strict typescript');
|
|
205
|
+
expect(results.length).toBeGreaterThanOrEqual(1);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('filters by type when specified', async () => {
|
|
209
|
+
const fetchMock = mockFetchOk([]);
|
|
210
|
+
globalThis.fetch = fetchMock;
|
|
211
|
+
|
|
212
|
+
const store = new KnowledgeStore(makeConfig());
|
|
213
|
+
await store.semanticSearch('rendering', { type: 'gotcha' });
|
|
214
|
+
|
|
215
|
+
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
216
|
+
expect(body.type).toBe('gotcha');
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('filters by minConfidence', async () => {
|
|
220
|
+
const remoteEntries = [
|
|
221
|
+
{ id: 'r1', type: 'wisdom', content: 'High confidence', metadata: { confidence: 0.9, domain: 'general' } },
|
|
222
|
+
{ id: 'r2', type: 'wisdom', content: 'Low confidence', metadata: { confidence: 0.3, domain: 'general' } },
|
|
223
|
+
];
|
|
224
|
+
globalThis.fetch = mockFetchOk(remoteEntries);
|
|
225
|
+
|
|
226
|
+
const store = new KnowledgeStore(makeConfig());
|
|
227
|
+
const results = await store.semanticSearch('confidence', { minConfidence: 0.5 });
|
|
228
|
+
|
|
229
|
+
expect(results).toHaveLength(1);
|
|
230
|
+
expect(results[0].id).toBe('r1');
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it('respects limit parameter', async () => {
|
|
234
|
+
const remoteEntries = Array.from({ length: 20 }, (_, i) => ({
|
|
235
|
+
id: `r${i}`,
|
|
236
|
+
type: 'wisdom',
|
|
237
|
+
content: `Entry ${i}`,
|
|
238
|
+
metadata: { domain: 'general', confidence: 0.5 },
|
|
239
|
+
}));
|
|
240
|
+
globalThis.fetch = mockFetchOk(remoteEntries);
|
|
241
|
+
|
|
242
|
+
const store = new KnowledgeStore(makeConfig());
|
|
243
|
+
const results = await store.semanticSearch('entry', { limit: 5 });
|
|
244
|
+
|
|
245
|
+
expect(results).toHaveLength(5);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it('hybrid search merges remote + local, deduped by ID', async () => {
|
|
249
|
+
const remoteEntries = [
|
|
250
|
+
{ id: 'r1', type: 'wisdom', content: 'Remote only', metadata: { domain: 'general', confidence: 0.9 } },
|
|
251
|
+
{ id: 'shared', type: 'wisdom', content: 'Remote version', metadata: { domain: 'general', confidence: 0.8 } },
|
|
252
|
+
];
|
|
253
|
+
globalThis.fetch = mockFetchOk(remoteEntries);
|
|
254
|
+
|
|
255
|
+
const store = new KnowledgeStore(makeConfig());
|
|
256
|
+
// Publish a local entry that has the same ID as a remote entry
|
|
257
|
+
const local = store.publish(makeInsight({ content: 'Local entry about general topics' }), 'agent-a');
|
|
258
|
+
|
|
259
|
+
const results = await store.semanticSearch('general topics', { hybridSearch: true, limit: 10 });
|
|
260
|
+
|
|
261
|
+
// Should contain remote entries + local entries, no duplicate IDs
|
|
262
|
+
const ids = results.map(r => r.id);
|
|
263
|
+
const uniqueIds = new Set(ids);
|
|
264
|
+
expect(ids.length).toBe(uniqueIds.size);
|
|
265
|
+
|
|
266
|
+
// Remote entries should be present
|
|
267
|
+
expect(ids).toContain('r1');
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it('hybrid search: remote wins on ID conflict', async () => {
|
|
271
|
+
// Create a store with a local entry
|
|
272
|
+
const store = new KnowledgeStore(makeConfig());
|
|
273
|
+
store.publish(makeInsight({ content: 'Local version of knowledge' }), 'agent-a');
|
|
274
|
+
const localId = store.all()[0].id;
|
|
275
|
+
|
|
276
|
+
// Remote returns an entry with the same ID but different content
|
|
277
|
+
const remoteEntries = [
|
|
278
|
+
{ id: localId, type: 'wisdom', content: 'Remote version of knowledge', metadata: { domain: 'compilation', confidence: 0.95 } },
|
|
279
|
+
];
|
|
280
|
+
globalThis.fetch = mockFetchOk(remoteEntries);
|
|
281
|
+
|
|
282
|
+
const results = await store.semanticSearch('knowledge', { hybridSearch: true });
|
|
283
|
+
|
|
284
|
+
// The entry with localId should appear exactly once
|
|
285
|
+
const matching = results.filter(r => r.id === localId);
|
|
286
|
+
expect(matching).toHaveLength(1);
|
|
287
|
+
// Remote wins (appears first in merge)
|
|
288
|
+
expect(matching[0].content).toBe('Remote version of knowledge');
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
});
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Brain — Domain-specific consolidation, excitability, half-lives.
|
|
3
|
+
*
|
|
4
|
+
* Absorbed from mcp-server/src/holomesh/types.ts (V9/V11 neuroscience model).
|
|
5
|
+
* The knowledge store uses these for search ranking, decay, and consolidation.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ── Domains ──
|
|
9
|
+
|
|
10
|
+
export const KNOWLEDGE_DOMAINS = [
|
|
11
|
+
'security',
|
|
12
|
+
'rendering',
|
|
13
|
+
'agents',
|
|
14
|
+
'compilation',
|
|
15
|
+
'general',
|
|
16
|
+
] as const;
|
|
17
|
+
|
|
18
|
+
export type KnowledgeDomain = (typeof KNOWLEDGE_DOMAINS)[number];
|
|
19
|
+
|
|
20
|
+
// ── Consolidation Config ──
|
|
21
|
+
|
|
22
|
+
export interface DomainConsolidationConfig {
|
|
23
|
+
hotBufferTTL: number;
|
|
24
|
+
sleepFrequencyMs: number;
|
|
25
|
+
maxEntries: number;
|
|
26
|
+
competitionMetric: 'citation_count' | 'query_frequency' | 'peer_corroboration';
|
|
27
|
+
downscaleFactor: number;
|
|
28
|
+
minCorroborations: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const DOMAIN_CONSOLIDATION: Record<KnowledgeDomain, DomainConsolidationConfig> = {
|
|
32
|
+
security: {
|
|
33
|
+
hotBufferTTL: 1 * 60 * 60 * 1000,
|
|
34
|
+
sleepFrequencyMs: 6 * 60 * 60 * 1000,
|
|
35
|
+
maxEntries: 50,
|
|
36
|
+
competitionMetric: 'peer_corroboration',
|
|
37
|
+
downscaleFactor: 0.85,
|
|
38
|
+
minCorroborations: 2,
|
|
39
|
+
},
|
|
40
|
+
rendering: {
|
|
41
|
+
hotBufferTTL: 24 * 60 * 60 * 1000,
|
|
42
|
+
sleepFrequencyMs: 24 * 60 * 60 * 1000,
|
|
43
|
+
maxEntries: 200,
|
|
44
|
+
competitionMetric: 'query_frequency',
|
|
45
|
+
downscaleFactor: 0.95,
|
|
46
|
+
minCorroborations: 1,
|
|
47
|
+
},
|
|
48
|
+
agents: {
|
|
49
|
+
hotBufferTTL: 12 * 60 * 60 * 1000,
|
|
50
|
+
sleepFrequencyMs: 12 * 60 * 60 * 1000,
|
|
51
|
+
maxEntries: 150,
|
|
52
|
+
competitionMetric: 'query_frequency',
|
|
53
|
+
downscaleFactor: 0.90,
|
|
54
|
+
minCorroborations: 1,
|
|
55
|
+
},
|
|
56
|
+
compilation: {
|
|
57
|
+
hotBufferTTL: 12 * 60 * 60 * 1000,
|
|
58
|
+
sleepFrequencyMs: 12 * 60 * 60 * 1000,
|
|
59
|
+
maxEntries: 100,
|
|
60
|
+
competitionMetric: 'citation_count',
|
|
61
|
+
downscaleFactor: 0.90,
|
|
62
|
+
minCorroborations: 1,
|
|
63
|
+
},
|
|
64
|
+
general: {
|
|
65
|
+
hotBufferTTL: 6 * 60 * 60 * 1000,
|
|
66
|
+
sleepFrequencyMs: 12 * 60 * 60 * 1000,
|
|
67
|
+
maxEntries: 300,
|
|
68
|
+
competitionMetric: 'query_frequency',
|
|
69
|
+
downscaleFactor: 0.92,
|
|
70
|
+
minCorroborations: 1,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// ── Half-Lives ──
|
|
75
|
+
|
|
76
|
+
export const DOMAIN_HALF_LIVES: Record<KnowledgeDomain, number> = {
|
|
77
|
+
security: 2 * 24 * 60 * 60 * 1000, // 2 days
|
|
78
|
+
rendering: 14 * 24 * 60 * 60 * 1000, // 14 days
|
|
79
|
+
agents: 7 * 24 * 60 * 60 * 1000, // 7 days
|
|
80
|
+
compilation: 21 * 24 * 60 * 60 * 1000, // 21 days
|
|
81
|
+
general: 7 * 24 * 60 * 60 * 1000, // 7 days
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// ── Hot Buffer ──
|
|
85
|
+
|
|
86
|
+
export interface HotBufferEntry {
|
|
87
|
+
id: string;
|
|
88
|
+
domain: KnowledgeDomain;
|
|
89
|
+
content: string;
|
|
90
|
+
type: string;
|
|
91
|
+
authorDid: string;
|
|
92
|
+
tags: string[];
|
|
93
|
+
ingestedAt: number;
|
|
94
|
+
corroborations: string[];
|
|
95
|
+
sourcePeerDid: string;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ── Excitability ──
|
|
99
|
+
|
|
100
|
+
export interface ExcitabilityMetadata {
|
|
101
|
+
queryCount: number;
|
|
102
|
+
citationCount: number;
|
|
103
|
+
corroborationCount: number;
|
|
104
|
+
excitability: number;
|
|
105
|
+
lastRetrievedAt: number;
|
|
106
|
+
lastReconsolidatedAt: number;
|
|
107
|
+
consolidationSurvivals: number;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Compute excitability score from metadata. */
|
|
111
|
+
export function computeExcitability(meta: Omit<ExcitabilityMetadata, 'excitability'>): number {
|
|
112
|
+
return (
|
|
113
|
+
2 * meta.queryCount +
|
|
114
|
+
3 * meta.citationCount +
|
|
115
|
+
1.5 * meta.corroborationCount +
|
|
116
|
+
0.5 * meta.consolidationSurvivals
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Apply domain half-life decay to a score. */
|
|
121
|
+
export function applyHalfLifeDecay(score: number, ageMs: number, domain: KnowledgeDomain): number {
|
|
122
|
+
const halfLife = DOMAIN_HALF_LIVES[domain] || DOMAIN_HALF_LIVES.general;
|
|
123
|
+
return score * Math.pow(0.5, ageMs / halfLife);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ── Consolidation Result ──
|
|
127
|
+
|
|
128
|
+
export interface ConsolidationResult {
|
|
129
|
+
domain: KnowledgeDomain;
|
|
130
|
+
promoted: number;
|
|
131
|
+
merged: number;
|
|
132
|
+
evicted: number;
|
|
133
|
+
dropped: number;
|
|
134
|
+
downscaleFactor: number;
|
|
135
|
+
consolidatedAt: number;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ── Reconsolidation ──
|
|
139
|
+
|
|
140
|
+
export interface ReconsolidationEvent {
|
|
141
|
+
entryId: string;
|
|
142
|
+
domain: KnowledgeDomain;
|
|
143
|
+
retrievedAt: number;
|
|
144
|
+
excitabilityDelta: number;
|
|
145
|
+
windowOpen: boolean;
|
|
146
|
+
windowClosesAt: number;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Default reconsolidation window duration (5 minutes). */
|
|
150
|
+
export const RECONSOLIDATION_WINDOW_MS = 5 * 60 * 1000;
|
|
151
|
+
|
|
152
|
+
/** Create a reconsolidation event when an entry is retrieved. */
|
|
153
|
+
export function triggerReconsolidation(
|
|
154
|
+
entryId: string,
|
|
155
|
+
domain: KnowledgeDomain,
|
|
156
|
+
excitabilityDelta: number
|
|
157
|
+
): ReconsolidationEvent {
|
|
158
|
+
const now = Date.now();
|
|
159
|
+
return {
|
|
160
|
+
entryId,
|
|
161
|
+
domain,
|
|
162
|
+
retrievedAt: now,
|
|
163
|
+
excitabilityDelta,
|
|
164
|
+
windowOpen: true,
|
|
165
|
+
windowClosesAt: now + RECONSOLIDATION_WINDOW_MS,
|
|
166
|
+
};
|
|
167
|
+
}
|