@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,286 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ TrainingDataGenerator,
4
+ createTrainingDataGenerator,
5
+ ALL_CATEGORIES,
6
+ type TrainingExample,
7
+ type TrainingCategory,
8
+ } from '../TrainingDataGenerator';
9
+
10
+ describe('TrainingDataGenerator', () => {
11
+ describe('initialization', () => {
12
+ it('should create generator', () => {
13
+ const generator = new TrainingDataGenerator();
14
+ expect(generator).toBeDefined();
15
+ });
16
+
17
+ it('should create generator via factory', () => {
18
+ const generator = createTrainingDataGenerator();
19
+ expect(generator).toBeDefined();
20
+ });
21
+ });
22
+
23
+ describe('generateAll', () => {
24
+ it('should return all examples', () => {
25
+ const generator = new TrainingDataGenerator();
26
+ const examples = generator.generateAll();
27
+
28
+ expect(examples.length).toBeGreaterThan(40);
29
+ });
30
+
31
+ it('should have required fields for each example', () => {
32
+ const generator = new TrainingDataGenerator();
33
+ const examples = generator.generateAll();
34
+
35
+ for (const ex of examples) {
36
+ expect(ex.id).toBeDefined();
37
+ expect(ex.category).toBeDefined();
38
+ expect(ex.description).toBeDefined();
39
+ expect(ex.holoScript).toBeDefined();
40
+ expect(ex.tags).toBeDefined();
41
+ expect(ex.complexity).toBeDefined();
42
+ }
43
+ });
44
+
45
+ it('should have valid HoloScript code', () => {
46
+ const generator = new TrainingDataGenerator();
47
+ const examples = generator.generateAll();
48
+
49
+ for (const ex of examples) {
50
+ expect(ex.holoScript.length).toBeGreaterThan(10);
51
+ // Should contain at least one keyword
52
+ const hasKeyword = ['object', 'composition', 'template', 'ui_', 'zone'].some((kw) =>
53
+ ex.holoScript.includes(kw)
54
+ );
55
+ expect(hasKeyword).toBe(true);
56
+ }
57
+ });
58
+ });
59
+
60
+ describe('generate with options', () => {
61
+ it('should filter by category', () => {
62
+ const generator = new TrainingDataGenerator();
63
+ const examples = generator.generate({ categories: ['geometry'] });
64
+
65
+ expect(examples.length).toBeGreaterThan(0);
66
+ for (const ex of examples) {
67
+ expect(ex.category).toBe('geometry');
68
+ }
69
+ });
70
+
71
+ it('should filter by multiple categories', () => {
72
+ const generator = new TrainingDataGenerator();
73
+ const examples = generator.generate({ categories: ['geometry', 'materials'] });
74
+
75
+ expect(examples.length).toBeGreaterThan(0);
76
+ for (const ex of examples) {
77
+ expect(['geometry', 'materials']).toContain(ex.category);
78
+ }
79
+ });
80
+
81
+ it('should filter by complexity', () => {
82
+ const generator = new TrainingDataGenerator();
83
+ const examples = generator.generate({ complexityFilter: ['basic'] });
84
+
85
+ expect(examples.length).toBeGreaterThan(0);
86
+ for (const ex of examples) {
87
+ expect(ex.complexity).toBe('basic');
88
+ }
89
+ });
90
+
91
+ it('should limit count', () => {
92
+ const generator = new TrainingDataGenerator();
93
+ const examples = generator.generate({ count: 5 });
94
+
95
+ expect(examples.length).toBe(5);
96
+ });
97
+
98
+ it('should combine filters', () => {
99
+ const generator = new TrainingDataGenerator();
100
+ const examples = generator.generate({
101
+ categories: ['physics'],
102
+ complexityFilter: ['basic', 'intermediate'],
103
+ count: 3,
104
+ });
105
+
106
+ expect(examples.length).toBeLessThanOrEqual(3);
107
+ for (const ex of examples) {
108
+ expect(ex.category).toBe('physics');
109
+ expect(['basic', 'intermediate']).toContain(ex.complexity);
110
+ }
111
+ });
112
+ });
113
+
114
+ describe('getByCategory', () => {
115
+ it('should return geometry examples', () => {
116
+ const generator = new TrainingDataGenerator();
117
+ const examples = generator.getByCategory('geometry');
118
+
119
+ expect(examples.length).toBeGreaterThan(5);
120
+ for (const ex of examples) {
121
+ expect(ex.category).toBe('geometry');
122
+ }
123
+ });
124
+
125
+ it('should return UI examples', () => {
126
+ const generator = new TrainingDataGenerator();
127
+ const examples = generator.getByCategory('ui');
128
+
129
+ expect(examples.length).toBeGreaterThan(3);
130
+ });
131
+
132
+ it('should return physics examples', () => {
133
+ const generator = new TrainingDataGenerator();
134
+ const examples = generator.getByCategory('physics');
135
+
136
+ expect(examples.length).toBeGreaterThan(3);
137
+ });
138
+ });
139
+
140
+ describe('getByComplexity', () => {
141
+ it('should return basic examples', () => {
142
+ const generator = new TrainingDataGenerator();
143
+ const examples = generator.getByComplexity('basic');
144
+
145
+ expect(examples.length).toBeGreaterThan(5);
146
+ for (const ex of examples) {
147
+ expect(ex.complexity).toBe('basic');
148
+ }
149
+ });
150
+
151
+ it('should return advanced examples', () => {
152
+ const generator = new TrainingDataGenerator();
153
+ const examples = generator.getByComplexity('advanced');
154
+
155
+ expect(examples.length).toBeGreaterThan(5);
156
+ for (const ex of examples) {
157
+ expect(ex.complexity).toBe('advanced');
158
+ }
159
+ });
160
+ });
161
+
162
+ describe('getByTag', () => {
163
+ it('should return examples by tag', () => {
164
+ const generator = new TrainingDataGenerator();
165
+ const examples = generator.getByTag('physics');
166
+
167
+ expect(examples.length).toBeGreaterThan(0);
168
+ for (const ex of examples) {
169
+ expect(ex.tags).toContain('physics');
170
+ }
171
+ });
172
+
173
+ it('should find VR-related examples', () => {
174
+ const generator = new TrainingDataGenerator();
175
+ const vrExamples = generator.getByTag('vr');
176
+
177
+ expect(vrExamples.length).toBeGreaterThan(0);
178
+ });
179
+ });
180
+
181
+ describe('getStats', () => {
182
+ it('should return category counts', () => {
183
+ const generator = new TrainingDataGenerator();
184
+ const stats = generator.getStats();
185
+
186
+ expect(stats.geometry).toBeGreaterThan(0);
187
+ expect(stats.materials).toBeGreaterThan(0);
188
+ expect(stats.physics).toBeGreaterThan(0);
189
+ expect(stats.interactions).toBeGreaterThan(0);
190
+ });
191
+
192
+ it('should have all categories represented', () => {
193
+ const generator = new TrainingDataGenerator();
194
+ const stats = generator.getStats();
195
+
196
+ const categories = Object.keys(stats);
197
+ expect(categories.length).toBeGreaterThanOrEqual(10);
198
+ });
199
+ });
200
+
201
+ describe('export', () => {
202
+ it('should export as JSON', () => {
203
+ const generator = new TrainingDataGenerator();
204
+ const json = generator.exportJSON();
205
+
206
+ expect(json).toBeDefined();
207
+ const parsed = JSON.parse(json);
208
+ expect(Array.isArray(parsed)).toBe(true);
209
+ expect(parsed.length).toBeGreaterThan(0);
210
+ });
211
+
212
+ it('should export as JSONL', () => {
213
+ const generator = new TrainingDataGenerator();
214
+ const jsonl = generator.exportJSONL();
215
+
216
+ expect(jsonl).toBeDefined();
217
+ const lines = jsonl.split('\n');
218
+ expect(lines.length).toBeGreaterThan(0);
219
+
220
+ // Each line should be valid JSON
221
+ for (const line of lines) {
222
+ expect(() => JSON.parse(line)).not.toThrow();
223
+ }
224
+ });
225
+ });
226
+
227
+ describe('ALL_CATEGORIES constant', () => {
228
+ it('should include all expected categories', () => {
229
+ expect(ALL_CATEGORIES).toContain('geometry');
230
+ expect(ALL_CATEGORIES).toContain('materials');
231
+ expect(ALL_CATEGORIES).toContain('physics');
232
+ expect(ALL_CATEGORIES).toContain('interactions');
233
+ expect(ALL_CATEGORIES).toContain('audio');
234
+ expect(ALL_CATEGORIES).toContain('ui');
235
+ expect(ALL_CATEGORIES).toContain('composition');
236
+ expect(ALL_CATEGORIES).toContain('state');
237
+ expect(ALL_CATEGORIES).toContain('logic');
238
+ expect(ALL_CATEGORIES).toContain('traits');
239
+ expect(ALL_CATEGORIES).toContain('animations');
240
+ expect(ALL_CATEGORIES).toContain('ar_vr');
241
+ });
242
+ });
243
+
244
+ describe('Example content quality', () => {
245
+ it('should have diverse examples for geometry', () => {
246
+ const generator = new TrainingDataGenerator();
247
+ const examples = generator.getByCategory('geometry');
248
+
249
+ const geometryTypes = new Set(
250
+ examples.map((ex) => {
251
+ const match = ex.holoScript.match(/geometry:\s*"(\w+)"/);
252
+ return match ? match[1] : null;
253
+ })
254
+ );
255
+
256
+ // Should have multiple geometry types
257
+ expect(geometryTypes.size).toBeGreaterThan(3);
258
+ });
259
+
260
+ it('should have examples with traits', () => {
261
+ const generator = new TrainingDataGenerator();
262
+ const allExamples = generator.generateAll();
263
+
264
+ const examplesWithTraits = allExamples.filter((ex) => ex.holoScript.includes('@'));
265
+ expect(examplesWithTraits.length).toBeGreaterThan(10);
266
+ });
267
+
268
+ it('should have examples with logic blocks', () => {
269
+ const generator = new TrainingDataGenerator();
270
+ const allExamples = generator.generateAll();
271
+
272
+ const examplesWithLogic = allExamples.filter((ex) => ex.holoScript.includes('logic {'));
273
+ expect(examplesWithLogic.length).toBeGreaterThan(5);
274
+ });
275
+
276
+ it('should have unique IDs', () => {
277
+ const generator = new TrainingDataGenerator();
278
+ const examples = generator.generateAll();
279
+
280
+ const ids = examples.map((ex) => ex.id);
281
+ const uniqueIds = new Set(ids);
282
+
283
+ expect(uniqueIds.size).toBe(ids.length);
284
+ });
285
+ });
286
+ });
@@ -0,0 +1,207 @@
1
+ /**
2
+ * UtilityAI.prod.test.ts — Sprint CLXX
3
+ *
4
+ * Production edge-case integration tests for the Utility AI orchestrator.
5
+ * Ensures complex quadratic falloffs, dual-agent prioritization,
6
+ * cooldown evasion, and fuzzy logic integration correctness.
7
+ */
8
+
9
+ import { describe, it, expect, beforeEach } from 'vitest';
10
+ import { UtilityAI } from '../UtilityAI';
11
+ import type { UtilityAction, Consideration } from '../UtilityAI';
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Helpers
15
+ // ---------------------------------------------------------------------------
16
+
17
+ let ai: UtilityAI;
18
+ let globalTime = 0;
19
+
20
+ beforeEach(() => {
21
+ ai = new UtilityAI();
22
+ globalTime = 0;
23
+ });
24
+
25
+ function createAction(
26
+ id: string,
27
+ inputFn: () => number,
28
+ weight = 1.0,
29
+ cooldown = 0,
30
+ curve: 'linear' | 'quadratic' | 'logistic' | 'step' = 'linear'
31
+ ): UtilityAction {
32
+ return {
33
+ id,
34
+ name: id,
35
+ considerations: [
36
+ {
37
+ name: 'default',
38
+ input: inputFn,
39
+ curve,
40
+ weight,
41
+ invert: false,
42
+ },
43
+ ],
44
+ cooldown,
45
+ lastExecuted: -Infinity,
46
+ bonus: 0,
47
+ execute: () => {},
48
+ };
49
+ }
50
+
51
+ // ---------------------------------------------------------------------------
52
+ // Tests
53
+ // ---------------------------------------------------------------------------
54
+
55
+ describe('UtilityAI Complex Integration', () => {
56
+ it('handles 100 simultaneous actions, correctly prioritizing mathematically', () => {
57
+ for (let i = 0; i < 100; i++) {
58
+ ai.addAction(createAction(`action-${i}`, () => i / 100, 1.0));
59
+ }
60
+
61
+ // action-99 should have the highest score (99/100)
62
+ const best = ai.selectBest();
63
+ expect(best?.name).toBe('action-99');
64
+ });
65
+
66
+ it('quadratic score modifiers apply correctly over base weights', () => {
67
+ // Action A: Input 0.5, Weight 1.0, Quadratic -> Final: 1.0 * (0.5)^2 = 0.25
68
+ ai.addAction(createAction('A', () => 0.5, 1.0, 0, 'quadratic'));
69
+
70
+ // Action B: Input 0.4, Weight 2.0, Linear -> Final: 2.0 * 0.4 = 0.8
71
+ // Wait, earlier I assumed Weight * Input^2. Let's make B quadratic too.
72
+ // Action B: Input 0.4, Weight 2.0, Quadratic -> Final: 2.0 * (0.4)^2 = 0.32
73
+ ai.addAction(createAction('B', () => 0.4, 2.0, 0, 'quadratic'));
74
+
75
+ const best = ai.selectBest();
76
+ expect(best?.name).toBe('B'); // 0.32 > 0.25
77
+ });
78
+
79
+ it('returns null if all tasks score exactly 0', () => {
80
+ ai.addAction(createAction('A', () => 0));
81
+ ai.addAction(createAction('B', () => 0));
82
+ expect(ai.executeBest()).toBeNull();
83
+ });
84
+
85
+ it('dynamic context changes dynamically swap active action', () => {
86
+ let health = 100;
87
+ let enemyDistance = 50;
88
+
89
+ ai.addAction(createAction('attack', () => (100 - enemyDistance) / 100));
90
+ ai.addAction(createAction('heal', () => (100 - health) / 100));
91
+
92
+ // Enemy is 50m away (attack=0.5), health is full (heal=0.0). Attack!
93
+ expect(ai.selectBest()?.name).toBe('attack');
94
+
95
+ // Health drops to 10. Heal score = 0.9. Attack score = 0.5. Heal!
96
+ health = 10;
97
+ expect(ai.selectBest()?.name).toBe('heal');
98
+
99
+ // Enemy is 5m away (attack=0.95). Health is 30 (heal=0.7). Attack!
100
+ enemyDistance = 5;
101
+ health = 30;
102
+ expect(ai.selectBest()?.name).toBe('attack');
103
+ });
104
+
105
+ it('cooldown logic completely zeros out otherwise highly weighted actions', () => {
106
+ const ultimate = createAction('ultimate-attack', () => 1.0, 1.0, 5.0);
107
+ ai.addAction(ultimate);
108
+ ai.addAction(createAction('punch', () => 0.5));
109
+
110
+ // Ultimate is available and scores > 0
111
+ expect(ai.scoreAction(ultimate)).toBeGreaterThan(0);
112
+
113
+ // Execute ultimate
114
+ ai.setTime(0);
115
+ ai.executeBest();
116
+
117
+ // Now it is on cooldown
118
+ expect(ai.scoreAction(ultimate)).toBe(0);
119
+
120
+ // Wait 2 seconds (still on cooldown)
121
+ ai.setTime(2.0);
122
+ expect(ai.scoreAction(ultimate)).toBe(0);
123
+
124
+ // Wait 4 more seconds (2 + 4 = 6)
125
+ ai.setTime(6.0);
126
+ // Now it is off cooldown
127
+ expect(ai.scoreAction(ultimate)).toBeGreaterThan(0);
128
+ });
129
+
130
+ it('keeps running current action if its priority drops slightly but not below others', () => {
131
+ let runs = 0;
132
+ let scoreA = 0.9;
133
+
134
+ const actionA = createAction('A', () => scoreA);
135
+ actionA.execute = () => {
136
+ runs++;
137
+ };
138
+
139
+ ai.addAction(actionA);
140
+ ai.addAction(createAction('B', () => 0.5));
141
+
142
+ ai.executeBest();
143
+ expect(runs).toBe(1);
144
+
145
+ scoreA = 0.6; // Priority dropped, but still > 0.5
146
+ ai.executeBest();
147
+ expect(runs).toBe(2);
148
+ });
149
+
150
+ it('multiple considerations combine multiplicatively with flat bonus addition', () => {
151
+ const action = createAction('complex', () => 0);
152
+ action.considerations = [
153
+ { name: 'c1', input: () => 0.8, curve: 'linear', weight: 1.0, invert: false },
154
+ { name: 'c2', input: () => 0.5, curve: 'linear', weight: 2.0, invert: false },
155
+ ];
156
+ action.bonus = 0.2;
157
+ // Score should be: (0.8 * 1.0) * (0.5 * 2.0) + 0.2 = 0.8 * 1.0 + 0.2 = 1.0
158
+ // Wait, the formula is: score = 1. For each c: score *= c.value * c.weight
159
+ // So: score = 1 * (0.8 * 1.0) * (0.5 * 2.0) = 0.8. Total with bonus: 0.8 + 0.2 = 1.0
160
+ ai.addAction(action);
161
+
162
+ expect(ai.scoreAction(action)).toBeCloseTo(1.0);
163
+ });
164
+
165
+ it('logistic curve calculation correctness', () => {
166
+ const action = createAction('logistic', () => 0.5, 1.0, 0, 'logistic');
167
+ ai.addAction(action);
168
+
169
+ // logistic: 1 / (1 + Math.exp(-10 * (input - 0.5)))
170
+ // For input 0.5: 1 / (1 + exp(0)) = 0.5
171
+ expect(ai.scoreAction(action)).toBeCloseTo(0.5);
172
+
173
+ action.considerations[0].input = () => 1.0;
174
+ // For input 1.0: 1 / (1 + exp(-5)) ~ 0.9933
175
+ expect(ai.scoreAction(action)).toBeCloseTo(0.9933, 3);
176
+ });
177
+
178
+ it('step curve calculation correctness', () => {
179
+ const action = createAction('step', () => 0.49, 1.0, 0, 'step');
180
+ ai.addAction(action);
181
+ // < 0.5 = 0
182
+ expect(ai.scoreAction(action)).toBe(0);
183
+
184
+ // >= 0.5 returns 1.0
185
+ action.considerations[0].input = () => 0.5;
186
+ expect(ai.scoreAction(action)).toBe(1.0);
187
+ });
188
+
189
+ it('scoreAll returns correctly sorted array of scores', () => {
190
+ ai.addAction(createAction('C', () => 0.2));
191
+ ai.addAction(createAction('A', () => 0.8));
192
+ ai.addAction(createAction('B', () => 0.5));
193
+
194
+ const scores = ai.scoreAll();
195
+ expect(scores.length).toBe(3);
196
+ expect(scores[0].actionId).toBe('A');
197
+ expect(scores[1].actionId).toBe('B');
198
+ expect(scores[2].actionId).toBe('C');
199
+ });
200
+
201
+ it('executeBest handles no valid actions correctly', () => {
202
+ expect(ai.executeBest()).toBeNull();
203
+
204
+ ai.addAction(createAction('A', () => 0));
205
+ expect(ai.executeBest()).toBeNull();
206
+ });
207
+ });
@@ -0,0 +1,155 @@
1
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
2
+ import { UtilityAI, type UtilityAction, type Consideration } from '../UtilityAI';
3
+
4
+ function makeAction(id: string, overrides: Partial<UtilityAction> = {}): UtilityAction {
5
+ return {
6
+ id,
7
+ name: id,
8
+ considerations: [{ name: 'always', input: () => 1, curve: 'linear', weight: 1, invert: false }],
9
+ cooldown: 0,
10
+ lastExecuted: -999,
11
+ bonus: 0,
12
+ execute: vi.fn(),
13
+ ...overrides,
14
+ };
15
+ }
16
+
17
+ describe('UtilityAI', () => {
18
+ let ai: UtilityAI;
19
+
20
+ beforeEach(() => {
21
+ ai = new UtilityAI();
22
+ });
23
+
24
+ // ---------------------------------------------------------------------------
25
+ // Action Management
26
+ // ---------------------------------------------------------------------------
27
+
28
+ it('addAction registers action', () => {
29
+ ai.addAction(makeAction('a'));
30
+ expect(ai.getActionCount()).toBe(1);
31
+ });
32
+
33
+ it('removeAction unregisters', () => {
34
+ ai.addAction(makeAction('a'));
35
+ ai.removeAction('a');
36
+ expect(ai.getActionCount()).toBe(0);
37
+ });
38
+
39
+ // ---------------------------------------------------------------------------
40
+ // Scoring
41
+ // ---------------------------------------------------------------------------
42
+
43
+ it('scoreAction returns positive for available action', () => {
44
+ const act = makeAction('a');
45
+ ai.addAction(act);
46
+ expect(ai.scoreAction(act)).toBeGreaterThan(0);
47
+ });
48
+
49
+ it('scoreAction returns 0 during cooldown', () => {
50
+ const act = makeAction('a', { cooldown: 5, lastExecuted: 0 });
51
+ ai.addAction(act);
52
+ ai.setTime(2); // only 2s since lastExecuted, cooldown is 5
53
+ expect(ai.scoreAction(act)).toBe(0);
54
+ });
55
+
56
+ it('scoreAction applies quadratic curve', () => {
57
+ const c: Consideration = {
58
+ name: 'c',
59
+ input: () => 0.5,
60
+ curve: 'quadratic',
61
+ weight: 1,
62
+ invert: false,
63
+ };
64
+ const act = makeAction('a', { considerations: [c] });
65
+ ai.addAction(act);
66
+ expect(ai.scoreAction(act)).toBeCloseTo(0.25); // 0.5^2
67
+ });
68
+
69
+ it('scoreAction applies step curve', () => {
70
+ const cLow: Consideration = {
71
+ name: 'c',
72
+ input: () => 0.3,
73
+ curve: 'step',
74
+ weight: 1,
75
+ invert: false,
76
+ };
77
+ const cHigh: Consideration = {
78
+ name: 'c2',
79
+ input: () => 0.7,
80
+ curve: 'step',
81
+ weight: 1,
82
+ invert: false,
83
+ };
84
+ expect(ai.scoreAction(makeAction('lo', { considerations: [cLow] }))).toBe(0);
85
+ expect(ai.scoreAction(makeAction('hi', { considerations: [cHigh] }))).toBe(1);
86
+ });
87
+
88
+ it('scoreAction with invert flips input', () => {
89
+ const c: Consideration = {
90
+ name: 'c',
91
+ input: () => 0.2,
92
+ curve: 'linear',
93
+ weight: 1,
94
+ invert: true,
95
+ };
96
+ const act = makeAction('a', { considerations: [c] });
97
+ expect(ai.scoreAction(act)).toBeCloseTo(0.8);
98
+ });
99
+
100
+ it('scoreAction adds bonus', () => {
101
+ const act = makeAction('a', { bonus: 5 });
102
+ expect(ai.scoreAction(act)).toBe(6); // 1 (from consideration) + 5
103
+ });
104
+
105
+ // ---------------------------------------------------------------------------
106
+ // Score All
107
+ // ---------------------------------------------------------------------------
108
+
109
+ it('scoreAll returns sorted scores', () => {
110
+ ai.addAction(makeAction('low', { bonus: 0 }));
111
+ ai.addAction(makeAction('high', { bonus: 10 }));
112
+ const scores = ai.scoreAll();
113
+ expect(scores[0].actionId).toBe('high');
114
+ expect(scores[0].score).toBeGreaterThan(scores[1].score);
115
+ });
116
+
117
+ // ---------------------------------------------------------------------------
118
+ // Selection & Execution
119
+ // ---------------------------------------------------------------------------
120
+
121
+ it('selectBest returns highest scored action', () => {
122
+ ai.addAction(makeAction('low', { bonus: 0 }));
123
+ ai.addAction(makeAction('high', { bonus: 10 }));
124
+ expect(ai.selectBest()!.id).toBe('high');
125
+ });
126
+
127
+ it('executeBest calls execute and returns id', () => {
128
+ const act = makeAction('a');
129
+ ai.addAction(act);
130
+ ai.setTime(10);
131
+ const result = ai.executeBest();
132
+ expect(result).toBe('a');
133
+ expect(act.execute).toHaveBeenCalledTimes(1);
134
+ });
135
+
136
+ it('executeBest returns null when all on cooldown', () => {
137
+ ai.addAction(makeAction('a', { cooldown: 100, lastExecuted: 0 }));
138
+ ai.setTime(1);
139
+ expect(ai.executeBest()).toBeNull();
140
+ });
141
+
142
+ // ---------------------------------------------------------------------------
143
+ // History
144
+ // ---------------------------------------------------------------------------
145
+
146
+ it('history records executed actions', () => {
147
+ ai.addAction(makeAction('a'));
148
+ ai.setTime(5);
149
+ ai.executeBest();
150
+ const hist = ai.getHistory();
151
+ expect(hist).toHaveLength(1);
152
+ expect(hist[0].actionId).toBe('a');
153
+ expect(hist[0].timestamp).toBe(5);
154
+ });
155
+ });