lex-agentic-inference 0.1.0

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 (328) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +12 -0
  3. data/Gemfile +5 -0
  4. data/LICENSE +21 -0
  5. data/README.md +13 -0
  6. data/lex-agentic-inference.gemspec +30 -0
  7. data/lib/legion/extensions/agentic/inference/abductive/client.rb +25 -0
  8. data/lib/legion/extensions/agentic/inference/abductive/helpers/abduction_engine.rb +164 -0
  9. data/lib/legion/extensions/agentic/inference/abductive/helpers/constants.rb +39 -0
  10. data/lib/legion/extensions/agentic/inference/abductive/helpers/hypothesis.rb +106 -0
  11. data/lib/legion/extensions/agentic/inference/abductive/helpers/observation.rb +39 -0
  12. data/lib/legion/extensions/agentic/inference/abductive/runners/abductive_reasoning.rb +129 -0
  13. data/lib/legion/extensions/agentic/inference/abductive/version.rb +13 -0
  14. data/lib/legion/extensions/agentic/inference/abductive.rb +20 -0
  15. data/lib/legion/extensions/agentic/inference/affordance/actors/scan.rb +31 -0
  16. data/lib/legion/extensions/agentic/inference/affordance/client.rb +28 -0
  17. data/lib/legion/extensions/agentic/inference/affordance/helpers/affordance_field.rb +123 -0
  18. data/lib/legion/extensions/agentic/inference/affordance/helpers/affordance_item.rb +75 -0
  19. data/lib/legion/extensions/agentic/inference/affordance/helpers/constants.rb +42 -0
  20. data/lib/legion/extensions/agentic/inference/affordance/runners/affordance.rb +90 -0
  21. data/lib/legion/extensions/agentic/inference/affordance/version.rb +13 -0
  22. data/lib/legion/extensions/agentic/inference/affordance.rb +19 -0
  23. data/lib/legion/extensions/agentic/inference/analogical/client.rb +28 -0
  24. data/lib/legion/extensions/agentic/inference/analogical/helpers/analogy_engine.rb +209 -0
  25. data/lib/legion/extensions/agentic/inference/analogical/helpers/constants.rb +38 -0
  26. data/lib/legion/extensions/agentic/inference/analogical/helpers/structure_map.rb +113 -0
  27. data/lib/legion/extensions/agentic/inference/analogical/runners/analogical_reasoning.rb +106 -0
  28. data/lib/legion/extensions/agentic/inference/analogical/version.rb +13 -0
  29. data/lib/legion/extensions/agentic/inference/analogical.rb +19 -0
  30. data/lib/legion/extensions/agentic/inference/argument_mapping/client.rb +19 -0
  31. data/lib/legion/extensions/agentic/inference/argument_mapping/helpers/argument.rb +102 -0
  32. data/lib/legion/extensions/agentic/inference/argument_mapping/helpers/argument_engine.rb +131 -0
  33. data/lib/legion/extensions/agentic/inference/argument_mapping/helpers/constants.rb +44 -0
  34. data/lib/legion/extensions/agentic/inference/argument_mapping/runners/argument_mapping.rb +78 -0
  35. data/lib/legion/extensions/agentic/inference/argument_mapping/version.rb +13 -0
  36. data/lib/legion/extensions/agentic/inference/argument_mapping.rb +19 -0
  37. data/lib/legion/extensions/agentic/inference/bayesian/client.rb +28 -0
  38. data/lib/legion/extensions/agentic/inference/bayesian/helpers/belief.rb +96 -0
  39. data/lib/legion/extensions/agentic/inference/bayesian/helpers/belief_network.rb +147 -0
  40. data/lib/legion/extensions/agentic/inference/bayesian/helpers/constants.rb +36 -0
  41. data/lib/legion/extensions/agentic/inference/bayesian/runners/bayesian_belief.rb +125 -0
  42. data/lib/legion/extensions/agentic/inference/bayesian/version.rb +13 -0
  43. data/lib/legion/extensions/agentic/inference/bayesian.rb +19 -0
  44. data/lib/legion/extensions/agentic/inference/belief_revision/client.rb +19 -0
  45. data/lib/legion/extensions/agentic/inference/belief_revision/helpers/belief.rb +155 -0
  46. data/lib/legion/extensions/agentic/inference/belief_revision/helpers/belief_network.rb +193 -0
  47. data/lib/legion/extensions/agentic/inference/belief_revision/helpers/constants.rb +54 -0
  48. data/lib/legion/extensions/agentic/inference/belief_revision/helpers/evidence.rb +49 -0
  49. data/lib/legion/extensions/agentic/inference/belief_revision/runners/belief_revision.rb +89 -0
  50. data/lib/legion/extensions/agentic/inference/belief_revision/version.rb +13 -0
  51. data/lib/legion/extensions/agentic/inference/belief_revision.rb +21 -0
  52. data/lib/legion/extensions/agentic/inference/causal_attribution/client.rb +27 -0
  53. data/lib/legion/extensions/agentic/inference/causal_attribution/helpers/attribution.rb +92 -0
  54. data/lib/legion/extensions/agentic/inference/causal_attribution/helpers/attribution_engine.rb +159 -0
  55. data/lib/legion/extensions/agentic/inference/causal_attribution/runners/causal_attribution.rb +111 -0
  56. data/lib/legion/extensions/agentic/inference/causal_attribution/version.rb +13 -0
  57. data/lib/legion/extensions/agentic/inference/causal_attribution.rb +18 -0
  58. data/lib/legion/extensions/agentic/inference/causal_reasoning/client.rb +24 -0
  59. data/lib/legion/extensions/agentic/inference/causal_reasoning/helpers/causal_edge.rb +101 -0
  60. data/lib/legion/extensions/agentic/inference/causal_reasoning/helpers/causal_graph.rb +184 -0
  61. data/lib/legion/extensions/agentic/inference/causal_reasoning/helpers/constants.rb +40 -0
  62. data/lib/legion/extensions/agentic/inference/causal_reasoning/runners/causal_reasoning.rb +111 -0
  63. data/lib/legion/extensions/agentic/inference/causal_reasoning/version.rb +13 -0
  64. data/lib/legion/extensions/agentic/inference/causal_reasoning.rb +19 -0
  65. data/lib/legion/extensions/agentic/inference/coherence/client.rb +28 -0
  66. data/lib/legion/extensions/agentic/inference/coherence/helpers/coherence_engine.rb +170 -0
  67. data/lib/legion/extensions/agentic/inference/coherence/helpers/constants.rb +35 -0
  68. data/lib/legion/extensions/agentic/inference/coherence/helpers/proposition.rb +100 -0
  69. data/lib/legion/extensions/agentic/inference/coherence/runners/cognitive_coherence.rb +123 -0
  70. data/lib/legion/extensions/agentic/inference/coherence/version.rb +13 -0
  71. data/lib/legion/extensions/agentic/inference/coherence.rb +19 -0
  72. data/lib/legion/extensions/agentic/inference/counterfactual/client.rb +19 -0
  73. data/lib/legion/extensions/agentic/inference/counterfactual/helpers/constants.rb +40 -0
  74. data/lib/legion/extensions/agentic/inference/counterfactual/helpers/counterfactual_engine.rb +157 -0
  75. data/lib/legion/extensions/agentic/inference/counterfactual/helpers/scenario.rb +98 -0
  76. data/lib/legion/extensions/agentic/inference/counterfactual/runners/counterfactual.rb +106 -0
  77. data/lib/legion/extensions/agentic/inference/counterfactual/version.rb +13 -0
  78. data/lib/legion/extensions/agentic/inference/counterfactual.rb +19 -0
  79. data/lib/legion/extensions/agentic/inference/debugging/client.rb +30 -0
  80. data/lib/legion/extensions/agentic/inference/debugging/helpers/causal_trace.rb +51 -0
  81. data/lib/legion/extensions/agentic/inference/debugging/helpers/constants.rb +58 -0
  82. data/lib/legion/extensions/agentic/inference/debugging/helpers/correction.rb +56 -0
  83. data/lib/legion/extensions/agentic/inference/debugging/helpers/debugging_engine.rb +156 -0
  84. data/lib/legion/extensions/agentic/inference/debugging/helpers/reasoning_error.rb +97 -0
  85. data/lib/legion/extensions/agentic/inference/debugging/runners/cognitive_debugging.rb +178 -0
  86. data/lib/legion/extensions/agentic/inference/debugging/version.rb +13 -0
  87. data/lib/legion/extensions/agentic/inference/debugging.rb +21 -0
  88. data/lib/legion/extensions/agentic/inference/enactive_cognition/client.rb +27 -0
  89. data/lib/legion/extensions/agentic/inference/enactive_cognition/helpers/enaction_engine.rb +120 -0
  90. data/lib/legion/extensions/agentic/inference/enactive_cognition/helpers/sensorimotor_loop.rb +122 -0
  91. data/lib/legion/extensions/agentic/inference/enactive_cognition/runners/enactive_cognition.rb +124 -0
  92. data/lib/legion/extensions/agentic/inference/enactive_cognition/version.rb +13 -0
  93. data/lib/legion/extensions/agentic/inference/enactive_cognition.rb +18 -0
  94. data/lib/legion/extensions/agentic/inference/expectation_violation/helpers/client.rb +17 -0
  95. data/lib/legion/extensions/agentic/inference/expectation_violation/helpers/constants.rb +47 -0
  96. data/lib/legion/extensions/agentic/inference/expectation_violation/helpers/expectation.rb +82 -0
  97. data/lib/legion/extensions/agentic/inference/expectation_violation/helpers/violation_engine.rb +126 -0
  98. data/lib/legion/extensions/agentic/inference/expectation_violation/runners/expectation_violation.rb +76 -0
  99. data/lib/legion/extensions/agentic/inference/expectation_violation/version.rb +13 -0
  100. data/lib/legion/extensions/agentic/inference/expectation_violation.rb +19 -0
  101. data/lib/legion/extensions/agentic/inference/free_energy/client.rb +19 -0
  102. data/lib/legion/extensions/agentic/inference/free_energy/helpers/belief.rb +127 -0
  103. data/lib/legion/extensions/agentic/inference/free_energy/helpers/constants.rb +58 -0
  104. data/lib/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine.rb +156 -0
  105. data/lib/legion/extensions/agentic/inference/free_energy/runners/free_energy.rb +97 -0
  106. data/lib/legion/extensions/agentic/inference/free_energy/version.rb +13 -0
  107. data/lib/legion/extensions/agentic/inference/free_energy.rb +19 -0
  108. data/lib/legion/extensions/agentic/inference/gravity/client.rb +29 -0
  109. data/lib/legion/extensions/agentic/inference/gravity/helpers/attractor.rb +77 -0
  110. data/lib/legion/extensions/agentic/inference/gravity/helpers/constants.rb +76 -0
  111. data/lib/legion/extensions/agentic/inference/gravity/helpers/gravity_engine.rb +164 -0
  112. data/lib/legion/extensions/agentic/inference/gravity/helpers/orbiting_thought.rb +64 -0
  113. data/lib/legion/extensions/agentic/inference/gravity/runners/gravity.rb +132 -0
  114. data/lib/legion/extensions/agentic/inference/gravity/version.rb +13 -0
  115. data/lib/legion/extensions/agentic/inference/gravity.rb +20 -0
  116. data/lib/legion/extensions/agentic/inference/horizon/actors/adjust.rb +45 -0
  117. data/lib/legion/extensions/agentic/inference/horizon/client.rb +28 -0
  118. data/lib/legion/extensions/agentic/inference/horizon/helpers/constants.rb +43 -0
  119. data/lib/legion/extensions/agentic/inference/horizon/helpers/horizon_engine.rb +110 -0
  120. data/lib/legion/extensions/agentic/inference/horizon/helpers/projection.rb +59 -0
  121. data/lib/legion/extensions/agentic/inference/horizon/runners/cognitive_horizon.rb +107 -0
  122. data/lib/legion/extensions/agentic/inference/horizon/version.rb +13 -0
  123. data/lib/legion/extensions/agentic/inference/horizon.rb +19 -0
  124. data/lib/legion/extensions/agentic/inference/hypothesis_testing/client.rb +28 -0
  125. data/lib/legion/extensions/agentic/inference/hypothesis_testing/helpers/constants.rb +37 -0
  126. data/lib/legion/extensions/agentic/inference/hypothesis_testing/helpers/hypothesis.rb +83 -0
  127. data/lib/legion/extensions/agentic/inference/hypothesis_testing/helpers/hypothesis_engine.rb +97 -0
  128. data/lib/legion/extensions/agentic/inference/hypothesis_testing/runners/hypothesis_testing.rb +115 -0
  129. data/lib/legion/extensions/agentic/inference/hypothesis_testing/version.rb +13 -0
  130. data/lib/legion/extensions/agentic/inference/hypothesis_testing.rb +19 -0
  131. data/lib/legion/extensions/agentic/inference/intuition/client.rb +19 -0
  132. data/lib/legion/extensions/agentic/inference/intuition/helpers/constants.rb +60 -0
  133. data/lib/legion/extensions/agentic/inference/intuition/helpers/heuristic.rb +66 -0
  134. data/lib/legion/extensions/agentic/inference/intuition/helpers/intuition_engine.rb +157 -0
  135. data/lib/legion/extensions/agentic/inference/intuition/helpers/pattern.rb +105 -0
  136. data/lib/legion/extensions/agentic/inference/intuition/runners/intuition.rb +87 -0
  137. data/lib/legion/extensions/agentic/inference/intuition/version.rb +13 -0
  138. data/lib/legion/extensions/agentic/inference/intuition.rb +20 -0
  139. data/lib/legion/extensions/agentic/inference/magnet/client.rb +29 -0
  140. data/lib/legion/extensions/agentic/inference/magnet/helpers/constants.rb +57 -0
  141. data/lib/legion/extensions/agentic/inference/magnet/helpers/field.rb +105 -0
  142. data/lib/legion/extensions/agentic/inference/magnet/helpers/magnet_engine.rb +179 -0
  143. data/lib/legion/extensions/agentic/inference/magnet/helpers/pole.rb +80 -0
  144. data/lib/legion/extensions/agentic/inference/magnet/runners/cognitive_magnet.rb +124 -0
  145. data/lib/legion/extensions/agentic/inference/magnet/version.rb +13 -0
  146. data/lib/legion/extensions/agentic/inference/magnet.rb +21 -0
  147. data/lib/legion/extensions/agentic/inference/momentum/helpers/client.rb +17 -0
  148. data/lib/legion/extensions/agentic/inference/momentum/helpers/constants.rb +65 -0
  149. data/lib/legion/extensions/agentic/inference/momentum/helpers/idea.rb +112 -0
  150. data/lib/legion/extensions/agentic/inference/momentum/helpers/momentum_engine.rb +127 -0
  151. data/lib/legion/extensions/agentic/inference/momentum/runners/cognitive_momentum.rb +101 -0
  152. data/lib/legion/extensions/agentic/inference/momentum/version.rb +13 -0
  153. data/lib/legion/extensions/agentic/inference/momentum.rb +19 -0
  154. data/lib/legion/extensions/agentic/inference/perceptual_inference/client.rb +28 -0
  155. data/lib/legion/extensions/agentic/inference/perceptual_inference/helpers/constants.rb +34 -0
  156. data/lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb +154 -0
  157. data/lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_hypothesis.rb +100 -0
  158. data/lib/legion/extensions/agentic/inference/perceptual_inference/runners/perceptual_inference.rb +120 -0
  159. data/lib/legion/extensions/agentic/inference/perceptual_inference/version.rb +13 -0
  160. data/lib/legion/extensions/agentic/inference/perceptual_inference.rb +19 -0
  161. data/lib/legion/extensions/agentic/inference/prediction/actors/expire_predictions.rb +45 -0
  162. data/lib/legion/extensions/agentic/inference/prediction/client.rb +27 -0
  163. data/lib/legion/extensions/agentic/inference/prediction/helpers/modes.rb +28 -0
  164. data/lib/legion/extensions/agentic/inference/prediction/helpers/prediction_store.rb +66 -0
  165. data/lib/legion/extensions/agentic/inference/prediction/runners/prediction.rb +146 -0
  166. data/lib/legion/extensions/agentic/inference/prediction/version.rb +13 -0
  167. data/lib/legion/extensions/agentic/inference/prediction.rb +18 -0
  168. data/lib/legion/extensions/agentic/inference/predictive_coding/actors/decay.rb +45 -0
  169. data/lib/legion/extensions/agentic/inference/predictive_coding/client.rb +28 -0
  170. data/lib/legion/extensions/agentic/inference/predictive_coding/helpers/constants.rb +46 -0
  171. data/lib/legion/extensions/agentic/inference/predictive_coding/helpers/generative_model.rb +187 -0
  172. data/lib/legion/extensions/agentic/inference/predictive_coding/helpers/prediction_error.rb +59 -0
  173. data/lib/legion/extensions/agentic/inference/predictive_coding/runners/predictive_coding.rb +171 -0
  174. data/lib/legion/extensions/agentic/inference/predictive_coding/version.rb +13 -0
  175. data/lib/legion/extensions/agentic/inference/predictive_coding.rb +20 -0
  176. data/lib/legion/extensions/agentic/inference/predictive_processing/client.rb +28 -0
  177. data/lib/legion/extensions/agentic/inference/predictive_processing/helpers/constants.rb +35 -0
  178. data/lib/legion/extensions/agentic/inference/predictive_processing/helpers/generative_model.rb +142 -0
  179. data/lib/legion/extensions/agentic/inference/predictive_processing/helpers/predictive_processor.rb +129 -0
  180. data/lib/legion/extensions/agentic/inference/predictive_processing/runners/predictive_processing.rb +104 -0
  181. data/lib/legion/extensions/agentic/inference/predictive_processing/version.rb +13 -0
  182. data/lib/legion/extensions/agentic/inference/predictive_processing.rb +19 -0
  183. data/lib/legion/extensions/agentic/inference/reality_testing/client.rb +28 -0
  184. data/lib/legion/extensions/agentic/inference/reality_testing/helpers/belief.rb +98 -0
  185. data/lib/legion/extensions/agentic/inference/reality_testing/helpers/constants.rb +41 -0
  186. data/lib/legion/extensions/agentic/inference/reality_testing/helpers/reality_engine.rb +104 -0
  187. data/lib/legion/extensions/agentic/inference/reality_testing/runners/reality_testing.rb +94 -0
  188. data/lib/legion/extensions/agentic/inference/reality_testing/version.rb +13 -0
  189. data/lib/legion/extensions/agentic/inference/reality_testing.rb +19 -0
  190. data/lib/legion/extensions/agentic/inference/schema/client.rb +26 -0
  191. data/lib/legion/extensions/agentic/inference/schema/helpers/causal_relation.rb +70 -0
  192. data/lib/legion/extensions/agentic/inference/schema/helpers/constants.rb +50 -0
  193. data/lib/legion/extensions/agentic/inference/schema/helpers/world_model.rb +173 -0
  194. data/lib/legion/extensions/agentic/inference/schema/runners/schema.rb +101 -0
  195. data/lib/legion/extensions/agentic/inference/schema/version.rb +13 -0
  196. data/lib/legion/extensions/agentic/inference/schema.rb +19 -0
  197. data/lib/legion/extensions/agentic/inference/uncertainty_tolerance/client.rb +28 -0
  198. data/lib/legion/extensions/agentic/inference/uncertainty_tolerance/helpers/constants.rb +42 -0
  199. data/lib/legion/extensions/agentic/inference/uncertainty_tolerance/helpers/decision.rb +66 -0
  200. data/lib/legion/extensions/agentic/inference/uncertainty_tolerance/helpers/tolerance_engine.rb +139 -0
  201. data/lib/legion/extensions/agentic/inference/uncertainty_tolerance/runners/uncertainty_tolerance.rb +129 -0
  202. data/lib/legion/extensions/agentic/inference/uncertainty_tolerance/version.rb +13 -0
  203. data/lib/legion/extensions/agentic/inference/uncertainty_tolerance.rb +19 -0
  204. data/lib/legion/extensions/agentic/inference/version.rb +11 -0
  205. data/lib/legion/extensions/agentic/inference.rb +44 -0
  206. data/spec/legion/extensions/agentic/inference/abductive/client_spec.rb +25 -0
  207. data/spec/legion/extensions/agentic/inference/abductive/runners/abductive_reasoning_spec.rb +349 -0
  208. data/spec/legion/extensions/agentic/inference/affordance/client_spec.rb +26 -0
  209. data/spec/legion/extensions/agentic/inference/affordance/helpers/affordance_field_spec.rb +131 -0
  210. data/spec/legion/extensions/agentic/inference/affordance/helpers/affordance_item_spec.rb +107 -0
  211. data/spec/legion/extensions/agentic/inference/affordance/runners/affordance_spec.rb +78 -0
  212. data/spec/legion/extensions/agentic/inference/analogical/client_spec.rb +31 -0
  213. data/spec/legion/extensions/agentic/inference/analogical/helpers/analogy_engine_spec.rb +276 -0
  214. data/spec/legion/extensions/agentic/inference/analogical/helpers/structure_map_spec.rb +255 -0
  215. data/spec/legion/extensions/agentic/inference/analogical/runners/analogical_reasoning_spec.rb +213 -0
  216. data/spec/legion/extensions/agentic/inference/argument_mapping/client_spec.rb +18 -0
  217. data/spec/legion/extensions/agentic/inference/argument_mapping/helpers/argument_engine_spec.rb +218 -0
  218. data/spec/legion/extensions/agentic/inference/argument_mapping/helpers/argument_spec.rb +231 -0
  219. data/spec/legion/extensions/agentic/inference/argument_mapping/runners/argument_mapping_spec.rb +171 -0
  220. data/spec/legion/extensions/agentic/inference/bayesian/client_spec.rb +20 -0
  221. data/spec/legion/extensions/agentic/inference/bayesian/helpers/belief_network_spec.rb +178 -0
  222. data/spec/legion/extensions/agentic/inference/bayesian/helpers/belief_spec.rb +137 -0
  223. data/spec/legion/extensions/agentic/inference/bayesian/runners/bayesian_belief_spec.rb +176 -0
  224. data/spec/legion/extensions/agentic/inference/belief_revision/client_spec.rb +31 -0
  225. data/spec/legion/extensions/agentic/inference/belief_revision/helpers/belief_network_spec.rb +176 -0
  226. data/spec/legion/extensions/agentic/inference/belief_revision/helpers/belief_spec.rb +153 -0
  227. data/spec/legion/extensions/agentic/inference/belief_revision/helpers/evidence_spec.rb +51 -0
  228. data/spec/legion/extensions/agentic/inference/belief_revision/runners/belief_revision_spec.rb +106 -0
  229. data/spec/legion/extensions/agentic/inference/causal_attribution/client_spec.rb +24 -0
  230. data/spec/legion/extensions/agentic/inference/causal_attribution/helpers/attribution_engine_spec.rb +181 -0
  231. data/spec/legion/extensions/agentic/inference/causal_attribution/helpers/attribution_spec.rb +108 -0
  232. data/spec/legion/extensions/agentic/inference/causal_attribution/runners/causal_attribution_spec.rb +142 -0
  233. data/spec/legion/extensions/agentic/inference/causal_reasoning/client_spec.rb +35 -0
  234. data/spec/legion/extensions/agentic/inference/causal_reasoning/helpers/causal_edge_spec.rb +158 -0
  235. data/spec/legion/extensions/agentic/inference/causal_reasoning/helpers/causal_graph_spec.rb +259 -0
  236. data/spec/legion/extensions/agentic/inference/causal_reasoning/runners/causal_reasoning_spec.rb +161 -0
  237. data/spec/legion/extensions/agentic/inference/coherence/client_spec.rb +17 -0
  238. data/spec/legion/extensions/agentic/inference/coherence/runners/cognitive_coherence_spec.rb +267 -0
  239. data/spec/legion/extensions/agentic/inference/counterfactual/client_spec.rb +48 -0
  240. data/spec/legion/extensions/agentic/inference/counterfactual/helpers/constants_spec.rb +55 -0
  241. data/spec/legion/extensions/agentic/inference/counterfactual/helpers/counterfactual_engine_spec.rb +234 -0
  242. data/spec/legion/extensions/agentic/inference/counterfactual/helpers/scenario_spec.rb +193 -0
  243. data/spec/legion/extensions/agentic/inference/counterfactual/runners/counterfactual_spec.rb +179 -0
  244. data/spec/legion/extensions/agentic/inference/debugging/client_spec.rb +46 -0
  245. data/spec/legion/extensions/agentic/inference/debugging/helpers/causal_trace_spec.rb +84 -0
  246. data/spec/legion/extensions/agentic/inference/debugging/helpers/constants_spec.rb +97 -0
  247. data/spec/legion/extensions/agentic/inference/debugging/helpers/correction_spec.rb +98 -0
  248. data/spec/legion/extensions/agentic/inference/debugging/helpers/debugging_engine_spec.rb +290 -0
  249. data/spec/legion/extensions/agentic/inference/debugging/helpers/reasoning_error_spec.rb +164 -0
  250. data/spec/legion/extensions/agentic/inference/debugging/runners/cognitive_debugging_spec.rb +301 -0
  251. data/spec/legion/extensions/agentic/inference/enactive_cognition/client_spec.rb +19 -0
  252. data/spec/legion/extensions/agentic/inference/enactive_cognition/helpers/enaction_engine_spec.rb +181 -0
  253. data/spec/legion/extensions/agentic/inference/enactive_cognition/helpers/sensorimotor_loop_spec.rb +184 -0
  254. data/spec/legion/extensions/agentic/inference/enactive_cognition/runners/enactive_cognition_spec.rb +214 -0
  255. data/spec/legion/extensions/agentic/inference/expectation_violation/expectation_violation_spec.rb +11 -0
  256. data/spec/legion/extensions/agentic/inference/expectation_violation/helpers/expectation_spec.rb +102 -0
  257. data/spec/legion/extensions/agentic/inference/expectation_violation/helpers/violation_engine_spec.rb +121 -0
  258. data/spec/legion/extensions/agentic/inference/expectation_violation/runners/expectation_violation_spec.rb +59 -0
  259. data/spec/legion/extensions/agentic/inference/free_energy/client_spec.rb +46 -0
  260. data/spec/legion/extensions/agentic/inference/free_energy/helpers/belief_spec.rb +183 -0
  261. data/spec/legion/extensions/agentic/inference/free_energy/helpers/free_energy_engine_spec.rb +211 -0
  262. data/spec/legion/extensions/agentic/inference/free_energy/runners/free_energy_spec.rb +118 -0
  263. data/spec/legion/extensions/agentic/inference/gravity/client_spec.rb +24 -0
  264. data/spec/legion/extensions/agentic/inference/gravity/helpers/attractor_spec.rb +143 -0
  265. data/spec/legion/extensions/agentic/inference/gravity/helpers/constants_spec.rb +107 -0
  266. data/spec/legion/extensions/agentic/inference/gravity/helpers/gravity_engine_spec.rb +193 -0
  267. data/spec/legion/extensions/agentic/inference/gravity/helpers/orbiting_thought_spec.rb +103 -0
  268. data/spec/legion/extensions/agentic/inference/gravity/runners/gravity_spec.rb +159 -0
  269. data/spec/legion/extensions/agentic/inference/horizon/client_spec.rb +58 -0
  270. data/spec/legion/extensions/agentic/inference/horizon/helpers/constants_spec.rb +98 -0
  271. data/spec/legion/extensions/agentic/inference/horizon/helpers/horizon_engine_spec.rb +325 -0
  272. data/spec/legion/extensions/agentic/inference/horizon/helpers/projection_spec.rb +155 -0
  273. data/spec/legion/extensions/agentic/inference/horizon/runners/cognitive_horizon_spec.rb +269 -0
  274. data/spec/legion/extensions/agentic/inference/hypothesis_testing/helpers/constants_spec.rb +38 -0
  275. data/spec/legion/extensions/agentic/inference/hypothesis_testing/helpers/hypothesis_engine_spec.rb +182 -0
  276. data/spec/legion/extensions/agentic/inference/hypothesis_testing/helpers/hypothesis_spec.rb +172 -0
  277. data/spec/legion/extensions/agentic/inference/hypothesis_testing/hypothesis_testing_spec.rb +16 -0
  278. data/spec/legion/extensions/agentic/inference/hypothesis_testing/runners/hypothesis_testing_spec.rb +159 -0
  279. data/spec/legion/extensions/agentic/inference/intuition/client_spec.rb +33 -0
  280. data/spec/legion/extensions/agentic/inference/intuition/helpers/heuristic_spec.rb +82 -0
  281. data/spec/legion/extensions/agentic/inference/intuition/helpers/intuition_engine_spec.rb +163 -0
  282. data/spec/legion/extensions/agentic/inference/intuition/helpers/pattern_spec.rb +160 -0
  283. data/spec/legion/extensions/agentic/inference/intuition/runners/intuition_spec.rb +107 -0
  284. data/spec/legion/extensions/agentic/inference/magnet/client_spec.rb +30 -0
  285. data/spec/legion/extensions/agentic/inference/magnet/helpers/constants_spec.rb +120 -0
  286. data/spec/legion/extensions/agentic/inference/magnet/helpers/field_spec.rb +193 -0
  287. data/spec/legion/extensions/agentic/inference/magnet/helpers/magnet_engine_spec.rb +281 -0
  288. data/spec/legion/extensions/agentic/inference/magnet/helpers/pole_spec.rb +211 -0
  289. data/spec/legion/extensions/agentic/inference/magnet/runners/cognitive_magnet_spec.rb +201 -0
  290. data/spec/legion/extensions/agentic/inference/momentum/cognitive_momentum_spec.rb +11 -0
  291. data/spec/legion/extensions/agentic/inference/momentum/helpers/idea_spec.rb +152 -0
  292. data/spec/legion/extensions/agentic/inference/momentum/helpers/momentum_engine_spec.rb +154 -0
  293. data/spec/legion/extensions/agentic/inference/momentum/runners/cognitive_momentum_spec.rb +97 -0
  294. data/spec/legion/extensions/agentic/inference/perceptual_inference/client_spec.rb +39 -0
  295. data/spec/legion/extensions/agentic/inference/perceptual_inference/helpers/constants_spec.rb +97 -0
  296. data/spec/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field_spec.rb +270 -0
  297. data/spec/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_hypothesis_spec.rb +206 -0
  298. data/spec/legion/extensions/agentic/inference/perceptual_inference/runners/perceptual_inference_spec.rb +305 -0
  299. data/spec/legion/extensions/agentic/inference/prediction/actors/expire_predictions_spec.rb +46 -0
  300. data/spec/legion/extensions/agentic/inference/prediction/client_spec.rb +14 -0
  301. data/spec/legion/extensions/agentic/inference/prediction/helpers/modes_spec.rb +118 -0
  302. data/spec/legion/extensions/agentic/inference/prediction/helpers/prediction_store_spec.rb +262 -0
  303. data/spec/legion/extensions/agentic/inference/prediction/runners/prediction_spec.rb +116 -0
  304. data/spec/legion/extensions/agentic/inference/predictive_coding/client_spec.rb +74 -0
  305. data/spec/legion/extensions/agentic/inference/predictive_coding/helpers/generative_model_spec.rb +194 -0
  306. data/spec/legion/extensions/agentic/inference/predictive_coding/helpers/prediction_error_spec.rb +109 -0
  307. data/spec/legion/extensions/agentic/inference/predictive_coding/runners/predictive_coding_spec.rb +210 -0
  308. data/spec/legion/extensions/agentic/inference/predictive_processing/client_spec.rb +82 -0
  309. data/spec/legion/extensions/agentic/inference/predictive_processing/helpers/generative_model_spec.rb +220 -0
  310. data/spec/legion/extensions/agentic/inference/predictive_processing/helpers/predictive_processor_spec.rb +206 -0
  311. data/spec/legion/extensions/agentic/inference/predictive_processing/runners/predictive_processing_spec.rb +213 -0
  312. data/spec/legion/extensions/agentic/inference/reality_testing/client_spec.rb +29 -0
  313. data/spec/legion/extensions/agentic/inference/reality_testing/helpers/belief_spec.rb +197 -0
  314. data/spec/legion/extensions/agentic/inference/reality_testing/helpers/constants_spec.rb +78 -0
  315. data/spec/legion/extensions/agentic/inference/reality_testing/helpers/reality_engine_spec.rb +191 -0
  316. data/spec/legion/extensions/agentic/inference/reality_testing/runners/reality_testing_spec.rb +154 -0
  317. data/spec/legion/extensions/agentic/inference/schema/client_spec.rb +53 -0
  318. data/spec/legion/extensions/agentic/inference/schema/helpers/causal_relation_spec.rb +108 -0
  319. data/spec/legion/extensions/agentic/inference/schema/helpers/constants_spec.rb +54 -0
  320. data/spec/legion/extensions/agentic/inference/schema/helpers/world_model_spec.rb +179 -0
  321. data/spec/legion/extensions/agentic/inference/schema/runners/schema_spec.rb +146 -0
  322. data/spec/legion/extensions/agentic/inference/uncertainty_tolerance/client_spec.rb +18 -0
  323. data/spec/legion/extensions/agentic/inference/uncertainty_tolerance/helpers/constants_spec.rb +62 -0
  324. data/spec/legion/extensions/agentic/inference/uncertainty_tolerance/helpers/decision_spec.rb +125 -0
  325. data/spec/legion/extensions/agentic/inference/uncertainty_tolerance/helpers/tolerance_engine_spec.rb +184 -0
  326. data/spec/legion/extensions/agentic/inference/uncertainty_tolerance/runners/uncertainty_tolerance_spec.rb +157 -0
  327. data/spec/spec_helper.rb +46 -0
  328. metadata +412 -0
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Inference::PredictiveCoding::Helpers::PredictionError do
4
+ let(:constants) { Legion::Extensions::Agentic::Inference::PredictiveCoding::Helpers::Constants }
5
+
6
+ describe '#initialize' do
7
+ it 'stores domain, predicted, actual' do
8
+ error = described_class.new(domain: :vision, predicted: 0.8, actual: 0.9)
9
+ expect(error.domain).to eq(:vision)
10
+ expect(error.predicted).to eq(0.8)
11
+ expect(error.actual).to eq(0.9)
12
+ end
13
+
14
+ it 'stores a timestamp' do
15
+ error = described_class.new(domain: :vision, predicted: 0.5, actual: 0.5)
16
+ expect(error.timestamp).to be_a(Time)
17
+ end
18
+
19
+ it 'uses DEFAULT_PRECISION when none provided' do
20
+ error = described_class.new(domain: :vision, predicted: 0.5, actual: 0.5)
21
+ expect(error.precision).to eq(constants::DEFAULT_PRECISION)
22
+ end
23
+
24
+ it 'accepts explicit precision' do
25
+ error = described_class.new(domain: :vision, predicted: 0.5, actual: 0.5, precision: 0.9)
26
+ expect(error.precision).to eq(0.9)
27
+ end
28
+ end
29
+
30
+ describe '#error_magnitude' do
31
+ it 'computes absolute difference for numeric values' do
32
+ error = described_class.new(domain: :x, predicted: 0.3, actual: 0.8)
33
+ expect(error.error_magnitude).to be_within(0.001).of(0.5)
34
+ end
35
+
36
+ it 'clamps error magnitude to 1.0 for values differing by more than 1' do
37
+ error = described_class.new(domain: :x, predicted: 0.0, actual: 2.0)
38
+ expect(error.error_magnitude).to eq(1.0)
39
+ end
40
+
41
+ it 'returns 0.0 when predicted equals actual for numeric values' do
42
+ error = described_class.new(domain: :x, predicted: 0.5, actual: 0.5)
43
+ expect(error.error_magnitude).to eq(0.0)
44
+ end
45
+
46
+ it 'returns 0.0 when predicted equals actual for non-numeric values' do
47
+ error = described_class.new(domain: :x, predicted: :foo, actual: :foo)
48
+ expect(error.error_magnitude).to eq(0.0)
49
+ end
50
+
51
+ it 'returns 1.0 when non-numeric predicted differs from actual' do
52
+ error = described_class.new(domain: :x, predicted: :foo, actual: :bar)
53
+ expect(error.error_magnitude).to eq(1.0)
54
+ end
55
+ end
56
+
57
+ describe '#weighted_error' do
58
+ it 'equals error_magnitude * precision' do
59
+ error = described_class.new(domain: :x, predicted: 0.2, actual: 0.6, precision: 0.8)
60
+ expected = (0.6 - 0.2).abs * 0.8
61
+ expect(error.weighted_error).to be_within(0.001).of(expected)
62
+ end
63
+ end
64
+
65
+ describe '#surprising?' do
66
+ it 'returns true when error_magnitude >= SURPRISE_THRESHOLD' do
67
+ error = described_class.new(domain: :x, predicted: 0.0, actual: 1.0)
68
+ expect(error.surprising?).to be true
69
+ end
70
+
71
+ it 'returns false when error_magnitude < SURPRISE_THRESHOLD' do
72
+ error = described_class.new(domain: :x, predicted: 0.5, actual: 0.55)
73
+ expect(error.surprising?).to be false
74
+ end
75
+ end
76
+
77
+ describe '#level' do
78
+ it 'returns :negligible for very small errors' do
79
+ error = described_class.new(domain: :x, predicted: 0.5, actual: 0.505)
80
+ expect(error.level).to eq(:negligible)
81
+ end
82
+
83
+ it 'returns :surprising for large errors' do
84
+ error = described_class.new(domain: :x, predicted: 0.0, actual: 1.0)
85
+ expect(error.level).to eq(:surprising)
86
+ end
87
+
88
+ it 'returns :moderate for mid-range errors' do
89
+ error = described_class.new(domain: :x, predicted: 0.0, actual: 0.4)
90
+ expect(error.level).to eq(:moderate)
91
+ end
92
+ end
93
+
94
+ describe '#to_h' do
95
+ it 'returns a hash with all fields' do
96
+ error = described_class.new(domain: :vision, predicted: 0.3, actual: 0.7, precision: 0.6)
97
+ h = error.to_h
98
+ expect(h[:domain]).to eq(:vision)
99
+ expect(h[:predicted]).to eq(0.3)
100
+ expect(h[:actual]).to eq(0.7)
101
+ expect(h[:error_magnitude]).to be_a(Float)
102
+ expect(h[:precision]).to eq(0.6)
103
+ expect(h[:weighted_error]).to be_a(Float)
104
+ expect(h[:surprising]).to be(true).or be(false)
105
+ expect(h[:level]).to be_a(Symbol)
106
+ expect(h[:timestamp]).to be_a(Time)
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,210 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/inference/predictive_coding/client'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Inference::PredictiveCoding::Runners::PredictiveCoding do
6
+ let(:client) { Legion::Extensions::Agentic::Inference::PredictiveCoding::Client.new }
7
+
8
+ describe '#generate_prediction' do
9
+ it 'returns success with domain and prediction' do
10
+ result = client.generate_prediction(domain: :vision)
11
+ expect(result[:success]).to be true
12
+ expect(result[:domain]).to eq(:vision)
13
+ expect(result[:predicted]).to be_a(Numeric)
14
+ expect(result[:confidence]).to be_a(Float)
15
+ end
16
+
17
+ it 'passes context to the generative model' do
18
+ result = client.generate_prediction(domain: :audio, context: { expected: 0.7 })
19
+ expect(result[:success]).to be true
20
+ expect(result[:predicted]).to be_within(0.001).of(0.7)
21
+ end
22
+
23
+ it 'accepts extra keyword arguments without error' do
24
+ expect { client.generate_prediction(domain: :x, extra: :ignored) }.not_to raise_error
25
+ end
26
+ end
27
+
28
+ describe '#report_outcome' do
29
+ it 'returns success with error details' do
30
+ result = client.report_outcome(domain: :vision, predicted: 0.5, actual: 0.9)
31
+ expect(result[:success]).to be true
32
+ expect(result[:error_magnitude]).to be_a(Float)
33
+ expect(result[:weighted_error]).to be_a(Float)
34
+ expect(result[:precision]).to be_a(Float)
35
+ expect(result[:surprising]).to be(true).or be(false)
36
+ expect(result[:level]).to be_a(Symbol)
37
+ end
38
+
39
+ it 'marks zero-error outcomes as non-surprising' do
40
+ result = client.report_outcome(domain: :x, predicted: 0.5, actual: 0.5)
41
+ expect(result[:surprising]).to be false
42
+ expect(result[:error_magnitude]).to eq(0.0)
43
+ end
44
+
45
+ it 'marks large-error outcomes as surprising' do
46
+ result = client.report_outcome(domain: :x, predicted: 0.0, actual: 1.0)
47
+ expect(result[:surprising]).to be true
48
+ end
49
+ end
50
+
51
+ describe '#precision_for' do
52
+ it 'returns DEFAULT_PRECISION for unknown domain' do
53
+ result = client.precision_for(domain: :unknown_domain_xyz)
54
+ expect(result[:success]).to be true
55
+ expect(result[:precision]).to eq(Legion::Extensions::Agentic::Inference::PredictiveCoding::Helpers::Constants::DEFAULT_PRECISION)
56
+ end
57
+
58
+ it 'returns updated precision after reporting outcomes' do
59
+ client.report_outcome(domain: :sensor, predicted: 0.5, actual: 0.5)
60
+ result = client.precision_for(domain: :sensor)
61
+ expect(result[:precision]).to be_a(Float)
62
+ end
63
+ end
64
+
65
+ describe '#surprising_errors' do
66
+ it 'returns empty list when no surprising errors' do
67
+ result = client.surprising_errors
68
+ expect(result[:success]).to be true
69
+ expect(result[:errors]).to be_an(Array)
70
+ expect(result[:count]).to eq(0)
71
+ end
72
+
73
+ it 'returns errors above surprise threshold' do
74
+ client.report_outcome(domain: :x, predicted: 0.0, actual: 1.0)
75
+ result = client.surprising_errors
76
+ expect(result[:count]).to be >= 1
77
+ expect(result[:errors].first[:surprising]).to be true
78
+ end
79
+ end
80
+
81
+ describe '#free_energy_status' do
82
+ it 'returns free energy value and level' do
83
+ result = client.free_energy_status
84
+ expect(result[:success]).to be true
85
+ expect(result[:free_energy]).to be_a(Float)
86
+ expect(result[:level]).to be_a(Symbol)
87
+ expect(result[:model_stats]).to be_a(Hash)
88
+ end
89
+
90
+ it 'reflects accumulated errors in free energy' do
91
+ initial = client.free_energy_status[:free_energy]
92
+ 5.times { client.report_outcome(domain: :x, predicted: 0.0, actual: 1.0) }
93
+ elevated = client.free_energy_status[:free_energy]
94
+ expect(elevated).to be > initial
95
+ end
96
+ end
97
+
98
+ describe '#active_inference_candidates' do
99
+ it 'returns empty list for fresh client' do
100
+ result = client.active_inference_candidates
101
+ expect(result[:success]).to be true
102
+ expect(result[:candidates]).to be_an(Array)
103
+ end
104
+
105
+ it 'includes domains with persistent high errors' do
106
+ 10.times { client.report_outcome(domain: :faulty, predicted: 0.0, actual: 1.0) }
107
+ result = client.active_inference_candidates
108
+ expect(result[:candidates]).to include(:faulty)
109
+ end
110
+ end
111
+
112
+ describe '#register_active_inference' do
113
+ it 'registers and returns an inference_id' do
114
+ result = client.register_active_inference(domain: :motor, action: :increase_gain, expected_outcome: 0.8)
115
+ expect(result[:success]).to be true
116
+ expect(result[:inference_id]).to match(/\A[0-9a-f-]{36}\z/)
117
+ expect(result[:status]).to eq(:pending)
118
+ end
119
+
120
+ it 'accepts extra keyword arguments' do
121
+ expect do
122
+ client.register_active_inference(domain: :x, action: :test, expected_outcome: 0.5, extra: :ignored)
123
+ end.not_to raise_error
124
+ end
125
+ end
126
+
127
+ describe '#resolve_active_inference' do
128
+ it 'resolves a registered inference and returns error details' do
129
+ reg = client.register_active_inference(domain: :motor, action: :increase_gain, expected_outcome: 0.8)
130
+ result = client.resolve_active_inference(
131
+ domain: :motor,
132
+ action: :increase_gain,
133
+ actual_outcome: 0.85,
134
+ inference_id: reg[:inference_id]
135
+ )
136
+ expect(result[:success]).to be true
137
+ expect(result[:error_magnitude]).to be_a(Float)
138
+ expect(result).to have_key(:action_helpful)
139
+ end
140
+
141
+ it 'returns not_found when inference does not exist' do
142
+ result = client.resolve_active_inference(
143
+ domain: :missing,
144
+ action: :noop,
145
+ actual_outcome: 0.5,
146
+ inference_id: 'nonexistent-id'
147
+ )
148
+ expect(result[:success]).to be false
149
+ expect(result[:reason]).to eq(:not_found)
150
+ end
151
+
152
+ it 'marks action_helpful true when error is below surprise threshold' do
153
+ reg = client.register_active_inference(domain: :x, action: :nudge, expected_outcome: 0.5)
154
+ result = client.resolve_active_inference(
155
+ domain: :x,
156
+ action: :nudge,
157
+ actual_outcome: 0.51,
158
+ inference_id: reg[:inference_id]
159
+ )
160
+ expect(result[:action_helpful]).to be true
161
+ end
162
+
163
+ it 'marks action_helpful false when error is above surprise threshold' do
164
+ reg = client.register_active_inference(domain: :x, action: :nudge, expected_outcome: 0.0)
165
+ result = client.resolve_active_inference(
166
+ domain: :x,
167
+ action: :nudge,
168
+ actual_outcome: 1.0,
169
+ inference_id: reg[:inference_id]
170
+ )
171
+ expect(result[:action_helpful]).to be false
172
+ end
173
+ end
174
+
175
+ describe '#update_predictive_coding' do
176
+ it 'returns success' do
177
+ result = client.update_predictive_coding
178
+ expect(result[:success]).to be true
179
+ end
180
+
181
+ it 'prunes resolved inferences' do
182
+ reg = client.register_active_inference(domain: :x, action: :test, expected_outcome: 0.5)
183
+ client.resolve_active_inference(domain: :x, action: :test, actual_outcome: 0.5, inference_id: reg[:inference_id])
184
+ result = client.update_predictive_coding
185
+ expect(result[:pruned_inferences]).to be >= 1
186
+ end
187
+
188
+ it 'returns pruned count of zero when nothing resolved' do
189
+ result = client.update_predictive_coding
190
+ expect(result[:pruned_inferences]).to eq(0)
191
+ end
192
+ end
193
+
194
+ describe '#predictive_coding_stats' do
195
+ it 'returns full stats hash' do
196
+ result = client.predictive_coding_stats
197
+ expect(result[:success]).to be true
198
+ expect(result[:model]).to be_a(Hash)
199
+ expect(result[:active_inferences]).to be_a(Integer)
200
+ expect(result[:pending_inferences]).to be_a(Integer)
201
+ end
202
+
203
+ it 'counts active inferences correctly' do
204
+ client.register_active_inference(domain: :x, action: :test, expected_outcome: 0.5)
205
+ result = client.predictive_coding_stats
206
+ expect(result[:active_inferences]).to eq(1)
207
+ expect(result[:pending_inferences]).to eq(1)
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Inference::PredictiveProcessing::Client do
4
+ subject(:client) { described_class.new }
5
+
6
+ describe '#initialize' do
7
+ it 'creates a client with a default processor' do
8
+ expect(client).to be_a(described_class)
9
+ end
10
+
11
+ it 'accepts an injected processor' do
12
+ processor = Legion::Extensions::Agentic::Inference::PredictiveProcessing::Helpers::PredictiveProcessor.new
13
+ injected = described_class.new(processor: processor)
14
+ result = injected.predictive_processing_stats
15
+ expect(result[:success]).to be true
16
+ end
17
+ end
18
+
19
+ describe 'full workflow: add -> predict -> observe -> stats' do
20
+ it 'completes a full predictive processing cycle' do
21
+ client.add_generative_model(domain: :workflow)
22
+ prediction = client.predict_from_model(domain: :workflow, context: { step: 1 })
23
+ expect(prediction[:predicted]).to be true
24
+
25
+ expected_val = prediction[:prediction][:expected_value]
26
+ obs = client.observe_outcome(domain: :workflow, actual: 0.8, predicted: expected_val)
27
+ expect(obs[:observed]).to be true
28
+
29
+ stats = client.predictive_processing_stats
30
+ expect(stats[:stats][:model_count]).to eq(1)
31
+ end
32
+
33
+ it 'accumulates free energy after repeated high errors' do
34
+ client.add_generative_model(domain: :stress)
35
+ 5.times { client.observe_outcome(domain: :stress, actual: 1.0, predicted: 0.0) }
36
+ fe = client.free_energy(domain: :stress)
37
+ expect(fe[:free_energy]).to be > 0.0
38
+ end
39
+
40
+ it 'identifies active inference candidate after surprise' do
41
+ client.add_generative_model(domain: :act_candidate)
42
+ 5.times { client.observe_outcome(domain: :act_candidate, actual: 1.0, predicted: 0.0) }
43
+ result = client.active_inference_candidates
44
+ expect(result[:domains]).to include(:act_candidate)
45
+ end
46
+
47
+ it 'tick decays precision over time' do
48
+ client.add_generative_model(domain: :decaying)
49
+ initial_weight = client.instance_variable_get(:@default_processor).precision_weight(:decaying)
50
+ client.update_predictive_processing
51
+ after_weight = client.instance_variable_get(:@default_processor).precision_weight(:decaying)
52
+ expect(after_weight).to be < initial_weight
53
+ end
54
+ end
55
+
56
+ describe 'constants' do
57
+ it 'exposes INFERENCE_MODES' do
58
+ expect(Legion::Extensions::Agentic::Inference::PredictiveProcessing::Helpers::Constants::INFERENCE_MODES)
59
+ .to eq(%i[perceptual active hybrid])
60
+ end
61
+
62
+ it 'exposes MODEL_STATES' do
63
+ expect(Legion::Extensions::Agentic::Inference::PredictiveProcessing::Helpers::Constants::MODEL_STATES)
64
+ .to eq(%i[stable updating exploring surprised])
65
+ end
66
+
67
+ it 'exposes FREE_ENERGY_THRESHOLD' do
68
+ expect(Legion::Extensions::Agentic::Inference::PredictiveProcessing::Helpers::Constants::FREE_ENERGY_THRESHOLD)
69
+ .to eq(0.7)
70
+ end
71
+
72
+ it 'exposes ACTIVE_INFERENCE_THRESHOLD' do
73
+ expect(Legion::Extensions::Agentic::Inference::PredictiveProcessing::Helpers::Constants::ACTIVE_INFERENCE_THRESHOLD)
74
+ .to eq(0.5)
75
+ end
76
+
77
+ it 'exposes all PRECISION_LABELS keys as ranges' do
78
+ labels = Legion::Extensions::Agentic::Inference::PredictiveProcessing::Helpers::Constants::PRECISION_LABELS
79
+ expect(labels.values).to include(:certain, :confident, :uncertain, :vague, :noise)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,220 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Inference::PredictiveProcessing::Helpers::GenerativeModel do
4
+ subject(:model) { described_class.new(domain: :test_domain) }
5
+
6
+ describe '#initialize' do
7
+ it 'assigns a unique id' do
8
+ expect(model.id).to match(/\A[0-9a-f-]{36}\z/)
9
+ end
10
+
11
+ it 'sets domain' do
12
+ expect(model.domain).to eq(:test_domain)
13
+ end
14
+
15
+ it 'sets default confidence' do
16
+ expect(model.confidence).to eq(described_class::DEFAULT_PRECISION)
17
+ end
18
+
19
+ it 'sets default precision' do
20
+ expect(model.precision).to eq(described_class::DEFAULT_PRECISION)
21
+ end
22
+
23
+ it 'starts with zero prediction error' do
24
+ expect(model.prediction_error).to eq(0.0)
25
+ end
26
+
27
+ it 'starts in stable state' do
28
+ expect(model.state).to eq(:stable)
29
+ end
30
+
31
+ it 'records created_at timestamp' do
32
+ expect(model.created_at).to be_a(Time)
33
+ end
34
+
35
+ it 'records updated_at timestamp' do
36
+ expect(model.updated_at).to be_a(Time)
37
+ end
38
+ end
39
+
40
+ describe '#predict' do
41
+ it 'returns a prediction hash' do
42
+ result = model.predict(context: {})
43
+ expect(result).to be_a(Hash)
44
+ end
45
+
46
+ it 'includes expected_value' do
47
+ result = model.predict(context: {})
48
+ expect(result[:expected_value]).to be_a(Float)
49
+ end
50
+
51
+ it 'includes confidence' do
52
+ result = model.predict(context: {})
53
+ expect(result[:confidence]).to eq(model.confidence)
54
+ end
55
+
56
+ it 'includes domain' do
57
+ result = model.predict(context: {})
58
+ expect(result[:domain]).to eq(:test_domain)
59
+ end
60
+
61
+ it 'applies context richness bonus' do
62
+ sparse_pred = model.predict(context: {})
63
+ rich_pred = model.predict(context: { a: 1, b: 2, c: 3, d: 4, e: 5 })
64
+ expect(rich_pred[:expected_value]).to be >= sparse_pred[:expected_value]
65
+ end
66
+
67
+ it 'caps expected_value at 1.0' do
68
+ result = model.predict(context: (1..20).to_h { |i| [i, i] })
69
+ expect(result[:expected_value]).to be <= 1.0
70
+ end
71
+
72
+ it 'stores the prediction as last_prediction' do
73
+ model.predict(context: { key: :val })
74
+ expect(model.last_prediction).not_to be_nil
75
+ end
76
+
77
+ it 'uses default empty context when none provided' do
78
+ result = model.predict
79
+ expect(result[:context_size]).to eq(0)
80
+ end
81
+ end
82
+
83
+ describe '#observe' do
84
+ it 'returns a numeric error magnitude' do
85
+ error = model.observe(actual: 0.8, predicted: 0.5)
86
+ expect(error).to be_a(Float)
87
+ end
88
+
89
+ it 'computes absolute difference' do
90
+ error = model.observe(actual: 0.8, predicted: 0.5)
91
+ expect(error).to be_within(0.01).of(0.3)
92
+ end
93
+
94
+ it 'clamps error to 0..1' do
95
+ error = model.observe(actual: 5.0, predicted: 0.0)
96
+ expect(error).to eq(1.0)
97
+ end
98
+
99
+ it 'returns 0.0 for non-numeric inputs' do
100
+ error = model.observe(actual: 'abc', predicted: 0.5)
101
+ expect(error).to eq(0.0)
102
+ end
103
+
104
+ it 'updates updated_at' do
105
+ before = model.updated_at
106
+ sleep(0.01)
107
+ model.observe(actual: 0.9, predicted: 0.1)
108
+ expect(model.updated_at).to be >= before
109
+ end
110
+ end
111
+
112
+ describe '#free_energy' do
113
+ it 'returns 0.0 with no history' do
114
+ expect(model.free_energy).to eq(0.0)
115
+ end
116
+
117
+ it 'returns a positive value after observations' do
118
+ model.observe(actual: 1.0, predicted: 0.0)
119
+ expect(model.free_energy).to be >= 0.0
120
+ end
121
+
122
+ it 'returns higher free energy for larger errors' do
123
+ low_model = described_class.new(domain: :low)
124
+ high_model = described_class.new(domain: :high)
125
+ low_model.observe(actual: 0.51, predicted: 0.5)
126
+ high_model.observe(actual: 1.0, predicted: 0.0)
127
+ expect(high_model.free_energy).to be > low_model.free_energy
128
+ end
129
+ end
130
+
131
+ describe '#stable?' do
132
+ it 'returns true when free_energy is low' do
133
+ expect(model.stable?).to be true
134
+ end
135
+
136
+ it 'returns false when surprised' do
137
+ 5.times { model.observe(actual: 1.0, predicted: 0.0) }
138
+ expect(model.stable?).to be false
139
+ end
140
+ end
141
+
142
+ describe '#surprised?' do
143
+ it 'returns false initially' do
144
+ expect(model.surprised?).to be false
145
+ end
146
+
147
+ it 'returns true after repeated large errors' do
148
+ 5.times { model.observe(actual: 1.0, predicted: 0.0) }
149
+ expect(model.surprised?).to be true
150
+ end
151
+ end
152
+
153
+ describe '#update_model' do
154
+ it 'adjusts confidence downward on positive error' do
155
+ before = model.confidence
156
+ model.update_model(error: 0.5)
157
+ expect(model.confidence).to be < before
158
+ end
159
+
160
+ it 'does not drop confidence below MODEL_CONFIDENCE_FLOOR' do
161
+ 10.times { model.update_model(error: 1.0) }
162
+ expect(model.confidence).to be >= described_class::MODEL_CONFIDENCE_FLOOR
163
+ end
164
+
165
+ it 'sets state to updating' do
166
+ model.update_model(error: 0.3)
167
+ expect(model.state).to eq(:updating)
168
+ end
169
+ end
170
+
171
+ describe '#decay' do
172
+ it 'reduces precision' do
173
+ before = model.precision
174
+ model.decay
175
+ expect(model.precision).to be < before
176
+ end
177
+
178
+ it 'does not drop precision below PRECISION_FLOOR' do
179
+ 100.times { model.decay }
180
+ expect(model.precision).to be >= described_class::PRECISION_FLOOR
181
+ end
182
+ end
183
+
184
+ describe '#precision_label' do
185
+ it 'returns :uncertain for default precision (0.5)' do
186
+ expect(model.precision_label).to eq(:uncertain)
187
+ end
188
+
189
+ it 'returns :certain for high precision' do
190
+ allow(model).to receive(:precision).and_return(0.9)
191
+ expect(model.precision_label).to eq(:certain)
192
+ end
193
+
194
+ it 'returns :noise for very low precision' do
195
+ allow(model).to receive(:precision).and_return(0.1)
196
+ expect(model.precision_label).to eq(:noise)
197
+ end
198
+
199
+ it 'returns :vague for precision around 0.3' do
200
+ allow(model).to receive(:precision).and_return(0.3)
201
+ expect(model.precision_label).to eq(:vague)
202
+ end
203
+ end
204
+
205
+ describe '#to_h' do
206
+ it 'returns a hash with all required keys' do
207
+ h = model.to_h
208
+ %i[id domain confidence precision prediction_error free_energy state
209
+ precision_label stable surprised history_size created_at updated_at].each do |key|
210
+ expect(h).to have_key(key)
211
+ end
212
+ end
213
+
214
+ it 'reflects current model state' do
215
+ model.observe(actual: 0.8, predicted: 0.3)
216
+ h = model.to_h
217
+ expect(h[:history_size]).to eq(1)
218
+ end
219
+ end
220
+ end