@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,254 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { ProtocolAgent, runProtocolCycle } from '../protocol-agent';
3
+ import { ProtocolPhase } from '../protocol/implementations';
4
+ import type { AgentConfig } from '../types';
5
+
6
+ // ── Mock fetch globally ──
7
+
8
+ const mockFetchResponse = (content: string) => ({
9
+ ok: true,
10
+ json: async () => ({
11
+ content: [{ text: content }],
12
+ usage: { output_tokens: 10 },
13
+ }),
14
+ });
15
+
16
+ const mockOpenAIResponse = (content: string) => ({
17
+ ok: true,
18
+ json: async () => ({
19
+ choices: [{ message: { content } }],
20
+ usage: { completion_tokens: 10 },
21
+ }),
22
+ });
23
+
24
+ const testAgent: AgentConfig = {
25
+ name: 'TestAgent',
26
+ role: 'coder',
27
+ model: { provider: 'anthropic', model: 'claude-sonnet-4', apiKey: 'test-key' },
28
+ capabilities: ['code-generation', 'testing'],
29
+ claimFilter: { roles: ['coder'], maxPriority: 10 },
30
+ knowledgeDomains: ['typescript'],
31
+ };
32
+
33
+ describe('ProtocolAgent', () => {
34
+ let fetchSpy: ReturnType<typeof vi.fn>;
35
+
36
+ beforeEach(() => {
37
+ fetchSpy = vi.fn();
38
+ vi.stubGlobal('fetch', fetchSpy);
39
+ });
40
+
41
+ afterEach(() => {
42
+ vi.restoreAllMocks();
43
+ });
44
+
45
+ it('has correct identity from agent config', () => {
46
+ const agent = new ProtocolAgent(testAgent);
47
+ expect(agent.identity.name).toBe('TestAgent');
48
+ expect(agent.identity.domain).toBe('typescript');
49
+ expect(agent.identity.capabilities).toEqual(['code-generation', 'testing']);
50
+ });
51
+
52
+ it('intake phase gathers context without LLM call', async () => {
53
+ const agent = new ProtocolAgent(testAgent, 'some knowledge');
54
+ const result = await agent.intake({ task: 'Fix the bug' });
55
+
56
+ expect(result.phase).toBe(ProtocolPhase.INTAKE);
57
+ expect(result.status).toBe('success');
58
+ expect(fetchSpy).not.toHaveBeenCalled(); // no LLM call for intake
59
+
60
+ const data = result.data as Record<string, unknown>;
61
+ expect(data.task).toBe('Fix the bug');
62
+ expect(data.agent).toBe('TestAgent');
63
+ expect(data.knowledge).toBe('some knowledge');
64
+ });
65
+
66
+ it('reflect phase calls LLM with light model', async () => {
67
+ fetchSpy.mockResolvedValue(mockFetchResponse('Use TDD approach for this bug fix'));
68
+
69
+ const agent = new ProtocolAgent(testAgent);
70
+ const context = { task: 'Fix auth bug', role: 'coder', capabilities: ['code-generation'] };
71
+ const result = await agent.reflect(context);
72
+
73
+ expect(result.phase).toBe(ProtocolPhase.REFLECT);
74
+ expect(result.status).toBe('success');
75
+ expect(fetchSpy).toHaveBeenCalledTimes(1);
76
+
77
+ // Verify it used the light model (haiku)
78
+ const callBody = JSON.parse(fetchSpy.mock.calls[0][1].body);
79
+ expect(callBody.model).toBe('claude-haiku-4');
80
+ });
81
+
82
+ it('execute phase calls LLM with full model', async () => {
83
+ fetchSpy.mockResolvedValue(mockFetchResponse('Fixed the authentication bug by updating JWT validation'));
84
+
85
+ const agent = new ProtocolAgent(testAgent);
86
+ const plan = { plan: 'Use TDD', context: { task: 'Fix auth bug' } };
87
+ const result = await agent.execute(plan);
88
+
89
+ expect(result.phase).toBe(ProtocolPhase.EXECUTE);
90
+ expect(result.status).toBe('success');
91
+
92
+ // Verify it used the full model (sonnet)
93
+ const callBody = JSON.parse(fetchSpy.mock.calls[0][1].body);
94
+ expect(callBody.model).toBe('claude-sonnet-4');
95
+
96
+ const data = result.data as { output: string };
97
+ expect(data.output).toContain('authentication');
98
+ });
99
+
100
+ it('compress phase extracts knowledge items', async () => {
101
+ fetchSpy.mockResolvedValue(
102
+ mockFetchResponse(
103
+ '[wisdom] JWT tokens should be validated on every request\n' +
104
+ '[pattern] Use middleware for auth validation\n' +
105
+ '[gotcha] Never store refresh tokens in localStorage'
106
+ )
107
+ );
108
+
109
+ const agent = new ProtocolAgent(testAgent);
110
+ const result = await agent.compress({ output: 'Fixed JWT validation', task: 'Fix auth' });
111
+
112
+ expect(result.phase).toBe(ProtocolPhase.COMPRESS);
113
+ expect(result.status).toBe('success');
114
+
115
+ const data = result.data as { insights: Array<{ type: string; content: string }> };
116
+ expect(data.insights).toHaveLength(3);
117
+ expect(data.insights[0].type).toBe('wisdom');
118
+ expect(data.insights[1].type).toBe('pattern');
119
+ expect(data.insights[2].type).toBe('gotcha');
120
+ });
121
+
122
+ it('reintake phase skips LLM when no insights', async () => {
123
+ const agent = new ProtocolAgent(testAgent);
124
+ const result = await agent.reintake({ insights: [], rawOutput: 'some output' });
125
+
126
+ expect(result.phase).toBe(ProtocolPhase.REINTAKE);
127
+ expect(result.status).toBe('success');
128
+ expect(fetchSpy).not.toHaveBeenCalled();
129
+ });
130
+
131
+ it('grow phase skips LLM when no validated insights', async () => {
132
+ const agent = new ProtocolAgent(testAgent);
133
+ const result = await agent.grow({ validated: [], rawOutput: 'some output' });
134
+
135
+ expect(result.phase).toBe(ProtocolPhase.GROW);
136
+ expect(result.status).toBe('success');
137
+ expect(fetchSpy).not.toHaveBeenCalled();
138
+ });
139
+
140
+ it('evolve phase skips LLM when no validated insights', async () => {
141
+ const agent = new ProtocolAgent(testAgent);
142
+ const result = await agent.evolve({ patterns: '', validated: [] });
143
+
144
+ expect(result.phase).toBe(ProtocolPhase.EVOLVE);
145
+ expect(result.status).toBe('success');
146
+ expect(fetchSpy).not.toHaveBeenCalled();
147
+ });
148
+ });
149
+
150
+ describe('runProtocolCycle', () => {
151
+ let fetchSpy: ReturnType<typeof vi.fn>;
152
+
153
+ beforeEach(() => {
154
+ fetchSpy = vi.fn();
155
+ vi.stubGlobal('fetch', fetchSpy);
156
+ });
157
+
158
+ afterEach(() => {
159
+ vi.restoreAllMocks();
160
+ });
161
+
162
+ it('executes all 7 phases and returns structured result', async () => {
163
+ let callCount = 0;
164
+ fetchSpy.mockImplementation(async () => {
165
+ callCount++;
166
+ // Phase 1 (reflect): light model
167
+ if (callCount === 1) return mockFetchResponse('Approach: fix validation logic');
168
+ // Phase 2 (execute): full model
169
+ if (callCount === 2) return mockFetchResponse('SUMMARY: Fixed JWT validation\nDone.');
170
+ // Phase 3 (compress): extract knowledge
171
+ if (callCount === 3) return mockFetchResponse('[wisdom] Always validate token expiry\n[pattern] Use middleware for auth');
172
+ // Phase 4 (reintake): validate
173
+ if (callCount === 4) return mockFetchResponse('[wisdom] Always validate token expiry');
174
+ // Phase 5 (grow): patterns
175
+ if (callCount === 5) return mockFetchResponse('Auth validation is a cross-cutting concern');
176
+ // Phase 6 (evolve): suggestions
177
+ if (callCount === 6) return mockFetchResponse('Add auth middleware to all routes');
178
+ return mockFetchResponse('ok');
179
+ });
180
+
181
+ const result = await runProtocolCycle(
182
+ testAgent,
183
+ { title: 'Fix JWT auth', description: 'JWT tokens not validated properly' },
184
+ '[pattern] Use middleware'
185
+ );
186
+
187
+ expect(result.summary).toContain('Fixed JWT validation');
188
+ expect(result.insights.length).toBeGreaterThan(0);
189
+ expect(result.insights[0].type).toBe('wisdom');
190
+ expect(result.phaseResults).toHaveLength(7);
191
+ expect(result.totalDurationMs).toBeGreaterThanOrEqual(0);
192
+
193
+ // 6 LLM calls: reflect + execute + compress + reintake + grow + evolve
194
+ // (intake is local, no LLM)
195
+ expect(fetchSpy).toHaveBeenCalledTimes(6);
196
+ });
197
+
198
+ it('returns summary from execute phase even when compress finds nothing', async () => {
199
+ fetchSpy.mockImplementation(async () =>
200
+ mockFetchResponse('Completed the task successfully')
201
+ );
202
+
203
+ const result = await runProtocolCycle(
204
+ testAgent,
205
+ { title: 'Simple task', description: 'Do something' },
206
+ ''
207
+ );
208
+
209
+ expect(result.summary).toContain('Completed the task');
210
+ // Empty insights are fine
211
+ expect(result.insights).toBeDefined();
212
+ expect(result.phaseResults).toHaveLength(7);
213
+ });
214
+
215
+ it('works with OpenAI provider', async () => {
216
+ const openaiAgent: AgentConfig = {
217
+ ...testAgent,
218
+ model: { provider: 'openai', model: 'gpt-4o', apiKey: 'test-key' },
219
+ };
220
+
221
+ fetchSpy.mockImplementation(async () =>
222
+ mockOpenAIResponse('Task done')
223
+ );
224
+
225
+ const result = await runProtocolCycle(
226
+ openaiAgent,
227
+ { title: 'Test task', description: 'Test' },
228
+ ''
229
+ );
230
+
231
+ expect(result.phaseResults).toHaveLength(7);
232
+ expect(result.summary).toContain('Task done');
233
+
234
+ // Verify light model used for reflect (first call)
235
+ const firstCallBody = JSON.parse(fetchSpy.mock.calls[0][1].body);
236
+ expect(firstCallBody.model).toBe('gpt-4o-mini');
237
+ });
238
+
239
+ it('handles LLM errors gracefully via BaseAgent.runCycle', async () => {
240
+ fetchSpy.mockRejectedValue(new Error('API rate limit'));
241
+
242
+ const result = await runProtocolCycle(
243
+ testAgent,
244
+ { title: 'Failing task', description: 'Will fail' },
245
+ ''
246
+ );
247
+
248
+ // Should still return a result (BaseAgent catches phase errors)
249
+ expect(result.phaseResults.length).toBeGreaterThan(0);
250
+ // The reflect phase should fail, which cascades
251
+ const reflectPhase = result.phaseResults.find(p => p.phase === ProtocolPhase.REFLECT);
252
+ expect(reflectPhase?.status).toBe('failure');
253
+ });
254
+ });
@@ -0,0 +1,114 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { RevenueSplitter } from '../economy/RevenueSplitter';
3
+
4
+ describe('RevenueSplitter', () => {
5
+ it('splits 50/50 correctly', () => {
6
+ const splitter = new RevenueSplitter([
7
+ { id: 'creator', basisPoints: 5000 },
8
+ { id: 'platform', basisPoints: 5000 },
9
+ ]);
10
+ const result = splitter.split(1_000_000n);
11
+ expect(result.shares.get('creator')).toBe(500_000n);
12
+ expect(result.shares.get('platform')).toBe(500_000n);
13
+ expect(RevenueSplitter.validate(result)).toBe(true);
14
+ });
15
+
16
+ it('splits with dust allocation to first recipient', () => {
17
+ const splitter = new RevenueSplitter([
18
+ { id: 'creator', basisPoints: 3333 },
19
+ { id: 'platform', basisPoints: 3334 },
20
+ { id: 'referrer', basisPoints: 3333 },
21
+ ]);
22
+ const result = splitter.split(100n);
23
+ // Sum must equal 100
24
+ let sum = 0n;
25
+ for (const v of result.shares.values()) sum += v;
26
+ expect(sum).toBe(100n);
27
+ expect(RevenueSplitter.validate(result)).toBe(true);
28
+ });
29
+
30
+ it('handles zero amount', () => {
31
+ const splitter = new RevenueSplitter([
32
+ { id: 'a', basisPoints: 7000 },
33
+ { id: 'b', basisPoints: 3000 },
34
+ ]);
35
+ const result = splitter.split(0n);
36
+ expect(result.shares.get('a')).toBe(0n);
37
+ expect(result.shares.get('b')).toBe(0n);
38
+ expect(RevenueSplitter.validate(result)).toBe(true);
39
+ });
40
+
41
+ it('throws on basis points not summing to 10000', () => {
42
+ expect(() => new RevenueSplitter([
43
+ { id: 'a', basisPoints: 5000 },
44
+ { id: 'b', basisPoints: 4000 },
45
+ ])).toThrow('sum to 10000');
46
+ });
47
+
48
+ it('throws on empty recipients', () => {
49
+ expect(() => new RevenueSplitter([])).toThrow('At least one');
50
+ });
51
+
52
+ it('throws on negative basis points', () => {
53
+ expect(() => new RevenueSplitter([
54
+ { id: 'a', basisPoints: -1000 },
55
+ { id: 'b', basisPoints: 11000 },
56
+ ])).toThrow('Negative');
57
+ });
58
+
59
+ it('throws on duplicate IDs', () => {
60
+ expect(() => new RevenueSplitter([
61
+ { id: 'a', basisPoints: 5000 },
62
+ { id: 'a', basisPoints: 5000 },
63
+ ])).toThrow('Duplicate');
64
+ });
65
+
66
+ it('throws on negative amount', () => {
67
+ const splitter = new RevenueSplitter([
68
+ { id: 'a', basisPoints: 10000 },
69
+ ]);
70
+ expect(() => splitter.split(-1n)).toThrow('negative');
71
+ });
72
+
73
+ it('splitNumeric works as convenience wrapper', () => {
74
+ const splitter = new RevenueSplitter([
75
+ { id: 'creator', basisPoints: 8000 },
76
+ { id: 'platform', basisPoints: 2000 },
77
+ ]);
78
+ const result = splitter.splitNumeric(1_000_000);
79
+ expect(result.shares.get('creator')).toBe(800_000n);
80
+ expect(result.shares.get('platform')).toBe(200_000n);
81
+ });
82
+
83
+ it('provides breakdown with percentages', () => {
84
+ const splitter = new RevenueSplitter([
85
+ { id: 'creator', basisPoints: 7000 },
86
+ { id: 'platform', basisPoints: 3000 },
87
+ ]);
88
+ const result = splitter.split(1_000_000n);
89
+ expect(result.breakdown).toHaveLength(2);
90
+ expect(result.breakdown[0].percentage).toBe('70.00%');
91
+ expect(result.breakdown[1].percentage).toBe('30.00%');
92
+ });
93
+
94
+ it('getRecipients returns configured recipients', () => {
95
+ const splitter = new RevenueSplitter([
96
+ { id: 'a', basisPoints: 6000 },
97
+ { id: 'b', basisPoints: 4000 },
98
+ ]);
99
+ const recipients = splitter.getRecipients();
100
+ expect(recipients).toHaveLength(2);
101
+ expect(recipients[0].id).toBe('a');
102
+ });
103
+
104
+ it('maintains sum invariant for large amounts', () => {
105
+ const splitter = new RevenueSplitter([
106
+ { id: 'creator', basisPoints: 3333 },
107
+ { id: 'platform', basisPoints: 1667 },
108
+ { id: 'referrer', basisPoints: 2500 },
109
+ { id: 'treasury', basisPoints: 2500 },
110
+ ]);
111
+ const result = splitter.split(999_999_999_999n);
112
+ expect(RevenueSplitter.validate(result)).toBe(true);
113
+ });
114
+ });
@@ -0,0 +1,197 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { GoalSynthesizer, DOMAIN_GOALS, GENERIC_GOALS } from '../protocol/goal-synthesizer';
3
+ import type { KnowledgeStore, StoredEntry } from '../knowledge/knowledge-store';
4
+
5
+ // Mock KnowledgeStore
6
+ function mockKnowledgeStore(entries: Partial<StoredEntry>[] = []): KnowledgeStore {
7
+ return {
8
+ search: vi.fn().mockReturnValue(entries),
9
+ } as unknown as KnowledgeStore;
10
+ }
11
+
12
+ describe('Scenario-Driven Todo Generation', () => {
13
+
14
+ it('Scenario 1: High Network Latency/Timeout generates DevOps/Performance todos', async () => {
15
+ // Injecting a gotcha about network lag into the knowledge store
16
+ const store = mockKnowledgeStore([
17
+ {
18
+ id: 'G.NET.088',
19
+ type: 'gotcha',
20
+ content: 'Mesh gossip sync consistently dropping packets under node count > 50',
21
+ domain: 'performance',
22
+ confidence: 0.95,
23
+ source: 'telemetry',
24
+ queryCount: 1,
25
+ reuseCount: 0,
26
+ createdAt: new Date().toISOString(),
27
+ authorAgent: 'monitor-agent',
28
+ },
29
+ {
30
+ id: 'G.NET.089',
31
+ type: 'gotcha',
32
+ content: 'Unbounded memory growth observed in PR #202 telemetry reporting',
33
+ domain: 'devops',
34
+ confidence: 0.85,
35
+ source: 'telemetry',
36
+ queryCount: 0,
37
+ reuseCount: 0,
38
+ createdAt: new Date().toISOString(),
39
+ authorAgent: 'monitor-agent',
40
+ }
41
+ ]);
42
+
43
+ const synthesizer = new GoalSynthesizer({ knowledge: store });
44
+
45
+ const performanceTodos = await synthesizer.synthesizeMultiple({ domain: 'performance' }, 50);
46
+ const devopsTodos = await synthesizer.synthesizeMultiple({ domain: 'devops' }, 50);
47
+
48
+ // Performance agent should prioritize the dropping packets bug
49
+ expect(performanceTodos.some(t => t.category === 'knowledge-gap')).toBe(true);
50
+ expect(performanceTodos.some(t => t.description.includes('gossip sync consistently dropping'))).toBe(true);
51
+
52
+ // DevOps agent should look at telemetry reporting issues
53
+ expect(devopsTodos.some(t => t.category === 'knowledge-gap')).toBe(true);
54
+ expect(devopsTodos.some(t => t.description.includes('Unbounded memory growth'))).toBe(true);
55
+ });
56
+
57
+ it('Scenario 2: Team switches to "Testing" mode after major logic refactoring', async () => {
58
+ const synthesizer = new GoalSynthesizer();
59
+ // In "testing" mode with no specific recent knowledge, should yield pure heuristic testing goals
60
+ const testingTodos = await synthesizer.synthesizeMultiple({ domain: 'testing' }, 4);
61
+
62
+ expect(testingTodos.length).toBe(4);
63
+ const allowed = new Set([...DOMAIN_GOALS['testing'], ...DOMAIN_GOALS['performance'], ...DOMAIN_GOALS['devops'],
64
+ 'Analyze accumulated wisdom for contradictions',
65
+ 'Refactor internal pattern database for efficiency',
66
+ 'Explore adjacent domain knowledge',
67
+ 'Review recent failures and simulate alternative outcomes',
68
+ 'Update self-documentation and capability manifest',
69
+ 'Ping other agents for potential collaboration',
70
+ 'Optimize internal decision weights',
71
+ 'Study historical logs for anomaly detection',
72
+ ]);
73
+ expect(testingTodos.every(t => allowed.has(t.description) || t.description.startsWith('Investigate and resolve:'))).toBe(true);
74
+ });
75
+
76
+ it('Scenario 3: Architecture re-evaluates service bounds based off system-mandated source', async () => {
77
+ const synthesizer = new GoalSynthesizer();
78
+
79
+ // Simulate legacy synchronous call
80
+ const architectGoal = synthesizer.synthesize('architecture', 'system-mandate');
81
+
82
+ expect(architectGoal).toBeDefined();
83
+ expect(architectGoal.source).toBe('system-mandate');
84
+ expect(['knowledge-gap', 'self-improvement']).toContain(architectGoal.category);
85
+
86
+ // The description should match an architecture domain or generic fallback
87
+ const archDomains = DOMAIN_GOALS['architecture'];
88
+ expect(archDomains.includes(architectGoal.description) || GENERIC_GOALS.includes(architectGoal.description)).toBeTruthy();
89
+ });
90
+
91
+ it('Scenario 4: Security agent triages code injection vulnerability knowledge', async () => {
92
+ const store = mockKnowledgeStore([
93
+ {
94
+ id: 'G.SEC.999',
95
+ type: 'gotcha',
96
+ content: 'CRDT delta payloads bypassing type serialization checks causing prompt injection',
97
+ domain: 'security',
98
+ confidence: 0.99,
99
+ source: 'audit',
100
+ queryCount: 4,
101
+ reuseCount: 0,
102
+ createdAt: new Date().toISOString(),
103
+ authorAgent: 'security-scanner',
104
+ }
105
+ ]);
106
+
107
+ const synthesizer = new GoalSynthesizer({ knowledge: store });
108
+ const secTodos = await synthesizer.synthesizeMultiple({ domain: 'security' }, 50);
109
+
110
+ expect(secTodos.some(t => t.description.includes('CRDT delta payloads bypassing type serialization'))).toBe(true);
111
+ // Security agent should rank the injection gotcha with high priority
112
+ const injectionTodo = secTodos.find(t => t.description.includes('CRDT delta'));
113
+ expect(injectionTodo?.category).toBe('knowledge-gap');
114
+ });
115
+
116
+ it('Scenario 5: Goal Synthesizer todos are successfully converted and pushed to the Team board', async () => {
117
+ // We can isolate the goal-to-task pipeline
118
+ const synthesizer = new GoalSynthesizer();
119
+
120
+ // Synthesize some tasks for testing
121
+ const newGoals = await synthesizer.synthesizeMultiple({ domain: 'performance' }, 3);
122
+
123
+ // Convert to board tasks structure
124
+ const tasksToSubmit = newGoals.map(goal => ({
125
+ title: goal.description,
126
+ description: `[Auto-Synthesized] Rationale: ${goal.rationale}\nRelevance: ${goal.relevanceScore}`,
127
+ priority: goal.priority === 'high' ? 1 : goal.priority === 'medium' ? 2 : 3,
128
+ source: `synthesizer:${goal.id}`
129
+ }));
130
+
131
+ // Verify valid schema
132
+ expect(tasksToSubmit.length).toBe(3);
133
+ expect(tasksToSubmit[0].title).toBeDefined();
134
+ expect(tasksToSubmit[0].description).toContain('[Auto-Synthesized]');
135
+ expect(tasksToSubmit[0].priority).toBeGreaterThanOrEqual(1);
136
+ expect(tasksToSubmit[0].priority).toBeLessThanOrEqual(3);
137
+ });
138
+ it('Scenario 6: Research agent identifies knowledge gaps and proposes surveying', async () => {
139
+ const store = mockKnowledgeStore([
140
+ {
141
+ id: 'G.RES.101',
142
+ type: 'gotcha',
143
+ content: 'Neural Streaming data formats changing rapidly without backward compatibility',
144
+ domain: 'research',
145
+ confidence: 0.90,
146
+ source: 'external',
147
+ queryCount: 0,
148
+ reuseCount: 0,
149
+ createdAt: new Date().toISOString(),
150
+ authorAgent: 'researcher-agent',
151
+ }
152
+ ]);
153
+
154
+ const synthesizer = new GoalSynthesizer({ knowledge: store });
155
+ const researchTodos = await synthesizer.synthesizeMultiple({ domain: 'research' }, 50);
156
+
157
+ expect(researchTodos.some(t => t.description.includes('Neural Streaming'))).toBe(true);
158
+ // At least one task should fall back to general heuristic if we asked for higher count
159
+ const hasHeuristic = researchTodos.some(t => DOMAIN_GOALS['research'].includes(t.description));
160
+ expect(hasHeuristic).toBe(true);
161
+ });
162
+
163
+ it('Scenario 7: Coding agent reacts to legacy deprecation gotchas with targeted refactoring tasks', async () => {
164
+ const store = mockKnowledgeStore([
165
+ {
166
+ id: 'G.CODE.404',
167
+ type: 'gotcha',
168
+ content: 'V1 Mesh APIs are throwing silent UnhandledPromiseRejection errors under load',
169
+ domain: 'coding',
170
+ confidence: 0.98,
171
+ source: 'bug-tracker',
172
+ queryCount: 3,
173
+ reuseCount: 1,
174
+ createdAt: new Date().toISOString(),
175
+ authorAgent: 'dev-agent',
176
+ }
177
+ ]);
178
+
179
+ const synthesizer = new GoalSynthesizer({ knowledge: store });
180
+ const codingTodos = await synthesizer.synthesizeMultiple({ domain: 'coding' }, 50);
181
+
182
+ // Should prioritize the urgent deprecation / silent failure bug
183
+ expect(codingTodos.some(t => t.description.includes('UnhandledPromiseRejection')) || codingTodos.some(t => t.description.includes('V1 Mesh APIs'))).toBe(true);
184
+ });
185
+
186
+ it('Scenario 8: Reviewer agent generates task based on heuristic fallback', async () => {
187
+ const synthesizer = new GoalSynthesizer();
188
+ const reviewerTodos = await synthesizer.synthesizeMultiple({ domain: 'reviewer' }, 4);
189
+
190
+ expect(reviewerTodos.length).toBe(4);
191
+ const allExpectedDomains = DOMAIN_GOALS['reviewer'];
192
+ const hasReviewerHeuristic = reviewerTodos.some(t =>
193
+ allExpectedDomains.includes(t.description)
194
+ );
195
+ expect(hasReviewerHeuristic).toBe(true);
196
+ });
197
+ });