@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,694 @@
1
+ /**
2
+ * @holoscript/core - Negotiation Protocol
3
+ *
4
+ * Core protocol for multi-agent negotiation and consensus building.
5
+ * Manages negotiation sessions, proposals, voting, and resolution.
6
+ *
7
+ * Part of HoloScript v3.1 Agentic Choreography.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const protocol = new NegotiationProtocol();
12
+ *
13
+ * // Start a negotiation
14
+ * const session = await protocol.initiate({
15
+ * topic: 'task-assignment',
16
+ * participants: ['agent-1', 'agent-2', 'agent-3'],
17
+ * votingMechanism: 'majority',
18
+ * timeout: 60000,
19
+ * });
20
+ *
21
+ * // Submit proposals
22
+ * await protocol.propose(session.id, {
23
+ * proposerId: 'agent-1',
24
+ * title: 'Process sequentially',
25
+ * description: 'Handle tasks one at a time',
26
+ * content: { strategy: 'sequential' },
27
+ * });
28
+ *
29
+ * // Vote on proposals
30
+ * await protocol.vote(session.id, {
31
+ * agentId: 'agent-2',
32
+ * ranking: ['proposal-1'],
33
+ * });
34
+ *
35
+ * // Resolve when ready
36
+ * const resolution = await protocol.resolve(session.id);
37
+ * ```
38
+ *
39
+ * @version 3.1.0
40
+ * @Sprint v3.1 (March 2026)
41
+ */
42
+
43
+ import type {
44
+ NegotiationSession,
45
+ NegotiationConfig,
46
+ Proposal,
47
+ Vote,
48
+ Resolution,
49
+ ResolutionOutcome,
50
+ NegotiationEvents,
51
+ ProposalInput,
52
+ VoteInput,
53
+ InitiateOptions,
54
+ } from './NegotiationTypes';
55
+
56
+ import {
57
+ getVotingHandler,
58
+ checkQuorum,
59
+ getTrustWeight,
60
+ type VotingResult,
61
+ } from './VotingMechanisms';
62
+
63
+ // =============================================================================
64
+ // TYPES
65
+ // =============================================================================
66
+
67
+ /**
68
+ * Audit log entry
69
+ */
70
+ export interface AuditEntry {
71
+ timestamp: number;
72
+ sessionId: string;
73
+ action: 'initiated' | 'proposal_submitted' | 'vote_cast' | 'resolved' | 'timeout' | 'escalated';
74
+ agentId?: string;
75
+ details: Record<string, unknown>;
76
+ }
77
+
78
+ /**
79
+ * Session deadline info
80
+ */
81
+ interface DeadlineInfo {
82
+ sessionId: string;
83
+ timer: ReturnType<typeof setTimeout>;
84
+ }
85
+
86
+ /**
87
+ * Event handler type
88
+ */
89
+ type EventHandler<T> = (data: T) => void | Promise<void>;
90
+
91
+ // =============================================================================
92
+ // NEGOTIATION PROTOCOL
93
+ // =============================================================================
94
+
95
+ /**
96
+ * NegotiationProtocol manages multi-agent negotiation sessions.
97
+ *
98
+ * Features:
99
+ * - Multiple voting mechanisms (majority, consensus, ranked, etc.)
100
+ * - Proposal lifecycle management
101
+ * - Quorum and deadline enforcement
102
+ * - Deadlock detection and escalation
103
+ * - Full audit logging
104
+ */
105
+ export class NegotiationProtocol {
106
+ private sessions: Map<string, NegotiationSession> = new Map();
107
+ private auditLog: AuditEntry[] = [];
108
+ private deadlines: Map<string, DeadlineInfo> = new Map();
109
+ private eventHandlers: Map<keyof NegotiationEvents, Set<EventHandler<any>>> = new Map();
110
+ private sessionCounter = 0;
111
+ private proposalCounter = 0;
112
+ private voteCounter = 0;
113
+
114
+ // ===========================================================================
115
+ // PUBLIC API
116
+ // ===========================================================================
117
+
118
+ /**
119
+ * Initiate a new negotiation session
120
+ */
121
+ async initiate(options: InitiateOptions): Promise<NegotiationSession> {
122
+ const sessionId = this.generateSessionId();
123
+ const timeout = options.timeout ?? 60000;
124
+
125
+ const config: NegotiationConfig = {
126
+ mechanism: options.votingMechanism || 'majority',
127
+ votingMechanism: options.votingMechanism || 'majority',
128
+ quorum: options.quorum ?? 0.5,
129
+ timeout: timeout,
130
+ votingDeadline: timeout,
131
+ proposalDeadline: timeout,
132
+ maxRounds: options.maxRounds ?? 3,
133
+ allowAbstain: options.allowAbstain ?? true,
134
+ requireJustification: options.requireJustification ?? false,
135
+ tieBreaker: options.tieBreaker ?? 'random',
136
+ escalationPath: options.escalationPath,
137
+ };
138
+
139
+ const now = Date.now();
140
+ const session: NegotiationSession = {
141
+ id: sessionId,
142
+ topic: options.topic,
143
+ description: options.description,
144
+ participants: [...options.participants],
145
+ status: 'open',
146
+ proposals: [],
147
+ votes: [],
148
+ config,
149
+ round: 1,
150
+ currentRound: 1,
151
+ createdAt: now,
152
+ startedAt: now,
153
+ lastActivityAt: now,
154
+ deadline: now + timeout,
155
+ history: [],
156
+ metadata: options.metadata || {},
157
+ };
158
+
159
+ this.sessions.set(sessionId, session);
160
+ this.startDeadlineTimer(session);
161
+ this.audit('initiated', sessionId, undefined, {
162
+ topic: options.topic,
163
+ participants: options.participants,
164
+ config,
165
+ });
166
+
167
+ await this.emit('sessionStarted', { session });
168
+
169
+ return session;
170
+ }
171
+
172
+ /**
173
+ * Submit a proposal to a session
174
+ */
175
+ async propose(sessionId: string, input: ProposalInput): Promise<Proposal> {
176
+ const session = this.getSession(sessionId);
177
+ this.validateSessionOpen(session);
178
+ this.validateParticipant(session, input.proposerId);
179
+
180
+ const proposalId = this.generateProposalId();
181
+
182
+ const proposal: Proposal = {
183
+ id: proposalId,
184
+ sessionId,
185
+ proposerId: input.proposerId,
186
+ agentId: input.proposerId,
187
+ title: input.title,
188
+ description: input.description,
189
+ content: input.content,
190
+ priority: input.priority ?? 0,
191
+ status: 'submitted',
192
+ submittedAt: Date.now(),
193
+ metadata: input.metadata || {},
194
+ };
195
+
196
+ session.proposals.push(proposal);
197
+ session.lastActivityAt = Date.now();
198
+ this.audit('proposal_submitted', sessionId, input.proposerId, {
199
+ proposalId,
200
+ title: input.title,
201
+ });
202
+
203
+ await this.emit('proposalSubmitted', { session, proposal });
204
+
205
+ return proposal;
206
+ }
207
+
208
+ /**
209
+ * Cast a vote in a session
210
+ */
211
+ async vote(sessionId: string, input: VoteInput): Promise<Vote> {
212
+ const session = this.getSession(sessionId);
213
+ this.validateSessionOpen(session);
214
+ this.validateParticipant(session, input.agentId);
215
+ this.validateNotDuplicate(session, input.agentId);
216
+
217
+ const mechanism = session.config.mechanism || session.config.votingMechanism || 'majority';
218
+ const handler = getVotingHandler(mechanism);
219
+
220
+ // Create vote structure
221
+ const vote: Vote = {
222
+ id: this.generateVoteId(),
223
+ sessionId,
224
+ agentId: input.agentId,
225
+ ranking: input.ranking || [],
226
+ approvals: input.approvals,
227
+ weight: input.weight ?? getTrustWeight('local'),
228
+ justification: input.justification,
229
+ abstain: input.abstain ?? false,
230
+ timestamp: Date.now(),
231
+ };
232
+
233
+ // Validate vote if not abstaining
234
+ if (!vote.abstain && !handler.validateVote(vote, session.proposals)) {
235
+ throw new Error(
236
+ `Invalid vote: ranking must reference valid proposal IDs for mechanism '${mechanism}'`
237
+ );
238
+ }
239
+
240
+ session.votes.push(vote);
241
+ this.audit('vote_cast', sessionId, input.agentId, {
242
+ voteId: vote.id,
243
+ abstain: vote.abstain,
244
+ });
245
+
246
+ await this.emit('voteReceived', { session, vote });
247
+
248
+ // Check if all participants have voted
249
+ if (this.allVotesCast(session)) {
250
+ await this.tryAutoResolve(session);
251
+ }
252
+
253
+ return vote;
254
+ }
255
+
256
+ /**
257
+ * Resolve a negotiation session
258
+ */
259
+ async resolve(sessionId: string, force = false): Promise<Resolution> {
260
+ const session = this.getSession(sessionId);
261
+
262
+ if (session.status !== 'open' && session.status !== 'voting') {
263
+ if (session.resolution) {
264
+ return session.resolution;
265
+ }
266
+ throw new Error(`Session ${sessionId} is ${session.status}, cannot resolve`);
267
+ }
268
+
269
+ // Check quorum unless forced
270
+ const mechanism = session.config.mechanism || session.config.votingMechanism || 'majority';
271
+ if (!force) {
272
+ const quorumMet = checkQuorum(
273
+ session.votes,
274
+ session.participants.length,
275
+ session.config,
276
+ mechanism
277
+ );
278
+
279
+ if (!quorumMet) {
280
+ return this.createFailedResolution(session, 'quorum_not_met');
281
+ }
282
+ }
283
+
284
+ // Count votes
285
+ const handler = getVotingHandler(mechanism);
286
+ const result = handler.count(
287
+ session.votes.filter((v) => !v.abstain),
288
+ session.proposals,
289
+ session.config,
290
+ session.round || session.currentRound || 1
291
+ );
292
+
293
+ const resolution = this.buildResolution(session, result);
294
+
295
+ // Update session
296
+ session.status = resolution.outcome === 'deadlock' ? 'deadlock' : 'resolved';
297
+ session.resolution = resolution;
298
+ session.resolvedAt = Date.now();
299
+
300
+ this.clearDeadline(sessionId);
301
+ this.audit('resolved', sessionId, undefined, {
302
+ outcome: resolution.outcome,
303
+ winnerId: resolution.winnerId,
304
+ });
305
+
306
+ await this.emit('sessionResolved', { session, resolution });
307
+
308
+ return resolution;
309
+ }
310
+
311
+ /**
312
+ * Get session by ID
313
+ */
314
+ getSession(sessionId: string): NegotiationSession {
315
+ const session = this.sessions.get(sessionId);
316
+ if (!session) {
317
+ throw new Error(`Negotiation session not found: ${sessionId}`);
318
+ }
319
+ return session;
320
+ }
321
+
322
+ /**
323
+ * Get all active sessions
324
+ */
325
+ getActiveSessions(): NegotiationSession[] {
326
+ return Array.from(this.sessions.values()).filter(
327
+ (s) => s.status === 'open' || s.status === 'voting'
328
+ );
329
+ }
330
+
331
+ /**
332
+ * Get sessions for a specific agent
333
+ */
334
+ getAgentSessions(agentId: string): NegotiationSession[] {
335
+ return Array.from(this.sessions.values()).filter((s) => s.participants.includes(agentId));
336
+ }
337
+
338
+ /**
339
+ * Cancel a session
340
+ */
341
+ async cancel(sessionId: string, _reason?: string): Promise<void> {
342
+ const session = this.getSession(sessionId);
343
+
344
+ if (session.status === 'resolved' || session.status === 'cancelled') {
345
+ return;
346
+ }
347
+
348
+ session.status = 'cancelled';
349
+ const mechanism = session.config.mechanism || session.config.votingMechanism || 'majority';
350
+ session.resolution = {
351
+ sessionId,
352
+ outcome: 'cancelled',
353
+ tallies: [],
354
+ finalTallies: [],
355
+ mechanism,
356
+ rounds: session.round || 1,
357
+ resolvedAt: Date.now(),
358
+ participationRate: session.votes.length / session.participants.length,
359
+ timestamp: Date.now(),
360
+ };
361
+
362
+ this.clearDeadline(sessionId);
363
+ await this.emit('sessionResolved', {
364
+ session,
365
+ resolution: session.resolution,
366
+ });
367
+ }
368
+
369
+ /**
370
+ * Escalate a deadlocked session
371
+ */
372
+ async escalate(sessionId: string): Promise<Resolution> {
373
+ const session = this.getSession(sessionId);
374
+
375
+ if (!session.config.escalationPath) {
376
+ throw new Error(`No escalation path configured for session ${sessionId}`);
377
+ }
378
+
379
+ session.status = 'escalated';
380
+ this.audit('escalated', sessionId, undefined, {
381
+ escalationPath: session.config.escalationPath,
382
+ });
383
+
384
+ const mechanism = session.config.mechanism || session.config.votingMechanism || 'majority';
385
+ const resolution: Resolution = {
386
+ sessionId,
387
+ outcome: 'escalated',
388
+ tallies: session.resolution?.tallies || [],
389
+ finalTallies: session.resolution?.finalTallies || [],
390
+ mechanism,
391
+ rounds: session.round || 1,
392
+ resolvedAt: Date.now(),
393
+ participationRate: session.votes.length / session.participants.length,
394
+ timestamp: Date.now(),
395
+ escalatedTo: session.config.escalationPath,
396
+ };
397
+
398
+ session.resolution = resolution;
399
+ await this.emit('sessionResolved', { session, resolution });
400
+
401
+ return resolution;
402
+ }
403
+
404
+ /**
405
+ * Add a participant to an open session
406
+ */
407
+ addParticipant(sessionId: string, agentId: string): void {
408
+ const session = this.getSession(sessionId);
409
+ if (session.status !== 'open') {
410
+ throw new Error('Cannot add participant to non-open session');
411
+ }
412
+ if (!session.participants.includes(agentId)) {
413
+ session.participants.push(agentId);
414
+ }
415
+ }
416
+
417
+ /**
418
+ * Remove a participant from a session
419
+ */
420
+ removeParticipant(sessionId: string, agentId: string): void {
421
+ const session = this.getSession(sessionId);
422
+ if (session.status !== 'open') {
423
+ throw new Error('Cannot remove participant from non-open session');
424
+ }
425
+ session.participants = session.participants.filter((p) => p !== agentId);
426
+ }
427
+
428
+ /**
429
+ * Subscribe to negotiation events
430
+ */
431
+ on<K extends keyof NegotiationEvents>(
432
+ event: K,
433
+ handler: EventHandler<NegotiationEvents[K]>
434
+ ): () => void {
435
+ if (!this.eventHandlers.has(event)) {
436
+ this.eventHandlers.set(event, new Set());
437
+ }
438
+ this.eventHandlers.get(event)!.add(handler);
439
+
440
+ return () => {
441
+ this.eventHandlers.get(event)?.delete(handler);
442
+ };
443
+ }
444
+
445
+ /**
446
+ * Get audit log
447
+ */
448
+ getAuditLog(sessionId?: string): AuditEntry[] {
449
+ if (sessionId) {
450
+ return this.auditLog.filter((e) => e.sessionId === sessionId);
451
+ }
452
+ return [...this.auditLog];
453
+ }
454
+
455
+ /**
456
+ * Clear completed sessions older than maxAge
457
+ */
458
+ pruneOldSessions(maxAgeMs: number): number {
459
+ const cutoff = Date.now() - maxAgeMs;
460
+ let pruned = 0;
461
+
462
+ for (const [id, session] of this.sessions) {
463
+ const sessionTime = session.resolvedAt || session.createdAt || session.startedAt || 0;
464
+ if (
465
+ (session.status === 'resolved' || session.status === 'cancelled') &&
466
+ sessionTime < cutoff
467
+ ) {
468
+ this.sessions.delete(id);
469
+ pruned++;
470
+ }
471
+ }
472
+
473
+ return pruned;
474
+ }
475
+
476
+ /**
477
+ * Reset protocol state (for testing)
478
+ */
479
+ reset(): void {
480
+ for (const deadline of this.deadlines.values()) {
481
+ clearTimeout(deadline.timer);
482
+ }
483
+ this.sessions.clear();
484
+ this.auditLog = [];
485
+ this.deadlines.clear();
486
+ this.eventHandlers.clear();
487
+ this.sessionCounter = 0;
488
+ this.proposalCounter = 0;
489
+ this.voteCounter = 0;
490
+ }
491
+
492
+ // ===========================================================================
493
+ // PRIVATE METHODS
494
+ // ===========================================================================
495
+
496
+ private generateSessionId(): string {
497
+ return `neg-${Date.now()}-${++this.sessionCounter}`;
498
+ }
499
+
500
+ private generateProposalId(): string {
501
+ return `prop-${Date.now()}-${++this.proposalCounter}`;
502
+ }
503
+
504
+ private generateVoteId(): string {
505
+ return `vote-${Date.now()}-${++this.voteCounter}`;
506
+ }
507
+
508
+ private validateSessionOpen(session: NegotiationSession): void {
509
+ if (session.status !== 'open' && session.status !== 'voting') {
510
+ throw new Error(`Session ${session.id} is ${session.status}, not accepting input`);
511
+ }
512
+ }
513
+
514
+ private validateParticipant(session: NegotiationSession, agentId: string): void {
515
+ if (!session.participants.includes(agentId)) {
516
+ throw new Error(`Agent ${agentId} is not a participant in session ${session.id}`);
517
+ }
518
+ }
519
+
520
+ private validateNotDuplicate(session: NegotiationSession, agentId: string): void {
521
+ const roundVotes = session.votes.filter((v) => v.agentId === agentId && !v.supersededBy);
522
+ if (roundVotes.length > 0) {
523
+ throw new Error(`Agent ${agentId} has already voted in this round of session ${session.id}`);
524
+ }
525
+ }
526
+
527
+ private allVotesCast(session: NegotiationSession): boolean {
528
+ const voted = new Set(session.votes.map((v) => v.agentId));
529
+ return session.participants.every((p) => {
530
+ const participantId = typeof p === 'string' ? p : p.id;
531
+ return voted.has(participantId);
532
+ });
533
+ }
534
+
535
+ private async tryAutoResolve(session: NegotiationSession): Promise<void> {
536
+ // Transition to voting if proposals exist
537
+ if (session.status === 'open' && session.proposals.length > 0) {
538
+ session.status = 'voting';
539
+ }
540
+
541
+ // Auto-resolve if all have voted
542
+ if (this.allVotesCast(session)) {
543
+ await this.resolve(session.id);
544
+ }
545
+ }
546
+
547
+ private buildResolution(session: NegotiationSession, result: VotingResult): Resolution {
548
+ const winningProposal = result.winnerId
549
+ ? session.proposals.find((p) => p.id === result.winnerId)
550
+ : undefined;
551
+
552
+ const mechanism = session.config.mechanism || session.config.votingMechanism || 'majority';
553
+ const resolvedAt = Date.now();
554
+
555
+ return {
556
+ sessionId: session.id,
557
+ outcome: result.outcome,
558
+ winnerId: result.winnerId,
559
+ winner: winningProposal,
560
+ winningProposal,
561
+ tallies: result.tallies,
562
+ finalTallies: result.tallies,
563
+ mechanism,
564
+ rounds: session.round || 1,
565
+ round: session.round || session.currentRound,
566
+ resolvedAt,
567
+ consensusLevel: result.consensusLevel,
568
+ dissenters: result.dissenters,
569
+ participationRate: session.votes.length / session.participants.length,
570
+ timestamp: resolvedAt,
571
+ };
572
+ }
573
+
574
+ private createFailedResolution(
575
+ session: NegotiationSession,
576
+ outcome: ResolutionOutcome
577
+ ): Resolution {
578
+ session.status = outcome === 'timeout' ? 'timeout' : 'deadlock';
579
+
580
+ const mechanism = session.config.mechanism || session.config.votingMechanism || 'majority';
581
+ const resolvedAt = Date.now();
582
+
583
+ const resolution: Resolution = {
584
+ sessionId: session.id,
585
+ outcome,
586
+ tallies: [],
587
+ finalTallies: [],
588
+ mechanism,
589
+ rounds: session.round || 1,
590
+ resolvedAt,
591
+ participationRate: session.votes.length / session.participants.length,
592
+ timestamp: resolvedAt,
593
+ };
594
+
595
+ session.resolution = resolution;
596
+ this.clearDeadline(session.id);
597
+
598
+ return resolution;
599
+ }
600
+
601
+ private startDeadlineTimer(session: NegotiationSession): void {
602
+ const timeout = session.config.timeout || session.config.votingDeadline || 60000;
603
+ const timer = setTimeout(async () => {
604
+ if (session.status === 'open' || session.status === 'voting') {
605
+ this.audit('timeout', session.id, undefined, {
606
+ deadline: session.deadline,
607
+ });
608
+ await this.handleTimeout(session);
609
+ }
610
+ }, timeout);
611
+
612
+ this.deadlines.set(session.id, { sessionId: session.id, timer });
613
+ }
614
+
615
+ private async handleTimeout(session: NegotiationSession): Promise<void> {
616
+ // Try to resolve with current votes
617
+ if (session.votes.length > 0) {
618
+ try {
619
+ await this.resolve(session.id, true);
620
+ return;
621
+ } catch {
622
+ // Fall through to timeout
623
+ }
624
+ }
625
+
626
+ const resolution = this.createFailedResolution(session, 'timeout');
627
+ await this.emit('sessionResolved', { session, resolution });
628
+ }
629
+
630
+ private clearDeadline(sessionId: string): void {
631
+ const deadline = this.deadlines.get(sessionId);
632
+ if (deadline) {
633
+ clearTimeout(deadline.timer);
634
+ this.deadlines.delete(sessionId);
635
+ }
636
+ }
637
+
638
+ private audit(
639
+ action: AuditEntry['action'],
640
+ sessionId: string,
641
+ agentId: string | undefined,
642
+ details: Record<string, unknown>
643
+ ): void {
644
+ this.auditLog.push({
645
+ timestamp: Date.now(),
646
+ sessionId,
647
+ action,
648
+ agentId,
649
+ details,
650
+ });
651
+ }
652
+
653
+ private async emit<K extends keyof NegotiationEvents>(
654
+ event: K,
655
+ data: NegotiationEvents[K]
656
+ ): Promise<void> {
657
+ const handlers = this.eventHandlers.get(event);
658
+ if (handlers) {
659
+ for (const handler of handlers) {
660
+ try {
661
+ await handler(data);
662
+ } catch (err) {
663
+ console.error(`Error in negotiation event handler for ${event}:`, err);
664
+ }
665
+ }
666
+ }
667
+ }
668
+ }
669
+
670
+ // =============================================================================
671
+ // SINGLETON INSTANCE
672
+ // =============================================================================
673
+
674
+ let defaultProtocol: NegotiationProtocol | null = null;
675
+
676
+ /**
677
+ * Get the default NegotiationProtocol instance
678
+ */
679
+ export function getNegotiationProtocol(): NegotiationProtocol {
680
+ if (!defaultProtocol) {
681
+ defaultProtocol = new NegotiationProtocol();
682
+ }
683
+ return defaultProtocol;
684
+ }
685
+
686
+ /**
687
+ * Reset the default protocol instance (for testing)
688
+ */
689
+ export function resetNegotiationProtocol(): void {
690
+ if (defaultProtocol) {
691
+ defaultProtocol.reset();
692
+ defaultProtocol = null;
693
+ }
694
+ }