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,153 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Learning
7
+ module Catalyst
8
+ module Helpers
9
+ class CatalystEngine
10
+ include Constants
11
+
12
+ def initialize
13
+ @catalysts = {}
14
+ @reactions = {}
15
+ end
16
+
17
+ def create_catalyst(catalyst_type:, domain:, potency: 0.5, specificity: 0.5, **)
18
+ unless CATALYST_TYPES.include?(catalyst_type.to_sym)
19
+ raise ArgumentError,
20
+ "invalid catalyst_type: #{catalyst_type}"
21
+ end
22
+
23
+ evict_oldest_catalyst if @catalysts.size >= MAX_CATALYSTS
24
+ catalyst = Catalyst.new(
25
+ catalyst_type: catalyst_type.to_sym,
26
+ domain: domain,
27
+ potency: potency,
28
+ specificity: specificity
29
+ )
30
+ @catalysts[catalyst.id] = catalyst
31
+ catalyst
32
+ end
33
+
34
+ def create_reaction(reaction_type:, reactants:, activation_energy: ACTIVATION_ENERGY, **)
35
+ unless REACTION_TYPES.include?(reaction_type.to_sym)
36
+ raise ArgumentError,
37
+ "invalid reaction_type: #{reaction_type}"
38
+ end
39
+
40
+ evict_oldest_reaction if @reactions.size >= MAX_REACTIONS
41
+ reaction = Reaction.new(
42
+ reaction_type: reaction_type.to_sym,
43
+ reactants: reactants,
44
+ activation_energy: activation_energy
45
+ )
46
+ @reactions[reaction.id] = reaction
47
+ reaction
48
+ end
49
+
50
+ def apply_catalyst(catalyst_id:, reaction_id:)
51
+ catalyst = @catalysts[catalyst_id]
52
+ reaction = @reactions[reaction_id]
53
+
54
+ return { success: false, reason: :catalyst_not_found } unless catalyst
55
+ return { success: false, reason: :reaction_not_found } unless reaction
56
+ return { success: false, reason: :already_completed } if reaction.complete?
57
+
58
+ reaction.apply_catalyst!(catalyst)
59
+ {
60
+ success: true,
61
+ activation_energy: reaction.activation_energy,
62
+ catalyst_id: catalyst_id,
63
+ reaction_id: reaction_id
64
+ }
65
+ end
66
+
67
+ def attempt_reaction(reaction_id:, energy_input:)
68
+ reaction = @reactions[reaction_id]
69
+ return { success: false, reason: :not_found } unless reaction
70
+ return { success: false, reason: :already_completed } if reaction.complete?
71
+
72
+ completed = reaction.attempt!(energy_input)
73
+ {
74
+ success: true,
75
+ completed: completed,
76
+ yield_value: reaction.yield_value,
77
+ yield_label: reaction.yield_label,
78
+ catalyzed: reaction.catalyzed?,
79
+ activation_energy: reaction.activation_energy
80
+ }
81
+ end
82
+
83
+ def degrade_all!
84
+ @catalysts.each_value(&:degrade!)
85
+ end
86
+
87
+ def recharge_catalyst(catalyst_id:, amount:)
88
+ catalyst = @catalysts[catalyst_id]
89
+ return { success: false, reason: :not_found } unless catalyst
90
+
91
+ catalyst.recharge!(amount)
92
+ { success: true, potency: catalyst.potency, potency_label: catalyst.potency_label }
93
+ end
94
+
95
+ def all_catalysts
96
+ @catalysts.values
97
+ end
98
+
99
+ def all_reactions
100
+ @reactions.values
101
+ end
102
+
103
+ def completed_reactions
104
+ @reactions.values.select(&:complete?)
105
+ end
106
+
107
+ def catalyzed_rate
108
+ completed = completed_reactions
109
+ return 0.0 if completed.empty?
110
+
111
+ catalyzed_count = completed.count(&:catalyzed?)
112
+ (catalyzed_count.to_f / completed.size).round(10)
113
+ end
114
+
115
+ def catalyst_report
116
+ completed = completed_reactions
117
+ catalyzed_cnt = completed.count(&:catalyzed?)
118
+ avg_potency = if @catalysts.empty?
119
+ 0.0
120
+ else
121
+ (@catalysts.values.sum(&:potency) / @catalysts.size).round(10)
122
+ end
123
+
124
+ {
125
+ total_catalysts: @catalysts.size,
126
+ total_reactions: @reactions.size,
127
+ completed: completed.size,
128
+ catalyzed_count: catalyzed_cnt,
129
+ catalyzed_rate: catalyzed_rate,
130
+ avg_potency: avg_potency,
131
+ powerful_count: @catalysts.values.count(&:powerful?),
132
+ inert_count: @catalysts.values.count(&:inert?)
133
+ }
134
+ end
135
+
136
+ private
137
+
138
+ def evict_oldest_catalyst
139
+ oldest_id = @catalysts.min_by { |_id, c| c.created_at }&.first
140
+ @catalysts.delete(oldest_id) if oldest_id
141
+ end
142
+
143
+ def evict_oldest_reaction
144
+ oldest_id = @reactions.min_by { |_id, r| r.created_at }&.first
145
+ @reactions.delete(oldest_id) if oldest_id
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Learning
7
+ module Catalyst
8
+ module Helpers
9
+ module Constants
10
+ # Catalyst types — categories of experiences/insights that accelerate reactions
11
+ CATALYST_TYPES = %i[experience insight analogy pattern emotion].freeze
12
+
13
+ # Reaction types — categories of cognitive transformations
14
+ REACTION_TYPES = %i[synthesis decomposition exchange neutralization precipitation].freeze
15
+
16
+ # Storage limits
17
+ MAX_CATALYSTS = 500
18
+ MAX_REACTIONS = 200
19
+
20
+ # Activation energy — minimum energy to complete a reaction without a catalyst
21
+ ACTIVATION_ENERGY = 0.6
22
+
23
+ # How much a catalyst lowers the activation energy threshold
24
+ CATALYST_REDUCTION = 0.3
25
+
26
+ # Potency degradation rate from environmental wear (not from use)
27
+ POTENCY_DECAY = 0.02
28
+
29
+ # Bonus added when catalyst specificity matches reaction domain
30
+ SPECIFICITY_BONUS = 0.15
31
+
32
+ # Potency labels — range-based classification of catalyst strength
33
+ POTENCY_LABELS = {
34
+ (0.8..) => :powerful,
35
+ (0.6...0.8) => :strong,
36
+ (0.4...0.6) => :moderate,
37
+ (0.2...0.4) => :weak,
38
+ (..0.2) => :inert
39
+ }.freeze
40
+
41
+ # Yield labels — range-based classification of reaction output quality
42
+ YIELD_LABELS = {
43
+ (0.8..) => :excellent,
44
+ (0.6...0.8) => :good,
45
+ (0.4...0.6) => :fair,
46
+ (0.2...0.4) => :poor,
47
+ (..0.2) => :negligible
48
+ }.freeze
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Learning
9
+ module Catalyst
10
+ module Helpers
11
+ class Reaction
12
+ include Constants
13
+
14
+ attr_reader :id, :reaction_type, :reactants, :activation_energy,
15
+ :yield_value, :catalyzed, :catalyst_id, :completed, :created_at
16
+
17
+ def initialize(reaction_type:, reactants:, activation_energy: ACTIVATION_ENERGY)
18
+ @id = SecureRandom.uuid
19
+ @reaction_type = reaction_type
20
+ @reactants = Array(reactants)
21
+ @activation_energy = activation_energy.clamp(0.0, 1.0)
22
+ @yield_value = 0.0
23
+ @catalyzed = false
24
+ @catalyst_id = nil
25
+ @completed = false
26
+ @created_at = Time.now.utc
27
+ end
28
+
29
+ # Apply a catalyst to lower the activation energy threshold
30
+ def apply_catalyst!(catalyst)
31
+ reduction = catalyst.catalyze!(@reaction_type)
32
+ @activation_energy = (@activation_energy - reduction).clamp(0.0, 1.0).round(10)
33
+ @catalyzed = true
34
+ @catalyst_id = catalyst.id
35
+ end
36
+
37
+ # Attempt to complete the reaction with given energy input
38
+ # Completes if energy_input >= activation_energy; yield based on energy surplus
39
+ def attempt!(energy_input)
40
+ return false if @completed
41
+ return false if energy_input < @activation_energy
42
+
43
+ @completed = true
44
+ surplus = (energy_input - @activation_energy).clamp(0.0, 1.0)
45
+ @yield_value = (0.5 + (surplus * 0.5)).clamp(0.0, 1.0).round(10)
46
+ true
47
+ end
48
+
49
+ def complete?
50
+ @completed
51
+ end
52
+
53
+ def catalyzed?
54
+ @catalyzed
55
+ end
56
+
57
+ # Completed spontaneously — without a catalyst
58
+ def spontaneous?
59
+ @completed && !@catalyzed
60
+ end
61
+
62
+ def yield_label
63
+ YIELD_LABELS.find { |range, _| range.cover?(@yield_value) }&.last || :negligible
64
+ end
65
+
66
+ def to_h
67
+ {
68
+ id: @id,
69
+ reaction_type: @reaction_type,
70
+ reactants: @reactants,
71
+ activation_energy: @activation_energy,
72
+ yield_value: @yield_value,
73
+ yield_label: yield_label,
74
+ catalyzed: @catalyzed,
75
+ catalyst_id: @catalyst_id,
76
+ completed: @completed,
77
+ spontaneous: spontaneous?,
78
+ created_at: @created_at
79
+ }
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Learning
7
+ module Catalyst
8
+ module Runners
9
+ module CognitiveCatalyst
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex)
12
+
13
+ def create_catalyst(catalyst_type:, domain:, potency: nil, specificity: nil, engine: nil, **)
14
+ e = engine || default_engine
15
+ raise ArgumentError, "invalid catalyst_type: #{catalyst_type}" unless Helpers::Constants::CATALYST_TYPES.include?(catalyst_type.to_sym)
16
+
17
+ opts = {
18
+ catalyst_type: catalyst_type.to_sym,
19
+ domain: domain
20
+ }
21
+ opts[:potency] = potency unless potency.nil?
22
+ opts[:specificity] = specificity unless specificity.nil?
23
+
24
+ catalyst = e.create_catalyst(**opts)
25
+ Legion::Logging.debug "[cognitive_catalyst] create_catalyst id=#{catalyst.id[0..7]} " \
26
+ "type=#{catalyst_type} domain=#{domain} potency=#{catalyst.potency.round(2)}"
27
+ { success: true, catalyst: catalyst.to_h }
28
+ rescue ArgumentError => e
29
+ Legion::Logging.warn "[cognitive_catalyst] create_catalyst failed: #{e.message}"
30
+ { success: false, reason: e.message }
31
+ end
32
+
33
+ def create_reaction(reaction_type:, reactants:, activation_energy: nil, engine: nil, **)
34
+ e = engine || default_engine
35
+ raise ArgumentError, "invalid reaction_type: #{reaction_type}" unless Helpers::Constants::REACTION_TYPES.include?(reaction_type.to_sym)
36
+
37
+ opts = {
38
+ reaction_type: reaction_type.to_sym,
39
+ reactants: Array(reactants)
40
+ }
41
+ opts[:activation_energy] = activation_energy unless activation_energy.nil?
42
+
43
+ reaction = e.create_reaction(**opts)
44
+ Legion::Logging.debug "[cognitive_catalyst] create_reaction id=#{reaction.id[0..7]} " \
45
+ "type=#{reaction_type} reactants=#{reaction.reactants.size}"
46
+ { success: true, reaction: reaction.to_h }
47
+ rescue ArgumentError => e
48
+ Legion::Logging.warn "[cognitive_catalyst] create_reaction failed: #{e.message}"
49
+ { success: false, reason: e.message }
50
+ end
51
+
52
+ def apply_catalyst(catalyst_id:, reaction_id:, engine: nil, **)
53
+ e = engine || default_engine
54
+ result = e.apply_catalyst(catalyst_id: catalyst_id, reaction_id: reaction_id)
55
+ Legion::Logging.debug '[cognitive_catalyst] apply_catalyst ' \
56
+ "catalyst=#{catalyst_id[0..7]} reaction=#{reaction_id[0..7]} " \
57
+ "success=#{result[:success]}"
58
+ result
59
+ end
60
+
61
+ def attempt_reaction(reaction_id:, energy_input:, engine: nil, **)
62
+ e = engine || default_engine
63
+ result = e.attempt_reaction(reaction_id: reaction_id, energy_input: energy_input)
64
+ Legion::Logging.debug "[cognitive_catalyst] attempt_reaction id=#{reaction_id[0..7]} " \
65
+ "energy=#{energy_input} completed=#{result[:completed]}"
66
+ result
67
+ end
68
+
69
+ def recharge(catalyst_id:, amount:, engine: nil, **)
70
+ e = engine || default_engine
71
+ result = e.recharge_catalyst(catalyst_id: catalyst_id, amount: amount)
72
+ Legion::Logging.debug "[cognitive_catalyst] recharge id=#{catalyst_id[0..7]} " \
73
+ "amount=#{amount} potency=#{result[:potency]&.round(2)}"
74
+ result
75
+ end
76
+
77
+ def list_catalysts(engine: nil, **)
78
+ e = engine || default_engine
79
+ catalysts = e.all_catalysts
80
+ Legion::Logging.debug "[cognitive_catalyst] list_catalysts count=#{catalysts.size}"
81
+ { success: true, catalysts: catalysts.map(&:to_h), count: catalysts.size }
82
+ end
83
+
84
+ def catalyst_status(engine: nil, **)
85
+ e = engine || default_engine
86
+ report = e.catalyst_report
87
+ Legion::Logging.debug "[cognitive_catalyst] catalyst_status total=#{report[:total_catalysts]} " \
88
+ "reactions=#{report[:total_reactions]} rate=#{report[:catalyzed_rate].round(2)}"
89
+ { success: true }.merge(report)
90
+ end
91
+
92
+ private
93
+
94
+ def default_engine
95
+ @default_engine ||= Helpers::CatalystEngine.new
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Learning
7
+ module Catalyst
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 'catalyst/version'
6
+ require_relative 'catalyst/helpers/constants'
7
+ require_relative 'catalyst/helpers/catalyst'
8
+ require_relative 'catalyst/helpers/reaction'
9
+ require_relative 'catalyst/helpers/catalyst_engine'
10
+ require_relative 'catalyst/runners/cognitive_catalyst'
11
+ require_relative 'catalyst/client'
12
+
13
+ module Legion
14
+ module Extensions
15
+ module Agentic
16
+ module Learning
17
+ module Catalyst
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Agentic
6
+ module Learning
7
+ module Chrysalis
8
+ class Client
9
+ include Runners::CognitiveChrysalis
10
+
11
+ attr_reader :engine
12
+
13
+ def initialize(**)
14
+ @engine = Helpers::MetamorphosisEngine.new
15
+ @default_engine = @engine
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Learning
9
+ module Chrysalis
10
+ module Helpers
11
+ class Chrysalis
12
+ attr_reader :id, :chrysalis_type, :content, :stage,
13
+ :transformation_progress, :protection, :beauty, :created_at
14
+
15
+ def initialize(chrysalis_type:, content:, **)
16
+ @id = SecureRandom.uuid
17
+ @chrysalis_type = chrysalis_type.to_sym
18
+ @content = content.to_s
19
+ @stage = :larva
20
+ @transformation_progress = 0.0
21
+ @protection = 0.8
22
+ @beauty = 0.0
23
+ @created_at = Time.now.utc
24
+ @premature = false
25
+ end
26
+
27
+ def spin!
28
+ raise ArgumentError, "must be :larva to spin, currently #{@stage}" unless @stage == :larva
29
+
30
+ @stage = :spinning
31
+ true
32
+ end
33
+
34
+ def cocoon!
35
+ raise ArgumentError, "must be :spinning to cocoon, currently #{@stage}" unless @stage == :spinning
36
+
37
+ @stage = :cocooned
38
+ true
39
+ end
40
+
41
+ def transform!(rate = Helpers::Constants::TRANSFORMATION_RATE)
42
+ return false if @stage == :butterfly
43
+
44
+ @transformation_progress = (@transformation_progress + rate).clamp(0.0, 1.0).round(10)
45
+ @beauty = (@transformation_progress * 0.9).clamp(0.0, 1.0).round(10)
46
+ update_stage_from_progress!
47
+ true
48
+ end
49
+
50
+ def emerge!(force: false)
51
+ if @transformation_progress >= Helpers::Constants::EMERGENCE_THRESHOLD
52
+ @stage = :butterfly
53
+ @beauty = 1.0
54
+ elsif force
55
+ @premature = true
56
+ @stage = :butterfly
57
+ @beauty = (@beauty - Helpers::Constants::PREMATURE_PENALTY).clamp(0.0, 1.0).round(10)
58
+ else
59
+ return false
60
+ end
61
+ true
62
+ end
63
+
64
+ def decay_protection!
65
+ @protection = (@protection - Helpers::Constants::PROTECTION_DECAY).clamp(0.0, 1.0).round(10)
66
+ end
67
+
68
+ def disturb!(force)
69
+ @protection = (@protection - force.to_f).clamp(0.0, 1.0).round(10)
70
+ emerge!(force: true) if @protection <= 0 && %i[cocooned transforming].include?(@stage)
71
+ end
72
+
73
+ def butterfly?
74
+ @stage == :butterfly
75
+ end
76
+
77
+ def cocooned?
78
+ @stage == :cocooned
79
+ end
80
+
81
+ def transforming?
82
+ @stage == :transforming
83
+ end
84
+
85
+ def premature?
86
+ butterfly? && @beauty < 0.5
87
+ end
88
+
89
+ def stage_label
90
+ Helpers::Constants.label_for(Helpers::Constants::STAGE_LABELS, @transformation_progress)
91
+ end
92
+
93
+ def beauty_label
94
+ Helpers::Constants.label_for(Helpers::Constants::BEAUTY_LABELS, @beauty)
95
+ end
96
+
97
+ def to_h
98
+ {
99
+ id: @id,
100
+ chrysalis_type: @chrysalis_type,
101
+ content: @content,
102
+ stage: @stage,
103
+ transformation_progress: @transformation_progress,
104
+ protection: @protection,
105
+ beauty: @beauty,
106
+ stage_label: stage_label,
107
+ beauty_label: beauty_label,
108
+ premature: @premature,
109
+ created_at: @created_at
110
+ }
111
+ end
112
+
113
+ private
114
+
115
+ def update_stage_from_progress!
116
+ progress_stage = if @transformation_progress >= 0.8
117
+ :emerging
118
+ elsif @transformation_progress >= 0.6
119
+ :transforming
120
+ elsif @transformation_progress >= 0.4
121
+ :cocooned
122
+ elsif @transformation_progress >= 0.2
123
+ :spinning
124
+ else
125
+ :larva
126
+ end
127
+ current_rank = Helpers::Constants::LIFE_STAGES.index(@stage) || 0
128
+ progress_rank = Helpers::Constants::LIFE_STAGES.index(progress_stage) || 0
129
+ @stage = Helpers::Constants::LIFE_STAGES[[current_rank, progress_rank].max]
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Learning
9
+ module Chrysalis
10
+ module Helpers
11
+ class Cocoon
12
+ attr_reader :id, :environment, :temperature, :humidity, :chrysalis_ids, :created_at
13
+
14
+ TEMP_ADJUST = 0.05
15
+ HUMID_ADJUST = 0.05
16
+
17
+ def initialize(environment:, temperature: 0.5, humidity: 0.5, **)
18
+ @id = SecureRandom.uuid
19
+ @environment = environment.to_s
20
+ @temperature = temperature.to_f.clamp(0.0, 1.0)
21
+ @humidity = humidity.to_f.clamp(0.0, 1.0)
22
+ @chrysalis_ids = []
23
+ @created_at = Time.now.utc
24
+ end
25
+
26
+ def shelter(chrysalis_id)
27
+ @chrysalis_ids << chrysalis_id unless @chrysalis_ids.include?(chrysalis_id)
28
+ true
29
+ end
30
+
31
+ def expose(chrysalis_id)
32
+ @chrysalis_ids.delete(chrysalis_id)
33
+ true
34
+ end
35
+
36
+ def warm!
37
+ @temperature = (@temperature + TEMP_ADJUST).clamp(0.0, 1.0).round(10)
38
+ end
39
+
40
+ def cool!
41
+ @temperature = (@temperature - TEMP_ADJUST).clamp(0.0, 1.0).round(10)
42
+ end
43
+
44
+ def moisten!
45
+ @humidity = (@humidity + HUMID_ADJUST).clamp(0.0, 1.0).round(10)
46
+ end
47
+
48
+ def dry!
49
+ @humidity = (@humidity - HUMID_ADJUST).clamp(0.0, 1.0).round(10)
50
+ end
51
+
52
+ def ideal?
53
+ @temperature.between?(0.4, 0.7) && @humidity.between?(0.4, 0.7)
54
+ end
55
+
56
+ def hostile?
57
+ @temperature > 0.9 || @humidity < 0.1
58
+ end
59
+
60
+ def growth_modifier
61
+ if ideal?
62
+ 0.1
63
+ elsif hostile?
64
+ -0.05
65
+ else
66
+ 0.0
67
+ end
68
+ end
69
+
70
+ def to_h
71
+ {
72
+ id: @id,
73
+ environment: @environment,
74
+ temperature: @temperature,
75
+ humidity: @humidity,
76
+ chrysalis_ids: @chrysalis_ids.dup,
77
+ ideal: ideal?,
78
+ hostile: hostile?,
79
+ growth_modifier: growth_modifier,
80
+ created_at: @created_at
81
+ }
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end