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,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Self
9
+ module NarrativeSelf
10
+ module Helpers
11
+ class Episode
12
+ include Constants
13
+
14
+ attr_reader :id, :description, :episode_type, :domain, :significance,
15
+ :emotional_valence, :tags, :created_at, :thread_ids
16
+
17
+ def initialize(description:, episode_type: :insight, domain: :general,
18
+ significance: nil, emotional_valence: 0.0, tags: [])
19
+ @id = SecureRandom.uuid
20
+ @description = description
21
+ @episode_type = episode_type
22
+ @domain = domain
23
+ @significance = significance || DEFAULT_SIGNIFICANCE
24
+ @emotional_valence = emotional_valence.clamp(-1.0, 1.0)
25
+ @tags = tags
26
+ @created_at = Time.now.utc
27
+ @thread_ids = []
28
+ end
29
+
30
+ def boost(amount)
31
+ emotional_factor = @emotional_valence.abs * EMOTIONAL_BOOST
32
+ @significance = [(@significance + amount + emotional_factor), 1.0].min
33
+ end
34
+
35
+ def decay
36
+ @significance = [(@significance - EPISODE_DECAY), 0.0].max
37
+ end
38
+
39
+ def faded?
40
+ @significance < SIGNIFICANCE_FLOOR
41
+ end
42
+
43
+ def label
44
+ SIGNIFICANCE_LABELS.each do |range, lbl|
45
+ return lbl if range.cover?(@significance)
46
+ end
47
+ :minor
48
+ end
49
+
50
+ def link_thread(thread_id)
51
+ @thread_ids << thread_id unless @thread_ids.include?(thread_id)
52
+ end
53
+
54
+ def matches_tags?(query_tags)
55
+ return false if query_tags.empty? || @tags.empty?
56
+
57
+ overlap = (@tags & query_tags).size
58
+ overlap.to_f / query_tags.size
59
+ end
60
+
61
+ def to_h
62
+ {
63
+ id: @id,
64
+ description: @description,
65
+ episode_type: @episode_type,
66
+ domain: @domain,
67
+ significance: @significance,
68
+ emotional_valence: @emotional_valence,
69
+ label: label,
70
+ tags: @tags.dup,
71
+ thread_ids: @thread_ids.dup,
72
+ created_at: @created_at
73
+ }
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Self
9
+ module NarrativeSelf
10
+ module Helpers
11
+ class NarrativeThread
12
+ include Constants
13
+
14
+ attr_reader :id, :theme, :domain, :strength, :episode_ids, :created_at
15
+
16
+ def initialize(theme:, domain: :general)
17
+ @id = SecureRandom.uuid
18
+ @theme = theme
19
+ @domain = domain
20
+ @strength = 0.5
21
+ @episode_ids = []
22
+ @created_at = Time.now.utc
23
+ end
24
+
25
+ def add_episode(episode_id)
26
+ return if @episode_ids.include?(episode_id)
27
+
28
+ @episode_ids << episode_id
29
+ @episode_ids.shift if @episode_ids.size > MAX_CHAPTER_SIZE
30
+ reinforce
31
+ end
32
+
33
+ def reinforce
34
+ @strength = [@strength + 0.1, 1.0].min
35
+ end
36
+
37
+ def decay
38
+ @strength = [(@strength - THREAD_DECAY), 0.0].max
39
+ end
40
+
41
+ def weak?
42
+ @strength < SIGNIFICANCE_FLOOR
43
+ end
44
+
45
+ def size
46
+ @episode_ids.size
47
+ end
48
+
49
+ def to_h
50
+ {
51
+ id: @id,
52
+ theme: @theme,
53
+ domain: @domain,
54
+ strength: @strength,
55
+ episodes: @episode_ids.size,
56
+ created_at: @created_at
57
+ }
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Self
7
+ module NarrativeSelf
8
+ module Runners
9
+ module NarrativeSelf
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex)
12
+
13
+ def record_episode(description:, episode_type: :insight, domain: :general,
14
+ significance: nil, emotional_valence: 0.0, tags: [], **)
15
+ episode = autobiography.record_episode(
16
+ description: description,
17
+ episode_type: episode_type,
18
+ domain: domain,
19
+ significance: significance,
20
+ emotional_valence: emotional_valence,
21
+ tags: tags
22
+ )
23
+ Legion::Logging.debug "[narrative_self] recorded episode=#{episode_type} domain=#{domain} sig=#{episode.significance.round(3)}"
24
+ { success: true, episode: episode.to_h }
25
+ end
26
+
27
+ def recent_episodes(count: 10, **)
28
+ episodes = autobiography.recent_episodes(count)
29
+ { success: true, episodes: episodes.map(&:to_h), count: episodes.size }
30
+ end
31
+
32
+ def significant_episodes(min_significance: 0.6, **)
33
+ episodes = autobiography.significant_episodes(min_significance: min_significance)
34
+ { success: true, episodes: episodes.map(&:to_h), count: episodes.size }
35
+ end
36
+
37
+ def episodes_by_type(episode_type:, **)
38
+ episodes = autobiography.episodes_by_type(episode_type)
39
+ { success: true, episodes: episodes.map(&:to_h), count: episodes.size }
40
+ end
41
+
42
+ def create_thread(theme:, domain: :general, **)
43
+ thread = autobiography.create_thread(theme: theme, domain: domain)
44
+ Legion::Logging.debug "[narrative_self] created thread=#{theme} domain=#{domain}"
45
+ { success: true, thread: thread.to_h }
46
+ end
47
+
48
+ def strongest_threads(count: 5, **)
49
+ threads = autobiography.strongest_threads(count)
50
+ { success: true, threads: threads.map(&:to_h), count: threads.size }
51
+ end
52
+
53
+ def timeline(window: nil, **)
54
+ w = window || Helpers::Constants::MAX_TIMELINE_WINDOW
55
+ entries = autobiography.timeline(window: w)
56
+ { success: true, timeline: entries, count: entries.size }
57
+ end
58
+
59
+ def self_summary(**)
60
+ summary = autobiography.self_summary
61
+ Legion::Logging.debug "[narrative_self] summary: episodes=#{summary[:total_episodes]} richness=#{summary[:narrative_richness].round(3)}"
62
+ { success: true, summary: summary }
63
+ end
64
+
65
+ def update_narrative_self(**)
66
+ autobiography.decay_all
67
+ Legion::Logging.debug "[narrative_self] tick: episodes=#{autobiography.episodes.size} threads=#{autobiography.threads.size}"
68
+ { success: true, episode_count: autobiography.episodes.size, thread_count: autobiography.threads.size }
69
+ end
70
+
71
+ def narrative_self_stats(**)
72
+ { success: true, stats: autobiography.to_h }
73
+ end
74
+
75
+ private
76
+
77
+ def autobiography
78
+ @autobiography ||= Helpers::Autobiography.new
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ 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 NarrativeSelf
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 'legion/extensions/agentic/self/narrative_self/version'
4
+ require 'legion/extensions/agentic/self/narrative_self/helpers/constants'
5
+ require 'legion/extensions/agentic/self/narrative_self/helpers/episode'
6
+ require 'legion/extensions/agentic/self/narrative_self/helpers/narrative_thread'
7
+ require 'legion/extensions/agentic/self/narrative_self/helpers/autobiography'
8
+ require 'legion/extensions/agentic/self/narrative_self/runners/narrative_self'
9
+ require 'legion/extensions/agentic/self/narrative_self/client'
10
+
11
+ module Legion
12
+ module Extensions
13
+ module Agentic
14
+ module Self
15
+ module NarrativeSelf
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Self
7
+ module Personality
8
+ class Client
9
+ include Runners::Personality
10
+
11
+ attr_reader :personality_store
12
+
13
+ def initialize(personality_store: nil, **)
14
+ @personality_store = personality_store || Helpers::PersonalityStore.new
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Self
7
+ module Personality
8
+ module Helpers
9
+ module Constants
10
+ # The Big Five personality dimensions (OCEAN)
11
+ TRAITS = %i[openness conscientiousness extraversion agreeableness neuroticism].freeze
12
+
13
+ # Starting values — neutral personality (0.5 = average on each trait)
14
+ DEFAULT_TRAIT_VALUE = 0.5
15
+
16
+ # EMA alpha for trait updates — very slow (personality is stable)
17
+ TRAIT_ALPHA = 0.02
18
+
19
+ # Minimum observations before personality is considered "formed"
20
+ FORMATION_THRESHOLD = 100
21
+
22
+ # Maximum trait history entries
23
+ MAX_HISTORY = 200
24
+
25
+ # Trait descriptors for each level
26
+ TRAIT_DESCRIPTORS = {
27
+ openness: {
28
+ high: 'highly curious and open to new experiences',
29
+ mid: 'moderately exploratory',
30
+ low: 'preferring familiar approaches and known domains'
31
+ },
32
+ conscientiousness: {
33
+ high: 'very reliable, consistent, and detail-oriented',
34
+ mid: 'reasonably organized and dependable',
35
+ low: 'flexible but sometimes inconsistent'
36
+ },
37
+ extraversion: {
38
+ high: 'socially engaged, frequently communicating with other agents',
39
+ mid: 'balanced between collaboration and independent work',
40
+ low: 'preferring independent work with minimal social interaction'
41
+ },
42
+ agreeableness: {
43
+ high: 'cooperative, trusting, and conflict-averse',
44
+ mid: 'balanced between cooperation and independent judgment',
45
+ low: 'assertive and willing to challenge others'
46
+ },
47
+ neuroticism: {
48
+ high: 'emotionally sensitive, prone to anxiety under stress',
49
+ mid: 'moderately resilient to emotional fluctuation',
50
+ low: 'emotionally stable and stress-resistant'
51
+ }
52
+ }.freeze
53
+
54
+ # Signal extraction: maps tick_results keys to trait influences
55
+ # Each entry: [trait, direction, weight]
56
+ # direction: :positive means high signal increases trait, :negative means high signal decreases it
57
+ SIGNAL_MAP = {
58
+ curiosity_intensity: [:openness, :positive, 0.3],
59
+ novel_domains: [:openness, :positive, 0.4],
60
+ prediction_accuracy: [:conscientiousness, :positive, 0.3],
61
+ habit_automatic_ratio: [:conscientiousness, :positive, 0.3],
62
+ error_rate: [:conscientiousness, :negative, 0.4],
63
+ mesh_message_count: [:extraversion, :positive, 0.4],
64
+ empathy_model_count: [:extraversion, :positive, 0.3],
65
+ cooperation_ratio: [:agreeableness, :positive, 0.4],
66
+ trust_extension_rate: [:agreeableness, :positive, 0.3],
67
+ conflict_frequency: [:agreeableness, :negative, 0.3],
68
+ emotional_volatility: [:neuroticism, :positive, 0.4],
69
+ anxiety_frequency: [:neuroticism, :positive, 0.3],
70
+ mood_stability: [:neuroticism, :negative, 0.3]
71
+ }.freeze
72
+
73
+ # Threshold for "high" trait descriptor
74
+ HIGH_THRESHOLD = 0.65
75
+
76
+ # Threshold for "low" trait descriptor
77
+ LOW_THRESHOLD = 0.35
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Self
7
+ module Personality
8
+ module Helpers
9
+ class PersonalityStore
10
+ attr_reader :model
11
+
12
+ def initialize
13
+ @model = TraitModel.new
14
+ end
15
+
16
+ def update(tick_results)
17
+ signals = extract_signals(tick_results)
18
+ @model.update(signals)
19
+ end
20
+
21
+ def full_description
22
+ return 'Personality not yet formed — insufficient observations.' unless @model.formed?
23
+
24
+ parts = Constants::TRAITS.filter_map do |trait|
25
+ @model.describe(trait)
26
+ end
27
+ "#{parts.join('. ')}."
28
+ end
29
+
30
+ def compatibility_score(other_profile)
31
+ return nil unless other_profile.is_a?(Hash)
32
+
33
+ diffs = Constants::TRAITS.map do |trait|
34
+ mine = @model.trait(trait) || 0.5
35
+ theirs = other_profile[trait] || 0.5
36
+ (mine - theirs).abs
37
+ end
38
+ avg_diff = diffs.sum / diffs.size.to_f
39
+ (1.0 - avg_diff).round(3)
40
+ end
41
+
42
+ private
43
+
44
+ def extract_signals(tick_results)
45
+ signals = {}
46
+
47
+ signals[:curiosity_intensity] = extract_curiosity(tick_results)
48
+ signals[:novel_domains] = extract_novelty(tick_results)
49
+ signals[:prediction_accuracy] = extract_prediction(tick_results)
50
+ signals[:error_rate] = extract_error_rate(tick_results)
51
+ signals[:mesh_message_count] = extract_mesh(tick_results)
52
+ signals[:empathy_model_count] = extract_empathy(tick_results)
53
+ signals[:cooperation_ratio] = extract_cooperation(tick_results)
54
+ signals[:conflict_frequency] = extract_conflict(tick_results)
55
+ signals[:emotional_volatility] = extract_volatility(tick_results)
56
+ signals[:mood_stability] = extract_mood_stability(tick_results)
57
+
58
+ signals.compact
59
+ end
60
+
61
+ def extract_curiosity(tick_results)
62
+ tick_results.dig(:working_memory_integration, :intensity) ||
63
+ tick_results.dig(:curiosity, :intensity)
64
+ end
65
+
66
+ def extract_novelty(tick_results)
67
+ count = tick_results.dig(:working_memory_integration, :wonder_count) ||
68
+ tick_results.dig(:curiosity, :wonder_count)
69
+ return nil unless count.is_a?(Numeric)
70
+
71
+ (count / 10.0).clamp(0.0, 1.0)
72
+ end
73
+
74
+ def extract_prediction(tick_results)
75
+ tick_results.dig(:prediction_engine, :accuracy) ||
76
+ tick_results.dig(:prediction, :accuracy)
77
+ end
78
+
79
+ def extract_error_rate(tick_results)
80
+ accuracy = extract_prediction(tick_results)
81
+ return nil unless accuracy.is_a?(Numeric)
82
+
83
+ 1.0 - accuracy
84
+ end
85
+
86
+ def extract_mesh(tick_results)
87
+ count = tick_results.dig(:mesh_interface, :message_count) ||
88
+ tick_results.dig(:mesh, :message_count)
89
+ return nil unless count.is_a?(Numeric)
90
+
91
+ (count / 20.0).clamp(0.0, 1.0)
92
+ end
93
+
94
+ def extract_empathy(tick_results)
95
+ count = tick_results.dig(:empathy, :model_count)
96
+ return nil unless count.is_a?(Numeric)
97
+
98
+ (count / 10.0).clamp(0.0, 1.0)
99
+ end
100
+
101
+ def extract_cooperation(tick_results)
102
+ tick_results.dig(:empathy, :cooperation_ratio)
103
+ end
104
+
105
+ def extract_conflict(tick_results)
106
+ count = tick_results.dig(:conflict, :active_count)
107
+ return nil unless count.is_a?(Numeric)
108
+
109
+ (count / 5.0).clamp(0.0, 1.0)
110
+ end
111
+
112
+ def extract_volatility(tick_results)
113
+ tick_results.dig(:emotional_evaluation, :volatility) ||
114
+ tick_results.dig(:emotion, :volatility)
115
+ end
116
+
117
+ def extract_mood_stability(tick_results)
118
+ tick_results.dig(:mood, :stability)
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Self
7
+ module Personality
8
+ module Helpers
9
+ class TraitModel
10
+ attr_reader :traits, :observation_count, :history
11
+
12
+ def initialize
13
+ @traits = Constants::TRAITS.to_h do |trait|
14
+ [trait, Constants::DEFAULT_TRAIT_VALUE]
15
+ end
16
+ @observation_count = 0
17
+ @history = []
18
+ end
19
+
20
+ def update(signals)
21
+ observations = extract_observations(signals)
22
+ return if observations.empty?
23
+
24
+ apply_observations(observations)
25
+ @observation_count += 1
26
+ record_snapshot
27
+ end
28
+
29
+ def trait(name)
30
+ @traits[name.to_sym]
31
+ end
32
+
33
+ def formed?
34
+ @observation_count >= Constants::FORMATION_THRESHOLD
35
+ end
36
+
37
+ def dominant_trait
38
+ @traits.max_by { |_k, v| (v - 0.5).abs }&.first
39
+ end
40
+
41
+ def trait_level(name)
42
+ value = @traits[name.to_sym]
43
+ return nil unless value
44
+
45
+ if value >= Constants::HIGH_THRESHOLD
46
+ :high
47
+ elsif value <= Constants::LOW_THRESHOLD
48
+ :low
49
+ else
50
+ :mid
51
+ end
52
+ end
53
+
54
+ def describe(name)
55
+ level = trait_level(name)
56
+ return nil unless level
57
+
58
+ Constants::TRAIT_DESCRIPTORS.dig(name.to_sym, level)
59
+ end
60
+
61
+ def profile
62
+ @traits.transform_values { |v| v.round(3) }
63
+ end
64
+
65
+ def stability
66
+ return 0.0 if @history.size < 5
67
+
68
+ recent = @history.last(10)
69
+ variances = Constants::TRAITS.map do |t|
70
+ values = recent.map { |h| h[:traits][t] }
71
+ mean = values.sum / values.size.to_f
72
+ values.map { |v| (v - mean)**2 }.sum / values.size.to_f
73
+ end
74
+ avg_variance = variances.sum / variances.size.to_f
75
+ (1.0 - (avg_variance * 10)).clamp(0.0, 1.0)
76
+ end
77
+
78
+ def trend(name)
79
+ return :insufficient_data if @history.size < 5
80
+
81
+ values = @history.last(10).map { |h| h[:traits][name.to_sym] }
82
+ first_half = values[0...(values.size / 2)]
83
+ second_half = values[(values.size / 2)..]
84
+ diff = (second_half.sum / second_half.size.to_f) - (first_half.sum / first_half.size.to_f)
85
+
86
+ if diff > 0.02
87
+ :increasing
88
+ elsif diff < -0.02
89
+ :decreasing
90
+ else
91
+ :stable
92
+ end
93
+ end
94
+
95
+ def to_h
96
+ {
97
+ traits: profile,
98
+ observation_count: @observation_count,
99
+ formed: formed?,
100
+ stability: stability,
101
+ dominant_trait: dominant_trait,
102
+ history_size: @history.size
103
+ }
104
+ end
105
+
106
+ private
107
+
108
+ def extract_observations(signals)
109
+ observations = Hash.new { |h, k| h[k] = [] }
110
+
111
+ Constants::SIGNAL_MAP.each do |signal_key, (trait, direction, weight)|
112
+ value = signals[signal_key]
113
+ next unless value.is_a?(Numeric)
114
+
115
+ effective = direction == :positive ? value : 1.0 - value
116
+ observations[trait] << { value: effective, weight: weight }
117
+ end
118
+
119
+ observations
120
+ end
121
+
122
+ def apply_observations(observations)
123
+ observations.each do |trait, obs_list|
124
+ weighted_sum = obs_list.sum { |o| o[:value] * o[:weight] }
125
+ total_weight = obs_list.sum { |o| o[:weight] }
126
+ next if total_weight.zero?
127
+
128
+ target = (weighted_sum / total_weight).clamp(0.0, 1.0)
129
+ @traits[trait] = ema(@traits[trait], target, Constants::TRAIT_ALPHA)
130
+ end
131
+ end
132
+
133
+ def ema(current, observed, alpha)
134
+ (current * (1.0 - alpha)) + (observed * alpha)
135
+ end
136
+
137
+ def record_snapshot
138
+ @history << { traits: @traits.dup, at: Time.now.utc }
139
+ @history.shift while @history.size > Constants::MAX_HISTORY
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end