@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,212 @@
1
+ // STATUS: Scaffold — requires absorb service connection and LLM provider for production use
2
+ /**
3
+ * PromptOptimizer — A/B test prompts to find the most effective phrasing.
4
+ *
5
+ * @experimental
6
+ *
7
+ * Part of FW-1.0 self-evolution: the framework optimizes its own prompts
8
+ * by running controlled experiments and measuring quality metrics.
9
+ */
10
+
11
+ import { callLLM } from '../llm/llm-adapter';
12
+ import type { ModelConfig } from '../types';
13
+
14
+ export interface ABTestConfig {
15
+ /** LLM model configuration for running the test */
16
+ model: ModelConfig;
17
+ /** Number of runs per prompt variant (default: 3) */
18
+ runs?: number;
19
+ /** Evaluation criteria (default: quality + relevance) */
20
+ criteria?: EvaluationCriteria[];
21
+ /** Maximum tokens per response */
22
+ maxTokens?: number;
23
+ /** Temperature for test runs */
24
+ temperature?: number;
25
+ }
26
+
27
+ export interface EvaluationCriteria {
28
+ name: string;
29
+ description: string;
30
+ weight: number;
31
+ }
32
+
33
+ export interface PromptVariantResult {
34
+ prompt: string;
35
+ responses: string[];
36
+ avgScore: number;
37
+ scores: number[];
38
+ avgTokens: number;
39
+ avgLatencyMs: number;
40
+ }
41
+
42
+ export interface ABTestResult {
43
+ /** The task/question both prompts were tested against */
44
+ task: string;
45
+ /** Results for prompt A */
46
+ variantA: PromptVariantResult;
47
+ /** Results for prompt B */
48
+ variantB: PromptVariantResult;
49
+ /** Which variant won ('A' | 'B' | 'tie') */
50
+ winner: 'A' | 'B' | 'tie';
51
+ /** Confidence in the result (0-1, based on score delta and consistency) */
52
+ confidence: number;
53
+ /** Total tokens consumed across all runs */
54
+ totalTokens: number;
55
+ }
56
+
57
+ const DEFAULT_CRITERIA: EvaluationCriteria[] = [
58
+ { name: 'relevance', description: 'How relevant is the response to the task?', weight: 0.4 },
59
+ { name: 'quality', description: 'How well-structured and clear is the response?', weight: 0.3 },
60
+ { name: 'completeness', description: 'Does the response fully address the task?', weight: 0.3 },
61
+ ];
62
+
63
+ const JUDGE_SYSTEM = `You are a prompt quality evaluator. Score the following response on a scale of 1-10 for each criterion. Return ONLY a JSON object with scores, e.g.: {"relevance": 8, "quality": 7, "completeness": 9}`;
64
+
65
+ /**
66
+ * PromptOptimizer — A/B tests prompt variants to find the best one.
67
+ *
68
+ * @experimental
69
+ *
70
+ * Usage:
71
+ * ```ts
72
+ * const optimizer = new PromptOptimizer({
73
+ * model: { provider: 'anthropic', model: 'claude-sonnet-4-20250514' }
74
+ * });
75
+ * const result = await optimizer.abTest(
76
+ * 'Explain HoloScript in one paragraph.',
77
+ * 'You are a HoloScript expert. Explain HoloScript concisely.',
78
+ * 'What is HoloScript?'
79
+ * );
80
+ * console.log(`Winner: ${result.winner} (confidence: ${result.confidence})`);
81
+ * ```
82
+ */
83
+ export class PromptOptimizer {
84
+ private readonly config: ABTestConfig;
85
+
86
+ constructor(config: ABTestConfig) {
87
+ this.config = {
88
+ runs: 3,
89
+ criteria: DEFAULT_CRITERIA,
90
+ maxTokens: 1024,
91
+ temperature: 0.7,
92
+ ...config,
93
+ };
94
+ }
95
+
96
+ /**
97
+ * Run an A/B test comparing two prompt variants on a given task.
98
+ */
99
+ async abTest(promptA: string, promptB: string, task: string): Promise<ABTestResult> {
100
+ const runs = this.config.runs!;
101
+
102
+ const [variantA, variantB] = await Promise.all([
103
+ this.runVariant(promptA, task, runs),
104
+ this.runVariant(promptB, task, runs),
105
+ ]);
106
+
107
+ const delta = variantA.avgScore - variantB.avgScore;
108
+ const winner: 'A' | 'B' | 'tie' = Math.abs(delta) < 0.5 ? 'tie' : delta > 0 ? 'A' : 'B';
109
+
110
+ // Confidence: based on score delta magnitude and low variance
111
+ const varianceA = this.variance(variantA.scores);
112
+ const varianceB = this.variance(variantB.scores);
113
+ const avgVariance = (varianceA + varianceB) / 2;
114
+ const confidence = Math.min(1, Math.abs(delta) / 3) * Math.max(0.3, 1 - avgVariance / 10);
115
+
116
+ return {
117
+ task,
118
+ variantA,
119
+ variantB,
120
+ winner,
121
+ confidence: Math.round(confidence * 100) / 100,
122
+ totalTokens: variantA.avgTokens * runs + variantB.avgTokens * runs,
123
+ };
124
+ }
125
+
126
+ /**
127
+ * Run a single variant N times and evaluate.
128
+ */
129
+ private async runVariant(prompt: string, task: string, runs: number): Promise<PromptVariantResult> {
130
+ const responses: string[] = [];
131
+ const scores: number[] = [];
132
+ let totalTokens = 0;
133
+ let totalLatency = 0;
134
+
135
+ for (let i = 0; i < runs; i++) {
136
+ const start = Date.now();
137
+ const response = await callLLM(this.config.model, [
138
+ { role: 'system', content: prompt },
139
+ { role: 'user', content: task },
140
+ ], {
141
+ maxTokens: this.config.maxTokens,
142
+ temperature: this.config.temperature,
143
+ });
144
+ const latency = Date.now() - start;
145
+
146
+ responses.push(response.content);
147
+ totalTokens += response.tokensUsed ?? 0;
148
+ totalLatency += latency;
149
+
150
+ // Judge the response
151
+ const score = await this.judge(response.content, task);
152
+ scores.push(score);
153
+ }
154
+
155
+ return {
156
+ prompt,
157
+ responses,
158
+ avgScore: scores.reduce((a, b) => a + b, 0) / scores.length,
159
+ scores,
160
+ avgTokens: totalTokens / runs,
161
+ avgLatencyMs: totalLatency / runs,
162
+ };
163
+ }
164
+
165
+ /**
166
+ * Judge a response using the LLM as evaluator.
167
+ * Returns a weighted score (0-10).
168
+ */
169
+ private async judge(response: string, task: string): Promise<number> {
170
+ const criteria = this.config.criteria!;
171
+
172
+ try {
173
+ const judgeResponse = await callLLM(this.config.model, [
174
+ { role: 'system', content: JUDGE_SYSTEM },
175
+ {
176
+ role: 'user',
177
+ content: [
178
+ `Task: ${task}`,
179
+ `Response: ${response}`,
180
+ `Criteria: ${criteria.map(c => `${c.name} (${c.description})`).join(', ')}`,
181
+ ].join('\n'),
182
+ },
183
+ ], { maxTokens: 200, temperature: 0 });
184
+
185
+ const parsed = JSON.parse(judgeResponse.content) as Record<string, number>;
186
+ let weightedSum = 0;
187
+ let totalWeight = 0;
188
+
189
+ for (const c of criteria) {
190
+ const score = parsed[c.name];
191
+ if (typeof score === 'number' && score >= 1 && score <= 10) {
192
+ weightedSum += score * c.weight;
193
+ totalWeight += c.weight;
194
+ }
195
+ }
196
+
197
+ return totalWeight > 0 ? weightedSum / totalWeight : 5;
198
+ } catch {
199
+ // If judge fails, return neutral score
200
+ return 5;
201
+ }
202
+ }
203
+
204
+ /**
205
+ * Compute variance of a number array.
206
+ */
207
+ private variance(values: number[]): number {
208
+ if (values.length < 2) return 0;
209
+ const mean = values.reduce((a, b) => a + b, 0) / values.length;
210
+ return values.reduce((sum, v) => sum + (v - mean) ** 2, 0) / (values.length - 1);
211
+ }
212
+ }
@@ -0,0 +1,175 @@
1
+ // STATUS: Scaffold — requires absorb service connection and LLM provider for production use
2
+ /**
3
+ * TestGenerator — Auto-generate tests for framework source files.
4
+ *
5
+ * @experimental
6
+ *
7
+ * Uses the LLM adapter to generate vitest test files from source code.
8
+ * Part of FW-1.0 self-evolution: the framework writes its own tests.
9
+ */
10
+
11
+ import { callLLM } from '../llm/llm-adapter';
12
+ import type { ModelConfig } from '../types';
13
+ import { readFileSync, existsSync } from 'fs';
14
+ import { basename, dirname, resolve } from 'path';
15
+
16
+ export interface TestGeneratorConfig {
17
+ /** LLM model configuration */
18
+ model: ModelConfig;
19
+ /** Maximum tokens for test generation */
20
+ maxTokens?: number;
21
+ /** Temperature (lower = more deterministic tests) */
22
+ temperature?: number;
23
+ /** Test framework (default: vitest) */
24
+ testFramework?: 'vitest' | 'jest';
25
+ /** Additional context to include in the prompt */
26
+ additionalContext?: string;
27
+ }
28
+
29
+ export interface GeneratedTest {
30
+ /** Source file path */
31
+ sourceFile: string;
32
+ /** Generated test file content */
33
+ testContent: string;
34
+ /** Suggested test file path */
35
+ testFilePath: string;
36
+ /** Number of test cases generated */
37
+ testCount: number;
38
+ /** LLM tokens used */
39
+ tokensUsed: number;
40
+ }
41
+
42
+ const SYSTEM_PROMPT = `You are a test generation expert for TypeScript projects using vitest.
43
+ Given a source file, generate comprehensive test cases that:
44
+ 1. Test all exported functions and classes
45
+ 2. Cover happy paths and edge cases
46
+ 3. Use vi.mock() for external dependencies
47
+ 4. Follow the AAA pattern (Arrange, Act, Assert)
48
+ 5. Use descriptive test names
49
+
50
+ Output ONLY the test file content — no explanations, no markdown fences.
51
+ Use import { describe, it, expect, vi } from 'vitest';`;
52
+
53
+ const JEST_SYSTEM_PROMPT = SYSTEM_PROMPT.replace(
54
+ "import { describe, it, expect, vi } from 'vitest';",
55
+ "Use jest globals (describe, it, expect, jest)."
56
+ );
57
+
58
+ /**
59
+ * TestGenerator — generates test files from source code via LLM.
60
+ *
61
+ * @experimental
62
+ *
63
+ * Usage:
64
+ * ```ts
65
+ * const gen = new TestGenerator({ model: { provider: 'anthropic', model: 'claude-sonnet-4-20250514' } });
66
+ * const result = await gen.generateTests('src/self-improve/absorb-scanner.ts');
67
+ * ```
68
+ */
69
+ export class TestGenerator {
70
+ private readonly config: TestGeneratorConfig;
71
+
72
+ constructor(config: TestGeneratorConfig) {
73
+ this.config = {
74
+ maxTokens: 4096,
75
+ temperature: 0.3,
76
+ testFramework: 'vitest',
77
+ ...config,
78
+ };
79
+ }
80
+
81
+ /**
82
+ * Generate a test file for the given source file.
83
+ *
84
+ * @param filePath - Path to the TypeScript source file
85
+ * @returns Generated test content and metadata
86
+ */
87
+ async generateTests(filePath: string): Promise<GeneratedTest> {
88
+ const absPath = resolve(filePath);
89
+
90
+ if (!existsSync(absPath)) {
91
+ throw new Error(`Source file not found: ${absPath}`);
92
+ }
93
+
94
+ const source = readFileSync(absPath, 'utf-8');
95
+ const fileName = basename(absPath, '.ts');
96
+ const dir = dirname(absPath);
97
+
98
+ const systemPrompt = this.config.testFramework === 'jest'
99
+ ? JEST_SYSTEM_PROMPT
100
+ : SYSTEM_PROMPT;
101
+
102
+ const userPrompt = [
103
+ `Generate tests for this TypeScript file: ${basename(absPath)}`,
104
+ '',
105
+ '```typescript',
106
+ source,
107
+ '```',
108
+ this.config.additionalContext ? `\nAdditional context:\n${this.config.additionalContext}` : '',
109
+ ].join('\n');
110
+
111
+ const response = await callLLM(this.config.model, [
112
+ { role: 'system', content: systemPrompt },
113
+ { role: 'user', content: userPrompt },
114
+ ], {
115
+ maxTokens: this.config.maxTokens,
116
+ temperature: this.config.temperature,
117
+ });
118
+
119
+ const testContent = cleanTestOutput(response.content);
120
+ const testCount = countTestCases(testContent);
121
+
122
+ // Determine test file path
123
+ const testFilePath = resolve(dir, '__tests__', `${fileName}.test.ts`);
124
+
125
+ return {
126
+ sourceFile: absPath,
127
+ testContent,
128
+ testFilePath,
129
+ testCount,
130
+ tokensUsed: response.tokensUsed ?? 0,
131
+ };
132
+ }
133
+
134
+ /**
135
+ * Generate tests for multiple files.
136
+ *
137
+ * @param filePaths - Array of source file paths
138
+ * @returns Array of generated tests
139
+ */
140
+ async generateBatch(filePaths: string[]): Promise<GeneratedTest[]> {
141
+ const results: GeneratedTest[] = [];
142
+ for (const filePath of filePaths) {
143
+ try {
144
+ const result = await this.generateTests(filePath);
145
+ results.push(result);
146
+ } catch {
147
+ // Skip files that fail — don't block the batch
148
+ }
149
+ }
150
+ return results;
151
+ }
152
+ }
153
+
154
+ /** Strip markdown fences if the LLM included them. */
155
+ function cleanTestOutput(content: string): string {
156
+ let cleaned = content.trim();
157
+ // Remove leading ```typescript or ```ts
158
+ if (cleaned.startsWith('```')) {
159
+ const firstNewline = cleaned.indexOf('\n');
160
+ if (firstNewline !== -1) {
161
+ cleaned = cleaned.slice(firstNewline + 1);
162
+ }
163
+ }
164
+ // Remove trailing ```
165
+ if (cleaned.endsWith('```')) {
166
+ cleaned = cleaned.slice(0, -3).trimEnd();
167
+ }
168
+ return cleaned;
169
+ }
170
+
171
+ /** Count the number of it() or test() calls in the content. */
172
+ function countTestCases(content: string): number {
173
+ const matches = content.match(/\b(?:it|test)\s*\(/g);
174
+ return matches ? matches.length : 0;
175
+ }
@@ -0,0 +1,186 @@
1
+ /**
2
+ * SkillRouter — Skill-based task routing via agent capabilities.
3
+ *
4
+ * Matches task requirements to agent capabilities, scores by overlap,
5
+ * and returns the best-fit agent. Supports required vs preferred skills.
6
+ *
7
+ * FW-0.6 — Skill-based routing via agent capabilities.
8
+ *
9
+ * @module skill-router
10
+ */
11
+
12
+ import type { AgentConfig, TaskDef, SlotRole } from './types';
13
+
14
+ // =============================================================================
15
+ // TYPES
16
+ // =============================================================================
17
+
18
+ export interface RoutingResult {
19
+ /** The selected agent, or null if no match */
20
+ agent: AgentConfig | null;
21
+ /** Score of the selected agent (0-100) */
22
+ score: number;
23
+ /** All candidates with their scores, sorted descending */
24
+ candidates: ScoredCandidate[];
25
+ /** Reason for selection or rejection */
26
+ reason: string;
27
+ }
28
+
29
+ export interface ScoredCandidate {
30
+ agent: AgentConfig;
31
+ score: number;
32
+ matchedCapabilities: string[];
33
+ roleMatch: boolean;
34
+ }
35
+
36
+ export interface RoutingPolicy {
37
+ /** Minimum score threshold (0-100) to be eligible (default 10) */
38
+ minScore?: number;
39
+ /** Weight for capability matches (default 15) */
40
+ capabilityWeight?: number;
41
+ /** Weight for exact role match (default 25) */
42
+ roleWeight?: number;
43
+ /** Weight for priority alignment (default 10) */
44
+ priorityWeight?: number;
45
+ /** Required capabilities — agent MUST have all of these */
46
+ requiredCapabilities?: string[];
47
+ }
48
+
49
+ // =============================================================================
50
+ // SKILL ROUTER
51
+ // =============================================================================
52
+
53
+ export class SkillRouter {
54
+ private defaultPolicy: Required<RoutingPolicy>;
55
+
56
+ constructor(policy: RoutingPolicy = {}) {
57
+ this.defaultPolicy = {
58
+ minScore: policy.minScore ?? 10,
59
+ capabilityWeight: policy.capabilityWeight ?? 15,
60
+ roleWeight: policy.roleWeight ?? 25,
61
+ priorityWeight: policy.priorityWeight ?? 10,
62
+ requiredCapabilities: policy.requiredCapabilities ?? [],
63
+ };
64
+ }
65
+
66
+ /**
67
+ * Route a task to the best-fit agent.
68
+ *
69
+ * Scoring:
70
+ * - Each capability keyword match in task title/description: +capabilityWeight
71
+ * - Exact role match (task.role === agent role mapping): +roleWeight
72
+ * - Priority alignment (agent.claimFilter.maxPriority >= task.priority): +priorityWeight
73
+ * - Required capabilities must ALL be present or agent is filtered out
74
+ */
75
+ route(task: TaskDef, agents: AgentConfig[], policy?: RoutingPolicy): RoutingResult {
76
+ const p = { ...this.defaultPolicy, ...policy };
77
+
78
+ if (agents.length === 0) {
79
+ return { agent: null, score: 0, candidates: [], reason: 'No agents available' };
80
+ }
81
+
82
+ const taskText = `${task.title} ${task.description}`.toLowerCase();
83
+ const candidates: ScoredCandidate[] = [];
84
+
85
+ for (const agent of agents) {
86
+ // Check required capabilities
87
+ const agentCaps = new Set(agent.capabilities.map(c => c.toLowerCase()));
88
+ if (p.requiredCapabilities.length > 0) {
89
+ const hasAll = p.requiredCapabilities.every(rc => agentCaps.has(rc.toLowerCase()));
90
+ if (!hasAll) continue;
91
+ }
92
+
93
+ // Check priority alignment
94
+ if (task.priority > agent.claimFilter.maxPriority) continue;
95
+
96
+ let score = 0;
97
+ const matchedCapabilities: string[] = [];
98
+
99
+ // Capability matching — check if agent capabilities appear in task text
100
+ for (const cap of agent.capabilities) {
101
+ const capLower = cap.toLowerCase();
102
+ if (taskText.includes(capLower)) {
103
+ score += p.capabilityWeight;
104
+ matchedCapabilities.push(cap);
105
+ }
106
+ }
107
+
108
+ // Role matching
109
+ const roleMatch = task.role ? this.agentMatchesRole(agent, task.role) : false;
110
+ if (roleMatch) {
111
+ score += p.roleWeight;
112
+ }
113
+
114
+ // Priority alignment bonus (closer to task priority = better fit)
115
+ const priorityDelta = agent.claimFilter.maxPriority - task.priority;
116
+ if (priorityDelta >= 0) {
117
+ // Agents whose maxPriority closely matches get a bonus
118
+ score += Math.max(0, p.priorityWeight - priorityDelta);
119
+ }
120
+
121
+ // Base score for being eligible at all
122
+ score += 5;
123
+
124
+ candidates.push({ agent, score, matchedCapabilities, roleMatch });
125
+ }
126
+
127
+ // Sort by score descending
128
+ candidates.sort((a, b) => b.score - a.score);
129
+
130
+ // Apply minimum threshold
131
+ const eligible = candidates.filter(c => c.score >= p.minScore);
132
+
133
+ if (eligible.length === 0) {
134
+ return {
135
+ agent: null,
136
+ score: 0,
137
+ candidates,
138
+ reason: candidates.length > 0
139
+ ? `${candidates.length} candidates scored below minimum threshold (${p.minScore})`
140
+ : 'No candidates matched task requirements',
141
+ };
142
+ }
143
+
144
+ const winner = eligible[0];
145
+ return {
146
+ agent: winner.agent,
147
+ score: winner.score,
148
+ candidates,
149
+ reason: `Best fit: ${winner.agent.name} (score ${winner.score}, ${winner.matchedCapabilities.length} capability matches${winner.roleMatch ? ', role match' : ''})`,
150
+ };
151
+ }
152
+
153
+ /**
154
+ * Route a task to multiple agents (for parallel execution or fallback chains).
155
+ */
156
+ routeMultiple(
157
+ task: TaskDef,
158
+ agents: AgentConfig[],
159
+ count: number,
160
+ policy?: RoutingPolicy
161
+ ): RoutingResult {
162
+ const result = this.route(task, agents, policy);
163
+ // Already sorted — just return top N candidates
164
+ const topN = result.candidates.slice(0, count);
165
+ return {
166
+ ...result,
167
+ agent: topN[0]?.agent ?? null,
168
+ candidates: topN,
169
+ reason: `Top ${Math.min(count, topN.length)} candidates selected`,
170
+ };
171
+ }
172
+
173
+ // ── Private ──
174
+
175
+ private agentMatchesRole(agent: AgentConfig, taskRole: SlotRole): boolean {
176
+ // Map agent roles to slot roles
177
+ const roleMapping: Record<string, SlotRole[]> = {
178
+ architect: ['researcher', 'reviewer'],
179
+ coder: ['coder', 'flex'],
180
+ researcher: ['researcher'],
181
+ reviewer: ['reviewer', 'tester'],
182
+ };
183
+ const mappedRoles = roleMapping[agent.role] ?? [];
184
+ return mappedRoles.includes(taskRole) || agent.claimFilter.roles.includes(taskRole);
185
+ }
186
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Skills module barrel
3
+ * Re-exports all skills functionality from @holoscript/framework
4
+ */
5
+ export * from './skill-md-bridge';