@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,931 @@
1
+ // src/negotiation/VotingMechanisms.ts
2
+ function getTotalWeight(votes) {
3
+ return votes.reduce((sum, v) => sum + v.weight, 0);
4
+ }
5
+ function initializeTallies(proposals) {
6
+ const tallies = /* @__PURE__ */ new Map();
7
+ for (const p of proposals) {
8
+ tallies.set(p.id, {
9
+ proposalId: p.id,
10
+ voteCount: 0,
11
+ weightedScore: 0,
12
+ approvalCount: 0,
13
+ bordaPoints: 0,
14
+ percentage: 0
15
+ });
16
+ }
17
+ return tallies;
18
+ }
19
+ function talliesToArray(tallies, totalWeight) {
20
+ const arr = Array.from(tallies.values());
21
+ for (const t of arr) {
22
+ t.percentage = totalWeight > 0 ? t.weightedScore / totalWeight * 100 : 0;
23
+ }
24
+ return arr.sort((a, b) => b.weightedScore - a.weightedScore);
25
+ }
26
+ function findTies(tallies) {
27
+ if (tallies.length < 2) return [];
28
+ const topScore = tallies[0].weightedScore;
29
+ return tallies.filter((t) => t.weightedScore === topScore);
30
+ }
31
+ function breakTie(tied, proposals, config) {
32
+ if (tied.length === 0) return void 0;
33
+ if (tied.length === 1) return tied[0].proposalId;
34
+ switch (config.tieBreaker) {
35
+ case "random":
36
+ return tied[Math.floor(Math.random() * tied.length)].proposalId;
37
+ case "seniority": {
38
+ const proposalMap = new Map(proposals.map((p) => [p.id, p]));
39
+ const sorted = [...tied].sort((a, b) => {
40
+ const pa = proposalMap.get(a.proposalId);
41
+ const pb = proposalMap.get(b.proposalId);
42
+ return (pa?.submittedAt || 0) - (pb?.submittedAt || 0);
43
+ });
44
+ return sorted[0].proposalId;
45
+ }
46
+ case "priority": {
47
+ const proposalMap = new Map(proposals.map((p) => [p.id, p]));
48
+ const sorted = [...tied].sort((a, b) => {
49
+ const pa = proposalMap.get(a.proposalId);
50
+ const pb = proposalMap.get(b.proposalId);
51
+ return (pb?.priority || 0) - (pa?.priority || 0);
52
+ });
53
+ return sorted[0].proposalId;
54
+ }
55
+ case "proposer":
56
+ return tied[0].proposalId;
57
+ case "escalate":
58
+ default:
59
+ return void 0;
60
+ }
61
+ }
62
+ var majorityHandler = {
63
+ count(votes, proposals, config, _round) {
64
+ const tallies = initializeTallies(proposals);
65
+ const totalWeight = getTotalWeight(votes);
66
+ for (const vote of votes) {
67
+ if (vote.ranking.length > 0) {
68
+ const firstChoice = vote.ranking[0];
69
+ const tally = tallies.get(firstChoice);
70
+ if (tally) {
71
+ tally.voteCount++;
72
+ tally.weightedScore += vote.weight;
73
+ }
74
+ }
75
+ }
76
+ const sorted = talliesToArray(tallies, totalWeight);
77
+ const ties = findTies(sorted);
78
+ if (sorted.length > 0 && sorted[0].percentage > 50) {
79
+ return {
80
+ tallies: sorted,
81
+ winnerId: sorted[0].proposalId,
82
+ resolved: true,
83
+ outcome: "winner_declared",
84
+ consensusLevel: sorted[0].percentage / 100
85
+ };
86
+ }
87
+ if (ties.length > 1) {
88
+ const tieBreakWinner = breakTie(ties, proposals, config);
89
+ if (tieBreakWinner) {
90
+ return {
91
+ tallies: sorted,
92
+ winnerId: tieBreakWinner,
93
+ resolved: true,
94
+ outcome: "tie_broken",
95
+ tie: true
96
+ };
97
+ }
98
+ return {
99
+ tallies: sorted,
100
+ resolved: false,
101
+ outcome: "deadlock",
102
+ tie: true
103
+ };
104
+ }
105
+ if (sorted.length > 0) {
106
+ return {
107
+ tallies: sorted,
108
+ winnerId: sorted[0].proposalId,
109
+ resolved: true,
110
+ outcome: "winner_declared",
111
+ consensusLevel: sorted[0].percentage / 100
112
+ };
113
+ }
114
+ return {
115
+ tallies: sorted,
116
+ resolved: false,
117
+ outcome: "deadlock"
118
+ };
119
+ },
120
+ validateVote(vote, proposals) {
121
+ if (vote.ranking.length === 0) return false;
122
+ const proposalIds = new Set(proposals.map((p) => p.id));
123
+ return proposalIds.has(vote.ranking[0]);
124
+ },
125
+ getRequiredQuorum(config) {
126
+ return config.quorum || 0.5;
127
+ }
128
+ };
129
+ var supermajorityHandler = {
130
+ count(votes, proposals, _config, _round) {
131
+ const tallies = initializeTallies(proposals);
132
+ const totalWeight = getTotalWeight(votes);
133
+ for (const vote of votes) {
134
+ if (vote.ranking.length > 0) {
135
+ const firstChoice = vote.ranking[0];
136
+ const tally = tallies.get(firstChoice);
137
+ if (tally) {
138
+ tally.voteCount++;
139
+ tally.weightedScore += vote.weight;
140
+ }
141
+ }
142
+ }
143
+ const sorted = talliesToArray(tallies, totalWeight);
144
+ const threshold = 66.67;
145
+ if (sorted.length > 0 && sorted[0].percentage >= threshold) {
146
+ return {
147
+ tallies: sorted,
148
+ winnerId: sorted[0].proposalId,
149
+ resolved: true,
150
+ outcome: "winner_declared",
151
+ consensusLevel: sorted[0].percentage / 100
152
+ };
153
+ }
154
+ return {
155
+ tallies: sorted,
156
+ resolved: false,
157
+ outcome: "deadlock"
158
+ };
159
+ },
160
+ validateVote(vote, proposals) {
161
+ return majorityHandler.validateVote(vote, proposals);
162
+ },
163
+ getRequiredQuorum(config) {
164
+ return config.quorum || 0.67;
165
+ }
166
+ };
167
+ var weightedHandler = {
168
+ count(votes, proposals, config, round) {
169
+ return majorityHandler.count(votes, proposals, config, round);
170
+ },
171
+ validateVote(vote, proposals) {
172
+ return majorityHandler.validateVote(vote, proposals);
173
+ },
174
+ getRequiredQuorum(config) {
175
+ return config.quorum || 0.5;
176
+ }
177
+ };
178
+ var consensusHandler = {
179
+ count(votes, proposals, _config, _round) {
180
+ if (votes.length === 0) {
181
+ return {
182
+ tallies: [],
183
+ resolved: false,
184
+ outcome: "deadlock"
185
+ };
186
+ }
187
+ const tallies = initializeTallies(proposals);
188
+ const totalWeight = getTotalWeight(votes);
189
+ const firstChoices = /* @__PURE__ */ new Map();
190
+ for (const vote of votes) {
191
+ if (vote.ranking.length > 0) {
192
+ const choice = vote.ranking[0];
193
+ const tally = tallies.get(choice);
194
+ if (tally) {
195
+ tally.voteCount++;
196
+ tally.weightedScore += vote.weight;
197
+ }
198
+ if (!firstChoices.has(choice)) {
199
+ firstChoices.set(choice, []);
200
+ }
201
+ firstChoices.get(choice).push(vote.agentId);
202
+ }
203
+ }
204
+ const sorted = talliesToArray(tallies, totalWeight);
205
+ if (firstChoices.size === 1) {
206
+ const winnerId = Array.from(firstChoices.keys())[0];
207
+ return {
208
+ tallies: sorted,
209
+ winnerId,
210
+ resolved: true,
211
+ outcome: "consensus_reached",
212
+ consensusLevel: 1
213
+ };
214
+ }
215
+ const leader = sorted[0];
216
+ const leaderVoters = new Set(firstChoices.get(leader.proposalId) || []);
217
+ const dissenters = votes.filter((v) => !leaderVoters.has(v.agentId)).map((v) => v.agentId);
218
+ return {
219
+ tallies: sorted,
220
+ resolved: false,
221
+ outcome: "deadlock",
222
+ consensusLevel: leader.percentage / 100,
223
+ dissenters
224
+ };
225
+ },
226
+ validateVote(vote, proposals) {
227
+ return majorityHandler.validateVote(vote, proposals);
228
+ },
229
+ getRequiredQuorum() {
230
+ return 1;
231
+ }
232
+ };
233
+ var rankedHandler = {
234
+ count(votes, proposals, _config, _round) {
235
+ const eliminated = /* @__PURE__ */ new Set();
236
+ const runoffVotes = votes.map((v) => ({
237
+ ...v,
238
+ currentRanking: [...v.ranking]
239
+ }));
240
+ const totalWeight = getTotalWeight(votes);
241
+ let rounds = 0;
242
+ const maxRounds = proposals.length;
243
+ while (rounds < maxRounds) {
244
+ rounds++;
245
+ const tallies = initializeTallies(proposals.filter((p) => !eliminated.has(p.id)));
246
+ for (const vote of runoffVotes) {
247
+ const validChoice = vote.currentRanking.find((id) => !eliminated.has(id));
248
+ if (validChoice) {
249
+ const tally = tallies.get(validChoice);
250
+ if (tally) {
251
+ tally.voteCount++;
252
+ tally.weightedScore += vote.weight;
253
+ }
254
+ }
255
+ }
256
+ const sorted = talliesToArray(tallies, totalWeight);
257
+ if (sorted.length > 0 && sorted[0].percentage > 50) {
258
+ return {
259
+ tallies: sorted,
260
+ winnerId: sorted[0].proposalId,
261
+ resolved: true,
262
+ outcome: "winner_declared",
263
+ eliminated: Array.from(eliminated),
264
+ consensusLevel: sorted[0].percentage / 100
265
+ };
266
+ }
267
+ if (sorted.length > 1) {
268
+ const loser = sorted[sorted.length - 1];
269
+ eliminated.add(loser.proposalId);
270
+ } else if (sorted.length === 1) {
271
+ return {
272
+ tallies: sorted,
273
+ winnerId: sorted[0].proposalId,
274
+ resolved: true,
275
+ outcome: "winner_declared",
276
+ eliminated: Array.from(eliminated)
277
+ };
278
+ } else {
279
+ break;
280
+ }
281
+ }
282
+ return {
283
+ tallies: [],
284
+ resolved: false,
285
+ outcome: "deadlock",
286
+ eliminated: Array.from(eliminated)
287
+ };
288
+ },
289
+ validateVote(vote, proposals) {
290
+ if (vote.ranking.length === 0) return false;
291
+ const proposalIds = new Set(proposals.map((p) => p.id));
292
+ return vote.ranking.every((id) => proposalIds.has(id));
293
+ },
294
+ getRequiredQuorum(config) {
295
+ return config.quorum || 0.5;
296
+ }
297
+ };
298
+ var approvalHandler = {
299
+ count(votes, proposals, config, _round) {
300
+ const tallies = initializeTallies(proposals);
301
+ const totalVotes = votes.length;
302
+ for (const vote of votes) {
303
+ const approvals = vote.approvals || vote.ranking;
304
+ for (const proposalId of approvals) {
305
+ const tally = tallies.get(proposalId);
306
+ if (tally) {
307
+ tally.voteCount++;
308
+ tally.weightedScore += vote.weight;
309
+ tally.approvalCount = (tally.approvalCount || 0) + 1;
310
+ }
311
+ }
312
+ }
313
+ const sorted = talliesToArray(
314
+ tallies,
315
+ votes.reduce((s, v) => s + v.weight, 0)
316
+ );
317
+ const ties = findTies(sorted);
318
+ if (ties.length > 1) {
319
+ const tieBreakWinner = breakTie(ties, proposals, config);
320
+ if (tieBreakWinner) {
321
+ return {
322
+ tallies: sorted,
323
+ winnerId: tieBreakWinner,
324
+ resolved: true,
325
+ outcome: "tie_broken",
326
+ tie: true
327
+ };
328
+ }
329
+ }
330
+ if (sorted.length > 0) {
331
+ return {
332
+ tallies: sorted,
333
+ winnerId: sorted[0].proposalId,
334
+ resolved: true,
335
+ outcome: "winner_declared",
336
+ consensusLevel: totalVotes > 0 ? (sorted[0].approvalCount || 0) / totalVotes : 0
337
+ };
338
+ }
339
+ return {
340
+ tallies: sorted,
341
+ resolved: false,
342
+ outcome: "deadlock"
343
+ };
344
+ },
345
+ validateVote(vote, proposals) {
346
+ const approvals = vote.approvals || vote.ranking;
347
+ if (approvals.length === 0) return false;
348
+ const proposalIds = new Set(proposals.map((p) => p.id));
349
+ return approvals.every((id) => proposalIds.has(id));
350
+ },
351
+ getRequiredQuorum(config) {
352
+ return config.quorum || 0.5;
353
+ }
354
+ };
355
+ var bordaHandler = {
356
+ count(votes, proposals, config, _round) {
357
+ const tallies = initializeTallies(proposals);
358
+ const n = proposals.length;
359
+ for (const vote of votes) {
360
+ for (let i = 0; i < vote.ranking.length; i++) {
361
+ const proposalId = vote.ranking[i];
362
+ const tally = tallies.get(proposalId);
363
+ if (tally) {
364
+ const points = (n - 1 - i) * vote.weight;
365
+ tally.bordaPoints = (tally.bordaPoints || 0) + points;
366
+ tally.weightedScore += points;
367
+ tally.voteCount++;
368
+ }
369
+ }
370
+ }
371
+ const sorted = talliesToArray(tallies, n * votes.reduce((s, v) => s + v.weight, 0));
372
+ const ties = findTies(sorted);
373
+ if (ties.length > 1) {
374
+ const tieBreakWinner = breakTie(ties, proposals, config);
375
+ if (tieBreakWinner) {
376
+ return {
377
+ tallies: sorted,
378
+ winnerId: tieBreakWinner,
379
+ resolved: true,
380
+ outcome: "tie_broken",
381
+ tie: true
382
+ };
383
+ }
384
+ }
385
+ if (sorted.length > 0) {
386
+ return {
387
+ tallies: sorted,
388
+ winnerId: sorted[0].proposalId,
389
+ resolved: true,
390
+ outcome: "winner_declared"
391
+ };
392
+ }
393
+ return {
394
+ tallies: sorted,
395
+ resolved: false,
396
+ outcome: "deadlock"
397
+ };
398
+ },
399
+ validateVote(vote, proposals) {
400
+ return rankedHandler.validateVote(vote, proposals);
401
+ },
402
+ getRequiredQuorum(config) {
403
+ return config.quorum || 0.5;
404
+ }
405
+ };
406
+ function getVotingHandler(mechanism) {
407
+ switch (mechanism) {
408
+ case "majority":
409
+ return majorityHandler;
410
+ case "supermajority":
411
+ return supermajorityHandler;
412
+ case "weighted":
413
+ return weightedHandler;
414
+ case "consensus":
415
+ return consensusHandler;
416
+ case "ranked":
417
+ return rankedHandler;
418
+ case "approval":
419
+ return approvalHandler;
420
+ case "borda":
421
+ return bordaHandler;
422
+ case "custom":
423
+ default:
424
+ return majorityHandler;
425
+ }
426
+ }
427
+ function checkQuorum(votes, participants, config, mechanism) {
428
+ const handler = getVotingHandler(mechanism);
429
+ const requiredQuorum = handler.getRequiredQuorum(config);
430
+ const participation = participants > 0 ? votes.length / participants : 0;
431
+ return participation >= requiredQuorum;
432
+ }
433
+ function getTrustWeight(trustLevel) {
434
+ switch (trustLevel) {
435
+ case "local":
436
+ return 1;
437
+ case "verified":
438
+ return 0.8;
439
+ case "external":
440
+ return 0.5;
441
+ default:
442
+ return 0.5;
443
+ }
444
+ }
445
+
446
+ // src/negotiation/NegotiationProtocol.ts
447
+ var NegotiationProtocol = class {
448
+ sessions = /* @__PURE__ */ new Map();
449
+ auditLog = [];
450
+ deadlines = /* @__PURE__ */ new Map();
451
+ eventHandlers = /* @__PURE__ */ new Map();
452
+ sessionCounter = 0;
453
+ proposalCounter = 0;
454
+ voteCounter = 0;
455
+ // ===========================================================================
456
+ // PUBLIC API
457
+ // ===========================================================================
458
+ /**
459
+ * Initiate a new negotiation session
460
+ */
461
+ async initiate(options) {
462
+ const sessionId = this.generateSessionId();
463
+ const timeout = options.timeout ?? 6e4;
464
+ const config = {
465
+ mechanism: options.votingMechanism || "majority",
466
+ votingMechanism: options.votingMechanism || "majority",
467
+ quorum: options.quorum ?? 0.5,
468
+ timeout,
469
+ votingDeadline: timeout,
470
+ proposalDeadline: timeout,
471
+ maxRounds: options.maxRounds ?? 3,
472
+ allowAbstain: options.allowAbstain ?? true,
473
+ requireJustification: options.requireJustification ?? false,
474
+ tieBreaker: options.tieBreaker ?? "random",
475
+ escalationPath: options.escalationPath
476
+ };
477
+ const now = Date.now();
478
+ const session = {
479
+ id: sessionId,
480
+ topic: options.topic,
481
+ description: options.description,
482
+ participants: [...options.participants],
483
+ status: "open",
484
+ proposals: [],
485
+ votes: [],
486
+ config,
487
+ round: 1,
488
+ currentRound: 1,
489
+ createdAt: now,
490
+ startedAt: now,
491
+ lastActivityAt: now,
492
+ deadline: now + timeout,
493
+ history: [],
494
+ metadata: options.metadata || {}
495
+ };
496
+ this.sessions.set(sessionId, session);
497
+ this.startDeadlineTimer(session);
498
+ this.audit("initiated", sessionId, void 0, {
499
+ topic: options.topic,
500
+ participants: options.participants,
501
+ config
502
+ });
503
+ await this.emit("sessionStarted", { session });
504
+ return session;
505
+ }
506
+ /**
507
+ * Submit a proposal to a session
508
+ */
509
+ async propose(sessionId, input) {
510
+ const session = this.getSession(sessionId);
511
+ this.validateSessionOpen(session);
512
+ this.validateParticipant(session, input.proposerId);
513
+ const proposalId = this.generateProposalId();
514
+ const proposal = {
515
+ id: proposalId,
516
+ sessionId,
517
+ proposerId: input.proposerId,
518
+ agentId: input.proposerId,
519
+ title: input.title,
520
+ description: input.description,
521
+ content: input.content,
522
+ priority: input.priority ?? 0,
523
+ status: "submitted",
524
+ submittedAt: Date.now(),
525
+ metadata: input.metadata || {}
526
+ };
527
+ session.proposals.push(proposal);
528
+ session.lastActivityAt = Date.now();
529
+ this.audit("proposal_submitted", sessionId, input.proposerId, {
530
+ proposalId,
531
+ title: input.title
532
+ });
533
+ await this.emit("proposalSubmitted", { session, proposal });
534
+ return proposal;
535
+ }
536
+ /**
537
+ * Cast a vote in a session
538
+ */
539
+ async vote(sessionId, input) {
540
+ const session = this.getSession(sessionId);
541
+ this.validateSessionOpen(session);
542
+ this.validateParticipant(session, input.agentId);
543
+ this.validateNotDuplicate(session, input.agentId);
544
+ const mechanism = session.config.mechanism || session.config.votingMechanism || "majority";
545
+ const handler = getVotingHandler(mechanism);
546
+ const vote = {
547
+ id: this.generateVoteId(),
548
+ sessionId,
549
+ agentId: input.agentId,
550
+ ranking: input.ranking || [],
551
+ approvals: input.approvals,
552
+ weight: input.weight ?? getTrustWeight("local"),
553
+ justification: input.justification,
554
+ abstain: input.abstain ?? false,
555
+ timestamp: Date.now()
556
+ };
557
+ if (!vote.abstain && !handler.validateVote(vote, session.proposals)) {
558
+ throw new Error(
559
+ `Invalid vote: ranking must reference valid proposal IDs for mechanism '${mechanism}'`
560
+ );
561
+ }
562
+ session.votes.push(vote);
563
+ this.audit("vote_cast", sessionId, input.agentId, {
564
+ voteId: vote.id,
565
+ abstain: vote.abstain
566
+ });
567
+ await this.emit("voteReceived", { session, vote });
568
+ if (this.allVotesCast(session)) {
569
+ await this.tryAutoResolve(session);
570
+ }
571
+ return vote;
572
+ }
573
+ /**
574
+ * Resolve a negotiation session
575
+ */
576
+ async resolve(sessionId, force = false) {
577
+ const session = this.getSession(sessionId);
578
+ if (session.status !== "open" && session.status !== "voting") {
579
+ if (session.resolution) {
580
+ return session.resolution;
581
+ }
582
+ throw new Error(`Session ${sessionId} is ${session.status}, cannot resolve`);
583
+ }
584
+ const mechanism = session.config.mechanism || session.config.votingMechanism || "majority";
585
+ if (!force) {
586
+ const quorumMet = checkQuorum(
587
+ session.votes,
588
+ session.participants.length,
589
+ session.config,
590
+ mechanism
591
+ );
592
+ if (!quorumMet) {
593
+ return this.createFailedResolution(session, "quorum_not_met");
594
+ }
595
+ }
596
+ const handler = getVotingHandler(mechanism);
597
+ const result = handler.count(
598
+ session.votes.filter((v) => !v.abstain),
599
+ session.proposals,
600
+ session.config,
601
+ session.round || session.currentRound || 1
602
+ );
603
+ const resolution = this.buildResolution(session, result);
604
+ session.status = resolution.outcome === "deadlock" ? "deadlock" : "resolved";
605
+ session.resolution = resolution;
606
+ session.resolvedAt = Date.now();
607
+ this.clearDeadline(sessionId);
608
+ this.audit("resolved", sessionId, void 0, {
609
+ outcome: resolution.outcome,
610
+ winnerId: resolution.winnerId
611
+ });
612
+ await this.emit("sessionResolved", { session, resolution });
613
+ return resolution;
614
+ }
615
+ /**
616
+ * Get session by ID
617
+ */
618
+ getSession(sessionId) {
619
+ const session = this.sessions.get(sessionId);
620
+ if (!session) {
621
+ throw new Error(`Negotiation session not found: ${sessionId}`);
622
+ }
623
+ return session;
624
+ }
625
+ /**
626
+ * Get all active sessions
627
+ */
628
+ getActiveSessions() {
629
+ return Array.from(this.sessions.values()).filter(
630
+ (s) => s.status === "open" || s.status === "voting"
631
+ );
632
+ }
633
+ /**
634
+ * Get sessions for a specific agent
635
+ */
636
+ getAgentSessions(agentId) {
637
+ return Array.from(this.sessions.values()).filter((s) => s.participants.includes(agentId));
638
+ }
639
+ /**
640
+ * Cancel a session
641
+ */
642
+ async cancel(sessionId, _reason) {
643
+ const session = this.getSession(sessionId);
644
+ if (session.status === "resolved" || session.status === "cancelled") {
645
+ return;
646
+ }
647
+ session.status = "cancelled";
648
+ const mechanism = session.config.mechanism || session.config.votingMechanism || "majority";
649
+ session.resolution = {
650
+ sessionId,
651
+ outcome: "cancelled",
652
+ tallies: [],
653
+ finalTallies: [],
654
+ mechanism,
655
+ rounds: session.round || 1,
656
+ resolvedAt: Date.now(),
657
+ participationRate: session.votes.length / session.participants.length,
658
+ timestamp: Date.now()
659
+ };
660
+ this.clearDeadline(sessionId);
661
+ await this.emit("sessionResolved", {
662
+ session,
663
+ resolution: session.resolution
664
+ });
665
+ }
666
+ /**
667
+ * Escalate a deadlocked session
668
+ */
669
+ async escalate(sessionId) {
670
+ const session = this.getSession(sessionId);
671
+ if (!session.config.escalationPath) {
672
+ throw new Error(`No escalation path configured for session ${sessionId}`);
673
+ }
674
+ session.status = "escalated";
675
+ this.audit("escalated", sessionId, void 0, {
676
+ escalationPath: session.config.escalationPath
677
+ });
678
+ const mechanism = session.config.mechanism || session.config.votingMechanism || "majority";
679
+ const resolution = {
680
+ sessionId,
681
+ outcome: "escalated",
682
+ tallies: session.resolution?.tallies || [],
683
+ finalTallies: session.resolution?.finalTallies || [],
684
+ mechanism,
685
+ rounds: session.round || 1,
686
+ resolvedAt: Date.now(),
687
+ participationRate: session.votes.length / session.participants.length,
688
+ timestamp: Date.now(),
689
+ escalatedTo: session.config.escalationPath
690
+ };
691
+ session.resolution = resolution;
692
+ await this.emit("sessionResolved", { session, resolution });
693
+ return resolution;
694
+ }
695
+ /**
696
+ * Add a participant to an open session
697
+ */
698
+ addParticipant(sessionId, agentId) {
699
+ const session = this.getSession(sessionId);
700
+ if (session.status !== "open") {
701
+ throw new Error("Cannot add participant to non-open session");
702
+ }
703
+ if (!session.participants.includes(agentId)) {
704
+ session.participants.push(agentId);
705
+ }
706
+ }
707
+ /**
708
+ * Remove a participant from a session
709
+ */
710
+ removeParticipant(sessionId, agentId) {
711
+ const session = this.getSession(sessionId);
712
+ if (session.status !== "open") {
713
+ throw new Error("Cannot remove participant from non-open session");
714
+ }
715
+ session.participants = session.participants.filter((p) => p !== agentId);
716
+ }
717
+ /**
718
+ * Subscribe to negotiation events
719
+ */
720
+ on(event, handler) {
721
+ if (!this.eventHandlers.has(event)) {
722
+ this.eventHandlers.set(event, /* @__PURE__ */ new Set());
723
+ }
724
+ this.eventHandlers.get(event).add(handler);
725
+ return () => {
726
+ this.eventHandlers.get(event)?.delete(handler);
727
+ };
728
+ }
729
+ /**
730
+ * Get audit log
731
+ */
732
+ getAuditLog(sessionId) {
733
+ if (sessionId) {
734
+ return this.auditLog.filter((e) => e.sessionId === sessionId);
735
+ }
736
+ return [...this.auditLog];
737
+ }
738
+ /**
739
+ * Clear completed sessions older than maxAge
740
+ */
741
+ pruneOldSessions(maxAgeMs) {
742
+ const cutoff = Date.now() - maxAgeMs;
743
+ let pruned = 0;
744
+ for (const [id, session] of this.sessions) {
745
+ const sessionTime = session.resolvedAt || session.createdAt || session.startedAt || 0;
746
+ if ((session.status === "resolved" || session.status === "cancelled") && sessionTime < cutoff) {
747
+ this.sessions.delete(id);
748
+ pruned++;
749
+ }
750
+ }
751
+ return pruned;
752
+ }
753
+ /**
754
+ * Reset protocol state (for testing)
755
+ */
756
+ reset() {
757
+ for (const deadline of this.deadlines.values()) {
758
+ clearTimeout(deadline.timer);
759
+ }
760
+ this.sessions.clear();
761
+ this.auditLog = [];
762
+ this.deadlines.clear();
763
+ this.eventHandlers.clear();
764
+ this.sessionCounter = 0;
765
+ this.proposalCounter = 0;
766
+ this.voteCounter = 0;
767
+ }
768
+ // ===========================================================================
769
+ // PRIVATE METHODS
770
+ // ===========================================================================
771
+ generateSessionId() {
772
+ return `neg-${Date.now()}-${++this.sessionCounter}`;
773
+ }
774
+ generateProposalId() {
775
+ return `prop-${Date.now()}-${++this.proposalCounter}`;
776
+ }
777
+ generateVoteId() {
778
+ return `vote-${Date.now()}-${++this.voteCounter}`;
779
+ }
780
+ validateSessionOpen(session) {
781
+ if (session.status !== "open" && session.status !== "voting") {
782
+ throw new Error(`Session ${session.id} is ${session.status}, not accepting input`);
783
+ }
784
+ }
785
+ validateParticipant(session, agentId) {
786
+ if (!session.participants.includes(agentId)) {
787
+ throw new Error(`Agent ${agentId} is not a participant in session ${session.id}`);
788
+ }
789
+ }
790
+ validateNotDuplicate(session, agentId) {
791
+ const roundVotes = session.votes.filter((v) => v.agentId === agentId && !v.supersededBy);
792
+ if (roundVotes.length > 0) {
793
+ throw new Error(`Agent ${agentId} has already voted in this round of session ${session.id}`);
794
+ }
795
+ }
796
+ allVotesCast(session) {
797
+ const voted = new Set(session.votes.map((v) => v.agentId));
798
+ return session.participants.every((p) => {
799
+ const participantId = typeof p === "string" ? p : p.id;
800
+ return voted.has(participantId);
801
+ });
802
+ }
803
+ async tryAutoResolve(session) {
804
+ if (session.status === "open" && session.proposals.length > 0) {
805
+ session.status = "voting";
806
+ }
807
+ if (this.allVotesCast(session)) {
808
+ await this.resolve(session.id);
809
+ }
810
+ }
811
+ buildResolution(session, result) {
812
+ const winningProposal = result.winnerId ? session.proposals.find((p) => p.id === result.winnerId) : void 0;
813
+ const mechanism = session.config.mechanism || session.config.votingMechanism || "majority";
814
+ const resolvedAt = Date.now();
815
+ return {
816
+ sessionId: session.id,
817
+ outcome: result.outcome,
818
+ winnerId: result.winnerId,
819
+ winner: winningProposal,
820
+ winningProposal,
821
+ tallies: result.tallies,
822
+ finalTallies: result.tallies,
823
+ mechanism,
824
+ rounds: session.round || 1,
825
+ round: session.round || session.currentRound,
826
+ resolvedAt,
827
+ consensusLevel: result.consensusLevel,
828
+ dissenters: result.dissenters,
829
+ participationRate: session.votes.length / session.participants.length,
830
+ timestamp: resolvedAt
831
+ };
832
+ }
833
+ createFailedResolution(session, outcome) {
834
+ session.status = outcome === "timeout" ? "timeout" : "deadlock";
835
+ const mechanism = session.config.mechanism || session.config.votingMechanism || "majority";
836
+ const resolvedAt = Date.now();
837
+ const resolution = {
838
+ sessionId: session.id,
839
+ outcome,
840
+ tallies: [],
841
+ finalTallies: [],
842
+ mechanism,
843
+ rounds: session.round || 1,
844
+ resolvedAt,
845
+ participationRate: session.votes.length / session.participants.length,
846
+ timestamp: resolvedAt
847
+ };
848
+ session.resolution = resolution;
849
+ this.clearDeadline(session.id);
850
+ return resolution;
851
+ }
852
+ startDeadlineTimer(session) {
853
+ const timeout = session.config.timeout || session.config.votingDeadline || 6e4;
854
+ const timer = setTimeout(async () => {
855
+ if (session.status === "open" || session.status === "voting") {
856
+ this.audit("timeout", session.id, void 0, {
857
+ deadline: session.deadline
858
+ });
859
+ await this.handleTimeout(session);
860
+ }
861
+ }, timeout);
862
+ this.deadlines.set(session.id, { sessionId: session.id, timer });
863
+ }
864
+ async handleTimeout(session) {
865
+ if (session.votes.length > 0) {
866
+ try {
867
+ await this.resolve(session.id, true);
868
+ return;
869
+ } catch {
870
+ }
871
+ }
872
+ const resolution = this.createFailedResolution(session, "timeout");
873
+ await this.emit("sessionResolved", { session, resolution });
874
+ }
875
+ clearDeadline(sessionId) {
876
+ const deadline = this.deadlines.get(sessionId);
877
+ if (deadline) {
878
+ clearTimeout(deadline.timer);
879
+ this.deadlines.delete(sessionId);
880
+ }
881
+ }
882
+ audit(action, sessionId, agentId, details) {
883
+ this.auditLog.push({
884
+ timestamp: Date.now(),
885
+ sessionId,
886
+ action,
887
+ agentId,
888
+ details
889
+ });
890
+ }
891
+ async emit(event, data) {
892
+ const handlers = this.eventHandlers.get(event);
893
+ if (handlers) {
894
+ for (const handler of handlers) {
895
+ try {
896
+ await handler(data);
897
+ } catch (err) {
898
+ console.error(`Error in negotiation event handler for ${event}:`, err);
899
+ }
900
+ }
901
+ }
902
+ }
903
+ };
904
+ var defaultProtocol = null;
905
+ function getNegotiationProtocol() {
906
+ if (!defaultProtocol) {
907
+ defaultProtocol = new NegotiationProtocol();
908
+ }
909
+ return defaultProtocol;
910
+ }
911
+ function resetNegotiationProtocol() {
912
+ if (defaultProtocol) {
913
+ defaultProtocol.reset();
914
+ defaultProtocol = null;
915
+ }
916
+ }
917
+ export {
918
+ NegotiationProtocol,
919
+ approvalHandler,
920
+ bordaHandler,
921
+ checkQuorum,
922
+ consensusHandler,
923
+ getNegotiationProtocol,
924
+ getTrustWeight,
925
+ getVotingHandler,
926
+ majorityHandler,
927
+ rankedHandler,
928
+ resetNegotiationProtocol,
929
+ supermajorityHandler,
930
+ weightedHandler
931
+ };