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,174 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Attention
7
+ module Blindspot
8
+ module Helpers
9
+ class BlindspotEngine
10
+ include Constants
11
+
12
+ attr_reader :awareness_score
13
+
14
+ def initialize
15
+ @blindspots = {}
16
+ @boundaries = {}
17
+ @awareness_score = 1.0
18
+ end
19
+
20
+ def register_blindspot(domain:, discovered_by:, description:, severity: DEFAULT_SEVERITY)
21
+ prune_blindspots_if_needed
22
+ blindspot = Blindspot.new(domain: domain, discovered_by: discovered_by,
23
+ description: description, severity: severity)
24
+ @blindspots[blindspot.id] = blindspot
25
+ recalculate_awareness
26
+ blindspot
27
+ end
28
+
29
+ def acknowledge_blindspot(blindspot_id:)
30
+ blindspot = @blindspots.fetch(blindspot_id, nil)
31
+ return { found: false, blindspot_id: blindspot_id } unless blindspot
32
+
33
+ blindspot.acknowledge!
34
+ recalculate_awareness
35
+ { found: true, blindspot_id: blindspot_id, status: blindspot.status,
36
+ awareness_score: @awareness_score.round(10) }
37
+ end
38
+
39
+ def mitigate_blindspot(blindspot_id:, boost: SEVERITY_BOOST)
40
+ blindspot = @blindspots.fetch(blindspot_id, nil)
41
+ return { found: false, blindspot_id: blindspot_id } unless blindspot
42
+
43
+ blindspot.mitigate!(boost: boost)
44
+ recalculate_awareness
45
+ { found: true, blindspot_id: blindspot_id, status: blindspot.status,
46
+ severity: blindspot.severity, awareness_score: @awareness_score.round(10) }
47
+ end
48
+
49
+ def resolve_blindspot(blindspot_id:)
50
+ blindspot = @blindspots.fetch(blindspot_id, nil)
51
+ return { found: false, blindspot_id: blindspot_id } unless blindspot
52
+
53
+ blindspot.resolve!
54
+ recalculate_awareness
55
+ { found: true, blindspot_id: blindspot_id, status: blindspot.status,
56
+ awareness_score: @awareness_score.round(10) }
57
+ end
58
+
59
+ def set_boundary(domain:, confidence: 0.5, coverage_estimate: 0.5)
60
+ prune_boundaries_if_needed
61
+ existing = boundary_for_domain(domain)
62
+ return update_boundary!(existing, confidence, coverage_estimate) if existing
63
+
64
+ boundary = KnowledgeBoundary.new(domain: domain, confidence: confidence,
65
+ coverage_estimate: coverage_estimate)
66
+ @boundaries[boundary.id] = boundary
67
+ boundary
68
+ end
69
+
70
+ def detect_boundary_gap(domain:, error_occurred: false)
71
+ boundary = boundary_for_domain(domain)
72
+ return { gap_detected: false, domain: domain, reason: :no_boundary } unless boundary
73
+
74
+ { gap_detected: boundary.gap_detected?(error_occurred: error_occurred),
75
+ domain: domain, confidence: boundary.confidence,
76
+ coverage: boundary.coverage_estimate }
77
+ end
78
+
79
+ def blindspots_by_domain(domain)
80
+ d = domain.to_sym
81
+ @blindspots.values.select { |b| b.domain == d }
82
+ end
83
+
84
+ def active_blindspots = @blindspots.values.select(&:active?)
85
+ def acknowledged_blindspots = @blindspots.values.select { |b| b.status == :acknowledged }
86
+ def resolved_blindspots = @blindspots.values.select(&:resolved?)
87
+
88
+ def most_severe(limit: 5)
89
+ @blindspots.values.sort_by { |b| -b.severity }.first(limit)
90
+ end
91
+
92
+ def mitigation_strategies(domain: nil)
93
+ spots = domain ? blindspots_by_domain(domain) : @blindspots.values
94
+ spots.select(&:active?).map do |b|
95
+ { blindspot_id: b.id, domain: b.domain, severity: b.severity, strategy: strategy_for(b) }
96
+ end
97
+ end
98
+
99
+ def coverage_report = @boundaries.values.map(&:to_h)
100
+ def awareness_label = Constants.label_for(AWARENESS_LABELS, @awareness_score) || :unaware
101
+ def awareness_gap = (1.0 - @awareness_score).clamp(0.0, 1.0).round(10)
102
+
103
+ def johari_report
104
+ { total_blindspots: @blindspots.size,
105
+ active: active_blindspots.size,
106
+ acknowledged: acknowledged_blindspots.size,
107
+ resolved: resolved_blindspots.size,
108
+ awareness_score: @awareness_score.round(10),
109
+ awareness_label: awareness_label,
110
+ awareness_gap: awareness_gap,
111
+ boundaries_tracked: @boundaries.size,
112
+ most_severe: most_severe(limit: 3).map(&:to_h) }
113
+ end
114
+
115
+ def to_h
116
+ { total_blindspots: @blindspots.size,
117
+ active: active_blindspots.size,
118
+ acknowledged: acknowledged_blindspots.size,
119
+ resolved: resolved_blindspots.size,
120
+ awareness_score: @awareness_score.round(10),
121
+ awareness_label: awareness_label }
122
+ end
123
+
124
+ private
125
+
126
+ def update_boundary!(boundary, confidence, coverage_estimate)
127
+ boundary.update_confidence!(confidence)
128
+ boundary.update_coverage!(coverage_estimate)
129
+ boundary
130
+ end
131
+
132
+ def boundary_for_domain(domain)
133
+ d = domain.to_sym
134
+ @boundaries.values.find { |b| b.domain == d }
135
+ end
136
+
137
+ def recalculate_awareness
138
+ total = @blindspots.size.to_f
139
+ return @awareness_score = 1.0 if total.zero?
140
+
141
+ not_active = @blindspots.values.count { |b| !b.active? }.to_f
142
+ @awareness_score = (not_active / total).clamp(0.0, 1.0).round(10)
143
+ end
144
+
145
+ def strategy_for(blindspot)
146
+ case blindspot.severity
147
+ when (0.8..) then :immediate_external_audit
148
+ when (0.6...0.8) then :cross_domain_check
149
+ when (0.4...0.6) then :peer_feedback
150
+ else :self_reflection
151
+ end
152
+ end
153
+
154
+ def prune_blindspots_if_needed
155
+ return if @blindspots.size < MAX_BLINDSPOTS
156
+
157
+ target = resolved_blindspots.min_by(&:created_at) ||
158
+ @blindspots.values.min_by(&:severity)
159
+ @blindspots.delete(target.id) if target
160
+ end
161
+
162
+ def prune_boundaries_if_needed
163
+ return if @boundaries.size < MAX_BOUNDARIES
164
+
165
+ oldest = @boundaries.values.min_by(&:created_at)
166
+ @boundaries.delete(oldest.id) if oldest
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Attention
7
+ module Blindspot
8
+ module Helpers
9
+ module Constants
10
+ MAX_BLINDSPOTS = 300
11
+ MAX_BOUNDARIES = 50
12
+ DEFAULT_SEVERITY = 0.5
13
+ SEVERITY_BOOST = 0.1
14
+ AWARENESS_THRESHOLD = 0.6
15
+
16
+ DISCOVERY_METHODS = %i[
17
+ error_analysis peer_feedback cross_domain_check
18
+ contradiction_detection confidence_calibration
19
+ external_audit self_reflection unknown
20
+ ].freeze
21
+
22
+ SEVERITY_LABELS = {
23
+ (0.8..) => :critical,
24
+ (0.6...0.8) => :high,
25
+ (0.4...0.6) => :moderate,
26
+ (0.2...0.4) => :low,
27
+ (..0.2) => :negligible
28
+ }.freeze
29
+
30
+ AWARENESS_LABELS = {
31
+ (0.8..) => :highly_aware,
32
+ (0.6...0.8) => :aware,
33
+ (0.4...0.6) => :partially_blind,
34
+ (0.2...0.4) => :mostly_blind,
35
+ (..0.2) => :unaware
36
+ }.freeze
37
+
38
+ COVERAGE_LABELS = {
39
+ (0.8..) => :comprehensive,
40
+ (0.6...0.8) => :substantial,
41
+ (0.4...0.6) => :partial,
42
+ (0.2...0.4) => :limited,
43
+ (..0.2) => :minimal
44
+ }.freeze
45
+
46
+ STATUS_LABELS = {
47
+ active: 'Unknown unknown — not yet surfaced to awareness',
48
+ acknowledged: 'Known unknown — surfaced, not yet mitigated',
49
+ mitigated: 'Known unknown — mitigated with partial coverage',
50
+ resolved: 'Known unknown — fully addressed'
51
+ }.freeze
52
+
53
+ def self.label_for(labels, value)
54
+ match = labels.find { |range, _| range.cover?(value) }
55
+ match&.last
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Attention
9
+ module Blindspot
10
+ module Helpers
11
+ class KnowledgeBoundary
12
+ include Constants
13
+
14
+ attr_reader :id, :domain, :confidence, :coverage_estimate, :created_at, :updated_at
15
+
16
+ def initialize(domain:, confidence: 0.5, coverage_estimate: 0.5)
17
+ @id = SecureRandom.uuid
18
+ @domain = domain.to_sym
19
+ @confidence = confidence.to_f.clamp(0.0, 1.0)
20
+ @coverage_estimate = coverage_estimate.to_f.clamp(0.0, 1.0)
21
+ @created_at = Time.now.utc
22
+ @updated_at = Time.now.utc
23
+ end
24
+
25
+ def coverage_label
26
+ Constants.label_for(COVERAGE_LABELS, @coverage_estimate) || :minimal
27
+ end
28
+
29
+ def gap_detected?(error_occurred: false)
30
+ error_occurred && @confidence >= AWARENESS_THRESHOLD
31
+ end
32
+
33
+ def update_confidence!(new_confidence)
34
+ @confidence = new_confidence.to_f.clamp(0.0, 1.0)
35
+ @updated_at = Time.now.utc
36
+ self
37
+ end
38
+
39
+ def update_coverage!(new_coverage)
40
+ @coverage_estimate = new_coverage.to_f.clamp(0.0, 1.0)
41
+ @updated_at = Time.now.utc
42
+ self
43
+ end
44
+
45
+ def to_h
46
+ {
47
+ id: @id,
48
+ domain: @domain,
49
+ confidence: @confidence,
50
+ coverage_estimate: @coverage_estimate,
51
+ coverage_label: coverage_label,
52
+ created_at: @created_at,
53
+ updated_at: @updated_at
54
+ }
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Attention
7
+ module Blindspot
8
+ module Runners
9
+ module CognitiveBlindspot
10
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
11
+
12
+ def register_blindspot(domain:, discovered_by:, description:,
13
+ severity: nil, **)
14
+ sev = severity || Helpers::Constants::DEFAULT_SEVERITY
15
+ spot = engine.register_blindspot(
16
+ domain: domain,
17
+ discovered_by: discovered_by,
18
+ description: description,
19
+ severity: sev
20
+ )
21
+ { success: true }.merge(spot.to_h)
22
+ end
23
+
24
+ def acknowledge_blindspot(blindspot_id:, **)
25
+ result = engine.acknowledge_blindspot(blindspot_id: blindspot_id)
26
+ return { success: false, error: 'blindspot not found' } unless result[:found]
27
+
28
+ { success: true }.merge(result)
29
+ end
30
+
31
+ def mitigate_blindspot(blindspot_id:, boost: nil, **)
32
+ b = boost || Helpers::Constants::SEVERITY_BOOST
33
+ result = engine.mitigate_blindspot(blindspot_id: blindspot_id, boost: b)
34
+ return { success: false, error: 'blindspot not found' } unless result[:found]
35
+
36
+ { success: true }.merge(result)
37
+ end
38
+
39
+ def resolve_blindspot(blindspot_id:, **)
40
+ result = engine.resolve_blindspot(blindspot_id: blindspot_id)
41
+ return { success: false, error: 'blindspot not found' } unless result[:found]
42
+
43
+ { success: true }.merge(result)
44
+ end
45
+
46
+ def set_knowledge_boundary(domain:, confidence: 0.5, coverage_estimate: 0.5, **)
47
+ boundary = engine.set_boundary(
48
+ domain: domain,
49
+ confidence: confidence,
50
+ coverage_estimate: coverage_estimate
51
+ )
52
+ { success: true }.merge(boundary.to_h)
53
+ end
54
+
55
+ def detect_boundary_gap(domain:, error_occurred: false, **)
56
+ result = engine.detect_boundary_gap(domain: domain, error_occurred: error_occurred)
57
+ { success: true }.merge(result)
58
+ end
59
+
60
+ def active_blindspots_report(**)
61
+ spots = engine.active_blindspots
62
+ { success: true, count: spots.size, blindspots: spots.map(&:to_h) }
63
+ end
64
+
65
+ def most_severe_report(limit: 5, **)
66
+ spots = engine.most_severe(limit: limit)
67
+ { success: true, limit: limit, blindspots: spots.map(&:to_h) }
68
+ end
69
+
70
+ def mitigation_strategies_report(domain: nil, **)
71
+ strategies = engine.mitigation_strategies(domain: domain)
72
+ { success: true, count: strategies.size, strategies: strategies }
73
+ end
74
+
75
+ def coverage_report(**)
76
+ boundaries = engine.coverage_report
77
+ { success: true, count: boundaries.size, boundaries: boundaries }
78
+ end
79
+
80
+ def johari_report(**)
81
+ engine.johari_report
82
+ end
83
+
84
+ def awareness_score_report(**)
85
+ score = engine.awareness_score
86
+ {
87
+ success: true,
88
+ awareness_score: score.round(10),
89
+ awareness_label: engine.awareness_label,
90
+ awareness_gap: engine.awareness_gap
91
+ }
92
+ end
93
+
94
+ def blindspot_stats(**)
95
+ engine.to_h
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+ 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 Blindspot
8
+ VERSION = '0.1.0'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'blindspot/version'
4
+ require_relative 'blindspot/helpers/constants'
5
+ require_relative 'blindspot/helpers/blindspot'
6
+ require_relative 'blindspot/helpers/knowledge_boundary'
7
+ require_relative 'blindspot/helpers/blindspot_engine'
8
+ require_relative 'blindspot/runners/cognitive_blindspot'
9
+ require_relative 'blindspot/client'
10
+
11
+ module Legion
12
+ module Extensions
13
+ module Agentic
14
+ module Attention
15
+ module Blindspot
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Attention
7
+ module Blink
8
+ class Client
9
+ include Runners::AttentionalBlink
10
+
11
+ def engine
12
+ @engine ||= Helpers::BlinkEngine.new
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,171 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Attention
7
+ module Blink
8
+ module Helpers
9
+ class BlinkEngine
10
+ include Constants
11
+
12
+ def initialize
13
+ @stimuli = {}
14
+ @blink_active = false
15
+ @blink_start = nil
16
+ @blink_duration = DEFAULT_BLINK_DURATION
17
+ @recovery = 1.0
18
+ @total_blinks = 0
19
+ @total_misses = 0
20
+ end
21
+
22
+ def submit_stimulus(stimulus_type:, content:, salience: 0.5)
23
+ prune_stimuli_if_needed
24
+ stimulus = Stimulus.new(
25
+ stimulus_type: stimulus_type,
26
+ content: content,
27
+ salience: salience
28
+ )
29
+
30
+ quality = compute_processing_quality(stimulus)
31
+ stimulus.process!(quality: quality)
32
+
33
+ trigger_blink!(stimulus) if stimulus.salient? && !@blink_active
34
+ @total_misses += 1 if stimulus.missed?
35
+
36
+ @stimuli[stimulus.id] = stimulus
37
+ stimulus
38
+ end
39
+
40
+ def blink_active?
41
+ return false unless @blink_active
42
+
43
+ elapsed = Time.now.utc.to_f - @blink_start
44
+ if elapsed >= @blink_duration
45
+ @blink_active = false
46
+ @recovery = 1.0
47
+ return false
48
+ end
49
+
50
+ true
51
+ end
52
+
53
+ def recovery_level
54
+ return 1.0 unless @blink_active
55
+
56
+ elapsed = Time.now.utc.to_f - @blink_start
57
+ progress = (elapsed / @blink_duration).clamp(0.0, 1.0)
58
+ (progress**0.5).round(10)
59
+ end
60
+
61
+ def recovery_label
62
+ match = RECOVERY_LABELS.find { |range, _| range.cover?(recovery_level) }
63
+ match ? match.last : :saturated
64
+ end
65
+
66
+ def force_blink!(duration: DEFAULT_BLINK_DURATION)
67
+ @blink_active = true
68
+ @blink_start = Time.now.utc.to_f
69
+ @blink_duration = duration.to_f.clamp(MIN_BLINK_DURATION, MAX_BLINK_DURATION)
70
+ @recovery = 0.0
71
+ @total_blinks += 1
72
+ { blink_active: true, duration: @blink_duration, total_blinks: @total_blinks }
73
+ end
74
+
75
+ def force_recover!
76
+ @blink_active = false
77
+ @recovery = 1.0
78
+ @blink_start = nil
79
+ { blink_active: false, recovery: 1.0 }
80
+ end
81
+
82
+ def adjust_blink_duration(duration:)
83
+ @blink_duration = duration.to_f.clamp(MIN_BLINK_DURATION, MAX_BLINK_DURATION)
84
+ end
85
+
86
+ def miss_rate
87
+ return 0.0 if @stimuli.empty?
88
+
89
+ (@total_misses.to_f / @stimuli.size).round(10)
90
+ end
91
+
92
+ def recent_stimuli(limit: 10)
93
+ @stimuli.values.sort_by { |s| -s.arrival_time }.first(limit)
94
+ end
95
+
96
+ def missed_stimuli
97
+ @stimuli.values.select(&:missed?)
98
+ end
99
+
100
+ def stimuli_by_type(stimulus_type:)
101
+ st = stimulus_type.to_sym
102
+ @stimuli.values.select { |s| s.stimulus_type == st }
103
+ end
104
+
105
+ def processing_quality_average
106
+ return 0.0 if @stimuli.empty?
107
+
108
+ qualities = @stimuli.values.map(&:processing_quality)
109
+ (qualities.sum / qualities.size).round(10)
110
+ end
111
+
112
+ def blink_report
113
+ {
114
+ total_stimuli: @stimuli.size,
115
+ total_blinks: @total_blinks,
116
+ total_misses: @total_misses,
117
+ miss_rate: miss_rate,
118
+ blink_active: blink_active?,
119
+ recovery_level: recovery_level,
120
+ recovery_label: recovery_label,
121
+ blink_duration: @blink_duration,
122
+ avg_quality: processing_quality_average,
123
+ recent_missed: missed_stimuli.last(5).map(&:to_h)
124
+ }
125
+ end
126
+
127
+ def to_h
128
+ {
129
+ total_stimuli: @stimuli.size,
130
+ total_blinks: @total_blinks,
131
+ miss_rate: miss_rate,
132
+ blink_active: blink_active?,
133
+ avg_quality: processing_quality_average
134
+ }
135
+ end
136
+
137
+ private
138
+
139
+ def compute_processing_quality(stimulus)
140
+ if blink_active?
141
+ lag1_sparing = stimulus.salience >= (1.0 - LAG1_SPARING_THRESHOLD) ? 0.3 : 0.0
142
+ base = (recovery_level * 0.5) + lag1_sparing
143
+ [base, stimulus.salience * 0.3].max.clamp(0.0, 1.0).round(10)
144
+ else
145
+ base = 0.6 + (stimulus.salience * 0.4)
146
+ base.clamp(0.0, 1.0).round(10)
147
+ end
148
+ end
149
+
150
+ def trigger_blink!(stimulus)
151
+ @blink_active = true
152
+ @blink_start = Time.now.utc.to_f
153
+ scaled_duration = @blink_duration * (0.5 + (stimulus.salience * 0.5))
154
+ @blink_duration = scaled_duration.clamp(MIN_BLINK_DURATION, MAX_BLINK_DURATION)
155
+ @recovery = 0.0
156
+ @total_blinks += 1
157
+ end
158
+
159
+ def prune_stimuli_if_needed
160
+ return if @stimuli.size < MAX_STIMULI
161
+
162
+ oldest = @stimuli.values.min_by(&:arrival_time)
163
+ @stimuli.delete(oldest.id) if oldest
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Attention
7
+ module Blink
8
+ module Helpers
9
+ module Constants
10
+ MAX_STIMULI = 500
11
+ MAX_BLINKS = 200
12
+
13
+ DEFAULT_BLINK_DURATION = 3.0
14
+ MIN_BLINK_DURATION = 0.5
15
+ MAX_BLINK_DURATION = 10.0
16
+ RECOVERY_RATE = 0.15
17
+ SALIENCE_THRESHOLD = 0.6
18
+ LAG1_SPARING_THRESHOLD = 0.3
19
+
20
+ PROCESSING_LABELS = {
21
+ (0.8..) => :fully_available,
22
+ (0.6...0.8) => :mostly_available,
23
+ (0.4...0.6) => :partially_suppressed,
24
+ (0.2...0.4) => :mostly_suppressed,
25
+ (..0.2) => :blinked
26
+ }.freeze
27
+
28
+ RECOVERY_LABELS = {
29
+ (0.8..) => :recovered,
30
+ (0.6...0.8) => :recovering,
31
+ (0.4...0.6) => :refractory,
32
+ (0.2...0.4) => :deep_blink,
33
+ (..0.2) => :saturated
34
+ }.freeze
35
+
36
+ STIMULUS_TYPES = %i[
37
+ visual auditory semantic emotional
38
+ social threat reward novelty
39
+ ].freeze
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end