@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.
Files changed (329) hide show
  1. package/ALL-test-results.json +1 -0
  2. package/CHANGELOG.md +8 -0
  3. package/LICENSE +21 -0
  4. package/ROADMAP.md +175 -0
  5. package/dist/AgentManifest-CB4xM-Ma.d.cts +704 -0
  6. package/dist/AgentManifest-CB4xM-Ma.d.ts +704 -0
  7. package/dist/BehaviorTree-BrBFECv5.d.cts +103 -0
  8. package/dist/BehaviorTree-BrBFECv5.d.ts +103 -0
  9. package/dist/InvisibleWallet-BB6tFvRA.d.cts +1732 -0
  10. package/dist/InvisibleWallet-rtRrBOA8.d.ts +1732 -0
  11. package/dist/OrchestratorAgent-BvWgf9uw.d.cts +798 -0
  12. package/dist/OrchestratorAgent-Q_CbVTmO.d.ts +798 -0
  13. package/dist/agents/index.cjs +4790 -0
  14. package/dist/agents/index.d.cts +1788 -0
  15. package/dist/agents/index.d.ts +1788 -0
  16. package/dist/agents/index.js +4695 -0
  17. package/dist/ai/index.cjs +5347 -0
  18. package/dist/ai/index.d.cts +1753 -0
  19. package/dist/ai/index.d.ts +1753 -0
  20. package/dist/ai/index.js +5244 -0
  21. package/dist/behavior.cjs +449 -0
  22. package/dist/behavior.d.cts +130 -0
  23. package/dist/behavior.d.ts +130 -0
  24. package/dist/behavior.js +407 -0
  25. package/dist/economy/index.cjs +3659 -0
  26. package/dist/economy/index.d.cts +747 -0
  27. package/dist/economy/index.d.ts +747 -0
  28. package/dist/economy/index.js +3617 -0
  29. package/dist/implementations-D9T3un9D.d.cts +236 -0
  30. package/dist/implementations-D9T3un9D.d.ts +236 -0
  31. package/dist/index.cjs +24550 -0
  32. package/dist/index.d.cts +1729 -0
  33. package/dist/index.d.ts +1729 -0
  34. package/dist/index.js +24277 -0
  35. package/dist/learning/index.cjs +219 -0
  36. package/dist/learning/index.d.cts +104 -0
  37. package/dist/learning/index.d.ts +104 -0
  38. package/dist/learning/index.js +189 -0
  39. package/dist/negotiation/index.cjs +970 -0
  40. package/dist/negotiation/index.d.cts +610 -0
  41. package/dist/negotiation/index.d.ts +610 -0
  42. package/dist/negotiation/index.js +931 -0
  43. package/dist/skills/index.cjs +1118 -0
  44. package/dist/skills/index.d.cts +289 -0
  45. package/dist/skills/index.d.ts +289 -0
  46. package/dist/skills/index.js +1079 -0
  47. package/dist/swarm/index.cjs +5268 -0
  48. package/dist/swarm/index.d.cts +2433 -0
  49. package/dist/swarm/index.d.ts +2433 -0
  50. package/dist/swarm/index.js +5221 -0
  51. package/dist/training/index.cjs +2745 -0
  52. package/dist/training/index.d.cts +1734 -0
  53. package/dist/training/index.d.ts +1734 -0
  54. package/dist/training/index.js +2687 -0
  55. package/extract-failures.js +10 -0
  56. package/package.json +82 -0
  57. package/src/__tests__/bounty-marketplace.test.ts +374 -0
  58. package/src/__tests__/delegation.test.ts +144 -0
  59. package/src/__tests__/distributed-claimer.test.ts +147 -0
  60. package/src/__tests__/done-log-audit.test.ts +342 -0
  61. package/src/__tests__/framework.test.ts +865 -0
  62. package/src/__tests__/goal-synthesizer.test.ts +236 -0
  63. package/src/__tests__/presence.test.ts +223 -0
  64. package/src/__tests__/protocol-agent.test.ts +254 -0
  65. package/src/__tests__/revenue-splitter.test.ts +114 -0
  66. package/src/__tests__/scenario-driven-todo.test.ts +197 -0
  67. package/src/__tests__/self-improve.test.ts +349 -0
  68. package/src/__tests__/service-lifecycle.test.ts +237 -0
  69. package/src/__tests__/skill-router.test.ts +121 -0
  70. package/src/agents/AgentManifest.ts +493 -0
  71. package/src/agents/AgentRegistry.ts +475 -0
  72. package/src/agents/AgentTypes.ts +585 -0
  73. package/src/agents/AgentWalletRegistry.ts +83 -0
  74. package/src/agents/AuthenticatedCRDT.ts +388 -0
  75. package/src/agents/CapabilityMatcher.ts +453 -0
  76. package/src/agents/CrossRealityHandoff.ts +305 -0
  77. package/src/agents/CulturalMemory.ts +454 -0
  78. package/src/agents/FederatedRegistryAdapter.ts +429 -0
  79. package/src/agents/NormEngine.ts +450 -0
  80. package/src/agents/OrchestratorAgent.ts +414 -0
  81. package/src/agents/SkillWorkflowEngine.ts +472 -0
  82. package/src/agents/TaskDelegationService.ts +551 -0
  83. package/src/agents/__tests__/AgentManifest.prod.test.ts +134 -0
  84. package/src/agents/__tests__/AgentManifest.test.ts +182 -0
  85. package/src/agents/__tests__/AgentModule.test.ts +864 -0
  86. package/src/agents/__tests__/AgentRegistry.prod.test.ts +125 -0
  87. package/src/agents/__tests__/AgentRegistry.test.ts +148 -0
  88. package/src/agents/__tests__/AgentTypes.test.ts +534 -0
  89. package/src/agents/__tests__/AgentWalletRegistry.test.ts +152 -0
  90. package/src/agents/__tests__/AuthenticatedCRDT.test.ts +558 -0
  91. package/src/agents/__tests__/CapabilityMatcher.prod.test.ts +117 -0
  92. package/src/agents/__tests__/CapabilityMatcher.test.ts +178 -0
  93. package/src/agents/__tests__/CrossRealityHandoff.test.ts +402 -0
  94. package/src/agents/__tests__/CulturalMemory.test.ts +200 -0
  95. package/src/agents/__tests__/FederatedRegistryAdapter.test.ts +409 -0
  96. package/src/agents/__tests__/NormEngine.test.ts +276 -0
  97. package/src/agents/__tests__/OrchestratorAgent.test.ts +182 -0
  98. package/src/agents/__tests__/SkillWorkflowEngine.test.ts +357 -0
  99. package/src/agents/__tests__/TaskDelegationService.test.ts +446 -0
  100. package/src/agents/index.ts +107 -0
  101. package/src/agents/spatial-comms/Layer1RealTime.ts +621 -0
  102. package/src/agents/spatial-comms/Layer2A2A.ts +661 -0
  103. package/src/agents/spatial-comms/Layer3MCP.ts +651 -0
  104. package/src/agents/spatial-comms/ProtocolTypes.ts +543 -0
  105. package/src/agents/spatial-comms/SpatialCommClient.ts +483 -0
  106. package/src/agents/spatial-comms/__tests__/performance-benchmark.test.ts +465 -0
  107. package/src/agents/spatial-comms/examples/multi-agent-world-creation.ts +409 -0
  108. package/src/agents/spatial-comms/index.ts +66 -0
  109. package/src/ai/AIAdapter.ts +313 -0
  110. package/src/ai/AICopilot.ts +331 -0
  111. package/src/ai/AIOutputValidator.ts +203 -0
  112. package/src/ai/BTNodes.ts +239 -0
  113. package/src/ai/BehaviorSelector.ts +135 -0
  114. package/src/ai/BehaviorTree.ts +153 -0
  115. package/src/ai/Blackboard.ts +165 -0
  116. package/src/ai/GenerationAnalytics.ts +461 -0
  117. package/src/ai/GenerationCache.ts +265 -0
  118. package/src/ai/GoalPlanner.ts +165 -0
  119. package/src/ai/HoloScriptGenerator.ts +580 -0
  120. package/src/ai/InfluenceMap.ts +180 -0
  121. package/src/ai/NavMesh.ts +168 -0
  122. package/src/ai/PerceptionSystem.ts +178 -0
  123. package/src/ai/PromptTemplates.ts +453 -0
  124. package/src/ai/SemanticSearchService.ts +80 -0
  125. package/src/ai/StateMachine.ts +196 -0
  126. package/src/ai/SteeringBehavior.ts +150 -0
  127. package/src/ai/SteeringBehaviors.ts +244 -0
  128. package/src/ai/TrainingDataGenerator.ts +1082 -0
  129. package/src/ai/UtilityAI.ts +145 -0
  130. package/src/ai/__tests__/AIAdapter.prod.test.ts +259 -0
  131. package/src/ai/__tests__/AIAdapter.test.ts +109 -0
  132. package/src/ai/__tests__/AICopilot.prod.test.ts +341 -0
  133. package/src/ai/__tests__/AICopilot.test.ts +178 -0
  134. package/src/ai/__tests__/AIOutputValidator.prod.test.ts +226 -0
  135. package/src/ai/__tests__/AIOutputValidator.test.ts +138 -0
  136. package/src/ai/__tests__/BTNodes.prod.test.ts +391 -0
  137. package/src/ai/__tests__/BTNodes.test.ts +263 -0
  138. package/src/ai/__tests__/BehaviorSelector.prod.test.ts +129 -0
  139. package/src/ai/__tests__/BehaviorSelector.test.ts +132 -0
  140. package/src/ai/__tests__/BehaviorTree.prod.test.ts +266 -0
  141. package/src/ai/__tests__/BehaviorTree.test.ts +216 -0
  142. package/src/ai/__tests__/Blackboard.prod.test.ts +339 -0
  143. package/src/ai/__tests__/Blackboard.test.ts +183 -0
  144. package/src/ai/__tests__/GenerationAnalytics.prod.test.ts +141 -0
  145. package/src/ai/__tests__/GenerationAnalytics.test.ts +165 -0
  146. package/src/ai/__tests__/GenerationCache.prod.test.ts +144 -0
  147. package/src/ai/__tests__/GenerationCache.test.ts +171 -0
  148. package/src/ai/__tests__/GoalPlanner.prod.test.ts +189 -0
  149. package/src/ai/__tests__/GoalPlanner.test.ts +137 -0
  150. package/src/ai/__tests__/GoalPlannerDepth.prod.test.ts +217 -0
  151. package/src/ai/__tests__/HoloScriptGenerator.test.ts +125 -0
  152. package/src/ai/__tests__/InfluenceMap.prod.test.ts +146 -0
  153. package/src/ai/__tests__/InfluenceMap.test.ts +149 -0
  154. package/src/ai/__tests__/NavMesh.prod.test.ts +141 -0
  155. package/src/ai/__tests__/NavMesh.test.ts +159 -0
  156. package/src/ai/__tests__/PerceptionSystem.prod.test.ts +135 -0
  157. package/src/ai/__tests__/PerceptionSystem.test.ts +250 -0
  158. package/src/ai/__tests__/PromptTemplates.prod.test.ts +313 -0
  159. package/src/ai/__tests__/PromptTemplates.test.ts +146 -0
  160. package/src/ai/__tests__/SemanticSearch.test.ts +37 -0
  161. package/src/ai/__tests__/StateMachine.prod.test.ts +162 -0
  162. package/src/ai/__tests__/StateMachine.test.ts +163 -0
  163. package/src/ai/__tests__/SteeringBehavior.prod.test.ts +251 -0
  164. package/src/ai/__tests__/SteeringBehavior.test.ts +135 -0
  165. package/src/ai/__tests__/SteeringBehaviors.prod.test.ts +133 -0
  166. package/src/ai/__tests__/SteeringBehaviors.test.ts +151 -0
  167. package/src/ai/__tests__/TrainingDataGenerator.prod.test.ts +286 -0
  168. package/src/ai/__tests__/TrainingDataGenerator.test.ts +286 -0
  169. package/src/ai/__tests__/UtilityAI.prod.test.ts +207 -0
  170. package/src/ai/__tests__/UtilityAI.test.ts +155 -0
  171. package/src/ai/__tests__/adapters.prod.test.ts +263 -0
  172. package/src/ai/__tests__/adapters.test.ts +320 -0
  173. package/src/ai/adapters.ts +1585 -0
  174. package/src/ai/index.ts +130 -0
  175. package/src/behavior/BehaviorPresets.ts +140 -0
  176. package/src/behavior/BehaviorTree.ts +236 -0
  177. package/src/behavior/StateMachine.ts +176 -0
  178. package/src/behavior/StateTrait.ts +67 -0
  179. package/src/behavior/index.ts +8 -0
  180. package/src/behavior.ts +8 -0
  181. package/src/board/audit.ts +284 -0
  182. package/src/board/board-ops.ts +336 -0
  183. package/src/board/board-types.ts +302 -0
  184. package/src/board/index.ts +69 -0
  185. package/src/define-agent.ts +46 -0
  186. package/src/define-team.ts +33 -0
  187. package/src/delegation.ts +265 -0
  188. package/src/distributed-claimer.ts +228 -0
  189. package/src/economy/AgentBudgetEnforcer.ts +464 -0
  190. package/src/economy/BountyManager.ts +185 -0
  191. package/src/economy/CreatorRevenueAggregator.ts +460 -0
  192. package/src/economy/InvisibleWallet.ts +82 -0
  193. package/src/economy/KnowledgeMarketplace.ts +193 -0
  194. package/src/economy/PaymentWebhookService.ts +512 -0
  195. package/src/economy/RevenueSplitter.ts +156 -0
  196. package/src/economy/SubscriptionManager.ts +546 -0
  197. package/src/economy/UnifiedBudgetOptimizer.ts +635 -0
  198. package/src/economy/UsageMeter.ts +440 -0
  199. package/src/economy/_core-stubs.ts +219 -0
  200. package/src/economy/index.ts +100 -0
  201. package/src/economy/x402-facilitator.ts +1978 -0
  202. package/src/index.ts +348 -0
  203. package/src/knowledge/__tests__/knowledge-consolidator.test.ts +444 -0
  204. package/src/knowledge/__tests__/knowledge-store-vector.test.ts +291 -0
  205. package/src/knowledge/brain.ts +167 -0
  206. package/src/knowledge/consolidation.ts +581 -0
  207. package/src/knowledge/knowledge-consolidator.ts +510 -0
  208. package/src/knowledge/knowledge-store.ts +616 -0
  209. package/src/learning/MemoryConsolidator.ts +102 -0
  210. package/src/learning/MemoryScorer.ts +69 -0
  211. package/src/learning/ProceduralCompiler.ts +45 -0
  212. package/src/learning/SemanticClusterer.ts +66 -0
  213. package/src/learning/index.ts +8 -0
  214. package/src/llm/llm-adapter.ts +159 -0
  215. package/src/mesh/index.ts +309 -0
  216. package/src/negotiation/NegotiationProtocol.ts +694 -0
  217. package/src/negotiation/NegotiationTypes.ts +473 -0
  218. package/src/negotiation/VotingMechanisms.ts +691 -0
  219. package/src/negotiation/index.ts +49 -0
  220. package/src/protocol/goal-synthesizer.ts +317 -0
  221. package/src/protocol/implementations.ts +474 -0
  222. package/src/protocol/micro-phase-decomposer.ts +299 -0
  223. package/src/protocol/micro-step-decomposer.test.ts +306 -0
  224. package/src/protocol-agent.test.ts +353 -0
  225. package/src/protocol-agent.ts +670 -0
  226. package/src/self-improve/absorb-scanner.ts +252 -0
  227. package/src/self-improve/evolution-engine.ts +149 -0
  228. package/src/self-improve/framework-absorber.ts +214 -0
  229. package/src/self-improve/index.ts +50 -0
  230. package/src/self-improve/prompt-optimizer.ts +212 -0
  231. package/src/self-improve/test-generator.ts +175 -0
  232. package/src/skill-router.ts +186 -0
  233. package/src/skills/index.ts +5 -0
  234. package/src/skills/skill-md-bridge.ts +1699 -0
  235. package/src/swarm/ACOEngine.ts +261 -0
  236. package/src/swarm/CollectiveIntelligence.ts +383 -0
  237. package/src/swarm/ContributionSynthesizer.ts +481 -0
  238. package/src/swarm/LeaderElection.ts +393 -0
  239. package/src/swarm/PSOEngine.ts +206 -0
  240. package/src/swarm/QuorumPolicy.ts +173 -0
  241. package/src/swarm/SwarmCoordinator.ts +335 -0
  242. package/src/swarm/SwarmManager.ts +442 -0
  243. package/src/swarm/SwarmMembership.ts +456 -0
  244. package/src/swarm/VotingRound.ts +255 -0
  245. package/src/swarm/__tests__/ACOEngine.prod.test.ts +164 -0
  246. package/src/swarm/__tests__/ACOEngine.test.ts +117 -0
  247. package/src/swarm/__tests__/CollectiveIntelligence.prod.test.ts +296 -0
  248. package/src/swarm/__tests__/CollectiveIntelligence.test.ts +457 -0
  249. package/src/swarm/__tests__/ContributionSynthesizer.prod.test.ts +269 -0
  250. package/src/swarm/__tests__/ContributionSynthesizer.test.ts +254 -0
  251. package/src/swarm/__tests__/LeaderElection.prod.test.ts +196 -0
  252. package/src/swarm/__tests__/LeaderElection.test.ts +151 -0
  253. package/src/swarm/__tests__/PSOEngine.prod.test.ts +162 -0
  254. package/src/swarm/__tests__/PSOEngine.test.ts +106 -0
  255. package/src/swarm/__tests__/QuorumPolicy.prod.test.ts +216 -0
  256. package/src/swarm/__tests__/QuorumPolicy.test.ts +177 -0
  257. package/src/swarm/__tests__/SwarmCoordinator.prod.test.ts +186 -0
  258. package/src/swarm/__tests__/SwarmCoordinator.test.ts +167 -0
  259. package/src/swarm/__tests__/SwarmManager.prod.test.ts +308 -0
  260. package/src/swarm/__tests__/SwarmManager.test.ts +373 -0
  261. package/src/swarm/__tests__/SwarmMembership.prod.test.ts +273 -0
  262. package/src/swarm/__tests__/SwarmMembership.test.ts +264 -0
  263. package/src/swarm/__tests__/VotingRound.prod.test.ts +233 -0
  264. package/src/swarm/__tests__/VotingRound.test.ts +174 -0
  265. package/src/swarm/analytics/SwarmInspector.ts +476 -0
  266. package/src/swarm/analytics/SwarmMetrics.ts +449 -0
  267. package/src/swarm/analytics/__tests__/SwarmInspector.prod.test.ts +366 -0
  268. package/src/swarm/analytics/__tests__/SwarmInspector.test.ts +454 -0
  269. package/src/swarm/analytics/__tests__/SwarmMetrics.prod.test.ts +254 -0
  270. package/src/swarm/analytics/__tests__/SwarmMetrics.test.ts +370 -0
  271. package/src/swarm/analytics/index.ts +7 -0
  272. package/src/swarm/index.ts +69 -0
  273. package/src/swarm/messaging/BroadcastChannel.ts +509 -0
  274. package/src/swarm/messaging/GossipProtocol.ts +565 -0
  275. package/src/swarm/messaging/SwarmEventBus.ts +443 -0
  276. package/src/swarm/messaging/__tests__/BroadcastChannel.prod.test.ts +331 -0
  277. package/src/swarm/messaging/__tests__/BroadcastChannel.test.ts +333 -0
  278. package/src/swarm/messaging/__tests__/GossipProtocol.prod.test.ts +356 -0
  279. package/src/swarm/messaging/__tests__/GossipProtocol.test.ts +437 -0
  280. package/src/swarm/messaging/__tests__/SwarmEventBus.prod.test.ts +191 -0
  281. package/src/swarm/messaging/__tests__/SwarmEventBus.test.ts +247 -0
  282. package/src/swarm/messaging/index.ts +8 -0
  283. package/src/swarm/spatial/FlockingBehavior.ts +462 -0
  284. package/src/swarm/spatial/FormationController.ts +500 -0
  285. package/src/swarm/spatial/Vector3.ts +170 -0
  286. package/src/swarm/spatial/ZoneClaiming.ts +509 -0
  287. package/src/swarm/spatial/__tests__/FlockingBehavior.prod.test.ts +239 -0
  288. package/src/swarm/spatial/__tests__/FlockingBehavior.test.ts +298 -0
  289. package/src/swarm/spatial/__tests__/FormationController.prod.test.ts +240 -0
  290. package/src/swarm/spatial/__tests__/FormationController.test.ts +297 -0
  291. package/src/swarm/spatial/__tests__/Vector3.prod.test.ts +283 -0
  292. package/src/swarm/spatial/__tests__/Vector3.test.ts +224 -0
  293. package/src/swarm/spatial/__tests__/ZoneClaiming.prod.test.ts +246 -0
  294. package/src/swarm/spatial/__tests__/ZoneClaiming.test.ts +374 -0
  295. package/src/swarm/spatial/index.ts +28 -0
  296. package/src/team.ts +1245 -0
  297. package/src/training/LRScheduler.ts +377 -0
  298. package/src/training/QualityScoringPipeline.ts +139 -0
  299. package/src/training/SoftDedup.ts +461 -0
  300. package/src/training/SparsityMonitor.ts +685 -0
  301. package/src/training/SparsityMonitorTypes.ts +209 -0
  302. package/src/training/SpatialTrainingDataGenerator.ts +1526 -0
  303. package/src/training/SpatialTrainingDataTypes.ts +216 -0
  304. package/src/training/TrainingPipelineConfig.ts +215 -0
  305. package/src/training/constants.ts +94 -0
  306. package/src/training/index.ts +138 -0
  307. package/src/training/schema.ts +147 -0
  308. package/src/training/scripts/generate-novel-use-cases-dataset.ts +272 -0
  309. package/src/training/scripts/generate-spatial-dataset.ts +521 -0
  310. package/src/training/training/data/novel-use-cases.jsonl +153 -0
  311. package/src/training/training/data/spatial-reasoning-10k.jsonl +9354 -0
  312. package/src/training/trainingmonkey/TrainingMonkeyIntegration.ts +477 -0
  313. package/src/training/trainingmonkey/TrainingMonkeyTypes.ts +230 -0
  314. package/src/training/trainingmonkey/index.ts +26 -0
  315. package/src/training/trait-mappings.ts +157 -0
  316. package/src/types/core-stubs.d.ts +113 -0
  317. package/src/types.ts +304 -0
  318. package/test-output.txt +0 -0
  319. package/test-result.json +1 -0
  320. package/tsc-errors.txt +4 -0
  321. package/tsc_output.txt +0 -0
  322. package/tsconfig.json +14 -0
  323. package/tsup-learning-esm.config.ts +12 -0
  324. package/tsup.config.ts +21 -0
  325. package/typescript-errors-2.txt +0 -0
  326. package/typescript-errors.txt +22 -0
  327. package/vitest-log-utf8.txt +268 -0
  328. package/vitest-log.txt +0 -0
  329. package/vitest.config.ts +8 -0
@@ -0,0 +1,393 @@
1
+ /**
2
+ * Leader Election System
3
+ *
4
+ * Implements Raft-inspired leader election for agent clusters.
5
+ * Provides fault-tolerant leader selection with automatic failover.
6
+ */
7
+
8
+ import type { ILeaderElection } from '@holoscript/core';
9
+
10
+ export interface LeaderElectionConfig {
11
+ electionTimeoutMin: number; // Min election timeout (ms)
12
+ electionTimeoutMax: number; // Max election timeout (ms)
13
+ heartbeatInterval: number; // Leader heartbeat interval (ms)
14
+ quorumSize?: number; // Override quorum calculation
15
+ }
16
+
17
+ export type ElectionRole = 'leader' | 'follower' | 'candidate';
18
+
19
+ export interface ElectionState {
20
+ term: number;
21
+ votedFor: string | null;
22
+ role: ElectionRole;
23
+ leaderId: string | null;
24
+ votes: Set<string>;
25
+ }
26
+
27
+ const DEFAULT_CONFIG: LeaderElectionConfig = {
28
+ electionTimeoutMin: 150,
29
+ electionTimeoutMax: 300,
30
+ heartbeatInterval: 50,
31
+ };
32
+
33
+ /**
34
+ * Raft-inspired leader election for agent clusters
35
+ */
36
+ export class LeaderElection implements ILeaderElection {
37
+ private nodeId: string;
38
+ private clusterMembers: string[];
39
+ private config: LeaderElectionConfig;
40
+ private state: ElectionState;
41
+ private electionTimer: ReturnType<typeof setTimeout> | null = null;
42
+ private heartbeatTimer: ReturnType<typeof setInterval> | null = null;
43
+ private callbacks: Set<(leaderId: string | null) => void> = new Set();
44
+ private messageHandler: ((from: string, message: ElectionMessage) => void) | null = null;
45
+
46
+ constructor(
47
+ nodeId: string,
48
+ clusterMembers: string[],
49
+ config: Partial<LeaderElectionConfig> = {}
50
+ ) {
51
+ this.nodeId = nodeId;
52
+ this.clusterMembers = clusterMembers.filter((id) => id !== nodeId);
53
+ this.config = { ...DEFAULT_CONFIG, ...config };
54
+ this.state = {
55
+ term: 0,
56
+ votedFor: null,
57
+ role: 'follower',
58
+ leaderId: null,
59
+ votes: new Set(),
60
+ };
61
+ }
62
+
63
+ /**
64
+ * Start participating in leader election
65
+ */
66
+ async startElection(): Promise<string> {
67
+ this.becomeCandidate();
68
+
69
+ // Wait for election to complete
70
+ return new Promise((resolve) => {
71
+ const checkLeader = setInterval(() => {
72
+ if (this.state.leaderId !== null) {
73
+ clearInterval(checkLeader);
74
+ resolve(this.state.leaderId);
75
+ }
76
+ }, 10);
77
+
78
+ // Timeout safety
79
+ setTimeout(() => {
80
+ clearInterval(checkLeader);
81
+ resolve(this.state.leaderId ?? this.nodeId);
82
+ }, this.config.electionTimeoutMax * 3);
83
+ });
84
+ }
85
+
86
+ /**
87
+ * Get current leader
88
+ */
89
+ getLeader(): string | null {
90
+ return this.state.leaderId;
91
+ }
92
+
93
+ /**
94
+ * Get this node's current role
95
+ */
96
+ getRole(): ElectionRole {
97
+ return this.state.role;
98
+ }
99
+
100
+ /**
101
+ * Subscribe to leader changes
102
+ */
103
+ onLeaderChange(callback: (leaderId: string | null) => void): () => void {
104
+ this.callbacks.add(callback);
105
+ return () => this.callbacks.delete(callback);
106
+ }
107
+
108
+ /**
109
+ * Handle incoming election message
110
+ */
111
+ handleMessage(from: string, message: ElectionMessage): void {
112
+ switch (message.type) {
113
+ case 'request-vote':
114
+ this.handleVoteRequest(from, message);
115
+ break;
116
+ case 'vote-response':
117
+ this.handleVoteResponse(from, message);
118
+ break;
119
+ case 'heartbeat':
120
+ this.handleHeartbeat(from, message);
121
+ break;
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Set message handler for sending messages to other nodes
127
+ */
128
+ setMessageHandler(handler: (from: string, message: ElectionMessage) => void): void {
129
+ this.messageHandler = handler;
130
+ }
131
+
132
+ /**
133
+ * Simulate receiving vote from another node (for testing/local clusters)
134
+ */
135
+ receiveVote(voterId: string): void {
136
+ if (this.state.role === 'candidate') {
137
+ this.state.votes.add(voterId);
138
+ this.checkElectionWin();
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Stop participating in election
144
+ */
145
+ stop(): void {
146
+ if (this.electionTimer) {
147
+ clearTimeout(this.electionTimer);
148
+ this.electionTimer = null;
149
+ }
150
+ if (this.heartbeatTimer) {
151
+ clearInterval(this.heartbeatTimer);
152
+ this.heartbeatTimer = null;
153
+ }
154
+ }
155
+
156
+ /**
157
+ * Transition to candidate role and start election
158
+ */
159
+ private becomeCandidate(): void {
160
+ this.state.term++;
161
+ this.state.role = 'candidate';
162
+ this.state.votedFor = this.nodeId;
163
+ this.state.votes = new Set([this.nodeId]); // Vote for self
164
+
165
+ this.resetElectionTimer();
166
+ this.requestVotes();
167
+ this.checkElectionWin();
168
+ }
169
+
170
+ /**
171
+ * Transition to leader role
172
+ */
173
+ private becomeLeader(): void {
174
+ this.state.role = 'leader';
175
+ this.state.leaderId = this.nodeId;
176
+
177
+ if (this.electionTimer) {
178
+ clearTimeout(this.electionTimer);
179
+ this.electionTimer = null;
180
+ }
181
+
182
+ // Start sending heartbeats
183
+ this.heartbeatTimer = setInterval(() => {
184
+ this.sendHeartbeats();
185
+ }, this.config.heartbeatInterval);
186
+
187
+ this.notifyLeaderChange();
188
+ }
189
+
190
+ /**
191
+ * Transition to follower role
192
+ */
193
+ private becomeFollower(leaderId: string, term: number): void {
194
+ const wasLeader = this.state.role === 'leader';
195
+
196
+ this.state.role = 'follower';
197
+ this.state.leaderId = leaderId;
198
+ this.state.term = term;
199
+ this.state.votedFor = null;
200
+ this.state.votes.clear();
201
+
202
+ if (this.heartbeatTimer) {
203
+ clearInterval(this.heartbeatTimer);
204
+ this.heartbeatTimer = null;
205
+ }
206
+
207
+ this.resetElectionTimer();
208
+
209
+ if (wasLeader || this.state.leaderId !== leaderId) {
210
+ this.notifyLeaderChange();
211
+ }
212
+ }
213
+
214
+ /**
215
+ * Request votes from all cluster members
216
+ */
217
+ private requestVotes(): void {
218
+ const message: VoteRequestMessage = {
219
+ type: 'request-vote',
220
+ term: this.state.term,
221
+ candidateId: this.nodeId,
222
+ };
223
+
224
+ // In a real implementation, this would send over network
225
+ // For now, simulate immediate responses from local cluster
226
+ if (this.messageHandler) {
227
+ for (const member of this.clusterMembers) {
228
+ this.messageHandler(member, message);
229
+ }
230
+ } else {
231
+ // Simulate local cluster - all nodes vote for first candidate
232
+ for (const member of this.clusterMembers) {
233
+ this.receiveVote(member);
234
+ }
235
+ }
236
+ }
237
+
238
+ /**
239
+ * Check if we've won the election
240
+ */
241
+ private checkElectionWin(): void {
242
+ const quorum = this.getQuorumSize();
243
+
244
+ if (this.state.votes.size >= quorum && this.state.role === 'candidate') {
245
+ this.becomeLeader();
246
+ }
247
+ }
248
+
249
+ /**
250
+ * Send heartbeats to all followers
251
+ */
252
+ private sendHeartbeats(): void {
253
+ if (this.state.role !== 'leader') return;
254
+
255
+ const message: HeartbeatMessage = {
256
+ type: 'heartbeat',
257
+ term: this.state.term,
258
+ leaderId: this.nodeId,
259
+ };
260
+
261
+ if (this.messageHandler) {
262
+ for (const member of this.clusterMembers) {
263
+ this.messageHandler(member, message);
264
+ }
265
+ }
266
+ }
267
+
268
+ /**
269
+ * Handle vote request from candidate
270
+ */
271
+ private handleVoteRequest(from: string, message: VoteRequestMessage): void {
272
+ // If we've already voted in this term or candidate's term is old, reject
273
+ if (message.term < this.state.term) {
274
+ return;
275
+ }
276
+
277
+ // If candidate's term is newer, update our term
278
+ if (message.term > this.state.term) {
279
+ this.state.term = message.term;
280
+ this.state.votedFor = null;
281
+ }
282
+
283
+ // Grant vote if we haven't voted in this term
284
+ if (this.state.votedFor === null || this.state.votedFor === message.candidateId) {
285
+ this.state.votedFor = message.candidateId;
286
+
287
+ const response: VoteResponseMessage = {
288
+ type: 'vote-response',
289
+ term: this.state.term,
290
+ voteGranted: true,
291
+ };
292
+
293
+ if (this.messageHandler) {
294
+ this.messageHandler(from, response);
295
+ }
296
+ }
297
+ }
298
+
299
+ /**
300
+ * Handle vote response
301
+ */
302
+ private handleVoteResponse(from: string, message: VoteResponseMessage): void {
303
+ if (message.term > this.state.term) {
304
+ this.becomeFollower(from, message.term);
305
+ return;
306
+ }
307
+
308
+ if (this.state.role === 'candidate' && message.voteGranted) {
309
+ this.state.votes.add(from);
310
+ this.checkElectionWin();
311
+ }
312
+ }
313
+
314
+ /**
315
+ * Handle heartbeat from leader
316
+ */
317
+ private handleHeartbeat(from: string, message: HeartbeatMessage): void {
318
+ if (message.term >= this.state.term) {
319
+ this.becomeFollower(message.leaderId, message.term);
320
+ this.resetElectionTimer();
321
+ }
322
+ }
323
+
324
+ /**
325
+ * Reset election timeout
326
+ */
327
+ private resetElectionTimer(): void {
328
+ if (this.electionTimer) {
329
+ clearTimeout(this.electionTimer);
330
+ }
331
+
332
+ const timeout = this.getRandomElectionTimeout();
333
+
334
+ this.electionTimer = setTimeout(() => {
335
+ if (this.state.role !== 'leader') {
336
+ this.becomeCandidate();
337
+ }
338
+ }, timeout);
339
+ }
340
+
341
+ /**
342
+ * Get random election timeout in configured range
343
+ */
344
+ private getRandomElectionTimeout(): number {
345
+ const { electionTimeoutMin, electionTimeoutMax } = this.config;
346
+ return electionTimeoutMin + Math.random() * (electionTimeoutMax - electionTimeoutMin);
347
+ }
348
+
349
+ /**
350
+ * Calculate quorum size (majority)
351
+ */
352
+ private getQuorumSize(): number {
353
+ if (this.config.quorumSize) {
354
+ return this.config.quorumSize;
355
+ }
356
+ const totalNodes = this.clusterMembers.length + 1; // Include self
357
+ return Math.floor(totalNodes / 2) + 1;
358
+ }
359
+
360
+ /**
361
+ * Notify all callbacks of leader change
362
+ */
363
+ private notifyLeaderChange(): void {
364
+ for (const callback of this.callbacks) {
365
+ try {
366
+ callback(this.state.leaderId);
367
+ } catch (_error) {
368
+ // Ignore callback errors
369
+ }
370
+ }
371
+ }
372
+ }
373
+
374
+ // Message types
375
+ export type ElectionMessage = VoteRequestMessage | VoteResponseMessage | HeartbeatMessage;
376
+
377
+ export interface VoteRequestMessage {
378
+ type: 'request-vote';
379
+ term: number;
380
+ candidateId: string;
381
+ }
382
+
383
+ export interface VoteResponseMessage {
384
+ type: 'vote-response';
385
+ term: number;
386
+ voteGranted: boolean;
387
+ }
388
+
389
+ export interface HeartbeatMessage {
390
+ type: 'heartbeat';
391
+ term: number;
392
+ leaderId: string;
393
+ }
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Particle Swarm Optimization Engine
3
+ *
4
+ * Implements PSO algorithm for agent-task assignment optimization.
5
+ * Each particle represents a potential solution (task-to-agent mapping).
6
+ */
7
+
8
+ export interface PSOConfig {
9
+ populationSize: number;
10
+ maxIterations: number;
11
+ convergenceThreshold: number;
12
+ inertiaWeight: number;
13
+ cognitiveWeight: number;
14
+ socialWeight: number;
15
+ velocityClamp: number;
16
+ }
17
+
18
+ export interface Particle {
19
+ position: number[];
20
+ velocity: number[];
21
+ personalBest: number[];
22
+ personalBestFitness: number;
23
+ }
24
+
25
+ export interface PSOResult {
26
+ bestSolution: number[];
27
+ bestFitness: number;
28
+ converged: boolean;
29
+ iterations: number;
30
+ fitnessHistory: number[];
31
+ }
32
+
33
+ const DEFAULT_CONFIG: PSOConfig = {
34
+ populationSize: 30,
35
+ maxIterations: 100,
36
+ convergenceThreshold: 0.001,
37
+ inertiaWeight: 0.729,
38
+ cognitiveWeight: 1.49445,
39
+ socialWeight: 1.49445,
40
+ velocityClamp: 4.0,
41
+ };
42
+
43
+ /**
44
+ * Particle Swarm Optimization engine for task assignment
45
+ */
46
+ export class PSOEngine {
47
+ private config: PSOConfig;
48
+
49
+ constructor(config: Partial<PSOConfig> = {}) {
50
+ this.config = { ...DEFAULT_CONFIG, ...config };
51
+ }
52
+
53
+ /**
54
+ * Optimize task assignment using PSO
55
+ *
56
+ * @param agentCount Number of available agents
57
+ * @param taskCount Number of tasks to assign
58
+ * @param fitnessFunction Function to evaluate solution quality (higher is better)
59
+ * @returns Optimization result with best assignment
60
+ */
61
+ async optimize(
62
+ agentCount: number,
63
+ taskCount: number,
64
+ fitnessFunction: (assignment: number[]) => number
65
+ ): Promise<PSOResult> {
66
+ const { populationSize, maxIterations, convergenceThreshold } = this.config;
67
+
68
+ // Initialize swarm
69
+ const particles = this.initializeSwarm(populationSize, taskCount, agentCount);
70
+
71
+ // Track global best
72
+ let globalBest: number[] = [...particles[0].personalBest];
73
+ let globalBestFitness = particles[0].personalBestFitness;
74
+
75
+ // Find initial global best
76
+ for (const particle of particles) {
77
+ if (particle.personalBestFitness > globalBestFitness) {
78
+ globalBestFitness = particle.personalBestFitness;
79
+ globalBest = [...particle.personalBest];
80
+ }
81
+ }
82
+
83
+ const fitnessHistory: number[] = [globalBestFitness];
84
+ let converged = false;
85
+ let iteration = 0;
86
+
87
+ // Main optimization loop
88
+ for (iteration = 0; iteration < maxIterations; iteration++) {
89
+ const previousBest = globalBestFitness;
90
+
91
+ // Update each particle
92
+ for (const particle of particles) {
93
+ this.updateVelocity(particle, globalBest);
94
+ this.updatePosition(particle, agentCount);
95
+
96
+ // Evaluate new position
97
+ const fitness = fitnessFunction(this.discretize(particle.position, agentCount));
98
+
99
+ // Update personal best
100
+ if (fitness > particle.personalBestFitness) {
101
+ particle.personalBestFitness = fitness;
102
+ particle.personalBest = [...particle.position];
103
+
104
+ // Update global best
105
+ if (fitness > globalBestFitness) {
106
+ globalBestFitness = fitness;
107
+ globalBest = [...particle.personalBest];
108
+ }
109
+ }
110
+ }
111
+
112
+ fitnessHistory.push(globalBestFitness);
113
+
114
+ // Check convergence
115
+ const improvement = Math.abs(globalBestFitness - previousBest);
116
+ if (improvement < convergenceThreshold && iteration > 10) {
117
+ converged = true;
118
+ break;
119
+ }
120
+ }
121
+
122
+ return {
123
+ bestSolution: this.discretize(globalBest, agentCount),
124
+ bestFitness: globalBestFitness,
125
+ converged,
126
+ iterations: iteration + 1,
127
+ fitnessHistory,
128
+ };
129
+ }
130
+
131
+ /**
132
+ * Initialize the particle swarm with random positions
133
+ */
134
+ private initializeSwarm(
135
+ populationSize: number,
136
+ dimensions: number,
137
+ agentCount: number
138
+ ): Particle[] {
139
+ const particles: Particle[] = [];
140
+
141
+ for (let i = 0; i < populationSize; i++) {
142
+ const position = Array.from({ length: dimensions }, () => Math.random() * agentCount);
143
+ const velocity = Array.from({ length: dimensions }, () => (Math.random() - 0.5) * 2);
144
+
145
+ particles.push({
146
+ position,
147
+ velocity,
148
+ personalBest: [...position],
149
+ personalBestFitness: -Infinity,
150
+ });
151
+ }
152
+
153
+ return particles;
154
+ }
155
+
156
+ /**
157
+ * Update particle velocity based on PSO equations
158
+ */
159
+ private updateVelocity(particle: Particle, globalBest: number[]): void {
160
+ const { inertiaWeight, cognitiveWeight, socialWeight, velocityClamp } = this.config;
161
+
162
+ for (let d = 0; d < particle.position.length; d++) {
163
+ const r1 = Math.random();
164
+ const r2 = Math.random();
165
+
166
+ // PSO velocity update equation
167
+ const cognitive = cognitiveWeight * r1 * (particle.personalBest[d] - particle.position[d]);
168
+ const social = socialWeight * r2 * (globalBest[d] - particle.position[d]);
169
+
170
+ particle.velocity[d] = inertiaWeight * particle.velocity[d] + cognitive + social;
171
+
172
+ // Clamp velocity
173
+ particle.velocity[d] = Math.max(
174
+ -velocityClamp,
175
+ Math.min(velocityClamp, particle.velocity[d])
176
+ );
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Update particle position
182
+ */
183
+ private updatePosition(particle: Particle, agentCount: number): void {
184
+ for (let d = 0; d < particle.position.length; d++) {
185
+ particle.position[d] += particle.velocity[d];
186
+
187
+ // Clamp to valid range [0, agentCount)
188
+ particle.position[d] = Math.max(0, Math.min(agentCount - 0.001, particle.position[d]));
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Convert continuous positions to discrete agent indices
194
+ */
195
+ private discretize(position: number[], agentCount: number): number[] {
196
+ return position.map((p) => Math.floor(Math.max(0, Math.min(agentCount - 1, p))));
197
+ }
198
+
199
+ /**
200
+ * Get recommended population size for problem
201
+ */
202
+ getRecommendedPopulation(problemSize: number): number {
203
+ // Heuristic: 10-50 particles based on problem size
204
+ return Math.min(50, Math.max(10, Math.ceil(problemSize * 1.5)));
205
+ }
206
+ }