lex-agentic-learning 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 (192) 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-learning.gemspec +30 -0
  7. data/lib/legion/extensions/agentic/learning/anchoring/client.rb +26 -0
  8. data/lib/legion/extensions/agentic/learning/anchoring/helpers/anchor.rb +65 -0
  9. data/lib/legion/extensions/agentic/learning/anchoring/helpers/anchor_store.rb +132 -0
  10. data/lib/legion/extensions/agentic/learning/anchoring/helpers/constants.rb +31 -0
  11. data/lib/legion/extensions/agentic/learning/anchoring/runners/anchoring.rb +100 -0
  12. data/lib/legion/extensions/agentic/learning/anchoring/version.rb +13 -0
  13. data/lib/legion/extensions/agentic/learning/anchoring.rb +19 -0
  14. data/lib/legion/extensions/agentic/learning/catalyst/client.rb +15 -0
  15. data/lib/legion/extensions/agentic/learning/catalyst/helpers/catalyst.rb +87 -0
  16. data/lib/legion/extensions/agentic/learning/catalyst/helpers/catalyst_engine.rb +153 -0
  17. data/lib/legion/extensions/agentic/learning/catalyst/helpers/constants.rb +55 -0
  18. data/lib/legion/extensions/agentic/learning/catalyst/helpers/reaction.rb +87 -0
  19. data/lib/legion/extensions/agentic/learning/catalyst/runners/cognitive_catalyst.rb +103 -0
  20. data/lib/legion/extensions/agentic/learning/catalyst/version.rb +13 -0
  21. data/lib/legion/extensions/agentic/learning/catalyst.rb +22 -0
  22. data/lib/legion/extensions/agentic/learning/chrysalis/client.rb +22 -0
  23. data/lib/legion/extensions/agentic/learning/chrysalis/helpers/chrysalis.rb +137 -0
  24. data/lib/legion/extensions/agentic/learning/chrysalis/helpers/cocoon.rb +89 -0
  25. data/lib/legion/extensions/agentic/learning/chrysalis/helpers/constants.rb +49 -0
  26. data/lib/legion/extensions/agentic/learning/chrysalis/helpers/metamorphosis_engine.rb +157 -0
  27. data/lib/legion/extensions/agentic/learning/chrysalis/runners/cognitive_chrysalis.rb +129 -0
  28. data/lib/legion/extensions/agentic/learning/chrysalis/version.rb +13 -0
  29. data/lib/legion/extensions/agentic/learning/chrysalis.rb +21 -0
  30. data/lib/legion/extensions/agentic/learning/curiosity/client.rb +28 -0
  31. data/lib/legion/extensions/agentic/learning/curiosity/helpers/constants.rb +30 -0
  32. data/lib/legion/extensions/agentic/learning/curiosity/helpers/gap_detector.rb +167 -0
  33. data/lib/legion/extensions/agentic/learning/curiosity/helpers/wonder.rb +73 -0
  34. data/lib/legion/extensions/agentic/learning/curiosity/helpers/wonder_store.rb +149 -0
  35. data/lib/legion/extensions/agentic/learning/curiosity/runners/curiosity.rb +163 -0
  36. data/lib/legion/extensions/agentic/learning/curiosity/version.rb +13 -0
  37. data/lib/legion/extensions/agentic/learning/curiosity.rb +21 -0
  38. data/lib/legion/extensions/agentic/learning/epistemic_curiosity/client.rb +28 -0
  39. data/lib/legion/extensions/agentic/learning/epistemic_curiosity/helpers/constants.rb +31 -0
  40. data/lib/legion/extensions/agentic/learning/epistemic_curiosity/helpers/curiosity_engine.rb +122 -0
  41. data/lib/legion/extensions/agentic/learning/epistemic_curiosity/helpers/knowledge_gap.rb +70 -0
  42. data/lib/legion/extensions/agentic/learning/epistemic_curiosity/runners/epistemic_curiosity.rb +106 -0
  43. data/lib/legion/extensions/agentic/learning/epistemic_curiosity/version.rb +13 -0
  44. data/lib/legion/extensions/agentic/learning/epistemic_curiosity.rb +19 -0
  45. data/lib/legion/extensions/agentic/learning/fermentation/client.rb +19 -0
  46. data/lib/legion/extensions/agentic/learning/fermentation/helpers/batch.rb +75 -0
  47. data/lib/legion/extensions/agentic/learning/fermentation/helpers/constants.rb +78 -0
  48. data/lib/legion/extensions/agentic/learning/fermentation/helpers/fermentation_engine.rb +147 -0
  49. data/lib/legion/extensions/agentic/learning/fermentation/helpers/substrate.rb +108 -0
  50. data/lib/legion/extensions/agentic/learning/fermentation/runners/cognitive_fermentation.rb +60 -0
  51. data/lib/legion/extensions/agentic/learning/fermentation/version.rb +13 -0
  52. data/lib/legion/extensions/agentic/learning/fermentation.rb +22 -0
  53. data/lib/legion/extensions/agentic/learning/habit/client.rb +26 -0
  54. data/lib/legion/extensions/agentic/learning/habit/helpers/action_sequence.rb +120 -0
  55. data/lib/legion/extensions/agentic/learning/habit/helpers/constants.rb +44 -0
  56. data/lib/legion/extensions/agentic/learning/habit/helpers/habit_store.rb +148 -0
  57. data/lib/legion/extensions/agentic/learning/habit/runners/habit.rb +86 -0
  58. data/lib/legion/extensions/agentic/learning/habit/version.rb +13 -0
  59. data/lib/legion/extensions/agentic/learning/habit.rb +19 -0
  60. data/lib/legion/extensions/agentic/learning/hebbian/actors/decay.rb +45 -0
  61. data/lib/legion/extensions/agentic/learning/hebbian/client.rb +29 -0
  62. data/lib/legion/extensions/agentic/learning/hebbian/helpers/assembly.rb +82 -0
  63. data/lib/legion/extensions/agentic/learning/hebbian/helpers/assembly_network.rb +190 -0
  64. data/lib/legion/extensions/agentic/learning/hebbian/helpers/constants.rb +50 -0
  65. data/lib/legion/extensions/agentic/learning/hebbian/helpers/unit.rb +94 -0
  66. data/lib/legion/extensions/agentic/learning/hebbian/runners/hebbian_assembly.rb +94 -0
  67. data/lib/legion/extensions/agentic/learning/hebbian/version.rb +13 -0
  68. data/lib/legion/extensions/agentic/learning/hebbian.rb +20 -0
  69. data/lib/legion/extensions/agentic/learning/learning_rate/client.rb +25 -0
  70. data/lib/legion/extensions/agentic/learning/learning_rate/helpers/constants.rb +35 -0
  71. data/lib/legion/extensions/agentic/learning/learning_rate/helpers/rate_model.rb +133 -0
  72. data/lib/legion/extensions/agentic/learning/learning_rate/runners/learning_rate.rb +85 -0
  73. data/lib/legion/extensions/agentic/learning/learning_rate/version.rb +13 -0
  74. data/lib/legion/extensions/agentic/learning/learning_rate.rb +18 -0
  75. data/lib/legion/extensions/agentic/learning/meta_learning/client.rb +27 -0
  76. data/lib/legion/extensions/agentic/learning/meta_learning/helpers/constants.rb +46 -0
  77. data/lib/legion/extensions/agentic/learning/meta_learning/helpers/learning_domain.rb +85 -0
  78. data/lib/legion/extensions/agentic/learning/meta_learning/helpers/meta_learning_engine.rb +202 -0
  79. data/lib/legion/extensions/agentic/learning/meta_learning/helpers/strategy.rb +62 -0
  80. data/lib/legion/extensions/agentic/learning/meta_learning/runners/meta_learning.rb +118 -0
  81. data/lib/legion/extensions/agentic/learning/meta_learning/version.rb +13 -0
  82. data/lib/legion/extensions/agentic/learning/meta_learning.rb +20 -0
  83. data/lib/legion/extensions/agentic/learning/plasticity/client.rb +15 -0
  84. data/lib/legion/extensions/agentic/learning/plasticity/helpers/constants.rb +45 -0
  85. data/lib/legion/extensions/agentic/learning/plasticity/helpers/neural_pathway.rb +85 -0
  86. data/lib/legion/extensions/agentic/learning/plasticity/helpers/plasticity_engine.rb +130 -0
  87. data/lib/legion/extensions/agentic/learning/plasticity/runners/cognitive_plasticity.rb +85 -0
  88. data/lib/legion/extensions/agentic/learning/plasticity/version.rb +13 -0
  89. data/lib/legion/extensions/agentic/learning/plasticity.rb +19 -0
  90. data/lib/legion/extensions/agentic/learning/preference_learning/actors/decay.rb +45 -0
  91. data/lib/legion/extensions/agentic/learning/preference_learning/client.rb +28 -0
  92. data/lib/legion/extensions/agentic/learning/preference_learning/helpers/constants.rb +35 -0
  93. data/lib/legion/extensions/agentic/learning/preference_learning/helpers/option.rb +78 -0
  94. data/lib/legion/extensions/agentic/learning/preference_learning/helpers/preference_engine.rb +121 -0
  95. data/lib/legion/extensions/agentic/learning/preference_learning/runners/preference_learning.rb +84 -0
  96. data/lib/legion/extensions/agentic/learning/preference_learning/version.rb +13 -0
  97. data/lib/legion/extensions/agentic/learning/preference_learning.rb +19 -0
  98. data/lib/legion/extensions/agentic/learning/procedural/client.rb +19 -0
  99. data/lib/legion/extensions/agentic/learning/procedural/helpers/constants.rb +46 -0
  100. data/lib/legion/extensions/agentic/learning/procedural/helpers/learning_engine.rb +160 -0
  101. data/lib/legion/extensions/agentic/learning/procedural/helpers/production.rb +66 -0
  102. data/lib/legion/extensions/agentic/learning/procedural/helpers/skill.rb +101 -0
  103. data/lib/legion/extensions/agentic/learning/procedural/runners/procedural_learning.rb +96 -0
  104. data/lib/legion/extensions/agentic/learning/procedural/version.rb +13 -0
  105. data/lib/legion/extensions/agentic/learning/procedural.rb +20 -0
  106. data/lib/legion/extensions/agentic/learning/scaffolding/client.rb +26 -0
  107. data/lib/legion/extensions/agentic/learning/scaffolding/helpers/constants.rb +42 -0
  108. data/lib/legion/extensions/agentic/learning/scaffolding/helpers/scaffold.rb +136 -0
  109. data/lib/legion/extensions/agentic/learning/scaffolding/helpers/scaffolding_engine.rb +112 -0
  110. data/lib/legion/extensions/agentic/learning/scaffolding/runners/cognitive_scaffolding.rb +107 -0
  111. data/lib/legion/extensions/agentic/learning/scaffolding/version.rb +13 -0
  112. data/lib/legion/extensions/agentic/learning/scaffolding.rb +19 -0
  113. data/lib/legion/extensions/agentic/learning/version.rb +11 -0
  114. data/lib/legion/extensions/agentic/learning.rb +31 -0
  115. data/spec/legion/extensions/agentic/learning/anchoring/client_spec.rb +32 -0
  116. data/spec/legion/extensions/agentic/learning/anchoring/helpers/anchor_spec.rb +130 -0
  117. data/spec/legion/extensions/agentic/learning/anchoring/helpers/anchor_store_spec.rb +201 -0
  118. data/spec/legion/extensions/agentic/learning/anchoring/helpers/constants_spec.rb +63 -0
  119. data/spec/legion/extensions/agentic/learning/anchoring/runners/anchoring_spec.rb +199 -0
  120. data/spec/legion/extensions/agentic/learning/catalyst/client_spec.rb +58 -0
  121. data/spec/legion/extensions/agentic/learning/catalyst/cognitive_catalyst_spec.rb +49 -0
  122. data/spec/legion/extensions/agentic/learning/catalyst/helpers/catalyst_engine_spec.rb +263 -0
  123. data/spec/legion/extensions/agentic/learning/catalyst/helpers/catalyst_spec.rb +214 -0
  124. data/spec/legion/extensions/agentic/learning/catalyst/helpers/reaction_spec.rb +223 -0
  125. data/spec/legion/extensions/agentic/learning/catalyst/runners/cognitive_catalyst_spec.rb +217 -0
  126. data/spec/legion/extensions/agentic/learning/chrysalis/client_spec.rb +83 -0
  127. data/spec/legion/extensions/agentic/learning/chrysalis/cognitive_chrysalis_spec.rb +15 -0
  128. data/spec/legion/extensions/agentic/learning/chrysalis/helpers/chrysalis_engine_spec.rb +57 -0
  129. data/spec/legion/extensions/agentic/learning/chrysalis/helpers/chrysalis_spec.rb +305 -0
  130. data/spec/legion/extensions/agentic/learning/chrysalis/helpers/cocoon_spec.rb +206 -0
  131. data/spec/legion/extensions/agentic/learning/chrysalis/helpers/constants_spec.rb +109 -0
  132. data/spec/legion/extensions/agentic/learning/chrysalis/helpers/metamorphic_cycle_spec.rb +76 -0
  133. data/spec/legion/extensions/agentic/learning/chrysalis/helpers/metamorphosis_engine_spec.rb +247 -0
  134. data/spec/legion/extensions/agentic/learning/chrysalis/helpers/transformation_phase_spec.rb +98 -0
  135. data/spec/legion/extensions/agentic/learning/chrysalis/runners/cognitive_chrysalis_spec.rb +180 -0
  136. data/spec/legion/extensions/agentic/learning/chrysalis/runners/reporting_spec.rb +81 -0
  137. data/spec/legion/extensions/agentic/learning/chrysalis/runners/transformation_spec.rb +74 -0
  138. data/spec/legion/extensions/agentic/learning/curiosity/client_spec.rb +27 -0
  139. data/spec/legion/extensions/agentic/learning/curiosity/helpers/gap_detector_spec.rb +118 -0
  140. data/spec/legion/extensions/agentic/learning/curiosity/helpers/wonder_spec.rb +130 -0
  141. data/spec/legion/extensions/agentic/learning/curiosity/helpers/wonder_store_spec.rb +136 -0
  142. data/spec/legion/extensions/agentic/learning/curiosity/runners/curiosity_spec.rb +159 -0
  143. data/spec/legion/extensions/agentic/learning/epistemic_curiosity/client_spec.rb +47 -0
  144. data/spec/legion/extensions/agentic/learning/epistemic_curiosity/helpers/constants_spec.rb +45 -0
  145. data/spec/legion/extensions/agentic/learning/epistemic_curiosity/helpers/curiosity_engine_spec.rb +229 -0
  146. data/spec/legion/extensions/agentic/learning/epistemic_curiosity/helpers/knowledge_gap_spec.rb +188 -0
  147. data/spec/legion/extensions/agentic/learning/epistemic_curiosity/runners/epistemic_curiosity_spec.rb +175 -0
  148. data/spec/legion/extensions/agentic/learning/fermentation/client_spec.rb +36 -0
  149. data/spec/legion/extensions/agentic/learning/fermentation/helpers/batch_spec.rb +72 -0
  150. data/spec/legion/extensions/agentic/learning/fermentation/helpers/fermentation_engine_spec.rb +138 -0
  151. data/spec/legion/extensions/agentic/learning/fermentation/helpers/substrate_spec.rb +146 -0
  152. data/spec/legion/extensions/agentic/learning/habit/client_spec.rb +50 -0
  153. data/spec/legion/extensions/agentic/learning/habit/helpers/action_sequence_spec.rb +276 -0
  154. data/spec/legion/extensions/agentic/learning/habit/helpers/constants_spec.rb +115 -0
  155. data/spec/legion/extensions/agentic/learning/habit/helpers/habit_store_spec.rb +274 -0
  156. data/spec/legion/extensions/agentic/learning/habit/runners/habit_spec.rb +228 -0
  157. data/spec/legion/extensions/agentic/learning/hebbian/client_spec.rb +38 -0
  158. data/spec/legion/extensions/agentic/learning/hebbian/helpers/assembly_network_spec.rb +142 -0
  159. data/spec/legion/extensions/agentic/learning/hebbian/helpers/assembly_spec.rb +89 -0
  160. data/spec/legion/extensions/agentic/learning/hebbian/helpers/unit_spec.rb +119 -0
  161. data/spec/legion/extensions/agentic/learning/hebbian/runners/hebbian_assembly_spec.rb +109 -0
  162. data/spec/legion/extensions/agentic/learning/learning_rate/client_spec.rb +51 -0
  163. data/spec/legion/extensions/agentic/learning/learning_rate/helpers/constants_spec.rb +29 -0
  164. data/spec/legion/extensions/agentic/learning/learning_rate/helpers/rate_model_spec.rb +151 -0
  165. data/spec/legion/extensions/agentic/learning/learning_rate/runners/learning_rate_spec.rb +92 -0
  166. data/spec/legion/extensions/agentic/learning/meta_learning/client_spec.rb +27 -0
  167. data/spec/legion/extensions/agentic/learning/meta_learning/helpers/constants_spec.rb +43 -0
  168. data/spec/legion/extensions/agentic/learning/meta_learning/helpers/learning_domain_spec.rb +146 -0
  169. data/spec/legion/extensions/agentic/learning/meta_learning/helpers/meta_learning_engine_spec.rb +309 -0
  170. data/spec/legion/extensions/agentic/learning/meta_learning/helpers/strategy_spec.rb +82 -0
  171. data/spec/legion/extensions/agentic/learning/meta_learning/runners/meta_learning_spec.rb +185 -0
  172. data/spec/legion/extensions/agentic/learning/plasticity/helpers/constants_spec.rb +54 -0
  173. data/spec/legion/extensions/agentic/learning/plasticity/helpers/neural_pathway_spec.rb +136 -0
  174. data/spec/legion/extensions/agentic/learning/plasticity/helpers/plasticity_engine_spec.rb +157 -0
  175. data/spec/legion/extensions/agentic/learning/plasticity/runners/cognitive_plasticity_spec.rb +83 -0
  176. data/spec/legion/extensions/agentic/learning/preference_learning/client_spec.rb +17 -0
  177. data/spec/legion/extensions/agentic/learning/preference_learning/helpers/constants_spec.rb +67 -0
  178. data/spec/legion/extensions/agentic/learning/preference_learning/helpers/option_spec.rb +104 -0
  179. data/spec/legion/extensions/agentic/learning/preference_learning/helpers/preference_engine_spec.rb +151 -0
  180. data/spec/legion/extensions/agentic/learning/preference_learning/runners/preference_learning_spec.rb +86 -0
  181. data/spec/legion/extensions/agentic/learning/procedural/client_spec.rb +22 -0
  182. data/spec/legion/extensions/agentic/learning/procedural/helpers/learning_engine_spec.rb +135 -0
  183. data/spec/legion/extensions/agentic/learning/procedural/helpers/production_spec.rb +66 -0
  184. data/spec/legion/extensions/agentic/learning/procedural/helpers/skill_spec.rb +102 -0
  185. data/spec/legion/extensions/agentic/learning/procedural/runners/procedural_learning_spec.rb +94 -0
  186. data/spec/legion/extensions/agentic/learning/scaffolding/client_spec.rb +20 -0
  187. data/spec/legion/extensions/agentic/learning/scaffolding/helpers/constants_spec.rb +36 -0
  188. data/spec/legion/extensions/agentic/learning/scaffolding/helpers/scaffold_spec.rb +187 -0
  189. data/spec/legion/extensions/agentic/learning/scaffolding/helpers/scaffolding_engine_spec.rb +159 -0
  190. data/spec/legion/extensions/agentic/learning/scaffolding/runners/cognitive_scaffolding_spec.rb +163 -0
  191. data/spec/spec_helper.rb +46 -0
  192. metadata +277 -0
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Learning
7
+ module EpistemicCuriosity
8
+ module Runners
9
+ module EpistemicCuriosity
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex)
12
+
13
+ def create_gap(question:, domain:, gap_type: :factual, urgency: Helpers::Constants::DEFAULT_URGENCY, **)
14
+ result = engine.create_gap(question: question, domain: domain, gap_type: gap_type, urgency: urgency)
15
+ if result[:created]
16
+ Legion::Logging.info "[epistemic_curiosity] gap created: id=#{result[:gap][:id]} domain=#{domain} type=#{gap_type}"
17
+ else
18
+ Legion::Logging.debug "[epistemic_curiosity] gap not created: reason=#{result[:reason]}"
19
+ end
20
+ result
21
+ end
22
+
23
+ def explore_gap(gap_id:, **)
24
+ result = engine.explore_gap(gap_id: gap_id)
25
+ if result[:found]
26
+ gap = result[:gap]
27
+ Legion::Logging.debug "[epistemic_curiosity] explore: id=#{gap_id} explorations=#{gap[:explorations]} urgency=#{gap[:urgency]}"
28
+ else
29
+ Legion::Logging.debug "[epistemic_curiosity] explore: id=#{gap_id} not found"
30
+ end
31
+ result
32
+ end
33
+
34
+ def satisfy_gap(gap_id:, amount: 0.3, **)
35
+ result = engine.satisfy_gap(gap_id: gap_id, amount: amount)
36
+ if result[:found]
37
+ gap = result[:gap]
38
+ Legion::Logging.debug "[epistemic_curiosity] satisfy: id=#{gap_id} satisfaction=#{gap[:satisfaction]} resolved=#{gap[:resolved]}"
39
+ else
40
+ Legion::Logging.debug "[epistemic_curiosity] satisfy: id=#{gap_id} not found"
41
+ end
42
+ result
43
+ end
44
+
45
+ def resolve_gap(gap_id:, **)
46
+ result = engine.resolve_gap(gap_id: gap_id)
47
+ if result[:found]
48
+ Legion::Logging.info "[epistemic_curiosity] resolved: id=#{gap_id}"
49
+ else
50
+ Legion::Logging.debug "[epistemic_curiosity] resolve: id=#{gap_id} not found"
51
+ end
52
+ result
53
+ end
54
+
55
+ def most_urgent_gaps(limit: 5, **)
56
+ gaps = engine.most_urgent(limit: limit)
57
+ Legion::Logging.debug "[epistemic_curiosity] most_urgent: limit=#{limit} returned=#{gaps.size}"
58
+ { gaps: gaps.map(&:to_h), count: gaps.size }
59
+ end
60
+
61
+ def gaps_by_domain(domain:, **)
62
+ gaps = engine.by_domain(domain)
63
+ Legion::Logging.debug "[epistemic_curiosity] by_domain: domain=#{domain} count=#{gaps.size}"
64
+ { gaps: gaps.map(&:to_h), count: gaps.size, domain: domain }
65
+ end
66
+
67
+ def gaps_by_type(gap_type:, **)
68
+ gaps = engine.by_type(gap_type)
69
+ Legion::Logging.debug "[epistemic_curiosity] by_type: gap_type=#{gap_type} count=#{gaps.size}"
70
+ { gaps: gaps.map(&:to_h), count: gaps.size, gap_type: gap_type }
71
+ end
72
+
73
+ def decay_gaps(**)
74
+ count = engine.decay_all
75
+ Legion::Logging.debug "[epistemic_curiosity] decay cycle: gaps_updated=#{count}"
76
+ { decayed: count }
77
+ end
78
+
79
+ def curiosity_report(**)
80
+ report = engine.curiosity_report
81
+ Legion::Logging.debug "[epistemic_curiosity] report: open=#{report[:open_gaps]} debt=#{report[:information_debt]}"
82
+ report
83
+ end
84
+
85
+ def curiosity_status(**)
86
+ {
87
+ total_gaps: engine.open_gaps.size + engine.resolved_gaps.size,
88
+ open_gaps: engine.open_gaps.size,
89
+ resolved_gaps: engine.resolved_gaps.size,
90
+ information_debt: engine.information_debt,
91
+ exploration_efficiency: engine.exploration_efficiency
92
+ }
93
+ end
94
+
95
+ private
96
+
97
+ def engine
98
+ @engine ||= Helpers::CuriosityEngine.new
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Learning
7
+ module EpistemicCuriosity
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 'legion/extensions/agentic/learning/epistemic_curiosity/version'
4
+ require 'legion/extensions/agentic/learning/epistemic_curiosity/helpers/constants'
5
+ require 'legion/extensions/agentic/learning/epistemic_curiosity/helpers/knowledge_gap'
6
+ require 'legion/extensions/agentic/learning/epistemic_curiosity/helpers/curiosity_engine'
7
+ require 'legion/extensions/agentic/learning/epistemic_curiosity/runners/epistemic_curiosity'
8
+ require 'legion/extensions/agentic/learning/epistemic_curiosity/client'
9
+
10
+ module Legion
11
+ module Extensions
12
+ module Agentic
13
+ module Learning
14
+ module EpistemicCuriosity
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Learning
7
+ module Fermentation
8
+ class Client
9
+ include Runners::CognitiveFermentation
10
+
11
+ def initialize
12
+ @default_engine = Helpers::FermentationEngine.new
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Learning
7
+ module Fermentation
8
+ module Helpers
9
+ class Batch
10
+ include Constants
11
+
12
+ attr_reader :id, :domain, :substrates, :created_at
13
+
14
+ def initialize(domain:)
15
+ @id = SecureRandom.uuid
16
+ @domain = domain.to_sym
17
+ @substrates = []
18
+ @created_at = Time.now.utc
19
+ end
20
+
21
+ def add_substrate(substrate)
22
+ @substrates << substrate
23
+ substrate
24
+ end
25
+
26
+ def ferment_all!(rate = MATURATION_RATE)
27
+ @substrates.each { |s| s.ferment!(rate) }
28
+ end
29
+
30
+ def average_potency
31
+ return 0.0 if @substrates.empty?
32
+
33
+ (@substrates.sum(&:potency) / @substrates.size).round(10)
34
+ end
35
+
36
+ def average_maturity
37
+ return 0.0 if @substrates.empty?
38
+
39
+ (@substrates.sum(&:maturity) / @substrates.size).round(10)
40
+ end
41
+
42
+ def ripe_count = @substrates.count(&:ripe?)
43
+ def peak_count = @substrates.count(&:peak?)
44
+ def spoiled_count = @substrates.count(&:spoiled?)
45
+ def raw_count = @substrates.count(&:raw?)
46
+
47
+ def yield_rate
48
+ return 0.0 if @substrates.empty?
49
+
50
+ (ripe_count.to_f / @substrates.size).round(10)
51
+ end
52
+
53
+ def ready_to_harvest? = yield_rate >= 0.5
54
+
55
+ def to_h
56
+ {
57
+ id: @id,
58
+ domain: @domain,
59
+ substrate_count: @substrates.size,
60
+ average_potency: average_potency,
61
+ average_maturity: average_maturity,
62
+ ripe_count: ripe_count,
63
+ peak_count: peak_count,
64
+ spoiled_count: spoiled_count,
65
+ yield_rate: yield_rate,
66
+ ready_to_harvest: ready_to_harvest?
67
+ }
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Learning
7
+ module Fermentation
8
+ module Helpers
9
+ module Constants
10
+ MAX_SUBSTRATES = 500
11
+ MAX_BATCHES = 50
12
+
13
+ DEFAULT_POTENCY = 0.3
14
+ MATURATION_RATE = 0.05
15
+ VOLATILITY_DECAY = 0.02
16
+ CATALYSIS_BOOST = 0.12
17
+ SPOILAGE_THRESHOLD = 0.1
18
+ RIPE_THRESHOLD = 0.7
19
+ PEAK_THRESHOLD = 0.9
20
+ OVER_FERMENTED_DECAY = 0.03
21
+
22
+ SUBSTRATE_TYPES = %i[
23
+ raw_idea unresolved_problem partial_pattern
24
+ dormant_association vague_intuition half_formed_belief
25
+ contradictory_evidence lingering_question
26
+ ].freeze
27
+
28
+ FERMENTATION_STAGES = %i[
29
+ inoculation primary_fermentation secondary_fermentation
30
+ conditioning maturation aging peak over_fermented
31
+ ].freeze
32
+
33
+ CATALYST_TYPES = %i[
34
+ analogy contrast juxtaposition
35
+ emotional_charge sleep dream_residue
36
+ environmental_stimulus social_interaction
37
+ ].freeze
38
+
39
+ DOMAINS = %i[
40
+ cognitive emotional procedural semantic
41
+ episodic social creative analytical
42
+ ].freeze
43
+
44
+ POTENCY_LABELS = {
45
+ (0.8..) => :transcendent,
46
+ (0.6...0.8) => :potent,
47
+ (0.4...0.6) => :developing,
48
+ (0.2...0.4) => :mild,
49
+ (..0.2) => :inert
50
+ }.freeze
51
+
52
+ MATURITY_LABELS = {
53
+ (0.8..) => :peak,
54
+ (0.6...0.8) => :mature,
55
+ (0.4...0.6) => :developing,
56
+ (0.2...0.4) => :young,
57
+ (..0.2) => :raw
58
+ }.freeze
59
+
60
+ VOLATILITY_LABELS = {
61
+ (0.8..) => :explosive,
62
+ (0.6...0.8) => :volatile,
63
+ (0.4...0.6) => :active,
64
+ (0.2...0.4) => :stable,
65
+ (..0.2) => :dormant
66
+ }.freeze
67
+
68
+ def self.label_for(labels, value)
69
+ labels.each { |range, label| return label if range.cover?(value) }
70
+ :unknown
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Learning
7
+ module Fermentation
8
+ module Helpers
9
+ class FermentationEngine
10
+ include Constants
11
+
12
+ def initialize
13
+ @substrates = {}
14
+ @batches = {}
15
+ end
16
+
17
+ def create_substrate(substrate_type:, domain:, content: '', potency: nil, volatility: nil)
18
+ sub = Substrate.new(substrate_type: substrate_type, domain: domain, content: content,
19
+ potency: potency, volatility: volatility)
20
+ @substrates[sub.id] = sub
21
+ batch = find_or_create_batch(domain: domain)
22
+ batch.add_substrate(sub)
23
+ prune_substrates
24
+ sub
25
+ end
26
+
27
+ def ferment(substrate_id:, rate: MATURATION_RATE)
28
+ sub = @substrates[substrate_id]
29
+ return nil unless sub
30
+
31
+ sub.ferment!(rate)
32
+ sub
33
+ end
34
+
35
+ def catalyze(substrate_id:, catalyst_type:)
36
+ sub = @substrates[substrate_id]
37
+ return nil unless sub
38
+
39
+ sub.catalyze!(catalyst_type)
40
+ sub
41
+ end
42
+
43
+ def ferment_all!(rate: MATURATION_RATE)
44
+ @batches.each_value { |b| b.ferment_all!(rate) }
45
+ end
46
+
47
+ def substrates_by_domain(domain:) = @substrates.values.select { |s| s.domain == domain.to_sym }
48
+ def substrates_by_type(type:) = @substrates.values.select { |s| s.substrate_type == type.to_sym }
49
+ def substrates_by_stage(stage:) = @substrates.values.select { |s| s.stage == stage.to_sym }
50
+ def ripe_substrates = @substrates.values.select(&:ripe?)
51
+ def peak_substrates = @substrates.values.select(&:peak?)
52
+ def spoiled_substrates = @substrates.values.select(&:spoiled?)
53
+ def raw_substrates = @substrates.values.select(&:raw?)
54
+
55
+ def most_potent(limit: 5)
56
+ @substrates.values.sort_by { |s| -s.potency }.first(limit)
57
+ end
58
+
59
+ def most_mature(limit: 5)
60
+ @substrates.values.sort_by { |s| -s.maturity }.first(limit)
61
+ end
62
+
63
+ def overall_potency
64
+ return 0.0 if @substrates.empty?
65
+
66
+ (@substrates.values.sum(&:potency) / @substrates.size).round(10)
67
+ end
68
+
69
+ def overall_maturity
70
+ return 0.0 if @substrates.empty?
71
+
72
+ (@substrates.values.sum(&:maturity) / @substrates.size).round(10)
73
+ end
74
+
75
+ def overall_volatility
76
+ return 0.0 if @substrates.empty?
77
+
78
+ (@substrates.values.sum(&:volatility) / @substrates.size).round(10)
79
+ end
80
+
81
+ def yield_rate
82
+ return 0.0 if @substrates.empty?
83
+
84
+ (ripe_substrates.size.to_f / @substrates.size).round(10)
85
+ end
86
+
87
+ def stage_distribution
88
+ dist = Hash.new(0)
89
+ @substrates.each_value { |s| dist[s.stage] += 1 }
90
+ dist
91
+ end
92
+
93
+ def fermentation_report
94
+ {
95
+ total_substrates: @substrates.size,
96
+ total_batches: @batches.size,
97
+ overall_potency: overall_potency,
98
+ potency_label: Constants.label_for(POTENCY_LABELS, overall_potency),
99
+ overall_maturity: overall_maturity,
100
+ maturity_label: Constants.label_for(MATURITY_LABELS, overall_maturity),
101
+ overall_volatility: overall_volatility,
102
+ volatility_label: Constants.label_for(VOLATILITY_LABELS, overall_volatility),
103
+ yield_rate: yield_rate,
104
+ ripe_count: ripe_substrates.size,
105
+ peak_count: peak_substrates.size,
106
+ spoiled_count: spoiled_substrates.size,
107
+ stage_distribution: stage_distribution,
108
+ batches: @batches.values.map(&:to_h),
109
+ most_potent: most_potent(limit: 3).map(&:to_h)
110
+ }
111
+ end
112
+
113
+ def to_h
114
+ {
115
+ total_substrates: @substrates.size,
116
+ total_batches: @batches.size,
117
+ potency: overall_potency,
118
+ maturity: overall_maturity,
119
+ volatility: overall_volatility
120
+ }
121
+ end
122
+
123
+ private
124
+
125
+ def find_or_create_batch(domain:)
126
+ key = domain.to_sym
127
+ @batches[key] ||= Batch.new(domain: key)
128
+ end
129
+
130
+ def prune_substrates
131
+ return if @substrates.size <= MAX_SUBSTRATES
132
+
133
+ spoiled = @substrates.values.select(&:spoiled?)
134
+ spoiled.each { |s| @substrates.delete(s.id) }
135
+ return if @substrates.size <= MAX_SUBSTRATES
136
+
137
+ sorted = @substrates.values.sort_by(&:potency)
138
+ to_remove = sorted.first(@substrates.size - MAX_SUBSTRATES)
139
+ to_remove.each { |s| @substrates.delete(s.id) }
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Learning
7
+ module Fermentation
8
+ module Helpers
9
+ class Substrate
10
+ include Constants
11
+
12
+ attr_reader :id, :substrate_type, :domain, :content, :potency,
13
+ :maturity, :volatility, :stage, :created_at, :catalysts_applied
14
+
15
+ def initialize(substrate_type:, domain:, content: '', potency: nil, volatility: nil)
16
+ @id = SecureRandom.uuid
17
+ @substrate_type = substrate_type.to_sym
18
+ @domain = domain.to_sym
19
+ @content = content
20
+ @potency = (potency || DEFAULT_POTENCY).to_f.clamp(0.0, 1.0)
21
+ @maturity = 0.0
22
+ @volatility = (volatility || 0.5).to_f.clamp(0.0, 1.0)
23
+ @stage = :inoculation
24
+ @catalysts_applied = []
25
+ @created_at = Time.now.utc
26
+ end
27
+
28
+ def ferment!(rate = MATURATION_RATE)
29
+ @maturity = (@maturity + rate).clamp(0.0, 1.0).round(10)
30
+ @volatility = (@volatility - VOLATILITY_DECAY).clamp(0.0, 1.0).round(10)
31
+ advance_stage!
32
+ @potency = compute_potency
33
+ end
34
+
35
+ def catalyze!(catalyst_type)
36
+ @catalysts_applied << catalyst_type.to_sym
37
+ @potency = (@potency + CATALYSIS_BOOST).clamp(0.0, 1.0).round(10)
38
+ @volatility = (@volatility + 0.05).clamp(0.0, 1.0).round(10)
39
+ end
40
+
41
+ def spoil!
42
+ @potency = (@potency * 0.5).round(10)
43
+ @stage = :over_fermented
44
+ end
45
+
46
+ def ripe? = @potency >= RIPE_THRESHOLD && @maturity >= 0.5
47
+ def peak? = @potency >= PEAK_THRESHOLD && @stage == :peak
48
+ def spoiled? = @potency < SPOILAGE_THRESHOLD
49
+ def raw? = @stage == :inoculation
50
+ def aging? = @stage == :aging
51
+ def over_fermented? = @stage == :over_fermented
52
+ def multi_catalyzed? = @catalysts_applied.uniq.size >= 3
53
+
54
+ STAGE_THRESHOLDS = {
55
+ (0.0...0.1) => :inoculation,
56
+ (0.1...0.25) => :primary_fermentation,
57
+ (0.25...0.4) => :secondary_fermentation,
58
+ (0.4...0.55) => :conditioning,
59
+ (0.55...0.7) => :maturation,
60
+ (0.7...0.85) => :aging,
61
+ (0.85...0.95) => :peak,
62
+ (0.95..) => :over_fermented
63
+ }.freeze
64
+
65
+ def age
66
+ ((Time.now.utc - @created_at) / 60.0).round(2)
67
+ end
68
+
69
+ def to_h
70
+ {
71
+ id: @id,
72
+ substrate_type: @substrate_type,
73
+ domain: @domain,
74
+ content: @content,
75
+ potency: @potency.round(10),
76
+ maturity: @maturity.round(10),
77
+ volatility: @volatility.round(10),
78
+ stage: @stage,
79
+ ripe: ripe?,
80
+ peak: peak?,
81
+ spoiled: spoiled?,
82
+ catalysts_applied: @catalysts_applied.uniq,
83
+ age_minutes: age,
84
+ created_at: @created_at.iso8601
85
+ }
86
+ end
87
+
88
+ private
89
+
90
+ def advance_stage!
91
+ @stage = STAGE_THRESHOLDS.each do |range, stage|
92
+ break stage if range.cover?(@maturity)
93
+ end
94
+ end
95
+
96
+ def compute_potency
97
+ base = @potency
98
+ base += 0.02 if @stage == :peak
99
+ base -= OVER_FERMENTED_DECAY if @stage == :over_fermented
100
+ base.clamp(0.0, 1.0).round(10)
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Learning
7
+ module Fermentation
8
+ module Runners
9
+ module CognitiveFermentation
10
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
11
+
12
+ def create_substrate(substrate_type:, domain:, content: '', potency: nil,
13
+ volatility: nil, engine: nil, **)
14
+ eng = engine || @default_engine
15
+ sub = eng.create_substrate(substrate_type: substrate_type, domain: domain,
16
+ content: content, potency: potency, volatility: volatility)
17
+ { success: true, substrate: sub.to_h }
18
+ end
19
+
20
+ def ferment(substrate_id:, rate: nil, engine: nil, **)
21
+ eng = engine || @default_engine
22
+ sub = eng.ferment(substrate_id: substrate_id,
23
+ rate: rate || Helpers::Constants::MATURATION_RATE)
24
+ return { success: false, error: 'substrate not found' } unless sub
25
+
26
+ { success: true, substrate: sub.to_h }
27
+ end
28
+
29
+ def catalyze(substrate_id:, catalyst_type:, engine: nil, **)
30
+ eng = engine || @default_engine
31
+ sub = eng.catalyze(substrate_id: substrate_id, catalyst_type: catalyst_type)
32
+ return { success: false, error: 'substrate not found' } unless sub
33
+
34
+ { success: true, substrate: sub.to_h }
35
+ end
36
+
37
+ def ferment_all(rate: nil, engine: nil, **)
38
+ eng = engine || @default_engine
39
+ eng.ferment_all!(rate: rate || Helpers::Constants::MATURATION_RATE)
40
+ { success: true }
41
+ end
42
+
43
+ def list_ripe(engine: nil, **)
44
+ eng = engine || @default_engine
45
+ ripe = eng.ripe_substrates
46
+ { success: true, count: ripe.size, substrates: ripe.map(&:to_h) }
47
+ end
48
+
49
+ def fermentation_status(engine: nil, **)
50
+ eng = engine || @default_engine
51
+ report = eng.fermentation_report
52
+ { success: true, **report }
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Learning
7
+ module Fermentation
8
+ VERSION = '0.1.0'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ require_relative 'fermentation/version'
6
+ require_relative 'fermentation/helpers/constants'
7
+ require_relative 'fermentation/helpers/substrate'
8
+ require_relative 'fermentation/helpers/batch'
9
+ require_relative 'fermentation/helpers/fermentation_engine'
10
+ require_relative 'fermentation/runners/cognitive_fermentation'
11
+ require_relative 'fermentation/client'
12
+
13
+ module Legion
14
+ module Extensions
15
+ module Agentic
16
+ module Learning
17
+ module Fermentation
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end