lex-agentic-self 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 (249) 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-self.gemspec +31 -0
  7. data/lib/legion/extensions/agentic/self/agency/client.rb +21 -0
  8. data/lib/legion/extensions/agentic/self/agency/helpers/constants.rb +77 -0
  9. data/lib/legion/extensions/agentic/self/agency/helpers/efficacy_model.rb +136 -0
  10. data/lib/legion/extensions/agentic/self/agency/helpers/outcome_event.rb +52 -0
  11. data/lib/legion/extensions/agentic/self/agency/runners/agency.rb +117 -0
  12. data/lib/legion/extensions/agentic/self/agency/version.rb +13 -0
  13. data/lib/legion/extensions/agentic/self/agency.rb +19 -0
  14. data/lib/legion/extensions/agentic/self/anchor/client.rb +15 -0
  15. data/lib/legion/extensions/agentic/self/anchor/helpers/anchor.rb +92 -0
  16. data/lib/legion/extensions/agentic/self/anchor/helpers/anchor_engine.rb +123 -0
  17. data/lib/legion/extensions/agentic/self/anchor/helpers/chain.rb +93 -0
  18. data/lib/legion/extensions/agentic/self/anchor/helpers/constants.rb +46 -0
  19. data/lib/legion/extensions/agentic/self/anchor/runners/cognitive_anchor.rb +70 -0
  20. data/lib/legion/extensions/agentic/self/anchor/version.rb +13 -0
  21. data/lib/legion/extensions/agentic/self/anchor.rb +22 -0
  22. data/lib/legion/extensions/agentic/self/anosognosia/client.rb +28 -0
  23. data/lib/legion/extensions/agentic/self/anosognosia/helpers/anosognosia_engine.rb +153 -0
  24. data/lib/legion/extensions/agentic/self/anosognosia/helpers/cognitive_deficit.rb +71 -0
  25. data/lib/legion/extensions/agentic/self/anosognosia/helpers/constants.rb +29 -0
  26. data/lib/legion/extensions/agentic/self/anosognosia/runners/anosognosia.rb +98 -0
  27. data/lib/legion/extensions/agentic/self/anosognosia/version.rb +13 -0
  28. data/lib/legion/extensions/agentic/self/anosognosia.rb +19 -0
  29. data/lib/legion/extensions/agentic/self/architecture/client.rb +19 -0
  30. data/lib/legion/extensions/agentic/self/architecture/helpers/architecture_engine.rb +167 -0
  31. data/lib/legion/extensions/agentic/self/architecture/helpers/connection.rb +57 -0
  32. data/lib/legion/extensions/agentic/self/architecture/helpers/constants.rb +37 -0
  33. data/lib/legion/extensions/agentic/self/architecture/helpers/subsystem.rb +80 -0
  34. data/lib/legion/extensions/agentic/self/architecture/runners/cognitive_architecture.rb +125 -0
  35. data/lib/legion/extensions/agentic/self/architecture/version.rb +13 -0
  36. data/lib/legion/extensions/agentic/self/architecture.rb +20 -0
  37. data/lib/legion/extensions/agentic/self/default_mode_network/actors/idle.rb +45 -0
  38. data/lib/legion/extensions/agentic/self/default_mode_network/client.rb +28 -0
  39. data/lib/legion/extensions/agentic/self/default_mode_network/helpers/constants.rb +53 -0
  40. data/lib/legion/extensions/agentic/self/default_mode_network/helpers/dmn_engine.rb +221 -0
  41. data/lib/legion/extensions/agentic/self/default_mode_network/helpers/wandering_thought.rb +60 -0
  42. data/lib/legion/extensions/agentic/self/default_mode_network/runners/default_mode_network.rb +122 -0
  43. data/lib/legion/extensions/agentic/self/default_mode_network/version.rb +13 -0
  44. data/lib/legion/extensions/agentic/self/default_mode_network.rb +20 -0
  45. data/lib/legion/extensions/agentic/self/fingerprint/client.rb +28 -0
  46. data/lib/legion/extensions/agentic/self/fingerprint/helpers/cognitive_trait.rb +73 -0
  47. data/lib/legion/extensions/agentic/self/fingerprint/helpers/constants.rb +60 -0
  48. data/lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb +169 -0
  49. data/lib/legion/extensions/agentic/self/fingerprint/runners/cognitive_fingerprint.rb +86 -0
  50. data/lib/legion/extensions/agentic/self/fingerprint/version.rb +13 -0
  51. data/lib/legion/extensions/agentic/self/fingerprint.rb +19 -0
  52. data/lib/legion/extensions/agentic/self/identity/actors/credential_refresh.rb +49 -0
  53. data/lib/legion/extensions/agentic/self/identity/actors/orphan_check.rb +52 -0
  54. data/lib/legion/extensions/agentic/self/identity/client.rb +27 -0
  55. data/lib/legion/extensions/agentic/self/identity/helpers/dimensions.rb +75 -0
  56. data/lib/legion/extensions/agentic/self/identity/helpers/fingerprint.rb +170 -0
  57. data/lib/legion/extensions/agentic/self/identity/helpers/graph_client.rb +29 -0
  58. data/lib/legion/extensions/agentic/self/identity/helpers/graph_token.rb +36 -0
  59. data/lib/legion/extensions/agentic/self/identity/helpers/token_cache.rb +59 -0
  60. data/lib/legion/extensions/agentic/self/identity/helpers/vault_secrets.rb +80 -0
  61. data/lib/legion/extensions/agentic/self/identity/local_migrations/20260316000030_create_fingerprint.rb +20 -0
  62. data/lib/legion/extensions/agentic/self/identity/runners/entra.rb +402 -0
  63. data/lib/legion/extensions/agentic/self/identity/runners/identity.rb +90 -0
  64. data/lib/legion/extensions/agentic/self/identity/version.rb +13 -0
  65. data/lib/legion/extensions/agentic/self/identity.rb +28 -0
  66. data/lib/legion/extensions/agentic/self/metacognition/client.rb +27 -0
  67. data/lib/legion/extensions/agentic/self/metacognition/helpers/constants.rb +377 -0
  68. data/lib/legion/extensions/agentic/self/metacognition/helpers/narrator_bridge.rb +85 -0
  69. data/lib/legion/extensions/agentic/self/metacognition/helpers/registry_store.rb +70 -0
  70. data/lib/legion/extensions/agentic/self/metacognition/helpers/self_model.rb +160 -0
  71. data/lib/legion/extensions/agentic/self/metacognition/helpers/snapshot_store.rb +82 -0
  72. data/lib/legion/extensions/agentic/self/metacognition/runners/metacognition.rb +116 -0
  73. data/lib/legion/extensions/agentic/self/metacognition/runners/registry.rb +180 -0
  74. data/lib/legion/extensions/agentic/self/metacognition/version.rb +13 -0
  75. data/lib/legion/extensions/agentic/self/metacognition.rb +22 -0
  76. data/lib/legion/extensions/agentic/self/metacognitive_monitoring/client.rb +25 -0
  77. data/lib/legion/extensions/agentic/self/metacognitive_monitoring/helpers/calibration_tracker.rb +96 -0
  78. data/lib/legion/extensions/agentic/self/metacognitive_monitoring/helpers/constants.rb +47 -0
  79. data/lib/legion/extensions/agentic/self/metacognitive_monitoring/helpers/monitoring_engine.rb +141 -0
  80. data/lib/legion/extensions/agentic/self/metacognitive_monitoring/helpers/monitoring_judgment.rb +79 -0
  81. data/lib/legion/extensions/agentic/self/metacognitive_monitoring/runners/metacognitive_monitoring.rb +151 -0
  82. data/lib/legion/extensions/agentic/self/metacognitive_monitoring/version.rb +13 -0
  83. data/lib/legion/extensions/agentic/self/metacognitive_monitoring.rb +20 -0
  84. data/lib/legion/extensions/agentic/self/narrative_arc/client.rb +29 -0
  85. data/lib/legion/extensions/agentic/self/narrative_arc/helpers/arc.rb +137 -0
  86. data/lib/legion/extensions/agentic/self/narrative_arc/helpers/arc_engine.rb +119 -0
  87. data/lib/legion/extensions/agentic/self/narrative_arc/helpers/beat_event.rb +59 -0
  88. data/lib/legion/extensions/agentic/self/narrative_arc/helpers/constants.rb +66 -0
  89. data/lib/legion/extensions/agentic/self/narrative_arc/runners/narrative.rb +101 -0
  90. data/lib/legion/extensions/agentic/self/narrative_arc/version.rb +13 -0
  91. data/lib/legion/extensions/agentic/self/narrative_arc.rb +20 -0
  92. data/lib/legion/extensions/agentic/self/narrative_identity/actors/narrative_decay.rb +45 -0
  93. data/lib/legion/extensions/agentic/self/narrative_identity/client.rb +22 -0
  94. data/lib/legion/extensions/agentic/self/narrative_identity/helpers/chapter.rb +48 -0
  95. data/lib/legion/extensions/agentic/self/narrative_identity/helpers/constants.rb +62 -0
  96. data/lib/legion/extensions/agentic/self/narrative_identity/helpers/episode.rb +67 -0
  97. data/lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb +187 -0
  98. data/lib/legion/extensions/agentic/self/narrative_identity/helpers/theme.rb +50 -0
  99. data/lib/legion/extensions/agentic/self/narrative_identity/runners/narrative_identity.rb +158 -0
  100. data/lib/legion/extensions/agentic/self/narrative_identity/version.rb +13 -0
  101. data/lib/legion/extensions/agentic/self/narrative_identity.rb +21 -0
  102. data/lib/legion/extensions/agentic/self/narrative_self/client.rb +27 -0
  103. data/lib/legion/extensions/agentic/self/narrative_self/helpers/autobiography.rb +187 -0
  104. data/lib/legion/extensions/agentic/self/narrative_self/helpers/constants.rb +42 -0
  105. data/lib/legion/extensions/agentic/self/narrative_self/helpers/episode.rb +81 -0
  106. data/lib/legion/extensions/agentic/self/narrative_self/helpers/narrative_thread.rb +65 -0
  107. data/lib/legion/extensions/agentic/self/narrative_self/runners/narrative_self.rb +86 -0
  108. data/lib/legion/extensions/agentic/self/narrative_self/version.rb +13 -0
  109. data/lib/legion/extensions/agentic/self/narrative_self.rb +20 -0
  110. data/lib/legion/extensions/agentic/self/personality/client.rb +21 -0
  111. data/lib/legion/extensions/agentic/self/personality/helpers/constants.rb +84 -0
  112. data/lib/legion/extensions/agentic/self/personality/helpers/personality_store.rb +126 -0
  113. data/lib/legion/extensions/agentic/self/personality/helpers/trait_model.rb +147 -0
  114. data/lib/legion/extensions/agentic/self/personality/runners/personality.rb +102 -0
  115. data/lib/legion/extensions/agentic/self/personality/version.rb +13 -0
  116. data/lib/legion/extensions/agentic/self/personality.rb +19 -0
  117. data/lib/legion/extensions/agentic/self/reflection/client.rb +27 -0
  118. data/lib/legion/extensions/agentic/self/reflection/helpers/constants.rb +66 -0
  119. data/lib/legion/extensions/agentic/self/reflection/helpers/llm_enhancer.rb +166 -0
  120. data/lib/legion/extensions/agentic/self/reflection/helpers/monitors.rb +186 -0
  121. data/lib/legion/extensions/agentic/self/reflection/helpers/reflection.rb +54 -0
  122. data/lib/legion/extensions/agentic/self/reflection/helpers/reflection_store.rb +99 -0
  123. data/lib/legion/extensions/agentic/self/reflection/runners/reflection.rb +199 -0
  124. data/lib/legion/extensions/agentic/self/reflection/version.rb +13 -0
  125. data/lib/legion/extensions/agentic/self/reflection.rb +21 -0
  126. data/lib/legion/extensions/agentic/self/self_model/client.rb +19 -0
  127. data/lib/legion/extensions/agentic/self/self_model/helpers/capability.rb +93 -0
  128. data/lib/legion/extensions/agentic/self/self_model/helpers/constants.rb +46 -0
  129. data/lib/legion/extensions/agentic/self/self_model/helpers/knowledge_domain.rb +82 -0
  130. data/lib/legion/extensions/agentic/self/self_model/helpers/self_model.rb +150 -0
  131. data/lib/legion/extensions/agentic/self/self_model/runners/self_model.rb +82 -0
  132. data/lib/legion/extensions/agentic/self/self_model/version.rb +13 -0
  133. data/lib/legion/extensions/agentic/self/self_model.rb +21 -0
  134. data/lib/legion/extensions/agentic/self/self_talk/actors/volume_decay.rb +45 -0
  135. data/lib/legion/extensions/agentic/self/self_talk/client.rb +30 -0
  136. data/lib/legion/extensions/agentic/self/self_talk/helpers/constants.rb +63 -0
  137. data/lib/legion/extensions/agentic/self/self_talk/helpers/dialogue.rb +114 -0
  138. data/lib/legion/extensions/agentic/self/self_talk/helpers/dialogue_turn.rb +43 -0
  139. data/lib/legion/extensions/agentic/self/self_talk/helpers/inner_voice.rb +77 -0
  140. data/lib/legion/extensions/agentic/self/self_talk/helpers/llm_enhancer.rb +135 -0
  141. data/lib/legion/extensions/agentic/self/self_talk/helpers/self_talk_engine.rb +160 -0
  142. data/lib/legion/extensions/agentic/self/self_talk/runners/self_talk.rb +172 -0
  143. data/lib/legion/extensions/agentic/self/self_talk/version.rb +13 -0
  144. data/lib/legion/extensions/agentic/self/self_talk.rb +22 -0
  145. data/lib/legion/extensions/agentic/self/version.rb +11 -0
  146. data/lib/legion/extensions/agentic/self.rb +33 -0
  147. data/spec/legion/extensions/agentic/self/agency/client_spec.rb +67 -0
  148. data/spec/legion/extensions/agentic/self/agency/helpers/constants_spec.rb +73 -0
  149. data/spec/legion/extensions/agentic/self/agency/helpers/efficacy_model_spec.rb +190 -0
  150. data/spec/legion/extensions/agentic/self/agency/helpers/outcome_event_spec.rb +85 -0
  151. data/spec/legion/extensions/agentic/self/agency/runners/agency_spec.rb +132 -0
  152. data/spec/legion/extensions/agentic/self/anchor/client_spec.rb +30 -0
  153. data/spec/legion/extensions/agentic/self/anchor/helpers/anchor_engine_spec.rb +109 -0
  154. data/spec/legion/extensions/agentic/self/anchor/helpers/anchor_spec.rb +124 -0
  155. data/spec/legion/extensions/agentic/self/anchor/helpers/chain_spec.rb +106 -0
  156. data/spec/legion/extensions/agentic/self/anchor/helpers/constants_spec.rb +53 -0
  157. data/spec/legion/extensions/agentic/self/anchor/runners/cognitive_anchor_spec.rb +70 -0
  158. data/spec/legion/extensions/agentic/self/anosognosia/anosognosia_spec.rb +15 -0
  159. data/spec/legion/extensions/agentic/self/anosognosia/client_spec.rb +50 -0
  160. data/spec/legion/extensions/agentic/self/anosognosia/helpers/anosognosia_engine_spec.rb +266 -0
  161. data/spec/legion/extensions/agentic/self/anosognosia/helpers/cognitive_deficit_spec.rb +150 -0
  162. data/spec/legion/extensions/agentic/self/anosognosia/helpers/constants_spec.rb +58 -0
  163. data/spec/legion/extensions/agentic/self/anosognosia/runners/anosognosia_spec.rb +225 -0
  164. data/spec/legion/extensions/agentic/self/architecture/client_spec.rb +51 -0
  165. data/spec/legion/extensions/agentic/self/architecture/helpers/architecture_engine_spec.rb +321 -0
  166. data/spec/legion/extensions/agentic/self/architecture/helpers/connection_spec.rb +118 -0
  167. data/spec/legion/extensions/agentic/self/architecture/helpers/subsystem_spec.rb +189 -0
  168. data/spec/legion/extensions/agentic/self/architecture/runners/cognitive_architecture_spec.rb +181 -0
  169. data/spec/legion/extensions/agentic/self/default_mode_network/client_spec.rb +69 -0
  170. data/spec/legion/extensions/agentic/self/default_mode_network/helpers/constants_spec.rb +76 -0
  171. data/spec/legion/extensions/agentic/self/default_mode_network/helpers/dmn_engine_spec.rb +321 -0
  172. data/spec/legion/extensions/agentic/self/default_mode_network/helpers/wandering_thought_spec.rb +145 -0
  173. data/spec/legion/extensions/agentic/self/default_mode_network/runners/default_mode_network_spec.rb +269 -0
  174. data/spec/legion/extensions/agentic/self/fingerprint/client_spec.rb +54 -0
  175. data/spec/legion/extensions/agentic/self/fingerprint/helpers/cognitive_trait_spec.rb +180 -0
  176. data/spec/legion/extensions/agentic/self/fingerprint/helpers/constants_spec.rb +108 -0
  177. data/spec/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine_spec.rb +318 -0
  178. data/spec/legion/extensions/agentic/self/fingerprint/runners/cognitive_fingerprint_spec.rb +232 -0
  179. data/spec/legion/extensions/agentic/self/identity/actors/orphan_check_spec.rb +104 -0
  180. data/spec/legion/extensions/agentic/self/identity/client_spec.rb +32 -0
  181. data/spec/legion/extensions/agentic/self/identity/helpers/dimensions_spec.rb +51 -0
  182. data/spec/legion/extensions/agentic/self/identity/helpers/fingerprint_spec.rb +66 -0
  183. data/spec/legion/extensions/agentic/self/identity/helpers/graph_client_spec.rb +19 -0
  184. data/spec/legion/extensions/agentic/self/identity/helpers/graph_token_spec.rb +31 -0
  185. data/spec/legion/extensions/agentic/self/identity/helpers/token_cache_spec.rb +50 -0
  186. data/spec/legion/extensions/agentic/self/identity/local_persistence_spec.rb +329 -0
  187. data/spec/legion/extensions/agentic/self/identity/runners/entra_spec.rb +655 -0
  188. data/spec/legion/extensions/agentic/self/identity/runners/identity_spec.rb +61 -0
  189. data/spec/legion/extensions/agentic/self/metacognition/client_spec.rb +20 -0
  190. data/spec/legion/extensions/agentic/self/metacognition/helpers/constants_spec.rb +31 -0
  191. data/spec/legion/extensions/agentic/self/metacognition/helpers/narrator_bridge_spec.rb +102 -0
  192. data/spec/legion/extensions/agentic/self/metacognition/helpers/registry_store_spec.rb +227 -0
  193. data/spec/legion/extensions/agentic/self/metacognition/helpers/self_model_spec.rb +117 -0
  194. data/spec/legion/extensions/agentic/self/metacognition/helpers/snapshot_store_spec.rb +128 -0
  195. data/spec/legion/extensions/agentic/self/metacognition/runners/metacognition_spec.rb +110 -0
  196. data/spec/legion/extensions/agentic/self/metacognition/runners/registry_spec.rb +281 -0
  197. data/spec/legion/extensions/agentic/self/metacognitive_monitoring/client_spec.rb +59 -0
  198. data/spec/legion/extensions/agentic/self/metacognitive_monitoring/helpers/calibration_tracker_spec.rb +143 -0
  199. data/spec/legion/extensions/agentic/self/metacognitive_monitoring/helpers/constants_spec.rb +91 -0
  200. data/spec/legion/extensions/agentic/self/metacognitive_monitoring/helpers/monitoring_engine_spec.rb +198 -0
  201. data/spec/legion/extensions/agentic/self/metacognitive_monitoring/helpers/monitoring_judgment_spec.rb +172 -0
  202. data/spec/legion/extensions/agentic/self/metacognitive_monitoring/runners/metacognitive_monitoring_spec.rb +244 -0
  203. data/spec/legion/extensions/agentic/self/narrative_arc/client_spec.rb +22 -0
  204. data/spec/legion/extensions/agentic/self/narrative_arc/helpers/arc_engine_spec.rb +183 -0
  205. data/spec/legion/extensions/agentic/self/narrative_arc/helpers/arc_spec.rb +177 -0
  206. data/spec/legion/extensions/agentic/self/narrative_arc/helpers/beat_event_spec.rb +96 -0
  207. data/spec/legion/extensions/agentic/self/narrative_arc/helpers/constants_spec.rb +75 -0
  208. data/spec/legion/extensions/agentic/self/narrative_arc/runners/narrative_spec.rb +142 -0
  209. data/spec/legion/extensions/agentic/self/narrative_identity/client_spec.rb +69 -0
  210. data/spec/legion/extensions/agentic/self/narrative_identity/helpers/chapter_spec.rb +85 -0
  211. data/spec/legion/extensions/agentic/self/narrative_identity/helpers/constants_spec.rb +83 -0
  212. data/spec/legion/extensions/agentic/self/narrative_identity/helpers/episode_spec.rb +180 -0
  213. data/spec/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine_spec.rb +307 -0
  214. data/spec/legion/extensions/agentic/self/narrative_identity/helpers/theme_spec.rb +107 -0
  215. data/spec/legion/extensions/agentic/self/narrative_identity/runners/narrative_identity_spec.rb +240 -0
  216. data/spec/legion/extensions/agentic/self/narrative_self/client_spec.rb +67 -0
  217. data/spec/legion/extensions/agentic/self/narrative_self/helpers/autobiography_spec.rb +155 -0
  218. data/spec/legion/extensions/agentic/self/narrative_self/helpers/constants_spec.rb +28 -0
  219. data/spec/legion/extensions/agentic/self/narrative_self/helpers/episode_spec.rb +144 -0
  220. data/spec/legion/extensions/agentic/self/narrative_self/helpers/narrative_thread_spec.rb +87 -0
  221. data/spec/legion/extensions/agentic/self/narrative_self/runners/narrative_self_spec.rb +118 -0
  222. data/spec/legion/extensions/agentic/self/personality/client_spec.rb +20 -0
  223. data/spec/legion/extensions/agentic/self/personality/helpers/constants_spec.rb +41 -0
  224. data/spec/legion/extensions/agentic/self/personality/helpers/personality_store_spec.rb +66 -0
  225. data/spec/legion/extensions/agentic/self/personality/helpers/trait_model_spec.rb +148 -0
  226. data/spec/legion/extensions/agentic/self/personality/runners/personality_spec.rb +67 -0
  227. data/spec/legion/extensions/agentic/self/reflection/client_spec.rb +24 -0
  228. data/spec/legion/extensions/agentic/self/reflection/helpers/llm_enhancer_spec.rb +191 -0
  229. data/spec/legion/extensions/agentic/self/reflection/helpers/monitors_spec.rb +120 -0
  230. data/spec/legion/extensions/agentic/self/reflection/helpers/reflection_spec.rb +49 -0
  231. data/spec/legion/extensions/agentic/self/reflection/helpers/reflection_store_spec.rb +93 -0
  232. data/spec/legion/extensions/agentic/self/reflection/runners/reflection_spec.rb +204 -0
  233. data/spec/legion/extensions/agentic/self/self_model/client_spec.rb +55 -0
  234. data/spec/legion/extensions/agentic/self/self_model/helpers/capability_spec.rb +160 -0
  235. data/spec/legion/extensions/agentic/self/self_model/helpers/knowledge_domain_spec.rb +128 -0
  236. data/spec/legion/extensions/agentic/self/self_model/helpers/self_model_spec.rb +238 -0
  237. data/spec/legion/extensions/agentic/self/self_model/runners/self_model_spec.rb +143 -0
  238. data/spec/legion/extensions/agentic/self/self_talk/actors/volume_decay_spec.rb +46 -0
  239. data/spec/legion/extensions/agentic/self/self_talk/client_spec.rb +26 -0
  240. data/spec/legion/extensions/agentic/self/self_talk/helpers/constants_spec.rb +110 -0
  241. data/spec/legion/extensions/agentic/self/self_talk/helpers/dialogue_spec.rb +191 -0
  242. data/spec/legion/extensions/agentic/self/self_talk/helpers/dialogue_turn_spec.rb +78 -0
  243. data/spec/legion/extensions/agentic/self/self_talk/helpers/inner_voice_spec.rb +172 -0
  244. data/spec/legion/extensions/agentic/self/self_talk/helpers/llm_enhancer_spec.rb +206 -0
  245. data/spec/legion/extensions/agentic/self/self_talk/helpers/self_talk_engine_spec.rb +239 -0
  246. data/spec/legion/extensions/agentic/self/self_talk/runners/self_talk_llm_spec.rb +169 -0
  247. data/spec/legion/extensions/agentic/self/self_talk/runners/self_talk_spec.rb +196 -0
  248. data/spec/spec_helper.rb +46 -0
  249. metadata +347 -0
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Self
7
+ module Personality
8
+ module Runners
9
+ module Personality
10
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
11
+
12
+ def update_personality(tick_results: {}, **)
13
+ personality_store.update(tick_results)
14
+ model = personality_store.model
15
+
16
+ {
17
+ updated: true,
18
+ observation_count: model.observation_count,
19
+ formed: model.formed?,
20
+ profile: model.profile,
21
+ dominant_trait: model.dominant_trait
22
+ }
23
+ end
24
+
25
+ def personality_profile(**)
26
+ model = personality_store.model
27
+ {
28
+ traits: model.profile,
29
+ formed: model.formed?,
30
+ stability: model.stability,
31
+ dominant: model.dominant_trait,
32
+ observations: model.observation_count,
33
+ history_size: model.history.size
34
+ }
35
+ end
36
+
37
+ def describe_personality(**)
38
+ {
39
+ description: personality_store.full_description,
40
+ formed: personality_store.model.formed?
41
+ }
42
+ end
43
+
44
+ def trait_detail(trait:, **)
45
+ model = personality_store.model
46
+ value = model.trait(trait)
47
+ return { trait: trait.to_sym, error: :unknown_trait } unless value
48
+
49
+ {
50
+ trait: trait.to_sym,
51
+ value: value.round(3),
52
+ level: model.trait_level(trait),
53
+ description: model.describe(trait),
54
+ trend: model.trend(trait)
55
+ }
56
+ end
57
+
58
+ def personality_compatibility(other_profile:, **)
59
+ score = personality_store.compatibility_score(other_profile)
60
+ {
61
+ compatibility: score,
62
+ interpretation: interpret_compatibility(score)
63
+ }
64
+ end
65
+
66
+ def personality_stats(**)
67
+ model = personality_store.model
68
+ {
69
+ observation_count: model.observation_count,
70
+ formed: model.formed?,
71
+ stability: model.stability,
72
+ dominant_trait: model.dominant_trait,
73
+ profile: model.profile,
74
+ history_size: model.history.size,
75
+ trait_trends: Helpers::Constants::TRAITS.to_h { |t| [t, model.trend(t)] }
76
+ }
77
+ end
78
+
79
+ private
80
+
81
+ def interpret_compatibility(score)
82
+ return :unknown unless score.is_a?(Numeric)
83
+
84
+ if score >= 0.85
85
+ :highly_compatible
86
+ elsif score >= 0.7
87
+ :compatible
88
+ elsif score >= 0.5
89
+ :neutral
90
+ elsif score >= 0.3
91
+ :divergent
92
+ else
93
+ :incompatible
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Self
7
+ module Personality
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 'personality/version'
4
+ require_relative 'personality/helpers/constants'
5
+ require_relative 'personality/helpers/trait_model'
6
+ require_relative 'personality/helpers/personality_store'
7
+ require_relative 'personality/runners/personality'
8
+ require_relative 'personality/client'
9
+
10
+ module Legion
11
+ module Extensions
12
+ module Agentic
13
+ module Self
14
+ module Personality
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/self/reflection/helpers/constants'
4
+ require 'legion/extensions/agentic/self/reflection/helpers/reflection'
5
+ require 'legion/extensions/agentic/self/reflection/helpers/reflection_store'
6
+ require 'legion/extensions/agentic/self/reflection/helpers/monitors'
7
+ require 'legion/extensions/agentic/self/reflection/runners/reflection'
8
+
9
+ module Legion
10
+ module Extensions
11
+ module Agentic
12
+ module Self
13
+ module Reflection
14
+ class Client
15
+ include Runners::Reflection
16
+
17
+ attr_reader :reflection_store
18
+
19
+ def initialize(store: nil, **)
20
+ @reflection_store = store || Helpers::ReflectionStore.new
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Self
7
+ module Reflection
8
+ module Helpers
9
+ module Constants
10
+ CATEGORIES = %i[
11
+ prediction_calibration
12
+ curiosity_effectiveness
13
+ emotional_stability
14
+ trust_drift
15
+ memory_health
16
+ cognitive_load
17
+ mode_patterns
18
+ ].freeze
19
+
20
+ SEVERITIES = %i[trivial notable significant critical].freeze
21
+
22
+ RECOMMENDATIONS = %i[
23
+ increase_curiosity
24
+ decrease_curiosity
25
+ stabilize_emotion
26
+ rebuild_trust
27
+ consolidate_memory
28
+ reduce_load
29
+ celebrate_success
30
+ investigate
31
+ no_action
32
+ ].freeze
33
+
34
+ # Thresholds for monitor triggers
35
+ PREDICTION_ACCURACY_LOW = 0.4
36
+ PREDICTION_ACCURACY_DROP = 0.2
37
+ CURIOSITY_RESOLUTION_LOW = 0.2
38
+ CURIOSITY_RESOLUTION_HIGH = 0.8
39
+ EMOTION_INSTABILITY_THRESHOLD = 0.3
40
+ EMOTION_FLATNESS_THRESHOLD = 0.05
41
+ TRUST_DROP_THRESHOLD = 0.15
42
+ MEMORY_DECAY_RATIO_HIGH = 0.8
43
+ BUDGET_OVER_THRESHOLD = 0.9
44
+ MODE_OSCILLATION_THRESHOLD = 5
45
+
46
+ # Rolling window for metrics
47
+ METRIC_WINDOW_SIZE = 20
48
+
49
+ # Health score weights
50
+ HEALTH_WEIGHTS = {
51
+ prediction_calibration: 0.25,
52
+ curiosity_effectiveness: 0.15,
53
+ emotional_stability: 0.15,
54
+ trust_drift: 0.15,
55
+ memory_health: 0.15,
56
+ cognitive_load: 0.15
57
+ }.freeze
58
+
59
+ MAX_REFLECTIONS = 100
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Self
7
+ module Reflection
8
+ module Helpers
9
+ module LlmEnhancer
10
+ SYSTEM_PROMPT = <<~PROMPT
11
+ You are the metacognitive reflection engine for an autonomous AI agent built on LegionIO.
12
+ You analyze post-tick cognitive metrics and produce insightful observations.
13
+ Be analytical and specific. Reference the actual numbers. Identify correlations between metrics.
14
+ Write as internal reflection, not a report. Present tense, first person.
15
+ PROMPT
16
+
17
+ # Maps prompt label -> actual category symbol from Constants::CATEGORIES
18
+ CATEGORY_LABEL_MAP = {
19
+ 'EMOTION' => :emotional_stability,
20
+ 'PREDICTION' => :prediction_calibration,
21
+ 'MEMORY' => :memory_health,
22
+ 'TRUST' => :trust_drift,
23
+ 'CURIOSITY' => :curiosity_effectiveness,
24
+ 'IDENTITY' => :mode_patterns
25
+ }.freeze
26
+
27
+ REFLECTION_CATEGORIES = CATEGORY_LABEL_MAP.keys.freeze
28
+
29
+ module_function
30
+
31
+ def available?
32
+ defined?(Legion::LLM) && Legion::LLM.respond_to?(:started?) && Legion::LLM.started?
33
+ rescue StandardError
34
+ false
35
+ end
36
+
37
+ def enhance_reflection(monitors_data:, health_scores:)
38
+ prompt = build_enhance_reflection_prompt(monitors_data: monitors_data, health_scores: health_scores)
39
+ response = llm_ask(prompt)
40
+ parse_enhance_reflection_response(response)
41
+ rescue StandardError => e
42
+ Legion::Logging.warn "[reflection:llm] enhance_reflection failed: #{e.message}"
43
+ nil
44
+ end
45
+
46
+ def reflect_on_dream(dream_results:)
47
+ prompt = build_reflect_on_dream_prompt(dream_results: dream_results)
48
+ response = llm_ask(prompt)
49
+ parse_reflect_on_dream_response(response)
50
+ rescue StandardError => e
51
+ Legion::Logging.warn "[reflection:llm] reflect_on_dream failed: #{e.message}"
52
+ nil
53
+ end
54
+
55
+ # --- Private helpers ---
56
+
57
+ def llm_ask(prompt)
58
+ chat = Legion::LLM.chat
59
+ chat.with_instructions(SYSTEM_PROMPT)
60
+ chat.ask(prompt)
61
+ end
62
+ private_class_method :llm_ask
63
+
64
+ def build_enhance_reflection_prompt(monitors_data:, health_scores:)
65
+ metrics_lines = format_monitors_data(monitors_data)
66
+ health_lines = health_scores.map { |cat, score| "#{cat}: #{score.round(3)}" }.join("\n")
67
+
68
+ <<~PROMPT
69
+ Analyze these post-tick cognitive metrics and generate insightful observations.
70
+
71
+ METRICS:
72
+ #{metrics_lines}
73
+
74
+ HEALTH SCORES:
75
+ #{health_lines}
76
+
77
+ For each category, write 1-2 sentences of genuine analytical observation.
78
+ Look for correlations between categories. Note concerning or interesting patterns.
79
+
80
+ Format EXACTLY as (one line per category):
81
+ EMOTION: <observation>
82
+ PREDICTION: <observation>
83
+ MEMORY: <observation>
84
+ TRUST: <observation>
85
+ CURIOSITY: <observation>
86
+ IDENTITY: <observation>
87
+ PROMPT
88
+ end
89
+ private_class_method :build_enhance_reflection_prompt
90
+
91
+ def format_monitors_data(monitors_data)
92
+ return '' unless monitors_data.is_a?(Array)
93
+
94
+ monitors_data.filter_map do |entry|
95
+ next unless entry.is_a?(Hash) && entry[:category]
96
+
97
+ metrics = entry[:metrics]
98
+ if metrics.is_a?(Hash) && metrics.any?
99
+ metric_str = metrics.map { |k, v| "#{k}=#{v.is_a?(Float) ? v.round(3) : v}" }.join(', ')
100
+ "#{entry[:category].to_s.upcase}: #{metric_str}"
101
+ else
102
+ entry[:category].to_s.upcase
103
+ end
104
+ end.join("\n")
105
+ end
106
+ private_class_method :format_monitors_data
107
+
108
+ def parse_enhance_reflection_response(response)
109
+ return nil unless response&.content
110
+
111
+ observations = {}
112
+ CATEGORY_LABEL_MAP.each do |label, category_sym|
113
+ match = response.content.match(/^#{label}:\s*(.+)$/i)
114
+ observations[category_sym] = match.captures.first.strip if match
115
+ end
116
+
117
+ observations.empty? ? nil : { observations: observations }
118
+ end
119
+ private_class_method :parse_enhance_reflection_response
120
+
121
+ def build_reflect_on_dream_prompt(dream_results:)
122
+ summary = format_dream_results(dream_results)
123
+
124
+ <<~PROMPT
125
+ Reflect on the completed dream cycle and its cognitive significance.
126
+
127
+ DREAM CYCLE RESULTS:
128
+ #{summary}
129
+
130
+ Generate a first-person, present-tense reflection on what emerged from this dream cycle.
131
+ Be specific about patterns, consolidations, and what needs attention.
132
+
133
+ Format EXACTLY as:
134
+ REFLECTION: <2-4 sentences of internal reflection>
135
+ PROMPT
136
+ end
137
+ private_class_method :build_reflect_on_dream_prompt
138
+
139
+ def format_dream_results(dream_results)
140
+ return 'no results' unless dream_results.is_a?(Hash) && dream_results.any?
141
+
142
+ dream_results.map do |phase, result|
143
+ next unless result.is_a?(Hash)
144
+
145
+ summary = result.except(:error).map { |k, v| "#{k}=#{v}" }.first(4).join(', ')
146
+ "#{phase}: #{summary}"
147
+ end.compact.join("\n")
148
+ end
149
+ private_class_method :format_dream_results
150
+
151
+ def parse_reflect_on_dream_response(response)
152
+ return nil unless response&.content
153
+
154
+ match = response.content.match(/REFLECTION:\s*(.+)/im)
155
+ return nil unless match
156
+
157
+ { reflection: match.captures.first.strip }
158
+ end
159
+ private_class_method :parse_reflect_on_dream_response
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Self
7
+ module Reflection
8
+ module Helpers
9
+ module Monitors
10
+ module_function
11
+
12
+ def run_all(tick_results, metric_history)
13
+ reflections = []
14
+ reflections.concat(monitor_predictions(tick_results, metric_history))
15
+ reflections.concat(monitor_curiosity(tick_results))
16
+ reflections.concat(monitor_emotions(tick_results))
17
+ reflections.concat(monitor_trust(tick_results, metric_history))
18
+ reflections.concat(monitor_memory(tick_results))
19
+ reflections.concat(monitor_cognitive_load(tick_results))
20
+ reflections
21
+ end
22
+
23
+ def monitor_predictions(tick_results, history)
24
+ prediction = tick_results[:prediction_engine]
25
+ return [] unless prediction.is_a?(Hash)
26
+
27
+ reflections = []
28
+ confidence = prediction[:confidence]
29
+
30
+ if confidence.is_a?(Numeric) && confidence < Constants::PREDICTION_ACCURACY_LOW
31
+ reflections << ReflectionFactory.new_reflection(
32
+ category: :prediction_calibration,
33
+ observation: "Prediction confidence is low at #{(confidence * 100).round}%",
34
+ severity: ReflectionFactory.severity_for_drop(1.0 - confidence),
35
+ metrics: { confidence: confidence },
36
+ recommendation: :increase_curiosity
37
+ )
38
+ end
39
+
40
+ reflections.concat(detect_accuracy_trend(history))
41
+ reflections
42
+ end
43
+
44
+ def monitor_curiosity(tick_results)
45
+ curiosity = tick_results[:working_memory_integration]
46
+ return [] unless curiosity.is_a?(Hash)
47
+
48
+ reflections = []
49
+
50
+ resolution_rate = curiosity[:resolution_rate] if curiosity.key?(:resolution_rate)
51
+ if resolution_rate.is_a?(Numeric)
52
+ if resolution_rate < Constants::CURIOSITY_RESOLUTION_LOW
53
+ reflections << ReflectionFactory.new_reflection(
54
+ category: :curiosity_effectiveness,
55
+ observation: "Curiosity resolution rate is low at #{(resolution_rate * 100).round}%",
56
+ severity: :notable,
57
+ metrics: { resolution_rate: resolution_rate },
58
+ recommendation: :decrease_curiosity
59
+ )
60
+ elsif resolution_rate > Constants::CURIOSITY_RESOLUTION_HIGH
61
+ reflections << ReflectionFactory.new_reflection(
62
+ category: :curiosity_effectiveness,
63
+ observation: "Curiosity resolution rate is excellent at #{(resolution_rate * 100).round}%",
64
+ severity: :trivial,
65
+ metrics: { resolution_rate: resolution_rate },
66
+ recommendation: :celebrate_success
67
+ )
68
+ end
69
+ end
70
+
71
+ reflections
72
+ end
73
+
74
+ def monitor_emotions(tick_results)
75
+ emotion = tick_results[:emotional_evaluation]
76
+ return [] unless emotion.is_a?(Hash)
77
+
78
+ reflections = []
79
+ stability = emotion[:stability] || emotion.dig(:momentum, :stability)
80
+
81
+ if stability.is_a?(Numeric)
82
+ if stability < Constants::EMOTION_INSTABILITY_THRESHOLD
83
+ reflections << ReflectionFactory.new_reflection(
84
+ category: :emotional_stability,
85
+ observation: "Emotional state is unstable (stability: #{stability.round(2)})",
86
+ severity: :significant,
87
+ metrics: { stability: stability },
88
+ recommendation: :stabilize_emotion
89
+ )
90
+ elsif stability > (1.0 - Constants::EMOTION_FLATNESS_THRESHOLD)
91
+ reflections << ReflectionFactory.new_reflection(
92
+ category: :emotional_stability,
93
+ observation: 'Emotional state is unusually flat — possible disengagement',
94
+ severity: :notable,
95
+ metrics: { stability: stability },
96
+ recommendation: :investigate
97
+ )
98
+ end
99
+ end
100
+
101
+ reflections
102
+ end
103
+
104
+ def monitor_trust(tick_results, history)
105
+ trust = tick_results[:action_selection]
106
+ return [] unless trust.is_a?(Hash) && trust[:trust_score].is_a?(Numeric)
107
+
108
+ trust_scores = history.filter_map { |h| h.dig(:action_selection, :trust_score) }
109
+ return [] if trust_scores.size < 3
110
+
111
+ recent_avg = trust_scores.last(5).sum / trust_scores.last(5).size.to_f
112
+ older_avg = trust_scores.first(5).sum / trust_scores.first(5).size.to_f
113
+ drop = older_avg - recent_avg
114
+
115
+ return [] unless drop > Constants::TRUST_DROP_THRESHOLD
116
+
117
+ [ReflectionFactory.new_reflection(
118
+ category: :trust_drift,
119
+ observation: "Trust scores have dropped by #{(drop * 100).round}% recently",
120
+ severity: ReflectionFactory.severity_for_drop(drop),
121
+ metrics: { drop: drop, recent_avg: recent_avg, older_avg: older_avg },
122
+ recommendation: :rebuild_trust
123
+ )]
124
+ end
125
+
126
+ def monitor_memory(tick_results)
127
+ memory = tick_results[:memory_consolidation]
128
+ return [] unless memory.is_a?(Hash)
129
+
130
+ pruned = memory[:pruned] || 0
131
+ total = memory[:total] || 1
132
+ ratio = pruned.to_f / [total, 1].max
133
+
134
+ return [] unless ratio > Constants::MEMORY_DECAY_RATIO_HIGH
135
+
136
+ [ReflectionFactory.new_reflection(
137
+ category: :memory_health,
138
+ observation: "High memory decay ratio: #{(ratio * 100).round}% of traces pruned",
139
+ severity: :significant,
140
+ metrics: { pruned: pruned, total: total, ratio: ratio },
141
+ recommendation: :consolidate_memory
142
+ )]
143
+ end
144
+
145
+ def monitor_cognitive_load(tick_results)
146
+ elapsed = tick_results[:elapsed]
147
+ budget = tick_results[:budget]
148
+ return [] unless elapsed.is_a?(Numeric) && budget.is_a?(Numeric) && budget.positive?
149
+
150
+ utilization = elapsed / budget
151
+ return [] unless utilization > Constants::BUDGET_OVER_THRESHOLD
152
+
153
+ [ReflectionFactory.new_reflection(
154
+ category: :cognitive_load,
155
+ observation: "Tick budget utilization at #{(utilization * 100).round}%",
156
+ severity: utilization > 1.0 ? :significant : :notable,
157
+ metrics: { utilization: utilization, elapsed: elapsed, budget: budget },
158
+ recommendation: :reduce_load
159
+ )]
160
+ end
161
+
162
+ def detect_accuracy_trend(history)
163
+ accuracies = history.filter_map { |h| h.dig(:prediction_engine, :confidence) }
164
+ return [] if accuracies.size < 5
165
+
166
+ recent = accuracies.last(5).sum / 5.0
167
+ older = accuracies.first(5).sum / 5.0
168
+ drop = older - recent
169
+
170
+ return [] unless drop > Constants::PREDICTION_ACCURACY_DROP
171
+
172
+ [ReflectionFactory.new_reflection(
173
+ category: :prediction_calibration,
174
+ observation: "Prediction accuracy trending down: #{(older * 100).round}% -> #{(recent * 100).round}%",
175
+ severity: ReflectionFactory.severity_for_drop(drop),
176
+ metrics: { trend_drop: drop, recent_avg: recent, older_avg: older },
177
+ recommendation: :increase_curiosity
178
+ )]
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Self
9
+ module Reflection
10
+ module Helpers
11
+ module ReflectionFactory
12
+ module_function
13
+
14
+ def new_reflection(category:, observation:, severity: :notable,
15
+ metrics: {}, recommendation: :no_action)
16
+ raise ArgumentError, "invalid category: #{category}" unless Constants::CATEGORIES.include?(category)
17
+ raise ArgumentError, "invalid severity: #{severity}" unless Constants::SEVERITIES.include?(severity)
18
+
19
+ {
20
+ reflection_id: SecureRandom.uuid,
21
+ category: category,
22
+ observation: observation,
23
+ severity: severity,
24
+ metrics: metrics,
25
+ recommendation: recommendation,
26
+ created_at: Time.now.utc,
27
+ acted_on: false
28
+ }
29
+ end
30
+
31
+ def severity_weight(severity)
32
+ case severity
33
+ when :critical then 1.0
34
+ when :significant then 0.7
35
+ when :notable then 0.4
36
+ when :trivial then 0.1
37
+ else 0.0
38
+ end
39
+ end
40
+
41
+ def severity_for_drop(drop)
42
+ if drop >= 0.4 then :critical
43
+ elsif drop >= 0.25 then :significant
44
+ elsif drop >= 0.1 then :notable
45
+ else :trivial
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end