lex-agentic-attention 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 (315) 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-attention.gemspec +30 -0
  7. data/lib/legion/extensions/agentic/attention/arousal/client.rb +27 -0
  8. data/lib/legion/extensions/agentic/attention/arousal/helpers/arousal_model.rb +84 -0
  9. data/lib/legion/extensions/agentic/attention/arousal/helpers/constants.rb +44 -0
  10. data/lib/legion/extensions/agentic/attention/arousal/runners/arousal.rb +119 -0
  11. data/lib/legion/extensions/agentic/attention/arousal/version.rb +13 -0
  12. data/lib/legion/extensions/agentic/attention/arousal.rb +18 -0
  13. data/lib/legion/extensions/agentic/attention/blindspot/client.rb +19 -0
  14. data/lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot.rb +98 -0
  15. data/lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb +174 -0
  16. data/lib/legion/extensions/agentic/attention/blindspot/helpers/constants.rb +63 -0
  17. data/lib/legion/extensions/agentic/attention/blindspot/helpers/knowledge_boundary.rb +62 -0
  18. data/lib/legion/extensions/agentic/attention/blindspot/runners/cognitive_blindspot.rb +103 -0
  19. data/lib/legion/extensions/agentic/attention/blindspot/version.rb +13 -0
  20. data/lib/legion/extensions/agentic/attention/blindspot.rb +20 -0
  21. data/lib/legion/extensions/agentic/attention/blink/client.rb +19 -0
  22. data/lib/legion/extensions/agentic/attention/blink/helpers/blink_engine.rb +171 -0
  23. data/lib/legion/extensions/agentic/attention/blink/helpers/constants.rb +46 -0
  24. data/lib/legion/extensions/agentic/attention/blink/helpers/stimulus.rb +68 -0
  25. data/lib/legion/extensions/agentic/attention/blink/runners/attentional_blink.rb +75 -0
  26. data/lib/legion/extensions/agentic/attention/blink/version.rb +13 -0
  27. data/lib/legion/extensions/agentic/attention/blink.rb +19 -0
  28. data/lib/legion/extensions/agentic/attention/economy/client.rb +28 -0
  29. data/lib/legion/extensions/agentic/attention/economy/helpers/attention_budget.rb +143 -0
  30. data/lib/legion/extensions/agentic/attention/economy/helpers/constants.rb +38 -0
  31. data/lib/legion/extensions/agentic/attention/economy/helpers/demand.rb +72 -0
  32. data/lib/legion/extensions/agentic/attention/economy/runners/attention_economy.rb +90 -0
  33. data/lib/legion/extensions/agentic/attention/economy/version.rb +13 -0
  34. data/lib/legion/extensions/agentic/attention/economy.rb +19 -0
  35. data/lib/legion/extensions/agentic/attention/feature_binding/actors/decay.rb +45 -0
  36. data/lib/legion/extensions/agentic/attention/feature_binding/client.rb +29 -0
  37. data/lib/legion/extensions/agentic/attention/feature_binding/helpers/binding_field.rb +124 -0
  38. data/lib/legion/extensions/agentic/attention/feature_binding/helpers/bound_object.rb +89 -0
  39. data/lib/legion/extensions/agentic/attention/feature_binding/helpers/constants.rb +52 -0
  40. data/lib/legion/extensions/agentic/attention/feature_binding/helpers/feature.rb +52 -0
  41. data/lib/legion/extensions/agentic/attention/feature_binding/runners/feature_binding.rb +102 -0
  42. data/lib/legion/extensions/agentic/attention/feature_binding/version.rb +13 -0
  43. data/lib/legion/extensions/agentic/attention/feature_binding.rb +20 -0
  44. data/lib/legion/extensions/agentic/attention/focus/client.rb +30 -0
  45. data/lib/legion/extensions/agentic/attention/focus/helpers/constants.rb +38 -0
  46. data/lib/legion/extensions/agentic/attention/focus/helpers/focus.rb +78 -0
  47. data/lib/legion/extensions/agentic/attention/focus/helpers/focus_manager.rb +67 -0
  48. data/lib/legion/extensions/agentic/attention/focus/helpers/habituation.rb +61 -0
  49. data/lib/legion/extensions/agentic/attention/focus/runners/attention.rb +121 -0
  50. data/lib/legion/extensions/agentic/attention/focus/version.rb +13 -0
  51. data/lib/legion/extensions/agentic/attention/focus.rb +20 -0
  52. data/lib/legion/extensions/agentic/attention/kaleidoscope/client.rb +15 -0
  53. data/lib/legion/extensions/agentic/attention/kaleidoscope/helpers/constants.rb +48 -0
  54. data/lib/legion/extensions/agentic/attention/kaleidoscope/helpers/facet.rb +90 -0
  55. data/lib/legion/extensions/agentic/attention/kaleidoscope/helpers/kaleidoscope_engine.rb +142 -0
  56. data/lib/legion/extensions/agentic/attention/kaleidoscope/helpers/pattern.rb +110 -0
  57. data/lib/legion/extensions/agentic/attention/kaleidoscope/runners/cognitive_kaleidoscope.rb +91 -0
  58. data/lib/legion/extensions/agentic/attention/kaleidoscope/version.rb +13 -0
  59. data/lib/legion/extensions/agentic/attention/kaleidoscope.rb +22 -0
  60. data/lib/legion/extensions/agentic/attention/latent_inhibition/client.rb +28 -0
  61. data/lib/legion/extensions/agentic/attention/latent_inhibition/helpers/constants.rb +33 -0
  62. data/lib/legion/extensions/agentic/attention/latent_inhibition/helpers/inhibition_engine.rb +118 -0
  63. data/lib/legion/extensions/agentic/attention/latent_inhibition/helpers/stimulus_record.rb +70 -0
  64. data/lib/legion/extensions/agentic/attention/latent_inhibition/runners/latent_inhibition.rb +78 -0
  65. data/lib/legion/extensions/agentic/attention/latent_inhibition/version.rb +13 -0
  66. data/lib/legion/extensions/agentic/attention/latent_inhibition.rb +19 -0
  67. data/lib/legion/extensions/agentic/attention/lens/client.rb +29 -0
  68. data/lib/legion/extensions/agentic/attention/lens/helpers/constants.rb +58 -0
  69. data/lib/legion/extensions/agentic/attention/lens/helpers/lens.rb +99 -0
  70. data/lib/legion/extensions/agentic/attention/lens/helpers/lens_engine.rb +101 -0
  71. data/lib/legion/extensions/agentic/attention/lens/helpers/lens_stack.rb +134 -0
  72. data/lib/legion/extensions/agentic/attention/lens/runners/cognitive_lens.rb +90 -0
  73. data/lib/legion/extensions/agentic/attention/lens/version.rb +13 -0
  74. data/lib/legion/extensions/agentic/attention/lens.rb +22 -0
  75. data/lib/legion/extensions/agentic/attention/lighthouse/client.rb +25 -0
  76. data/lib/legion/extensions/agentic/attention/lighthouse/helpers/beacon.rb +76 -0
  77. data/lib/legion/extensions/agentic/attention/lighthouse/helpers/constants.rb +49 -0
  78. data/lib/legion/extensions/agentic/attention/lighthouse/helpers/fog.rb +74 -0
  79. data/lib/legion/extensions/agentic/attention/lighthouse/helpers/lighthouse_engine.rb +127 -0
  80. data/lib/legion/extensions/agentic/attention/lighthouse/runners/cognitive_lighthouse.rb +80 -0
  81. data/lib/legion/extensions/agentic/attention/lighthouse/version.rb +13 -0
  82. data/lib/legion/extensions/agentic/attention/lighthouse.rb +22 -0
  83. data/lib/legion/extensions/agentic/attention/priming/client.rb +21 -0
  84. data/lib/legion/extensions/agentic/attention/priming/helpers/activation_network.rb +130 -0
  85. data/lib/legion/extensions/agentic/attention/priming/helpers/concept_node.rb +92 -0
  86. data/lib/legion/extensions/agentic/attention/priming/helpers/constants.rb +54 -0
  87. data/lib/legion/extensions/agentic/attention/priming/runners/priming.rb +94 -0
  88. data/lib/legion/extensions/agentic/attention/priming/version.rb +13 -0
  89. data/lib/legion/extensions/agentic/attention/priming.rb +19 -0
  90. data/lib/legion/extensions/agentic/attention/prism/client.rb +26 -0
  91. data/lib/legion/extensions/agentic/attention/prism/helpers/beam.rb +169 -0
  92. data/lib/legion/extensions/agentic/attention/prism/helpers/constants.rb +46 -0
  93. data/lib/legion/extensions/agentic/attention/prism/helpers/prism_engine.rb +136 -0
  94. data/lib/legion/extensions/agentic/attention/prism/helpers/spectral_component.rb +72 -0
  95. data/lib/legion/extensions/agentic/attention/prism/runners/cognitive_prism.rb +79 -0
  96. data/lib/legion/extensions/agentic/attention/prism/version.rb +13 -0
  97. data/lib/legion/extensions/agentic/attention/prism.rb +22 -0
  98. data/lib/legion/extensions/agentic/attention/regulation/client.rb +19 -0
  99. data/lib/legion/extensions/agentic/attention/regulation/helpers/attention_controller.rb +157 -0
  100. data/lib/legion/extensions/agentic/attention/regulation/helpers/attention_target.rb +64 -0
  101. data/lib/legion/extensions/agentic/attention/regulation/helpers/constants.rb +41 -0
  102. data/lib/legion/extensions/agentic/attention/regulation/runners/attention_regulation.rb +88 -0
  103. data/lib/legion/extensions/agentic/attention/regulation/version.rb +13 -0
  104. data/lib/legion/extensions/agentic/attention/regulation.rb +20 -0
  105. data/lib/legion/extensions/agentic/attention/relevance_theory/helpers/client.rb +17 -0
  106. data/lib/legion/extensions/agentic/attention/relevance_theory/helpers/cognitive_input.rb +88 -0
  107. data/lib/legion/extensions/agentic/attention/relevance_theory/helpers/constants.rb +50 -0
  108. data/lib/legion/extensions/agentic/attention/relevance_theory/helpers/relevance_engine.rb +152 -0
  109. data/lib/legion/extensions/agentic/attention/relevance_theory/runners/relevance_theory.rb +98 -0
  110. data/lib/legion/extensions/agentic/attention/relevance_theory/version.rb +13 -0
  111. data/lib/legion/extensions/agentic/attention/relevance_theory.rb +19 -0
  112. data/lib/legion/extensions/agentic/attention/salience/client.rb +21 -0
  113. data/lib/legion/extensions/agentic/attention/salience/helpers/constants.rb +44 -0
  114. data/lib/legion/extensions/agentic/attention/salience/helpers/salience_map.rb +122 -0
  115. data/lib/legion/extensions/agentic/attention/salience/helpers/signal_integrator.rb +97 -0
  116. data/lib/legion/extensions/agentic/attention/salience/runners/salience.rb +70 -0
  117. data/lib/legion/extensions/agentic/attention/salience/version.rb +13 -0
  118. data/lib/legion/extensions/agentic/attention/salience.rb +19 -0
  119. data/lib/legion/extensions/agentic/attention/schema/actors/decay.rb +45 -0
  120. data/lib/legion/extensions/agentic/attention/schema/client.rb +28 -0
  121. data/lib/legion/extensions/agentic/attention/schema/helpers/attention_schema_model.rb +226 -0
  122. data/lib/legion/extensions/agentic/attention/schema/helpers/constants.rb +66 -0
  123. data/lib/legion/extensions/agentic/attention/schema/helpers/schema_item.rb +68 -0
  124. data/lib/legion/extensions/agentic/attention/schema/runners/attention_schema.rb +117 -0
  125. data/lib/legion/extensions/agentic/attention/schema/version.rb +13 -0
  126. data/lib/legion/extensions/agentic/attention/schema.rb +19 -0
  127. data/lib/legion/extensions/agentic/attention/sensory_gating/client.rb +15 -0
  128. data/lib/legion/extensions/agentic/attention/sensory_gating/helpers/constants.rb +44 -0
  129. data/lib/legion/extensions/agentic/attention/sensory_gating/helpers/gating_engine.rb +109 -0
  130. data/lib/legion/extensions/agentic/attention/sensory_gating/helpers/sensory_filter.rb +100 -0
  131. data/lib/legion/extensions/agentic/attention/sensory_gating/runners/sensory_gating.rb +73 -0
  132. data/lib/legion/extensions/agentic/attention/sensory_gating/version.rb +13 -0
  133. data/lib/legion/extensions/agentic/attention/sensory_gating.rb +19 -0
  134. data/lib/legion/extensions/agentic/attention/signal_detection/client.rb +28 -0
  135. data/lib/legion/extensions/agentic/attention/signal_detection/helpers/constants.rb +66 -0
  136. data/lib/legion/extensions/agentic/attention/signal_detection/helpers/detection_engine.rb +129 -0
  137. data/lib/legion/extensions/agentic/attention/signal_detection/helpers/detector.rb +136 -0
  138. data/lib/legion/extensions/agentic/attention/signal_detection/runners/signal_detection.rb +113 -0
  139. data/lib/legion/extensions/agentic/attention/signal_detection/version.rb +13 -0
  140. data/lib/legion/extensions/agentic/attention/signal_detection.rb +19 -0
  141. data/lib/legion/extensions/agentic/attention/spotlight/client.rb +29 -0
  142. data/lib/legion/extensions/agentic/attention/spotlight/helpers/attention_target.rb +61 -0
  143. data/lib/legion/extensions/agentic/attention/spotlight/helpers/constants.rb +44 -0
  144. data/lib/legion/extensions/agentic/attention/spotlight/helpers/spotlight.rb +78 -0
  145. data/lib/legion/extensions/agentic/attention/spotlight/helpers/spotlight_engine.rb +163 -0
  146. data/lib/legion/extensions/agentic/attention/spotlight/runners/attention_spotlight.rb +122 -0
  147. data/lib/legion/extensions/agentic/attention/spotlight/version.rb +13 -0
  148. data/lib/legion/extensions/agentic/attention/spotlight.rb +20 -0
  149. data/lib/legion/extensions/agentic/attention/subliminal/client.rb +19 -0
  150. data/lib/legion/extensions/agentic/attention/subliminal/helpers/constants.rb +74 -0
  151. data/lib/legion/extensions/agentic/attention/subliminal/helpers/influence_event.rb +44 -0
  152. data/lib/legion/extensions/agentic/attention/subliminal/helpers/subliminal_engine.rb +149 -0
  153. data/lib/legion/extensions/agentic/attention/subliminal/helpers/subliminal_trace.rb +101 -0
  154. data/lib/legion/extensions/agentic/attention/subliminal/runners/subliminal.rb +71 -0
  155. data/lib/legion/extensions/agentic/attention/subliminal/version.rb +13 -0
  156. data/lib/legion/extensions/agentic/attention/subliminal.rb +20 -0
  157. data/lib/legion/extensions/agentic/attention/surprise/client.rb +22 -0
  158. data/lib/legion/extensions/agentic/attention/surprise/helpers/constants.rb +35 -0
  159. data/lib/legion/extensions/agentic/attention/surprise/helpers/habituation_model.rb +62 -0
  160. data/lib/legion/extensions/agentic/attention/surprise/helpers/surprise_event.rb +43 -0
  161. data/lib/legion/extensions/agentic/attention/surprise/helpers/surprise_store.rb +74 -0
  162. data/lib/legion/extensions/agentic/attention/surprise/runners/surprise.rb +174 -0
  163. data/lib/legion/extensions/agentic/attention/surprise/version.rb +13 -0
  164. data/lib/legion/extensions/agentic/attention/surprise.rb +20 -0
  165. data/lib/legion/extensions/agentic/attention/switching/client.rb +19 -0
  166. data/lib/legion/extensions/agentic/attention/switching/helpers/constants.rb +64 -0
  167. data/lib/legion/extensions/agentic/attention/switching/helpers/switch_event.rb +60 -0
  168. data/lib/legion/extensions/agentic/attention/switching/helpers/switching_engine.rb +172 -0
  169. data/lib/legion/extensions/agentic/attention/switching/helpers/task_set.rb +91 -0
  170. data/lib/legion/extensions/agentic/attention/switching/runners/attention_switching.rb +92 -0
  171. data/lib/legion/extensions/agentic/attention/switching/version.rb +13 -0
  172. data/lib/legion/extensions/agentic/attention/switching.rb +20 -0
  173. data/lib/legion/extensions/agentic/attention/synesthesia/client.rb +29 -0
  174. data/lib/legion/extensions/agentic/attention/synesthesia/helpers/constants.rb +52 -0
  175. data/lib/legion/extensions/agentic/attention/synesthesia/helpers/sensory_mapping.rb +70 -0
  176. data/lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine.rb +177 -0
  177. data/lib/legion/extensions/agentic/attention/synesthesia/helpers/synesthetic_event.rb +49 -0
  178. data/lib/legion/extensions/agentic/attention/synesthesia/runners/cognitive_synesthesia.rb +83 -0
  179. data/lib/legion/extensions/agentic/attention/synesthesia/version.rb +13 -0
  180. data/lib/legion/extensions/agentic/attention/synesthesia.rb +20 -0
  181. data/lib/legion/extensions/agentic/attention/telescope/client.rb +15 -0
  182. data/lib/legion/extensions/agentic/attention/telescope/helpers/constants.rb +60 -0
  183. data/lib/legion/extensions/agentic/attention/telescope/helpers/observation.rb +68 -0
  184. data/lib/legion/extensions/agentic/attention/telescope/helpers/observatory_engine.rb +126 -0
  185. data/lib/legion/extensions/agentic/attention/telescope/helpers/telescope.rb +129 -0
  186. data/lib/legion/extensions/agentic/attention/telescope/runners/cognitive_telescope.rb +103 -0
  187. data/lib/legion/extensions/agentic/attention/telescope/version.rb +13 -0
  188. data/lib/legion/extensions/agentic/attention/telescope.rb +22 -0
  189. data/lib/legion/extensions/agentic/attention/version.rb +11 -0
  190. data/lib/legion/extensions/agentic/attention.rb +41 -0
  191. data/spec/legion/extensions/agentic/attention/arousal/client_spec.rb +42 -0
  192. data/spec/legion/extensions/agentic/attention/arousal/helpers/arousal_model_spec.rb +160 -0
  193. data/spec/legion/extensions/agentic/attention/arousal/helpers/constants_spec.rb +61 -0
  194. data/spec/legion/extensions/agentic/attention/arousal/runners/arousal_spec.rb +137 -0
  195. data/spec/legion/extensions/agentic/attention/blindspot/client_spec.rb +41 -0
  196. data/spec/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine_spec.rb +246 -0
  197. data/spec/legion/extensions/agentic/attention/blindspot/helpers/blindspot_spec.rb +204 -0
  198. data/spec/legion/extensions/agentic/attention/blindspot/helpers/constants_spec.rb +82 -0
  199. data/spec/legion/extensions/agentic/attention/blindspot/helpers/knowledge_boundary_spec.rb +104 -0
  200. data/spec/legion/extensions/agentic/attention/blindspot/runners/cognitive_blindspot_spec.rb +179 -0
  201. data/spec/legion/extensions/agentic/attention/blink/client_spec.rb +18 -0
  202. data/spec/legion/extensions/agentic/attention/blink/helpers/blink_engine_spec.rb +147 -0
  203. data/spec/legion/extensions/agentic/attention/blink/helpers/constants_spec.rb +27 -0
  204. data/spec/legion/extensions/agentic/attention/blink/helpers/stimulus_spec.rb +77 -0
  205. data/spec/legion/extensions/agentic/attention/blink/runners/attentional_blink_spec.rb +77 -0
  206. data/spec/legion/extensions/agentic/attention/economy/client_spec.rb +30 -0
  207. data/spec/legion/extensions/agentic/attention/economy/helpers/attention_budget_spec.rb +222 -0
  208. data/spec/legion/extensions/agentic/attention/economy/helpers/constants_spec.rb +112 -0
  209. data/spec/legion/extensions/agentic/attention/economy/helpers/demand_spec.rb +128 -0
  210. data/spec/legion/extensions/agentic/attention/economy/runners/attention_economy_spec.rb +163 -0
  211. data/spec/legion/extensions/agentic/attention/feature_binding/client_spec.rb +20 -0
  212. data/spec/legion/extensions/agentic/attention/feature_binding/helpers/binding_field_spec.rb +207 -0
  213. data/spec/legion/extensions/agentic/attention/feature_binding/helpers/bound_object_spec.rb +149 -0
  214. data/spec/legion/extensions/agentic/attention/feature_binding/helpers/feature_spec.rb +86 -0
  215. data/spec/legion/extensions/agentic/attention/feature_binding/runners/feature_binding_spec.rb +106 -0
  216. data/spec/legion/extensions/agentic/attention/focus/client_spec.rb +19 -0
  217. data/spec/legion/extensions/agentic/attention/focus/helpers/focus_manager_spec.rb +105 -0
  218. data/spec/legion/extensions/agentic/attention/focus/helpers/focus_spec.rb +148 -0
  219. data/spec/legion/extensions/agentic/attention/focus/helpers/habituation_spec.rb +97 -0
  220. data/spec/legion/extensions/agentic/attention/focus/runners/attention_spec.rb +134 -0
  221. data/spec/legion/extensions/agentic/attention/kaleidoscope/client_spec.rb +38 -0
  222. data/spec/legion/extensions/agentic/attention/kaleidoscope/helpers/constants_spec.rb +79 -0
  223. data/spec/legion/extensions/agentic/attention/kaleidoscope/helpers/facet_spec.rb +155 -0
  224. data/spec/legion/extensions/agentic/attention/kaleidoscope/helpers/kaleidoscope_engine_spec.rb +164 -0
  225. data/spec/legion/extensions/agentic/attention/kaleidoscope/helpers/pattern_spec.rb +157 -0
  226. data/spec/legion/extensions/agentic/attention/kaleidoscope/runners/cognitive_kaleidoscope_spec.rb +112 -0
  227. data/spec/legion/extensions/agentic/attention/latent_inhibition/client_spec.rb +49 -0
  228. data/spec/legion/extensions/agentic/attention/latent_inhibition/helpers/constants_spec.rb +57 -0
  229. data/spec/legion/extensions/agentic/attention/latent_inhibition/helpers/inhibition_engine_spec.rb +207 -0
  230. data/spec/legion/extensions/agentic/attention/latent_inhibition/helpers/stimulus_record_spec.rb +175 -0
  231. data/spec/legion/extensions/agentic/attention/latent_inhibition/runners/latent_inhibition_spec.rb +148 -0
  232. data/spec/legion/extensions/agentic/attention/lens/client_spec.rb +64 -0
  233. data/spec/legion/extensions/agentic/attention/lens/helpers/constants_spec.rb +91 -0
  234. data/spec/legion/extensions/agentic/attention/lens/helpers/lens_engine_spec.rb +158 -0
  235. data/spec/legion/extensions/agentic/attention/lens/helpers/lens_spec.rb +222 -0
  236. data/spec/legion/extensions/agentic/attention/lens/helpers/lens_stack_spec.rb +179 -0
  237. data/spec/legion/extensions/agentic/attention/lens/runners/cognitive_lens_spec.rb +182 -0
  238. data/spec/legion/extensions/agentic/attention/lighthouse/client_spec.rb +103 -0
  239. data/spec/legion/extensions/agentic/attention/lighthouse/helpers/beacon_spec.rb +170 -0
  240. data/spec/legion/extensions/agentic/attention/lighthouse/helpers/constants_spec.rb +94 -0
  241. data/spec/legion/extensions/agentic/attention/lighthouse/helpers/fog_spec.rb +166 -0
  242. data/spec/legion/extensions/agentic/attention/lighthouse/helpers/lighthouse_engine_spec.rb +238 -0
  243. data/spec/legion/extensions/agentic/attention/lighthouse/runners/cognitive_lighthouse_spec.rb +182 -0
  244. data/spec/legion/extensions/agentic/attention/priming/client_spec.rb +80 -0
  245. data/spec/legion/extensions/agentic/attention/priming/helpers/activation_network_spec.rb +176 -0
  246. data/spec/legion/extensions/agentic/attention/priming/helpers/concept_node_spec.rb +165 -0
  247. data/spec/legion/extensions/agentic/attention/priming/helpers/constants_spec.rb +51 -0
  248. data/spec/legion/extensions/agentic/attention/priming/runners/priming_spec.rb +141 -0
  249. data/spec/legion/extensions/agentic/attention/prism/client_spec.rb +86 -0
  250. data/spec/legion/extensions/agentic/attention/prism/helpers/beam_spec.rb +182 -0
  251. data/spec/legion/extensions/agentic/attention/prism/helpers/constants_spec.rb +93 -0
  252. data/spec/legion/extensions/agentic/attention/prism/helpers/prism_engine_spec.rb +253 -0
  253. data/spec/legion/extensions/agentic/attention/prism/helpers/spectral_component_spec.rb +171 -0
  254. data/spec/legion/extensions/agentic/attention/prism/runners/cognitive_prism_spec.rb +132 -0
  255. data/spec/legion/extensions/agentic/attention/regulation/client_spec.rb +58 -0
  256. data/spec/legion/extensions/agentic/attention/regulation/helpers/attention_controller_spec.rb +295 -0
  257. data/spec/legion/extensions/agentic/attention/regulation/helpers/attention_target_spec.rb +122 -0
  258. data/spec/legion/extensions/agentic/attention/regulation/runners/attention_regulation_spec.rb +147 -0
  259. data/spec/legion/extensions/agentic/attention/relevance_theory/helpers/cognitive_input_spec.rb +121 -0
  260. data/spec/legion/extensions/agentic/attention/relevance_theory/helpers/relevance_engine_spec.rb +149 -0
  261. data/spec/legion/extensions/agentic/attention/relevance_theory/relevance_theory_spec.rb +11 -0
  262. data/spec/legion/extensions/agentic/attention/relevance_theory/runners/relevance_theory_spec.rb +86 -0
  263. data/spec/legion/extensions/agentic/attention/salience/client_spec.rb +60 -0
  264. data/spec/legion/extensions/agentic/attention/salience/helpers/constants_spec.rb +100 -0
  265. data/spec/legion/extensions/agentic/attention/salience/helpers/salience_map_spec.rb +189 -0
  266. data/spec/legion/extensions/agentic/attention/salience/helpers/signal_integrator_spec.rb +149 -0
  267. data/spec/legion/extensions/agentic/attention/salience/runners/salience_spec.rb +143 -0
  268. data/spec/legion/extensions/agentic/attention/schema/client_spec.rb +47 -0
  269. data/spec/legion/extensions/agentic/attention/schema/helpers/attention_schema_model_spec.rb +219 -0
  270. data/spec/legion/extensions/agentic/attention/schema/helpers/schema_item_spec.rb +114 -0
  271. data/spec/legion/extensions/agentic/attention/schema/runners/attention_schema_spec.rb +185 -0
  272. data/spec/legion/extensions/agentic/attention/sensory_gating/helpers/gating_engine_spec.rb +112 -0
  273. data/spec/legion/extensions/agentic/attention/sensory_gating/helpers/sensory_filter_spec.rb +121 -0
  274. data/spec/legion/extensions/agentic/attention/sensory_gating/runners/sensory_gating_spec.rb +61 -0
  275. data/spec/legion/extensions/agentic/attention/signal_detection/client_spec.rb +20 -0
  276. data/spec/legion/extensions/agentic/attention/signal_detection/helpers/constants_spec.rb +85 -0
  277. data/spec/legion/extensions/agentic/attention/signal_detection/helpers/detection_engine_spec.rb +143 -0
  278. data/spec/legion/extensions/agentic/attention/signal_detection/helpers/detector_spec.rb +179 -0
  279. data/spec/legion/extensions/agentic/attention/signal_detection/runners/signal_detection_spec.rb +151 -0
  280. data/spec/legion/extensions/agentic/attention/spotlight/client_spec.rb +31 -0
  281. data/spec/legion/extensions/agentic/attention/spotlight/helpers/attention_target_spec.rb +121 -0
  282. data/spec/legion/extensions/agentic/attention/spotlight/helpers/constants_spec.rb +82 -0
  283. data/spec/legion/extensions/agentic/attention/spotlight/helpers/spotlight_engine_spec.rb +275 -0
  284. data/spec/legion/extensions/agentic/attention/spotlight/helpers/spotlight_spec.rb +196 -0
  285. data/spec/legion/extensions/agentic/attention/spotlight/runners/attention_spotlight_spec.rb +251 -0
  286. data/spec/legion/extensions/agentic/attention/subliminal/client_spec.rb +21 -0
  287. data/spec/legion/extensions/agentic/attention/subliminal/helpers/influence_event_spec.rb +58 -0
  288. data/spec/legion/extensions/agentic/attention/subliminal/helpers/subliminal_engine_spec.rb +161 -0
  289. data/spec/legion/extensions/agentic/attention/subliminal/helpers/subliminal_trace_spec.rb +168 -0
  290. data/spec/legion/extensions/agentic/attention/subliminal/runners_spec.rb +78 -0
  291. data/spec/legion/extensions/agentic/attention/subliminal/subliminal_spec.rb +7 -0
  292. data/spec/legion/extensions/agentic/attention/surprise/client_spec.rb +122 -0
  293. data/spec/legion/extensions/agentic/attention/surprise/helpers/constants_spec.rb +112 -0
  294. data/spec/legion/extensions/agentic/attention/surprise/helpers/habituation_model_spec.rb +127 -0
  295. data/spec/legion/extensions/agentic/attention/surprise/helpers/surprise_event_spec.rb +102 -0
  296. data/spec/legion/extensions/agentic/attention/surprise/helpers/surprise_store_spec.rb +171 -0
  297. data/spec/legion/extensions/agentic/attention/surprise/runners/surprise_spec.rb +266 -0
  298. data/spec/legion/extensions/agentic/attention/switching/attention_switching_spec.rb +7 -0
  299. data/spec/legion/extensions/agentic/attention/switching/helpers/switch_event_spec.rb +74 -0
  300. data/spec/legion/extensions/agentic/attention/switching/helpers/switching_engine_spec.rb +164 -0
  301. data/spec/legion/extensions/agentic/attention/switching/helpers/task_set_spec.rb +134 -0
  302. data/spec/legion/extensions/agentic/attention/synesthesia/client_spec.rb +57 -0
  303. data/spec/legion/extensions/agentic/attention/synesthesia/helpers/constants_spec.rb +89 -0
  304. data/spec/legion/extensions/agentic/attention/synesthesia/helpers/sensory_mapping_spec.rb +135 -0
  305. data/spec/legion/extensions/agentic/attention/synesthesia/helpers/synesthesia_engine_spec.rb +260 -0
  306. data/spec/legion/extensions/agentic/attention/synesthesia/helpers/synesthetic_event_spec.rb +83 -0
  307. data/spec/legion/extensions/agentic/attention/synesthesia/runners/cognitive_synesthesia_spec.rb +192 -0
  308. data/spec/legion/extensions/agentic/attention/telescope/client_spec.rb +30 -0
  309. data/spec/legion/extensions/agentic/attention/telescope/helpers/constants_spec.rb +108 -0
  310. data/spec/legion/extensions/agentic/attention/telescope/helpers/observation_spec.rb +138 -0
  311. data/spec/legion/extensions/agentic/attention/telescope/helpers/observatory_engine_spec.rb +197 -0
  312. data/spec/legion/extensions/agentic/attention/telescope/helpers/telescope_spec.rb +251 -0
  313. data/spec/legion/extensions/agentic/attention/telescope/runners/cognitive_telescope_spec.rb +191 -0
  314. data/spec/spec_helper.rb +46 -0
  315. metadata +399 -0
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Attention
9
+ module SensoryGating
10
+ module Helpers
11
+ class SensoryFilter
12
+ include Constants
13
+
14
+ attr_reader :id, :modality, :gate_threshold, :habituation_level,
15
+ :stimuli_passed, :stimuli_blocked, :created_at
16
+
17
+ def initialize(modality:, gate_threshold: DEFAULT_GATE_THRESHOLD)
18
+ @id = SecureRandom.uuid
19
+ @modality = modality.to_sym
20
+ @gate_threshold = gate_threshold.to_f.clamp(0.0, 1.0)
21
+ @habituation_level = 0.0
22
+ @stimuli_passed = 0
23
+ @stimuli_blocked = 0
24
+ @created_at = Time.now.utc
25
+ end
26
+
27
+ def process(intensity:)
28
+ effective_threshold = (@gate_threshold + @habituation_level).clamp(0.0, 1.0).round(10)
29
+ if intensity >= effective_threshold
30
+ @stimuli_passed += 1
31
+ habituate!
32
+ :passed
33
+ else
34
+ @stimuli_blocked += 1
35
+ :blocked
36
+ end
37
+ end
38
+
39
+ def open_gate!(amount: GATE_ADJUSTMENT)
40
+ @gate_threshold = (@gate_threshold - amount).clamp(0.0, 1.0).round(10)
41
+ self
42
+ end
43
+
44
+ def close_gate!(amount: GATE_ADJUSTMENT)
45
+ @gate_threshold = (@gate_threshold + amount).clamp(0.0, 1.0).round(10)
46
+ self
47
+ end
48
+
49
+ def sensitize!(amount: SENSITIZATION_RATE)
50
+ @habituation_level = (@habituation_level - amount).clamp(-0.5, 0.5).round(10)
51
+ self
52
+ end
53
+
54
+ def habituate!(amount: HABITUATION_RATE)
55
+ @habituation_level = (@habituation_level + amount).clamp(-0.5, 0.5).round(10)
56
+ self
57
+ end
58
+
59
+ def reset_habituation!
60
+ @habituation_level = 0.0
61
+ self
62
+ end
63
+
64
+ def effective_threshold
65
+ (@gate_threshold + @habituation_level).clamp(0.0, 1.0).round(10)
66
+ end
67
+
68
+ def pass_rate
69
+ total = @stimuli_passed + @stimuli_blocked
70
+ return 0.0 if total.zero?
71
+
72
+ (@stimuli_passed.to_f / total).round(4)
73
+ end
74
+
75
+ def gate_label
76
+ match = GATE_LABELS.find { |range, _| range.cover?(@gate_threshold) }
77
+ match ? match.last : :blocked
78
+ end
79
+
80
+ def to_h
81
+ {
82
+ id: @id,
83
+ modality: @modality,
84
+ gate_threshold: @gate_threshold,
85
+ effective_threshold: effective_threshold,
86
+ habituation_level: @habituation_level,
87
+ gate_label: gate_label,
88
+ stimuli_passed: @stimuli_passed,
89
+ stimuli_blocked: @stimuli_blocked,
90
+ pass_rate: pass_rate,
91
+ created_at: @created_at
92
+ }
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Attention
7
+ module SensoryGating
8
+ module Runners
9
+ module SensoryGating
10
+ include Helpers::Constants
11
+
12
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
13
+
14
+ def create_filter(modality:, engine: nil, gate_threshold: DEFAULT_GATE_THRESHOLD, **)
15
+ eng = engine || default_engine
16
+ filter = eng.create_filter(modality: modality, gate_threshold: gate_threshold)
17
+ { success: true, filter: filter.to_h }
18
+ end
19
+
20
+ def process_stimulus(filter_id:, intensity:, engine: nil, **)
21
+ eng = engine || default_engine
22
+ result = eng.process_stimulus(filter_id: filter_id, intensity: intensity)
23
+ return { success: false, error: 'filter not found' } unless result
24
+
25
+ { success: true, outcome: result[:outcome], filter: result[:filter].to_h }
26
+ end
27
+
28
+ def open_gate(filter_id:, engine: nil, amount: GATE_ADJUSTMENT, **)
29
+ eng = engine || default_engine
30
+ result = eng.open_gate(filter_id: filter_id, amount: amount)
31
+ return { success: false, error: 'filter not found' } unless result
32
+
33
+ { success: true, filter: result.to_h }
34
+ end
35
+
36
+ def close_gate(filter_id:, engine: nil, amount: GATE_ADJUSTMENT, **)
37
+ eng = engine || default_engine
38
+ result = eng.close_gate(filter_id: filter_id, amount: amount)
39
+ return { success: false, error: 'filter not found' } unless result
40
+
41
+ { success: true, filter: result.to_h }
42
+ end
43
+
44
+ def sensitize(filter_id:, engine: nil, amount: SENSITIZATION_RATE, **)
45
+ eng = engine || default_engine
46
+ result = eng.sensitize(filter_id: filter_id, amount: amount)
47
+ return { success: false, error: 'filter not found' } unless result
48
+
49
+ { success: true, filter: result.to_h }
50
+ end
51
+
52
+ def average_pass_rate(engine: nil, **)
53
+ eng = engine || default_engine
54
+ { success: true, pass_rate: eng.average_pass_rate }
55
+ end
56
+
57
+ def gating_report(engine: nil, **)
58
+ eng = engine || default_engine
59
+ { success: true, report: eng.gating_report }
60
+ end
61
+
62
+ private
63
+
64
+ def default_engine
65
+ @default_engine ||= Helpers::GatingEngine.new
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Attention
7
+ module SensoryGating
8
+ VERSION = '0.1.0'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'sensory_gating/version'
4
+ require_relative 'sensory_gating/helpers/constants'
5
+ require_relative 'sensory_gating/helpers/sensory_filter'
6
+ require_relative 'sensory_gating/helpers/gating_engine'
7
+ require_relative 'sensory_gating/runners/sensory_gating'
8
+ require_relative 'sensory_gating/client'
9
+
10
+ module Legion
11
+ module Extensions
12
+ module Agentic
13
+ module Attention
14
+ module SensoryGating
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/attention/signal_detection/helpers/constants'
4
+ require 'legion/extensions/agentic/attention/signal_detection/helpers/detector'
5
+ require 'legion/extensions/agentic/attention/signal_detection/helpers/detection_engine'
6
+ require 'legion/extensions/agentic/attention/signal_detection/runners/signal_detection'
7
+
8
+ module Legion
9
+ module Extensions
10
+ module Agentic
11
+ module Attention
12
+ module SignalDetection
13
+ class Client
14
+ include Runners::SignalDetection
15
+
16
+ def initialize(**)
17
+ @detection_engine = Helpers::DetectionEngine.new
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :detection_engine
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Attention
7
+ module SignalDetection
8
+ module Helpers
9
+ module Constants
10
+ MAX_DETECTORS = 100
11
+ MAX_TRIALS = 1000
12
+ MAX_HISTORY = 300
13
+
14
+ DEFAULT_SENSITIVITY = 1.0
15
+ SENSITIVITY_FLOOR = 0.0
16
+ SENSITIVITY_CEILING = 5.0
17
+
18
+ DEFAULT_CRITERION = 0.0
19
+ CRITERION_FLOOR = -3.0
20
+ CRITERION_CEILING = 3.0
21
+
22
+ LEARNING_RATE = 0.05
23
+ DECAY_RATE = 0.01
24
+
25
+ TRIAL_OUTCOMES = %i[hit miss false_alarm correct_rejection].freeze
26
+
27
+ SENSITIVITY_LABELS = {
28
+ (3.0..) => :exceptional,
29
+ (2.0...3.0) => :excellent,
30
+ (1.0...2.0) => :good,
31
+ (0.5...1.0) => :moderate,
32
+ (..0.5) => :poor
33
+ }.freeze
34
+
35
+ BIAS_LABELS = {
36
+ (1.0..) => :very_conservative,
37
+ (0.3...1.0) => :conservative,
38
+ (-0.3...0.3) => :neutral,
39
+ (-1.0...-0.3) => :liberal,
40
+ (...-1.0) => :very_liberal
41
+ }.freeze
42
+
43
+ module_function
44
+
45
+ def sensitivity_label(d_prime)
46
+ SENSITIVITY_LABELS.find { |range, _| range.cover?(d_prime) }&.last || :poor
47
+ end
48
+
49
+ def bias_label(criterion)
50
+ BIAS_LABELS.find { |range, _| range.cover?(criterion) }&.last || :neutral
51
+ end
52
+
53
+ def clamp_sensitivity(value)
54
+ value.clamp(SENSITIVITY_FLOOR, SENSITIVITY_CEILING)
55
+ end
56
+
57
+ def clamp_criterion(value)
58
+ value.clamp(CRITERION_FLOOR, CRITERION_CEILING)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Attention
7
+ module SignalDetection
8
+ module Helpers
9
+ class DetectionEngine
10
+ def initialize
11
+ @detectors = {}
12
+ end
13
+
14
+ def create_detector(domain:)
15
+ raise ArgumentError, "max detectors reached (#{Constants::MAX_DETECTORS})" if @detectors.size >= Constants::MAX_DETECTORS
16
+
17
+ detector = Detector.new(domain: domain)
18
+ @detectors[detector.id] = detector
19
+ detector
20
+ end
21
+
22
+ def record_trial(detector_id:, signal_present:, responded_present:)
23
+ detector = fetch!(detector_id)
24
+ outcome = classify_outcome(signal_present: signal_present, responded_present: responded_present)
25
+ detector.record_trial(outcome: outcome)
26
+ { detector_id: detector_id, outcome: outcome, trial_count: detector.trial_count }
27
+ end
28
+
29
+ def compute_sensitivity(detector_id:)
30
+ detector = fetch!(detector_id)
31
+ {
32
+ detector_id: detector_id,
33
+ d_prime: detector.compute_dprime,
34
+ criterion: detector.compute_criterion,
35
+ accuracy: detector.accuracy,
36
+ hit_rate: detector.hit_rate,
37
+ false_alarm_rate: detector.false_alarm_rate,
38
+ sensitivity_label: detector.sensitivity_label,
39
+ bias_label: detector.bias_label
40
+ }
41
+ end
42
+
43
+ def adjust_bias(detector_id:, amount:)
44
+ detector = fetch!(detector_id)
45
+ detector.adjust_criterion(amount: amount)
46
+ { detector_id: detector_id, criterion: detector.criterion, bias_label: detector.bias_label }
47
+ end
48
+
49
+ def best_detectors(limit: 5)
50
+ @detectors.values
51
+ .sort_by { |d| -d.sensitivity }
52
+ .first(limit)
53
+ .map(&:to_h)
54
+ end
55
+
56
+ def by_domain(domain:)
57
+ @detectors.values.select { |d| d.domain == domain }.map(&:to_h)
58
+ end
59
+
60
+ def optimal_criterion(detector_id:, signal_probability: 0.5)
61
+ detector = fetch!(detector_id)
62
+ # Optimal criterion for equal cost: c* = 0.5 * ln((1-p)/p) in likelihood ratio terms
63
+ # In SDT criterion units: shift from neutral based on prior probability
64
+ prior_ratio = (1.0 - signal_probability) / signal_probability.clamp(0.001, 0.999)
65
+ optimal = 0.5 * Math.log(prior_ratio)
66
+ {
67
+ detector_id: detector_id,
68
+ optimal_criterion: Constants.clamp_criterion(optimal),
69
+ current_criterion: detector.criterion,
70
+ signal_probability: signal_probability
71
+ }
72
+ end
73
+
74
+ def roc_point(detector_id:)
75
+ detector = fetch!(detector_id)
76
+ {
77
+ detector_id: detector_id,
78
+ hit_rate: detector.hit_rate,
79
+ false_alarm_rate: detector.false_alarm_rate,
80
+ d_prime: detector.sensitivity
81
+ }
82
+ end
83
+
84
+ def decay_all
85
+ count = 0
86
+ @detectors.each_value do |detector|
87
+ next if detector.trial_count.zero?
88
+
89
+ detector.adjust_criterion(amount: Constants::DECAY_RATE * -detector.criterion.clamp(-1, 1))
90
+ count += 1
91
+ end
92
+ count
93
+ end
94
+
95
+ def get(detector_id)
96
+ @detectors[detector_id]
97
+ end
98
+
99
+ def count
100
+ @detectors.size
101
+ end
102
+
103
+ def to_h
104
+ {
105
+ detector_count: @detectors.size,
106
+ detectors: @detectors.transform_values(&:to_h)
107
+ }
108
+ end
109
+
110
+ private
111
+
112
+ def fetch!(detector_id)
113
+ @detectors.fetch(detector_id) { raise KeyError, "detector not found: #{detector_id}" }
114
+ end
115
+
116
+ def classify_outcome(signal_present:, responded_present:)
117
+ if signal_present && responded_present then :hit
118
+ elsif signal_present && !responded_present then :miss
119
+ elsif !signal_present && responded_present then :false_alarm
120
+ else :correct_rejection
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Attention
9
+ module SignalDetection
10
+ module Helpers
11
+ class Detector
12
+ include Constants
13
+
14
+ attr_reader :id, :domain, :hits, :misses, :false_alarms, :correct_rejections,
15
+ :trial_count, :created_at, :last_trial_at, :sensitivity, :criterion
16
+
17
+ def initialize(domain:)
18
+ @id = SecureRandom.uuid
19
+ @domain = domain
20
+ @sensitivity = Constants::DEFAULT_SENSITIVITY
21
+ @criterion = Constants::DEFAULT_CRITERION
22
+ @hits = 0
23
+ @misses = 0
24
+ @false_alarms = 0
25
+ @correct_rejections = 0
26
+ @trial_count = 0
27
+ @created_at = Time.now.utc
28
+ @last_trial_at = nil
29
+ end
30
+
31
+ def record_trial(outcome:)
32
+ raise ArgumentError, "invalid outcome: #{outcome}" unless Constants::TRIAL_OUTCOMES.include?(outcome)
33
+
34
+ case outcome
35
+ when :hit then @hits += 1
36
+ when :miss then @misses += 1
37
+ when :false_alarm then @false_alarms += 1
38
+ when :correct_rejection then @correct_rejections += 1
39
+ end
40
+
41
+ @trial_count += 1
42
+ @last_trial_at = Time.now.utc
43
+
44
+ update_sensitivity
45
+ end
46
+
47
+ def hit_rate
48
+ signal_total = @hits + @misses + 1
49
+ (@hits + 0.5) / signal_total.to_f
50
+ end
51
+
52
+ def false_alarm_rate
53
+ noise_total = @false_alarms + @correct_rejections + 1
54
+ (@false_alarms + 0.5) / noise_total.to_f
55
+ end
56
+
57
+ def compute_dprime
58
+ d = z_score(hit_rate) - z_score(false_alarm_rate)
59
+ Constants.clamp_sensitivity(d)
60
+ end
61
+
62
+ def compute_criterion
63
+ c = -0.5 * (z_score(hit_rate) + z_score(false_alarm_rate))
64
+ Constants.clamp_criterion(c)
65
+ end
66
+
67
+ def accuracy
68
+ return 0.0 if @trial_count.zero?
69
+
70
+ (@hits + @correct_rejections).to_f / @trial_count
71
+ end
72
+
73
+ def sensitivity_label
74
+ Constants.sensitivity_label(@sensitivity)
75
+ end
76
+
77
+ def bias_label
78
+ Constants.bias_label(@criterion)
79
+ end
80
+
81
+ def adjust_criterion(amount:)
82
+ @criterion = Constants.clamp_criterion(@criterion + amount)
83
+ end
84
+
85
+ def to_h
86
+ {
87
+ id: @id,
88
+ domain: @domain,
89
+ sensitivity: @sensitivity,
90
+ criterion: @criterion,
91
+ hits: @hits,
92
+ misses: @misses,
93
+ false_alarms: @false_alarms,
94
+ correct_rejections: @correct_rejections,
95
+ trial_count: @trial_count,
96
+ hit_rate: hit_rate,
97
+ false_alarm_rate: false_alarm_rate,
98
+ accuracy: accuracy,
99
+ sensitivity_label: sensitivity_label,
100
+ bias_label: bias_label,
101
+ created_at: @created_at,
102
+ last_trial_at: @last_trial_at
103
+ }
104
+ end
105
+
106
+ private
107
+
108
+ def update_sensitivity
109
+ return if @trial_count < 2
110
+
111
+ @sensitivity = compute_dprime
112
+ @criterion = compute_criterion
113
+ end
114
+
115
+ def z_score(probability)
116
+ prob = probability.clamp(0.001, 0.999)
117
+ Math.sqrt(2.0) * erfinv((2.0 * prob) - 1.0)
118
+ end
119
+
120
+ def erfinv(val)
121
+ # Winitzki (2008) rational approximation for inverse error function
122
+ a = 0.147
123
+ ln_term = Math.log(1.0 - (val * val))
124
+ two_pi_a = (2.0 / (Math::PI * a))
125
+ half_ln = ln_term / 2.0
126
+
127
+ inner = two_pi_a + half_ln
128
+ Math.sqrt(Math.sqrt((inner * inner) - (ln_term / a)) - inner) * (val.negative? ? -1 : 1)
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Attention
7
+ module SignalDetection
8
+ module Runners
9
+ module SignalDetection
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex)
12
+
13
+ def create_detector(domain:, **)
14
+ detector = detection_engine.create_detector(domain: domain)
15
+ Legion::Logging.info "[signal_detection] created detector id=#{detector.id[0..7]} domain=#{domain}"
16
+ { created: true, detector_id: detector.id, domain: domain }
17
+ rescue ArgumentError => e
18
+ Legion::Logging.warn "[signal_detection] create_detector failed: #{e.message}"
19
+ { created: false, reason: e.message }
20
+ end
21
+
22
+ def record_detection_trial(detector_id:, signal_present:, responded_present:, **)
23
+ result = detection_engine.record_trial(
24
+ detector_id: detector_id,
25
+ signal_present: signal_present,
26
+ responded_present: responded_present
27
+ )
28
+ Legion::Logging.debug "[signal_detection] trial: id=#{detector_id[0..7]} outcome=#{result[:outcome]} count=#{result[:trial_count]}"
29
+ result
30
+ rescue KeyError => e
31
+ Legion::Logging.warn "[signal_detection] record_trial failed: #{e.message}"
32
+ { recorded: false, reason: :not_found }
33
+ end
34
+
35
+ def compute_detector_sensitivity(detector_id:, **)
36
+ result = detection_engine.compute_sensitivity(detector_id: detector_id)
37
+ Legion::Logging.debug "[signal_detection] sensitivity: id=#{detector_id[0..7]} " \
38
+ "d_prime=#{result[:d_prime].round(3)} label=#{result[:sensitivity_label]}"
39
+ result
40
+ rescue KeyError => e
41
+ Legion::Logging.warn "[signal_detection] compute_sensitivity failed: #{e.message}"
42
+ { found: false, reason: :not_found }
43
+ end
44
+
45
+ def adjust_detector_bias(detector_id:, amount:, **)
46
+ result = detection_engine.adjust_bias(detector_id: detector_id, amount: amount)
47
+ Legion::Logging.debug "[signal_detection] bias adjusted: id=#{detector_id[0..7]} " \
48
+ "criterion=#{result[:criterion].round(3)} label=#{result[:bias_label]}"
49
+ result
50
+ rescue KeyError => e
51
+ Legion::Logging.warn "[signal_detection] adjust_bias failed: #{e.message}"
52
+ { adjusted: false, reason: :not_found }
53
+ end
54
+
55
+ def best_detectors(limit: 5, **)
56
+ detectors = detection_engine.best_detectors(limit: limit)
57
+ Legion::Logging.debug "[signal_detection] best detectors: count=#{detectors.size} limit=#{limit}"
58
+ { detectors: detectors, count: detectors.size }
59
+ end
60
+
61
+ def domain_detectors(domain:, **)
62
+ detectors = detection_engine.by_domain(domain: domain)
63
+ Legion::Logging.debug "[signal_detection] domain detectors: domain=#{domain} count=#{detectors.size}"
64
+ { detectors: detectors, count: detectors.size, domain: domain }
65
+ end
66
+
67
+ def optimal_detector_criterion(detector_id:, signal_probability: 0.5, **)
68
+ result = detection_engine.optimal_criterion(
69
+ detector_id: detector_id,
70
+ signal_probability: signal_probability
71
+ )
72
+ Legion::Logging.debug "[signal_detection] optimal criterion: id=#{detector_id[0..7]} optimal=#{result[:optimal_criterion].round(3)}"
73
+ result
74
+ rescue KeyError => e
75
+ Legion::Logging.warn "[signal_detection] optimal_criterion failed: #{e.message}"
76
+ { found: false, reason: :not_found }
77
+ end
78
+
79
+ def detector_roc_point(detector_id:, **)
80
+ result = detection_engine.roc_point(detector_id: detector_id)
81
+ Legion::Logging.debug "[signal_detection] roc point: id=#{detector_id[0..7]} " \
82
+ "hr=#{result[:hit_rate].round(3)} far=#{result[:false_alarm_rate].round(3)}"
83
+ result
84
+ rescue KeyError => e
85
+ Legion::Logging.warn "[signal_detection] roc_point failed: #{e.message}"
86
+ { found: false, reason: :not_found }
87
+ end
88
+
89
+ def update_signal_detection(**)
90
+ decayed = detection_engine.decay_all
91
+ Legion::Logging.debug "[signal_detection] decay cycle: detectors_updated=#{decayed}"
92
+ { decayed: decayed }
93
+ end
94
+
95
+ def signal_detection_stats(**)
96
+ {
97
+ total_detectors: detection_engine.count,
98
+ top_detectors: detection_engine.best_detectors(limit: 3)
99
+ }
100
+ end
101
+
102
+ private
103
+
104
+ def detection_engine
105
+ @detection_engine ||= Helpers::DetectionEngine.new
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end