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,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Inference
7
+ module CausalAttribution
8
+ module Helpers
9
+ class AttributionEngine
10
+ def initialize
11
+ @attributions = {}
12
+ @history = []
13
+ end
14
+
15
+ def create_attribution(event:, outcome:, domain:, locus:, stability:, controllability:,
16
+ confidence: Attribution::DEFAULT_CONFIDENCE)
17
+ trim_if_needed
18
+ attribution = Attribution.new(
19
+ event: event,
20
+ outcome: outcome,
21
+ domain: domain,
22
+ locus: locus,
23
+ stability: stability,
24
+ controllability: controllability,
25
+ confidence: confidence
26
+ )
27
+ @attributions[attribution.id] = attribution
28
+ attribution
29
+ end
30
+
31
+ def reattribute(attribution_id:, locus: nil, stability: nil, controllability: nil)
32
+ attr = @attributions[attribution_id]
33
+ return { found: false, attribution_id: attribution_id } unless attr
34
+
35
+ new_locus = locus || attr.locus
36
+ new_stability = stability || attr.stability
37
+ new_controllability = controllability || attr.controllability
38
+
39
+ updated = Attribution.new(
40
+ event: attr.event,
41
+ outcome: attr.outcome,
42
+ domain: attr.domain,
43
+ locus: new_locus,
44
+ stability: new_stability,
45
+ controllability: new_controllability,
46
+ confidence: attr.confidence
47
+ )
48
+ @history << attr.to_h if @history.size < Attribution::MAX_HISTORY
49
+ @attributions[attribution_id] = updated
50
+ updated
51
+ end
52
+
53
+ def by_pattern(locus: nil, stability: nil, controllability: nil)
54
+ @attributions.values.select do |a|
55
+ (locus.nil? || a.locus == locus) &&
56
+ (stability.nil? || a.stability == stability) &&
57
+ (controllability.nil? || a.controllability == controllability)
58
+ end
59
+ end
60
+
61
+ def by_domain(domain:)
62
+ @attributions.values.select { |a| a.domain == domain }
63
+ end
64
+
65
+ def by_outcome(outcome:)
66
+ @attributions.values.select { |a| a.outcome == outcome }
67
+ end
68
+
69
+ def attribution_bias
70
+ return { bias: :none, detail: 'no attributions' } if @attributions.empty?
71
+
72
+ all = @attributions.values
73
+ total = all.size.to_f
74
+ locus = bias_ratio(all, :locus, :external, total)
75
+ stab = bias_ratio(all, :stability, :stable, total)
76
+ control = bias_ratio(all, :controllability, :uncontrollable, total)
77
+
78
+ failures = all.select { |a| a.outcome == :failure }
79
+ external_failure_ratio = failures.empty? ? 0.0 : failures.count(&:external?).to_f / failures.size
80
+
81
+ {
82
+ external_locus_ratio: locus.round(3),
83
+ stable_ratio: stab.round(3),
84
+ uncontrollable_ratio: control.round(3),
85
+ external_failure_ratio: external_failure_ratio.round(3),
86
+ self_serving_bias_detected: external_failure_ratio > 0.6,
87
+ total_attributions: @attributions.size
88
+ }
89
+ end
90
+
91
+ def emotional_profile
92
+ counts = Hash.new(0)
93
+ @attributions.each_value { |a| counts[a.emotional_response] += 1 if a.emotional_response }
94
+ total = counts.values.sum.to_f
95
+ profile = counts.transform_values { |v| (v / total).round(3) }
96
+ dominant = counts.max_by { |_, v| v }&.first
97
+ { distribution: profile, dominant: dominant, total: counts.values.sum }
98
+ end
99
+
100
+ def most_common_pattern
101
+ return { pattern: nil, count: 0 } if @attributions.empty?
102
+
103
+ grouped = @attributions.values.group_by(&:pattern)
104
+ best = grouped.max_by { |_, attrs| attrs.size }
105
+ { pattern: best[0], count: best[1].size }
106
+ end
107
+
108
+ def decay_all
109
+ decayed = 0
110
+ @attributions.each_value do |a|
111
+ new_conf = (a.confidence - Attribution::DECAY_RATE).clamp(
112
+ Attribution::CONFIDENCE_FLOOR, Attribution::CONFIDENCE_CEILING
113
+ )
114
+ a.instance_variable_set(:@confidence, new_conf)
115
+ decayed += 1
116
+ end
117
+ decayed
118
+ end
119
+
120
+ def count
121
+ @attributions.size
122
+ end
123
+
124
+ def to_h
125
+ {
126
+ total_attributions: @attributions.size,
127
+ history_size: @history.size,
128
+ outcome_counts: outcome_counts,
129
+ locus_counts: locus_counts
130
+ }
131
+ end
132
+
133
+ private
134
+
135
+ def trim_if_needed
136
+ return unless @attributions.size >= Attribution::MAX_ATTRIBUTIONS
137
+
138
+ oldest_key = @attributions.min_by { |_, a| a.created_at }&.first
139
+ @attributions.delete(oldest_key)
140
+ end
141
+
142
+ def bias_ratio(all, dimension, value, total)
143
+ all.count { |a| a.public_send(dimension) == value } / total
144
+ end
145
+
146
+ def outcome_counts
147
+ @attributions.values.group_by(&:outcome).transform_values(&:size)
148
+ end
149
+
150
+ def locus_counts
151
+ @attributions.values.group_by(&:locus).transform_values(&:size)
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Inference
7
+ module CausalAttribution
8
+ module Runners
9
+ module CausalAttribution
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex)
12
+
13
+ def create_causal_attribution(event:, outcome:, domain:, locus:, stability:, controllability:,
14
+ confidence: nil, **)
15
+ conf = (confidence || Helpers::Attribution::DEFAULT_CONFIDENCE)
16
+ .clamp(Helpers::Attribution::CONFIDENCE_FLOOR, Helpers::Attribution::CONFIDENCE_CEILING)
17
+ attr = engine.create_attribution(
18
+ event: event,
19
+ outcome: outcome,
20
+ domain: domain,
21
+ locus: locus.to_sym,
22
+ stability: stability.to_sym,
23
+ controllability: controllability.to_sym,
24
+ confidence: conf
25
+ )
26
+ Legion::Logging.info "[causal_attribution] create id=#{attr.id} event=#{event} " \
27
+ "outcome=#{outcome} locus=#{locus} emotion=#{attr.emotional_response}"
28
+ { success: true, attribution: attr.to_h }
29
+ end
30
+
31
+ def reattribute_cause(attribution_id:, locus: nil, stability: nil, controllability: nil, **)
32
+ result = engine.reattribute(
33
+ attribution_id: attribution_id,
34
+ locus: locus&.to_sym,
35
+ stability: stability&.to_sym,
36
+ controllability: controllability&.to_sym
37
+ )
38
+ if result.is_a?(Hash) && result[:found] == false
39
+ Legion::Logging.warn "[causal_attribution] reattribute not_found id=#{attribution_id}"
40
+ return { success: false, attribution_id: attribution_id, found: false }
41
+ end
42
+
43
+ Legion::Logging.debug "[causal_attribution] reattribute id=#{attribution_id} " \
44
+ "locus=#{result.locus} emotion=#{result.emotional_response}"
45
+ { success: true, attribution: result.to_h }
46
+ end
47
+
48
+ def attributions_by_pattern(locus: nil, stability: nil, controllability: nil, **)
49
+ results = engine.by_pattern(
50
+ locus: locus&.to_sym,
51
+ stability: stability&.to_sym,
52
+ controllability: controllability&.to_sym
53
+ )
54
+ Legion::Logging.debug "[causal_attribution] by_pattern count=#{results.size}"
55
+ { success: true, attributions: results.map(&:to_h), count: results.size }
56
+ end
57
+
58
+ def domain_attributions(domain:, **)
59
+ results = engine.by_domain(domain: domain.to_sym)
60
+ Legion::Logging.debug "[causal_attribution] by_domain domain=#{domain} count=#{results.size}"
61
+ { success: true, attributions: results.map(&:to_h), count: results.size }
62
+ end
63
+
64
+ def outcome_attributions(outcome:, **)
65
+ results = engine.by_outcome(outcome: outcome.to_sym)
66
+ Legion::Logging.debug "[causal_attribution] by_outcome outcome=#{outcome} count=#{results.size}"
67
+ { success: true, attributions: results.map(&:to_h), count: results.size }
68
+ end
69
+
70
+ def attribution_bias_assessment(**)
71
+ bias = engine.attribution_bias
72
+ Legion::Logging.debug "[causal_attribution] bias_assessment self_serving=#{bias[:self_serving_bias_detected]}"
73
+ { success: true, bias: bias }
74
+ end
75
+
76
+ def emotional_attribution_profile(**)
77
+ profile = engine.emotional_profile
78
+ Legion::Logging.debug "[causal_attribution] emotional_profile dominant=#{profile[:dominant]} total=#{profile[:total]}"
79
+ { success: true, profile: profile }
80
+ end
81
+
82
+ def most_common_attribution(**)
83
+ result = engine.most_common_pattern
84
+ Legion::Logging.debug "[causal_attribution] most_common pattern=#{result[:pattern].inspect} count=#{result[:count]}"
85
+ { success: true, pattern: result[:pattern], count: result[:count] }
86
+ end
87
+
88
+ def update_causal_attribution(**)
89
+ decayed = engine.decay_all
90
+ Legion::Logging.debug "[causal_attribution] decay cycle entries=#{decayed}"
91
+ { success: true, decayed: decayed }
92
+ end
93
+
94
+ def causal_attribution_stats(**)
95
+ stats = engine.to_h
96
+ Legion::Logging.debug "[causal_attribution] stats total=#{stats[:total_attributions]}"
97
+ { success: true, stats: stats }
98
+ end
99
+
100
+ private
101
+
102
+ def engine
103
+ @engine ||= Helpers::AttributionEngine.new
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Inference
7
+ module CausalAttribution
8
+ VERSION = '0.1.0'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/inference/causal_attribution/version'
4
+ require 'legion/extensions/agentic/inference/causal_attribution/helpers/attribution'
5
+ require 'legion/extensions/agentic/inference/causal_attribution/helpers/attribution_engine'
6
+ require 'legion/extensions/agentic/inference/causal_attribution/runners/causal_attribution'
7
+ require 'legion/extensions/agentic/inference/causal_attribution/client'
8
+
9
+ module Legion
10
+ module Extensions
11
+ module Agentic
12
+ module Inference
13
+ module CausalAttribution
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/inference/causal_reasoning/helpers/constants'
4
+ require 'legion/extensions/agentic/inference/causal_reasoning/helpers/causal_edge'
5
+ require 'legion/extensions/agentic/inference/causal_reasoning/helpers/causal_graph'
6
+ require 'legion/extensions/agentic/inference/causal_reasoning/runners/causal_reasoning'
7
+
8
+ module Legion
9
+ module Extensions
10
+ module Agentic
11
+ module Inference
12
+ module CausalReasoning
13
+ class Client
14
+ include Runners::CausalReasoning
15
+
16
+ def initialize(graph: nil, **)
17
+ @graph = graph
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Inference
9
+ module CausalReasoning
10
+ module Helpers
11
+ class CausalEdge
12
+ include Constants
13
+
14
+ attr_reader :id, :cause, :effect, :edge_type, :domain, :evidence_count, :created_at, :updated_at, :strength
15
+
16
+ def initialize(cause:, effect:, edge_type:, domain: :general, strength: Constants::DEFAULT_STRENGTH)
17
+ @id = SecureRandom.uuid
18
+ @cause = cause
19
+ @effect = effect
20
+ @edge_type = edge_type
21
+ @domain = domain
22
+ @strength = strength.clamp(Constants::STRENGTH_FLOOR, Constants::STRENGTH_CEILING)
23
+ @evidence_count = 0
24
+ @created_at = Time.now.utc
25
+ @updated_at = Time.now.utc
26
+ end
27
+
28
+ def add_evidence
29
+ @evidence_count += 1
30
+ @strength = (@strength + Constants::REINFORCEMENT_RATE).clamp(
31
+ Constants::STRENGTH_FLOOR, Constants::STRENGTH_CEILING
32
+ )
33
+ @updated_at = Time.now.utc
34
+ self
35
+ end
36
+
37
+ def remove_evidence
38
+ @evidence_count = [@evidence_count - 1, 0].max
39
+ @strength = (@strength - Constants::REINFORCEMENT_RATE).clamp(
40
+ Constants::STRENGTH_FLOOR, Constants::STRENGTH_CEILING
41
+ )
42
+ @updated_at = Time.now.utc
43
+ self
44
+ end
45
+
46
+ def reinforce(amount: Constants::REINFORCEMENT_RATE)
47
+ @strength = (@strength + amount).clamp(
48
+ Constants::STRENGTH_FLOOR, Constants::STRENGTH_CEILING
49
+ )
50
+ @updated_at = Time.now.utc
51
+ self
52
+ end
53
+
54
+ def weaken(amount: Constants::REINFORCEMENT_RATE)
55
+ @strength = (@strength - amount).clamp(
56
+ Constants::STRENGTH_FLOOR, Constants::STRENGTH_CEILING
57
+ )
58
+ @updated_at = Time.now.utc
59
+ self
60
+ end
61
+
62
+ def decay
63
+ @strength = (@strength - Constants::DECAY_RATE).clamp(
64
+ Constants::STRENGTH_FLOOR, Constants::STRENGTH_CEILING
65
+ )
66
+ @updated_at = Time.now.utc
67
+ self
68
+ end
69
+
70
+ def confident?
71
+ @strength >= Constants::CAUSAL_THRESHOLD &&
72
+ @evidence_count >= Constants::EVIDENCE_THRESHOLD
73
+ end
74
+
75
+ def confidence_label
76
+ match = Constants::CONFIDENCE_LABELS.find { |range, _| range.cover?(@strength) }
77
+ match ? match[1] : :speculative
78
+ end
79
+
80
+ def to_h
81
+ {
82
+ id: @id,
83
+ cause: @cause,
84
+ effect: @effect,
85
+ edge_type: @edge_type,
86
+ domain: @domain,
87
+ strength: @strength,
88
+ evidence_count: @evidence_count,
89
+ confident: confident?,
90
+ label: confidence_label,
91
+ created_at: @created_at,
92
+ updated_at: @updated_at
93
+ }
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Inference
7
+ module CausalReasoning
8
+ module Helpers
9
+ class CausalGraph
10
+ def initialize
11
+ @variables = {}
12
+ @edges = {}
13
+ @edge_index = {}
14
+ end
15
+
16
+ def add_variable(name:, domain: :general)
17
+ return nil if @variables.key?(name)
18
+ return nil if @variables.size >= Constants::MAX_VARIABLES
19
+
20
+ @variables[name] = { name: name, domain: domain, added_at: Time.now.utc }
21
+ end
22
+
23
+ def variable_exists?(name)
24
+ @variables.key?(name)
25
+ end
26
+
27
+ def add_edge(cause:, effect:, edge_type:, domain: :general, strength: Constants::DEFAULT_STRENGTH)
28
+ return nil if @edges.size >= Constants::MAX_EDGES
29
+ return nil unless Constants::EDGE_TYPES.include?(edge_type)
30
+
31
+ add_variable(name: cause, domain: domain)
32
+ add_variable(name: effect, domain: domain)
33
+
34
+ edge = CausalEdge.new(cause: cause, effect: effect,
35
+ edge_type: edge_type, domain: domain, strength: strength)
36
+ @edges[edge.id] = edge
37
+ @edge_index[cause] ||= []
38
+ @edge_index[cause] << edge.id
39
+ edge
40
+ end
41
+
42
+ def remove_edge(edge_id:)
43
+ edge = @edges.delete(edge_id)
44
+ return nil unless edge
45
+
46
+ @edge_index[edge.cause]&.delete(edge_id)
47
+ edge
48
+ end
49
+
50
+ def causes_of(variable:)
51
+ @edges.values.select { |e| e.effect == variable }
52
+ end
53
+
54
+ def effects_of(variable:)
55
+ ids = @edge_index.fetch(variable, [])
56
+ ids.filter_map { |id| @edges[id] }
57
+ end
58
+
59
+ def causal_chain(from:, to:, max_depth: 5)
60
+ return [] if from == to
61
+
62
+ queue = [[from, [from]]]
63
+ visited = { from => true }
64
+ paths = []
65
+
66
+ until queue.empty?
67
+ current, path = queue.shift
68
+ next if path.size > max_depth + 1
69
+
70
+ effects_of(variable: current).each do |edge|
71
+ neighbor = edge.effect
72
+ new_path = path + [neighbor]
73
+
74
+ if neighbor == to
75
+ paths << new_path
76
+ next
77
+ end
78
+
79
+ next if visited[neighbor]
80
+
81
+ visited[neighbor] = true
82
+ queue << [neighbor, new_path]
83
+ end
84
+ end
85
+
86
+ paths
87
+ end
88
+
89
+ def intervene(variable:, value:)
90
+ downstream = []
91
+ queue = [variable]
92
+ visited = { variable => true }
93
+
94
+ until queue.empty?
95
+ current = queue.shift
96
+ effects_of(variable: current).each do |edge|
97
+ neighbor = edge.effect
98
+ downstream << { variable: neighbor, via_edge: edge.id, edge_type: edge.edge_type }
99
+ next if visited[neighbor]
100
+
101
+ visited[neighbor] = true
102
+ queue << neighbor
103
+ end
104
+ end
105
+
106
+ { intervention: variable, value: value, downstream_effects: downstream }
107
+ end
108
+
109
+ def observe(variable:, value:, evidence:)
110
+ affected = causes_of(variable: variable) + effects_of(variable: variable)
111
+ affected.each { |edge| edge.add_evidence if evidence }
112
+ { variable: variable, value: value, edges_updated: affected.size }
113
+ end
114
+
115
+ def confounders(var_a:, var_b:)
116
+ ancestors_a = ancestors_of(var_a)
117
+ ancestors_b = ancestors_of(var_b)
118
+ common = ancestors_a & ancestors_b
119
+ common.reject { |v| v == var_a || v == var_b }
120
+ end
121
+
122
+ def add_evidence(edge_id:)
123
+ edge = @edges[edge_id]
124
+ return nil unless edge
125
+
126
+ edge.add_evidence
127
+ end
128
+
129
+ def remove_evidence(edge_id:)
130
+ edge = @edges[edge_id]
131
+ return nil unless edge
132
+
133
+ edge.remove_evidence
134
+ end
135
+
136
+ def confident_edges
137
+ @edges.values.select(&:confident?)
138
+ end
139
+
140
+ def by_domain(domain:)
141
+ @edges.values.select { |e| e.domain == domain }
142
+ end
143
+
144
+ def by_type(type:)
145
+ @edges.values.select { |e| e.edge_type == type }
146
+ end
147
+
148
+ def decay_all
149
+ @edges.each_value(&:decay)
150
+ @edges.size
151
+ end
152
+
153
+ def prune_weak
154
+ weak_ids = @edges.select { |_, e| e.strength <= Constants::STRENGTH_FLOOR }.keys
155
+ weak_ids.each { |id| remove_edge(edge_id: id) }
156
+ weak_ids.size
157
+ end
158
+
159
+ def to_h
160
+ {
161
+ variables: @variables.size,
162
+ edges: @edges.size,
163
+ confident_edges: confident_edges.size,
164
+ edge_types: Constants::EDGE_TYPES.to_h { |t| [t, by_type(type: t).size] }
165
+ }
166
+ end
167
+
168
+ private
169
+
170
+ def ancestors_of(variable, visited = {})
171
+ return [] if visited[variable]
172
+
173
+ visited[variable] = true
174
+ direct_causes = causes_of(variable: variable).map(&:cause)
175
+ indirect = direct_causes.flat_map { |c| ancestors_of(c, visited) }
176
+ (direct_causes + indirect).uniq
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Inference
7
+ module CausalReasoning
8
+ module Helpers
9
+ module Constants
10
+ MAX_VARIABLES = 200
11
+ MAX_EDGES = 500
12
+ MAX_HISTORY = 300
13
+
14
+ DEFAULT_STRENGTH = 0.5
15
+ STRENGTH_FLOOR = 0.05
16
+ STRENGTH_CEILING = 0.95
17
+
18
+ EVIDENCE_THRESHOLD = 3
19
+ CAUSAL_THRESHOLD = 0.6
20
+
21
+ REINFORCEMENT_RATE = 0.1
22
+ DECAY_RATE = 0.01
23
+
24
+ EDGE_TYPES = %i[causes prevents enables inhibits modulates].freeze
25
+ INFERENCE_TYPES = %i[observation intervention counterfactual].freeze
26
+
27
+ CONFIDENCE_LABELS = {
28
+ (0.8..) => :strong,
29
+ (0.6...0.8) => :moderate,
30
+ (0.4...0.6) => :weak,
31
+ (0.2...0.4) => :tentative,
32
+ (..0.2) => :speculative
33
+ }.freeze
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end