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,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Self::Metacognition::Runners::Metacognition do
4
+ let(:store) { Legion::Extensions::Agentic::Self::Metacognition::Helpers::SnapshotStore.new }
5
+ let(:client) { Legion::Extensions::Agentic::Self::Metacognition::Client.new(snapshot_store: store) }
6
+
7
+ let(:tick_results) do
8
+ {
9
+ sensory_processing: { spotlight_count: 3, total_signals: 8 },
10
+ emotional_evaluation: { valence: 0.4, arousal: 0.6 },
11
+ prediction_engine: { confidence: 0.85, mode: :functional_mapping },
12
+ working_memory_integration: { curiosity_intensity: 0.5, open_wonders: 3 },
13
+ action_selection: { intentions: [{ drive: :curiosity }, { drive: :epistemic }] },
14
+ post_tick_reflection: { cognitive_health: 0.88 }
15
+ }
16
+ end
17
+
18
+ describe '#introspect' do
19
+ it 'builds and caches a self-model' do
20
+ model = client.introspect(tick_results: tick_results)
21
+ expect(model).to have_key(:identity)
22
+ expect(model).to have_key(:architecture)
23
+ expect(model).to have_key(:cognitive)
24
+ expect(store.size).to eq(1)
25
+ end
26
+
27
+ it 'uses cached model when not stale' do
28
+ client.introspect(tick_results: tick_results)
29
+ second = client.introspect(tick_results: {})
30
+ expect(store.size).to eq(1)
31
+ expect(second.dig(:cognitive, :health)).to eq(0.88)
32
+ end
33
+
34
+ it 'rebuilds when stale' do
35
+ old = Legion::Extensions::Agentic::Self::Metacognition::Helpers::SelfModel.build(tick_results: tick_results)
36
+ old[:assembled_at] = Time.now.utc - 60
37
+ store.store(old)
38
+
39
+ new_results = tick_results.merge(post_tick_reflection: { cognitive_health: 0.95 })
40
+ model = client.introspect(tick_results: new_results)
41
+ expect(model.dig(:cognitive, :health)).to eq(0.95)
42
+ expect(store.size).to eq(2)
43
+ end
44
+ end
45
+
46
+ describe '#self_narrative' do
47
+ it 'returns prose description with model' do
48
+ result = client.self_narrative(tick_results: tick_results)
49
+ expect(result[:prose]).to be_a(String)
50
+ expect(result[:prose].length).to be > 20
51
+ expect(result[:health]).to eq(0.88)
52
+ expect(result).to have_key(:model)
53
+ end
54
+ end
55
+
56
+ describe '#explain_subsystem' do
57
+ it 'returns info about a loaded subsystem' do
58
+ client.introspect(tick_results: tick_results)
59
+ result = client.explain_subsystem(subsystem: :metacognition)
60
+ expect(result[:loaded]).to be true
61
+ expect(result[:category]).to eq(:introspection)
62
+ end
63
+
64
+ it 'returns info about an unloaded subsystem' do
65
+ result = client.explain_subsystem(subsystem: :memory)
66
+ expect(result[:subsystem]).to eq(:memory)
67
+ end
68
+ end
69
+
70
+ describe '#architecture_overview' do
71
+ it 'returns identity and capability info' do
72
+ client.introspect(tick_results: tick_results)
73
+ result = client.architecture_overview
74
+ expect(result[:identity][:framework]).to eq('LegionIO')
75
+ expect(result).to have_key(:capabilities)
76
+ end
77
+ end
78
+
79
+ describe '#health_trend' do
80
+ it 'returns trend data' do
81
+ 3.times do |i|
82
+ model = Legion::Extensions::Agentic::Self::Metacognition::Helpers::SelfModel.build(tick_results: tick_results)
83
+ model[:cognitive] = { health: 0.8 + (i * 0.05) }
84
+ model[:assembled_at] = Time.now.utc - (100 - i)
85
+ store.store(model)
86
+ end
87
+
88
+ result = client.health_trend
89
+ expect(result).to have_key(:trend)
90
+ expect(result[:snapshots]).to eq(3)
91
+ end
92
+ end
93
+
94
+ describe '#architecture_changes' do
95
+ it 'returns change history' do
96
+ result = client.architecture_changes
97
+ expect(result[:changes]).to be_an(Array)
98
+ end
99
+ end
100
+
101
+ describe '#metacognition_stats' do
102
+ it 'returns aggregate stats' do
103
+ client.introspect(tick_results: tick_results)
104
+ result = client.metacognition_stats
105
+ expect(result[:snapshots_stored]).to eq(1)
106
+ expect(result[:loaded_extensions]).to be >= 1
107
+ expect(result[:cognitive_health]).to eq(0.88)
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,281 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Self::Metacognition::Runners::Registry do
4
+ subject(:runner) { described_class }
5
+
6
+ # Reset in-memory store between examples
7
+ before { runner.instance_variable_set(:@store, nil) }
8
+
9
+ let(:base_args) do
10
+ {
11
+ name: 'lex-memory',
12
+ module_name: 'Memory',
13
+ category: 'memory'
14
+ }
15
+ end
16
+
17
+ describe '#register_extension' do
18
+ it 'returns success: true with name and category' do
19
+ result = runner.register_extension(**base_args)
20
+ expect(result[:success]).to be true
21
+ expect(result[:name]).to eq('lex-memory')
22
+ expect(result[:category]).to eq('memory')
23
+ end
24
+
25
+ it 'stores the extension in-memory' do
26
+ runner.register_extension(**base_args)
27
+ status = runner.extension_status(name: 'lex-memory')
28
+ expect(status[:success]).to be true
29
+ expect(status[:extension][:module_name]).to eq('Memory')
30
+ end
31
+
32
+ it 'accepts optional description and cognitive_concept' do
33
+ runner.register_extension(
34
+ **base_args,
35
+ description: 'Trace-based episodic memory',
36
+ cognitive_concept: 'Hebbian learning'
37
+ )
38
+ ext = runner.extension_status(name: 'lex-memory')[:extension]
39
+ expect(ext[:description]).to eq('Trace-based episodic memory')
40
+ expect(ext[:cognitive_concept]).to eq('Hebbian learning')
41
+ end
42
+
43
+ it 'coerces category to string' do
44
+ runner.register_extension(**base_args, category: :perception)
45
+ ext = runner.extension_status(name: 'lex-memory')[:extension]
46
+ expect(ext[:category]).to eq('perception')
47
+ end
48
+
49
+ it 'defaults category to cognition when not provided' do
50
+ result = runner.register_extension(name: 'lex-tick', module_name: 'Tick')
51
+ expect(result[:category]).to eq('cognition')
52
+ end
53
+
54
+ it 'accepts spec_count and spec_pass_count' do
55
+ runner.register_extension(**base_args, spec_count: 42, spec_pass_count: 40)
56
+ ext = runner.extension_status(name: 'lex-memory')[:extension]
57
+ expect(ext[:spec_count]).to eq(42)
58
+ expect(ext[:spec_pass_count]).to eq(40)
59
+ end
60
+
61
+ it 'accepts build_batch' do
62
+ runner.register_extension(**base_args, build_batch: 3)
63
+ ext = runner.extension_status(name: 'lex-memory')[:extension]
64
+ expect(ext[:build_batch]).to eq(3)
65
+ end
66
+
67
+ it 'ignores extra keyword arguments via **' do
68
+ expect { runner.register_extension(**base_args, unknown_key: 'ignored') }.not_to raise_error
69
+ end
70
+ end
71
+
72
+ describe '#deregister_extension' do
73
+ before { runner.register_extension(**base_args) }
74
+
75
+ it 'returns success: true' do
76
+ result = runner.deregister_extension(name: 'lex-memory')
77
+ expect(result[:success]).to be true
78
+ expect(result[:name]).to eq('lex-memory')
79
+ end
80
+
81
+ it 'removes the extension from the store' do
82
+ runner.deregister_extension(name: 'lex-memory')
83
+ status = runner.extension_status(name: 'lex-memory')
84
+ expect(status[:success]).to be false
85
+ expect(status[:error]).to eq(:not_found)
86
+ end
87
+ end
88
+
89
+ describe '#list_extensions' do
90
+ before do
91
+ runner.register_extension(name: 'lex-memory', module_name: 'Memory', category: 'memory')
92
+ runner.register_extension(name: 'lex-emotion', module_name: 'Emotion', category: 'perception')
93
+ runner.register_extension(name: 'lex-tick', module_name: 'Tick', category: 'cognition')
94
+ end
95
+
96
+ it 'returns all extensions with no filter' do
97
+ result = runner.list_extensions
98
+ expect(result[:success]).to be true
99
+ expect(result[:count]).to eq(3)
100
+ expect(result[:extensions].size).to eq(3)
101
+ end
102
+
103
+ it 'filters by category' do
104
+ result = runner.list_extensions(category: 'memory')
105
+ expect(result[:count]).to eq(1)
106
+ expect(result[:extensions].first[:name]).to eq('lex-memory')
107
+ end
108
+
109
+ it 'filters by status' do
110
+ runner.update_extension(name: 'lex-tick', attrs: { status: 'inactive' })
111
+ result = runner.list_extensions(status: 'inactive')
112
+ expect(result[:count]).to eq(1)
113
+ expect(result[:extensions].first[:name]).to eq('lex-tick')
114
+ end
115
+
116
+ it 'returns empty list when no match' do
117
+ result = runner.list_extensions(category: 'nonexistent')
118
+ expect(result[:success]).to be true
119
+ expect(result[:count]).to eq(0)
120
+ end
121
+ end
122
+
123
+ describe '#extension_status' do
124
+ it 'returns not_found for unknown extension' do
125
+ result = runner.extension_status(name: 'lex-unknown')
126
+ expect(result[:success]).to be false
127
+ expect(result[:error]).to eq(:not_found)
128
+ end
129
+
130
+ it 'returns the extension data for a known extension' do
131
+ runner.register_extension(**base_args)
132
+ result = runner.extension_status(name: 'lex-memory')
133
+ expect(result[:success]).to be true
134
+ expect(result[:extension][:name]).to eq('lex-memory')
135
+ end
136
+ end
137
+
138
+ describe '#update_extension' do
139
+ before { runner.register_extension(**base_args) }
140
+
141
+ it 'returns success: true and updated data' do
142
+ result = runner.update_extension(name: 'lex-memory', attrs: { health_score: 0.6 })
143
+ expect(result[:success]).to be true
144
+ expect(result[:extension][:health_score]).to eq(0.6)
145
+ end
146
+
147
+ it 'returns not_found for unknown extension' do
148
+ result = runner.update_extension(name: 'lex-missing', attrs: { health_score: 0.5 })
149
+ expect(result[:success]).to be false
150
+ expect(result[:error]).to eq(:not_found)
151
+ end
152
+
153
+ it 'updates status' do
154
+ runner.update_extension(name: 'lex-memory', attrs: { status: 'degraded' })
155
+ ext = runner.extension_status(name: 'lex-memory')[:extension]
156
+ expect(ext[:status]).to eq('degraded')
157
+ end
158
+ end
159
+
160
+ describe '#category_distribution' do
161
+ before do
162
+ runner.register_extension(name: 'lex-memory', module_name: 'Memory', category: 'memory')
163
+ runner.register_extension(name: 'lex-emotion', module_name: 'Emotion', category: 'perception')
164
+ runner.register_extension(name: 'lex-tick', module_name: 'Tick', category: 'cognition')
165
+ runner.register_extension(name: 'lex-cortex', module_name: 'Cortex', category: 'cognition')
166
+ end
167
+
168
+ it 'returns success: true' do
169
+ expect(runner.category_distribution[:success]).to be true
170
+ end
171
+
172
+ it 'returns distribution counts' do
173
+ dist = runner.category_distribution[:distribution]
174
+ expect(dist['cognition']).to eq(2)
175
+ expect(dist['memory']).to eq(1)
176
+ expect(dist['perception']).to eq(1)
177
+ end
178
+
179
+ it 'returns percentage breakdown' do
180
+ percentages = runner.category_distribution[:percentages]
181
+ expect(percentages['cognition']).to eq(50.0)
182
+ end
183
+
184
+ it 'returns total count' do
185
+ expect(runner.category_distribution[:total]).to eq(4)
186
+ end
187
+
188
+ it 'returns zero percentages when store is empty' do
189
+ runner.instance_variable_set(:@store, nil)
190
+ result = runner.category_distribution
191
+ expect(result[:total]).to eq(0)
192
+ expect(result[:distribution]).to eq({})
193
+ end
194
+ end
195
+
196
+ describe '#degraded_extensions' do
197
+ before do
198
+ runner.register_extension(**base_args)
199
+ runner.update_extension(name: 'lex-memory', attrs: { health_score: 0.9 })
200
+ runner.register_extension(name: 'lex-emotion', module_name: 'Emotion', category: 'perception')
201
+ runner.update_extension(name: 'lex-emotion', attrs: { health_score: 0.2 })
202
+ runner.register_extension(name: 'lex-tick', module_name: 'Tick', category: 'cognition')
203
+ runner.update_extension(name: 'lex-tick', attrs: { health_score: 0.05 })
204
+ end
205
+
206
+ it 'returns success: true' do
207
+ expect(runner.degraded_extensions[:success]).to be true
208
+ end
209
+
210
+ it 'returns extensions below default threshold (0.4)' do
211
+ result = runner.degraded_extensions
212
+ expect(result[:count]).to eq(2)
213
+ result[:extensions].each { |e| expect(e[:health_score]).to be < 0.4 }
214
+ end
215
+
216
+ it 'accepts a custom threshold' do
217
+ result = runner.degraded_extensions(threshold: 0.1)
218
+ expect(result[:count]).to eq(1)
219
+ end
220
+
221
+ it 'returns empty list when all are healthy' do
222
+ runner.update_extension(name: 'lex-emotion', attrs: { health_score: 0.95 })
223
+ runner.update_extension(name: 'lex-tick', attrs: { health_score: 0.85 })
224
+ result = runner.degraded_extensions
225
+ expect(result[:count]).to eq(0)
226
+ end
227
+ end
228
+
229
+ describe '#seed_from_constants' do
230
+ let(:mock_capabilities) do
231
+ {
232
+ Memory: :memory,
233
+ Emotion: :perception,
234
+ Tick: :cognition
235
+ }
236
+ end
237
+
238
+ before do
239
+ stub_const(
240
+ 'Legion::Extensions::Agentic::Self::Metacognition::Helpers::Constants::EXTENSION_CAPABILITIES',
241
+ mock_capabilities
242
+ )
243
+ end
244
+
245
+ it 'returns success: true' do
246
+ expect(runner.seed_from_constants[:success]).to be true
247
+ end
248
+
249
+ it 'seeds entries for all capabilities' do
250
+ result = runner.seed_from_constants
251
+ expect(result[:seeded]).to eq(3)
252
+ expect(result[:total]).to eq(3)
253
+ end
254
+
255
+ it 'skips already-registered extensions' do
256
+ runner.register_extension(name: 'lex-memory', module_name: 'Memory', category: 'memory')
257
+ result = runner.seed_from_constants
258
+ expect(result[:seeded]).to eq(2)
259
+ end
260
+
261
+ it 'seeds with correct lex name derived from module name' do
262
+ runner.seed_from_constants
263
+ expect(runner.extension_status(name: 'lex-memory')[:success]).to be true
264
+ expect(runner.extension_status(name: 'lex-emotion')[:success]).to be true
265
+ expect(runner.extension_status(name: 'lex-tick')[:success]).to be true
266
+ end
267
+
268
+ it 'seeds with correct category from capabilities map' do
269
+ runner.seed_from_constants
270
+ expect(runner.extension_status(name: 'lex-memory')[:extension][:category]).to eq('memory')
271
+ expect(runner.extension_status(name: 'lex-emotion')[:extension][:category]).to eq('perception')
272
+ end
273
+
274
+ it 'is idempotent — running twice does not duplicate entries' do
275
+ runner.seed_from_constants
276
+ result = runner.seed_from_constants
277
+ expect(result[:seeded]).to eq(0)
278
+ expect(runner.list_extensions[:count]).to eq(3)
279
+ end
280
+ end
281
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/self/metacognitive_monitoring/client'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Self::MetacognitiveMonitoring::Client do
6
+ subject(:client) { described_class.new }
7
+
8
+ it 'responds to record_judgment' do
9
+ expect(client).to respond_to(:record_judgment)
10
+ end
11
+
12
+ it 'responds to resolve_judgment' do
13
+ expect(client).to respond_to(:resolve_judgment)
14
+ end
15
+
16
+ it 'responds to feeling_of_knowing' do
17
+ expect(client).to respond_to(:feeling_of_knowing)
18
+ end
19
+
20
+ it 'responds to judgment_of_learning' do
21
+ expect(client).to respond_to(:judgment_of_learning)
22
+ end
23
+
24
+ it 'responds to detect_overconfidence' do
25
+ expect(client).to respond_to(:detect_overconfidence)
26
+ end
27
+
28
+ it 'responds to detect_underconfidence' do
29
+ expect(client).to respond_to(:detect_underconfidence)
30
+ end
31
+
32
+ it 'responds to calibration_report' do
33
+ expect(client).to respond_to(:calibration_report)
34
+ end
35
+
36
+ it 'responds to monitoring_report' do
37
+ expect(client).to respond_to(:monitoring_report)
38
+ end
39
+
40
+ it 'responds to average_effort' do
41
+ expect(client).to respond_to(:average_effort)
42
+ end
43
+
44
+ it 'responds to calibration_curve' do
45
+ expect(client).to respond_to(:calibration_curve)
46
+ end
47
+
48
+ it 'accepts injected engine' do
49
+ engine = Legion::Extensions::Agentic::Self::MetacognitiveMonitoring::Helpers::MonitoringEngine.new
50
+ c = described_class.new(engine: engine)
51
+ c.record_judgment(type: :confidence_rating, domain: :test)
52
+ expect(engine.judgments.size).to eq(1)
53
+ end
54
+
55
+ it 'creates its own engine when none injected' do
56
+ c = described_class.new
57
+ expect { c.record_judgment(type: :feeling_of_knowing, domain: :test) }.not_to raise_error
58
+ end
59
+ end
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Self::MetacognitiveMonitoring::Helpers::CalibrationTracker do
4
+ subject(:tracker) { described_class.new }
5
+
6
+ describe '#initialize' do
7
+ it 'starts with empty points' do
8
+ expect(tracker.points).to be_empty
9
+ end
10
+ end
11
+
12
+ describe '#add_point' do
13
+ it 'adds a point' do
14
+ tracker.add_point(predicted: 0.7, actual: 0.6)
15
+ expect(tracker.count).to eq(1)
16
+ end
17
+
18
+ it 'returns self for chaining' do
19
+ result = tracker.add_point(predicted: 0.7, actual: 0.6)
20
+ expect(result).to eq(tracker)
21
+ end
22
+
23
+ it 'clamps predicted above 1.0' do
24
+ tracker.add_point(predicted: 1.5, actual: 0.5)
25
+ expect(tracker.points.first[:predicted]).to eq(1.0)
26
+ end
27
+
28
+ it 'clamps actual below 0.0' do
29
+ tracker.add_point(predicted: 0.5, actual: -0.1)
30
+ expect(tracker.points.first[:actual]).to eq(0.0)
31
+ end
32
+
33
+ it 'respects MAX_CALIBRATION_POINTS limit' do
34
+ Legion::Extensions::Agentic::Self::MetacognitiveMonitoring::Helpers::MAX_CALIBRATION_POINTS.times do
35
+ tracker.add_point(predicted: 0.5, actual: 0.5)
36
+ end
37
+ tracker.add_point(predicted: 0.9, actual: 0.9)
38
+ expect(tracker.count).to eq(Legion::Extensions::Agentic::Self::MetacognitiveMonitoring::Helpers::MAX_CALIBRATION_POINTS)
39
+ end
40
+ end
41
+
42
+ describe '#mean_calibration_error' do
43
+ it 'returns 0.0 when no points' do
44
+ expect(tracker.mean_calibration_error).to eq(0.0)
45
+ end
46
+
47
+ it 'computes mean of (predicted - actual)' do
48
+ tracker.add_point(predicted: 0.8, actual: 0.6)
49
+ tracker.add_point(predicted: 0.6, actual: 0.6)
50
+ expect(tracker.mean_calibration_error).to eq(0.1)
51
+ end
52
+
53
+ it 'returns negative for underconfidence' do
54
+ tracker.add_point(predicted: 0.3, actual: 0.8)
55
+ expect(tracker.mean_calibration_error).to be < 0
56
+ end
57
+ end
58
+
59
+ describe '#calibration_score' do
60
+ it 'returns 1.0 for perfect calibration' do
61
+ tracker.add_point(predicted: 0.7, actual: 0.7)
62
+ expect(tracker.calibration_score).to eq(1.0)
63
+ end
64
+
65
+ it 'decreases with larger error' do
66
+ tracker.add_point(predicted: 0.9, actual: 0.1)
67
+ expect(tracker.calibration_score).to be < 0.5
68
+ end
69
+
70
+ it 'never goes below 0.0' do
71
+ tracker.add_point(predicted: 1.0, actual: 0.0)
72
+ expect(tracker.calibration_score).to be >= 0.0
73
+ end
74
+ end
75
+
76
+ describe '#overconfident?' do
77
+ it 'returns true when mean error > OVERCONFIDENCE_THRESHOLD' do
78
+ tracker.add_point(predicted: 0.9, actual: 0.4)
79
+ expect(tracker.overconfident?).to be true
80
+ end
81
+
82
+ it 'returns false when well calibrated' do
83
+ tracker.add_point(predicted: 0.7, actual: 0.65)
84
+ expect(tracker.overconfident?).to be false
85
+ end
86
+ end
87
+
88
+ describe '#underconfident?' do
89
+ it 'returns true when mean error < UNDERCONFIDENCE_THRESHOLD' do
90
+ tracker.add_point(predicted: 0.2, actual: 0.9)
91
+ expect(tracker.underconfident?).to be true
92
+ end
93
+
94
+ it 'returns false when well calibrated' do
95
+ tracker.add_point(predicted: 0.7, actual: 0.65)
96
+ expect(tracker.underconfident?).to be false
97
+ end
98
+ end
99
+
100
+ describe '#calibration_label' do
101
+ it 'returns :well_calibrated for high score' do
102
+ tracker.add_point(predicted: 0.7, actual: 0.7)
103
+ expect(tracker.calibration_label).to eq(:well_calibrated)
104
+ end
105
+
106
+ it 'returns a symbol label' do
107
+ tracker.add_point(predicted: 0.8, actual: 0.1)
108
+ expect(tracker.calibration_label).to be_a(Symbol)
109
+ end
110
+ end
111
+
112
+ describe '#calibration_curve' do
113
+ before do
114
+ 10.times { |i| tracker.add_point(predicted: i * 0.1, actual: i * 0.1) }
115
+ end
116
+
117
+ it 'returns an array of bin hashes' do
118
+ curve = tracker.calibration_curve(bins: 5)
119
+ expect(curve).to be_an(Array)
120
+ expect(curve.size).to eq(5)
121
+ end
122
+
123
+ it 'each bin has required keys' do
124
+ curve = tracker.calibration_curve(bins: 5)
125
+ curve.each do |bin|
126
+ expect(bin).to include(:predicted_range, :sample_count, :actual_accuracy)
127
+ end
128
+ end
129
+
130
+ it 'returns empty array when no points' do
131
+ empty = described_class.new
132
+ expect(empty.calibration_curve).to be_empty
133
+ end
134
+ end
135
+
136
+ describe '#to_h' do
137
+ it 'includes all summary keys' do
138
+ h = tracker.to_h
139
+ expect(h).to include(:count, :mean_calibration_error, :calibration_score, :calibration_label,
140
+ :overconfident, :underconfident)
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Self::MetacognitiveMonitoring::Helpers do
4
+ describe 'JUDGMENT_TYPES' do
5
+ subject(:types) { described_class::JUDGMENT_TYPES }
6
+
7
+ it 'includes feeling_of_knowing' do
8
+ expect(types).to include(:feeling_of_knowing)
9
+ end
10
+
11
+ it 'includes judgment_of_learning' do
12
+ expect(types).to include(:judgment_of_learning)
13
+ end
14
+
15
+ it 'includes confidence_rating' do
16
+ expect(types).to include(:confidence_rating)
17
+ end
18
+
19
+ it 'includes effort_estimate' do
20
+ expect(types).to include(:effort_estimate)
21
+ end
22
+
23
+ it 'includes error_detection' do
24
+ expect(types).to include(:error_detection)
25
+ end
26
+
27
+ it 'is frozen' do
28
+ expect(types).to be_frozen
29
+ end
30
+ end
31
+
32
+ describe 'CALIBRATION_LABELS' do
33
+ subject(:labels) { described_class::CALIBRATION_LABELS }
34
+
35
+ it 'maps high score to :well_calibrated' do
36
+ label = labels.find { |range, _| range.cover? 0.9 }&.last
37
+ expect(label).to eq(:well_calibrated)
38
+ end
39
+
40
+ it 'maps low score to :uncalibrated' do
41
+ label = labels.find { |range, _| range.cover? 0.1 }&.last
42
+ expect(label).to eq(:uncalibrated)
43
+ end
44
+ end
45
+
46
+ describe 'CONFIDENCE_LABELS' do
47
+ subject(:labels) { described_class::CONFIDENCE_LABELS }
48
+
49
+ it 'maps 0.9 to :very_high' do
50
+ label = labels.find { |range, _| range.cover? 0.9 }&.last
51
+ expect(label).to eq(:very_high)
52
+ end
53
+
54
+ it 'maps 0.1 to :very_low' do
55
+ label = labels.find { |range, _| range.cover? 0.1 }&.last
56
+ expect(label).to eq(:very_low)
57
+ end
58
+ end
59
+
60
+ describe 'EFFORT_LABELS' do
61
+ subject(:labels) { described_class::EFFORT_LABELS }
62
+
63
+ it 'maps 0.9 to :extreme' do
64
+ label = labels.find { |range, _| range.cover? 0.9 }&.last
65
+ expect(label).to eq(:extreme)
66
+ end
67
+
68
+ it 'maps 0.1 to :minimal' do
69
+ label = labels.find { |range, _| range.cover? 0.1 }&.last
70
+ expect(label).to eq(:minimal)
71
+ end
72
+ end
73
+
74
+ describe 'thresholds' do
75
+ it 'OVERCONFIDENCE_THRESHOLD is 0.2' do
76
+ expect(described_class::OVERCONFIDENCE_THRESHOLD).to eq(0.2)
77
+ end
78
+
79
+ it 'UNDERCONFIDENCE_THRESHOLD is -0.2' do
80
+ expect(described_class::UNDERCONFIDENCE_THRESHOLD).to eq(-0.2)
81
+ end
82
+
83
+ it 'DEFAULT_CONFIDENCE is 0.5' do
84
+ expect(described_class::DEFAULT_CONFIDENCE).to eq(0.5)
85
+ end
86
+
87
+ it 'CALIBRATION_WINDOW is 50' do
88
+ expect(described_class::CALIBRATION_WINDOW).to eq(50)
89
+ end
90
+ end
91
+ end