lex-agentic-learning 0.1.1 → 0.1.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e3d434a965969263653baeab0cc752684ec0d7634b9b6eddf9caddc3de87883
4
- data.tar.gz: 739255e9c779173dc965bfbe2bb3b4eb6f960f24cd10650e18eff611b99ab530
3
+ metadata.gz: a8e389e9f54e7a9c30da3458b1cfda5723454543d12b47b76bc8a99c9a35e72f
4
+ data.tar.gz: 228ba88c5b55ee8a8886de351f10ce0a10abad53cbdca36e0131ad1b0e013ccb
5
5
  SHA512:
6
- metadata.gz: d368996971593e6615df6c0495edfd70571cfabfebe7d5d58a47a5fc41fb285a7594d877345cde439e0e276e97379982f30675de1a38c5d87223f3cc2751bd42
7
- data.tar.gz: 206ed5333af646c9261cf3647bdd521b6225a62092ed1f8e2aa863c41aa4ec1fdd2ba67aebda29ab9405ea8a7e4e7053b511118172e677ab5ec1b6f44285bcd1
6
+ metadata.gz: 638c8c4442081c5d1584b70cd6bbd579e468f4e63cc6aee9643dbc177ca9f254b4d562a5886a0ca5aa3686fe83b9bab16871bdcf44b65d7cbb70cafaa38746fe
7
+ data.tar.gz: c1ca765261443c56a76eadd376960950183b5435c7c53cdef9af0abcaa9a3cd8a205e47aa6dee4ebad0f97b5c144ced0cdc50d16c67f8b5406d86e25be99b25e
data/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.1.2] - 2026-03-22
6
+
7
+ ### Changed
8
+ - Add legion-* sub-gems as runtime dependencies (logging, settings, json, cache, crypt, data, transport)
9
+ - Replace direct Legion::Logging calls with injected log helper in all runner modules
10
+ - Update spec_helper with real sub-gem helper stubs
11
+
5
12
  ## [0.1.1] - 2026-03-18
6
13
 
7
14
  ### Changed
@@ -24,6 +24,14 @@ Gem::Specification.new do |spec|
24
24
  end
25
25
  spec.require_paths = ['lib']
26
26
 
27
+ spec.add_dependency 'legion-cache', '>= 1.3.11'
28
+ spec.add_dependency 'legion-crypt', '>= 1.4.9'
29
+ spec.add_dependency 'legion-data', '>= 1.4.17'
30
+ spec.add_dependency 'legion-json', '>= 1.2.1'
31
+ spec.add_dependency 'legion-logging', '>= 1.3.2'
32
+ spec.add_dependency 'legion-settings', '>= 1.3.14'
33
+ spec.add_dependency 'legion-transport', '>= 1.3.9'
34
+
27
35
  spec.add_development_dependency 'rspec', '~> 3.13'
28
36
  spec.add_development_dependency 'rubocop', '~> 1.60'
29
37
  spec.add_development_dependency 'rubocop-rspec', '~> 2.26'
@@ -12,28 +12,28 @@ module Legion
12
12
 
13
13
  def record_anchor(value:, domain: :general, **)
14
14
  anchor = anchor_store.add(value: value, domain: domain)
15
- Legion::Logging.debug "[anchoring] record_anchor domain=#{domain} value=#{value} id=#{anchor.id}"
15
+ log.debug "[anchoring] record_anchor domain=#{domain} value=#{value} id=#{anchor.id}"
16
16
  { success: true, anchor: anchor.to_h }
17
17
  end
18
18
 
19
19
  def evaluate_estimate(estimate:, domain: :general, **)
20
20
  result = anchor_store.evaluate(estimate: estimate, domain: domain)
21
- Legion::Logging.debug "[anchoring] evaluate_estimate domain=#{domain} estimate=#{estimate} " \
22
- "anchored=#{result[:anchored_estimate].round(4)} pull=#{result[:pull_strength].round(4)}"
21
+ log.debug "[anchoring] evaluate_estimate domain=#{domain} estimate=#{estimate} " \
22
+ "anchored=#{result[:anchored_estimate].round(4)} pull=#{result[:pull_strength].round(4)}"
23
23
  { success: true }.merge(result)
24
24
  end
25
25
 
26
26
  def reference_frame(value:, domain: :general, **)
27
27
  result = anchor_store.reference_frame(value: value, domain: domain)
28
- Legion::Logging.debug "[anchoring] reference_frame domain=#{domain} value=#{value} " \
29
- "gain_or_loss=#{result[:gain_or_loss]}"
28
+ log.debug "[anchoring] reference_frame domain=#{domain} value=#{value} " \
29
+ "gain_or_loss=#{result[:gain_or_loss]}"
30
30
  { success: true }.merge(result)
31
31
  end
32
32
 
33
33
  def de_anchor(estimate:, domain: :general, **)
34
34
  anchor = anchor_store.strongest(domain: domain)
35
35
  if anchor.nil?
36
- Legion::Logging.debug "[anchoring] de_anchor domain=#{domain} no anchor found"
36
+ log.debug "[anchoring] de_anchor domain=#{domain} no anchor found"
37
37
  return { success: true, corrected_estimate: estimate.to_f, anchor_bias: 0.0, domain: domain }
38
38
  end
39
39
 
@@ -41,8 +41,8 @@ module Legion
41
41
  bias = biased - estimate.to_f
42
42
  corrected = estimate.to_f - bias
43
43
 
44
- Legion::Logging.debug "[anchoring] de_anchor domain=#{domain} estimate=#{estimate} " \
45
- "corrected=#{corrected.round(4)} bias=#{bias.round(4)}"
44
+ log.debug "[anchoring] de_anchor domain=#{domain} estimate=#{estimate} " \
45
+ "corrected=#{corrected.round(4)} bias=#{bias.round(4)}"
46
46
 
47
47
  {
48
48
  success: true,
@@ -56,13 +56,13 @@ module Legion
56
56
 
57
57
  def shift_reference(domain:, new_reference:, **)
58
58
  result = anchor_store.shift_reference(domain: domain, new_reference: new_reference)
59
- Legion::Logging.info "[anchoring] shift_reference domain=#{domain} new=#{new_reference} significant=#{result[:significant]}"
59
+ log.info "[anchoring] shift_reference domain=#{domain} new=#{new_reference} significant=#{result[:significant]}"
60
60
  { success: true }.merge(result)
61
61
  end
62
62
 
63
63
  def update_anchoring(**)
64
64
  pruned = anchor_store.decay_all
65
- Legion::Logging.debug "[anchoring] update_anchoring pruned=#{pruned}"
65
+ log.debug "[anchoring] update_anchoring pruned=#{pruned}"
66
66
  { success: true, pruned: pruned }
67
67
  end
68
68
 
@@ -70,7 +70,7 @@ module Legion
70
70
  domain = domain.to_sym
71
71
  anchor = anchor_store.strongest(domain: domain)
72
72
  all_list = anchor_store.instance_variable_get(:@anchors)[domain] || []
73
- Legion::Logging.debug "[anchoring] domain_anchors domain=#{domain} count=#{all_list.size}"
73
+ log.debug "[anchoring] domain_anchors domain=#{domain} count=#{all_list.size}"
74
74
  {
75
75
  success: true,
76
76
  domain: domain,
@@ -82,7 +82,7 @@ module Legion
82
82
 
83
83
  def anchoring_stats(**)
84
84
  stats = anchor_store.to_h
85
- Legion::Logging.debug "[anchoring] stats domains=#{stats[:domain_count]} total=#{stats[:total_anchors]}"
85
+ log.debug "[anchoring] stats domains=#{stats[:domain_count]} total=#{stats[:total_anchors]}"
86
86
  { success: true }.merge(stats)
87
87
  end
88
88
 
@@ -22,11 +22,11 @@ module Legion
22
22
  opts[:specificity] = specificity unless specificity.nil?
23
23
 
24
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)}"
25
+ log.debug "[cognitive_catalyst] create_catalyst id=#{catalyst.id[0..7]} " \
26
+ "type=#{catalyst_type} domain=#{domain} potency=#{catalyst.potency.round(2)}"
27
27
  { success: true, catalyst: catalyst.to_h }
28
28
  rescue ArgumentError => e
29
- Legion::Logging.warn "[cognitive_catalyst] create_catalyst failed: #{e.message}"
29
+ log.warn "[cognitive_catalyst] create_catalyst failed: #{e.message}"
30
30
  { success: false, reason: e.message }
31
31
  end
32
32
 
@@ -41,51 +41,51 @@ module Legion
41
41
  opts[:activation_energy] = activation_energy unless activation_energy.nil?
42
42
 
43
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}"
44
+ log.debug "[cognitive_catalyst] create_reaction id=#{reaction.id[0..7]} " \
45
+ "type=#{reaction_type} reactants=#{reaction.reactants.size}"
46
46
  { success: true, reaction: reaction.to_h }
47
47
  rescue ArgumentError => e
48
- Legion::Logging.warn "[cognitive_catalyst] create_reaction failed: #{e.message}"
48
+ log.warn "[cognitive_catalyst] create_reaction failed: #{e.message}"
49
49
  { success: false, reason: e.message }
50
50
  end
51
51
 
52
52
  def apply_catalyst(catalyst_id:, reaction_id:, engine: nil, **)
53
53
  e = engine || default_engine
54
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]}"
55
+ log.debug '[cognitive_catalyst] apply_catalyst ' \
56
+ "catalyst=#{catalyst_id[0..7]} reaction=#{reaction_id[0..7]} " \
57
+ "success=#{result[:success]}"
58
58
  result
59
59
  end
60
60
 
61
61
  def attempt_reaction(reaction_id:, energy_input:, engine: nil, **)
62
62
  e = engine || default_engine
63
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]}"
64
+ log.debug "[cognitive_catalyst] attempt_reaction id=#{reaction_id[0..7]} " \
65
+ "energy=#{energy_input} completed=#{result[:completed]}"
66
66
  result
67
67
  end
68
68
 
69
69
  def recharge(catalyst_id:, amount:, engine: nil, **)
70
70
  e = engine || default_engine
71
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)}"
72
+ log.debug "[cognitive_catalyst] recharge id=#{catalyst_id[0..7]} " \
73
+ "amount=#{amount} potency=#{result[:potency]&.round(2)}"
74
74
  result
75
75
  end
76
76
 
77
77
  def list_catalysts(engine: nil, **)
78
78
  e = engine || default_engine
79
79
  catalysts = e.all_catalysts
80
- Legion::Logging.debug "[cognitive_catalyst] list_catalysts count=#{catalysts.size}"
80
+ log.debug "[cognitive_catalyst] list_catalysts count=#{catalysts.size}"
81
81
  { success: true, catalysts: catalysts.map(&:to_h), count: catalysts.size }
82
82
  end
83
83
 
84
84
  def catalyst_status(engine: nil, **)
85
85
  e = engine || default_engine
86
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)}"
87
+ log.debug "[cognitive_catalyst] catalyst_status total=#{report[:total_catalysts]} " \
88
+ "reactions=#{report[:total_reactions]} rate=#{report[:catalyzed_rate].round(2)}"
89
89
  { success: true }.merge(report)
90
90
  end
91
91
 
@@ -22,7 +22,7 @@ module Legion
22
22
  return { success: false, reason: :invalid_type, valid_types: Helpers::Constants::CHRYSALIS_TYPES }
23
23
  end
24
24
 
25
- Legion::Logging.debug "[cognitive_chrysalis] creating chrysalis type=#{type}"
25
+ log.debug "[cognitive_chrysalis] creating chrysalis type=#{type}"
26
26
  engine.create_chrysalis(chrysalis_type: type, content: content)
27
27
  rescue ArgumentError => e
28
28
  { success: false, reason: e.message }
@@ -30,7 +30,7 @@ module Legion
30
30
 
31
31
  def create_cocoon(environment: 'default', temperature: 0.5, humidity: 0.5, engine: nil, **)
32
32
  engine ||= default_engine
33
- Legion::Logging.debug "[cognitive_chrysalis] creating cocoon environment=#{environment}"
33
+ log.debug "[cognitive_chrysalis] creating cocoon environment=#{environment}"
34
34
  engine.create_cocoon(environment: environment, temperature: temperature, humidity: humidity)
35
35
  rescue ArgumentError => e
36
36
  { success: false, reason: e.message }
@@ -40,7 +40,7 @@ module Legion
40
40
  return { success: false, reason: :missing_chrysalis_id } if chrysalis_id.nil?
41
41
 
42
42
  engine ||= default_engine
43
- Legion::Logging.debug "[cognitive_chrysalis] spinning chrysalis=#{chrysalis_id}"
43
+ log.debug "[cognitive_chrysalis] spinning chrysalis=#{chrysalis_id}"
44
44
  engine.spin(chrysalis_id: chrysalis_id)
45
45
  rescue ArgumentError => e
46
46
  { success: false, reason: e.message }
@@ -51,7 +51,7 @@ module Legion
51
51
  return { success: false, reason: :missing_cocoon_id } if cocoon_id.nil?
52
52
 
53
53
  engine ||= default_engine
54
- Legion::Logging.debug "[cognitive_chrysalis] enclosing chrysalis=#{chrysalis_id} in cocoon=#{cocoon_id}"
54
+ log.debug "[cognitive_chrysalis] enclosing chrysalis=#{chrysalis_id} in cocoon=#{cocoon_id}"
55
55
  engine.enclose(chrysalis_id: chrysalis_id, cocoon_id: cocoon_id)
56
56
  rescue ArgumentError => e
57
57
  { success: false, reason: e.message }
@@ -61,7 +61,7 @@ module Legion
61
61
  return { success: false, reason: :missing_chrysalis_id } if chrysalis_id.nil?
62
62
 
63
63
  engine ||= default_engine
64
- Legion::Logging.debug "[cognitive_chrysalis] incubating chrysalis=#{chrysalis_id}"
64
+ log.debug "[cognitive_chrysalis] incubating chrysalis=#{chrysalis_id}"
65
65
  engine.incubate(chrysalis_id: chrysalis_id)
66
66
  rescue ArgumentError => e
67
67
  { success: false, reason: e.message }
@@ -69,7 +69,7 @@ module Legion
69
69
 
70
70
  def incubate_all(engine: nil, **)
71
71
  engine ||= default_engine
72
- Legion::Logging.debug '[cognitive_chrysalis] incubating all eligible chrysalises'
72
+ log.debug '[cognitive_chrysalis] incubating all eligible chrysalises'
73
73
  engine.incubate_all!
74
74
  rescue ArgumentError => e
75
75
  { success: false, reason: e.message }
@@ -79,7 +79,7 @@ module Legion
79
79
  return { success: false, reason: :missing_chrysalis_id } if chrysalis_id.nil?
80
80
 
81
81
  engine ||= default_engine
82
- Legion::Logging.debug "[cognitive_chrysalis] emerging chrysalis=#{chrysalis_id} force=#{force}"
82
+ log.debug "[cognitive_chrysalis] emerging chrysalis=#{chrysalis_id} force=#{force}"
83
83
  if force
84
84
  engine.force_emerge(chrysalis_id: chrysalis_id)
85
85
  else
@@ -93,7 +93,7 @@ module Legion
93
93
  return { success: false, reason: :missing_cocoon_id } if cocoon_id.nil?
94
94
 
95
95
  engine ||= default_engine
96
- Legion::Logging.debug "[cognitive_chrysalis] disturbing cocoon=#{cocoon_id} force=#{force}"
96
+ log.debug "[cognitive_chrysalis] disturbing cocoon=#{cocoon_id} force=#{force}"
97
97
  engine.disturb_cocoon(cocoon_id: cocoon_id, force: force)
98
98
  rescue ArgumentError => e
99
99
  { success: false, reason: e.message }
@@ -13,7 +13,7 @@ module Legion
13
13
 
14
14
  def detect_gaps(prior_results: {}, **)
15
15
  gaps = Helpers::GapDetector.detect(prior_results)
16
- Legion::Logging.debug "[curiosity] detected #{gaps.size} knowledge gaps"
16
+ log.debug "[curiosity] detected #{gaps.size} knowledge gaps"
17
17
 
18
18
  created = create_wonders_from_gaps(gaps)
19
19
  build_detect_result(gaps, created)
@@ -28,7 +28,7 @@ module Legion
28
28
  source_trace_ids: source_trace_ids
29
29
  )
30
30
  wonder_store.store(wonder)
31
- Legion::Logging.info "[curiosity] manually generated wonder: #{question}"
31
+ log.info "[curiosity] manually generated wonder: #{question}"
32
32
  wonder
33
33
  end
34
34
 
@@ -39,7 +39,7 @@ module Legion
39
39
  return { error: :not_explorable, reason: :max_attempts } unless Helpers::Wonder.explorable?(wonder)
40
40
 
41
41
  wonder_store.update(wonder_id, attempts: wonder[:attempts] + 1, last_explored_at: Time.now.utc)
42
- Legion::Logging.info "[curiosity] exploring: #{wonder[:question]} (attempt ##{wonder[:attempts] + 1})"
42
+ log.info "[curiosity] exploring: #{wonder[:question]} (attempt ##{wonder[:attempts] + 1})"
43
43
  { exploring: true, wonder_id: wonder_id, attempt: wonder[:attempts] + 1 }
44
44
  end
45
45
 
@@ -54,20 +54,20 @@ module Legion
54
54
 
55
55
  def curiosity_intensity(**)
56
56
  intensity = compute_intensity
57
- Legion::Logging.debug "[curiosity] intensity=#{intensity.round(3)}"
57
+ log.debug "[curiosity] intensity=#{intensity.round(3)}"
58
58
  { intensity: intensity, active_wonders: wonder_store.active_count,
59
59
  resolution_rate: wonder_store.resolution_rate.round(3), top_domain: top_curiosity_domain }
60
60
  end
61
61
 
62
62
  def top_wonders(limit: 5, **)
63
63
  wonders = wonder_store.top_balanced(limit: limit)
64
- Legion::Logging.debug "[curiosity] top #{wonders.size} wonders requested"
64
+ log.debug "[curiosity] top #{wonders.size} wonders requested"
65
65
  { wonders: wonders.map { |w| format_wonder(w) } }
66
66
  end
67
67
 
68
68
  def form_agenda(**)
69
69
  wonders = wonder_store.top_balanced(limit: 5)
70
- Legion::Logging.debug "[curiosity] forming agenda from #{wonders.size} wonders"
70
+ log.debug "[curiosity] forming agenda from #{wonders.size} wonders"
71
71
  { agenda_items: wonders.map { |w| format_agenda_item(w) }, source: :curiosity }
72
72
  end
73
73
 
@@ -79,7 +79,7 @@ module Legion
79
79
 
80
80
  def decay_wonders(hours_elapsed: 1.0, **)
81
81
  pruned = wonder_store.decay_all(hours_elapsed: hours_elapsed)
82
- Legion::Logging.debug "[curiosity] decay: pruned=#{pruned} remaining=#{wonder_store.active_count}"
82
+ log.debug "[curiosity] decay: pruned=#{pruned} remaining=#{wonder_store.active_count}"
83
83
  { pruned: pruned, remaining: wonder_store.active_count }
84
84
  end
85
85
 
@@ -97,14 +97,14 @@ module Legion
97
97
  :salience, :information_gain, :source_trace_ids))
98
98
  wonder_store.store(wonder)
99
99
  created << wonder
100
- Legion::Logging.info "[curiosity] new wonder: #{wonder[:question]} (#{wonder[:gap_type]}/#{wonder[:domain]})"
100
+ log.info "[curiosity] new wonder: #{wonder[:question]} (#{wonder[:gap_type]}/#{wonder[:domain]})"
101
101
  end
102
102
  end
103
103
 
104
104
  def build_detect_result(gaps, created)
105
105
  intensity = compute_intensity
106
106
  top = wonder_store.top_balanced(limit: 3)
107
- Legion::Logging.debug "[curiosity] intensity=#{intensity.round(3)} active=#{wonder_store.active_count}"
107
+ log.debug "[curiosity] intensity=#{intensity.round(3)} active=#{wonder_store.active_count}"
108
108
  { gaps_detected: gaps.size, wonders_created: created.size, curiosity_intensity: intensity,
109
109
  top_wonders: top.map { |w| { wonder_id: w[:wonder_id], question: w[:question], score: Helpers::Wonder.score(w).round(3) } },
110
110
  active_count: wonder_store.active_count }
@@ -112,7 +112,7 @@ module Legion
112
112
 
113
113
  def build_resolve_result(wonder, resolved, actual_gain)
114
114
  reward = actual_gain * Helpers::Constants::CURIOSITY_REWARD_MULTIPLIER
115
- Legion::Logging.info "[curiosity] resolved: #{wonder[:question]} gain=#{actual_gain.round(2)}"
115
+ log.info "[curiosity] resolved: #{wonder[:question]} gain=#{actual_gain.round(2)}"
116
116
  { resolved: true, wonder_id: wonder[:wonder_id], actual_gain: actual_gain,
117
117
  expected_gain: wonder[:information_gain], reward: reward,
118
118
  domain: resolved[:domain], resolution_rate: wonder_store.resolution_rate.round(3) }
@@ -13,9 +13,9 @@ module Legion
13
13
  def create_gap(question:, domain:, gap_type: :factual, urgency: Helpers::Constants::DEFAULT_URGENCY, **)
14
14
  result = engine.create_gap(question: question, domain: domain, gap_type: gap_type, urgency: urgency)
15
15
  if result[:created]
16
- Legion::Logging.info "[epistemic_curiosity] gap created: id=#{result[:gap][:id]} domain=#{domain} type=#{gap_type}"
16
+ log.info "[epistemic_curiosity] gap created: id=#{result[:gap][:id]} domain=#{domain} type=#{gap_type}"
17
17
  else
18
- Legion::Logging.debug "[epistemic_curiosity] gap not created: reason=#{result[:reason]}"
18
+ log.debug "[epistemic_curiosity] gap not created: reason=#{result[:reason]}"
19
19
  end
20
20
  result
21
21
  end
@@ -24,9 +24,9 @@ module Legion
24
24
  result = engine.explore_gap(gap_id: gap_id)
25
25
  if result[:found]
26
26
  gap = result[:gap]
27
- Legion::Logging.debug "[epistemic_curiosity] explore: id=#{gap_id} explorations=#{gap[:explorations]} urgency=#{gap[:urgency]}"
27
+ log.debug "[epistemic_curiosity] explore: id=#{gap_id} explorations=#{gap[:explorations]} urgency=#{gap[:urgency]}"
28
28
  else
29
- Legion::Logging.debug "[epistemic_curiosity] explore: id=#{gap_id} not found"
29
+ log.debug "[epistemic_curiosity] explore: id=#{gap_id} not found"
30
30
  end
31
31
  result
32
32
  end
@@ -35,9 +35,9 @@ module Legion
35
35
  result = engine.satisfy_gap(gap_id: gap_id, amount: amount)
36
36
  if result[:found]
37
37
  gap = result[:gap]
38
- Legion::Logging.debug "[epistemic_curiosity] satisfy: id=#{gap_id} satisfaction=#{gap[:satisfaction]} resolved=#{gap[:resolved]}"
38
+ log.debug "[epistemic_curiosity] satisfy: id=#{gap_id} satisfaction=#{gap[:satisfaction]} resolved=#{gap[:resolved]}"
39
39
  else
40
- Legion::Logging.debug "[epistemic_curiosity] satisfy: id=#{gap_id} not found"
40
+ log.debug "[epistemic_curiosity] satisfy: id=#{gap_id} not found"
41
41
  end
42
42
  result
43
43
  end
@@ -45,40 +45,40 @@ module Legion
45
45
  def resolve_gap(gap_id:, **)
46
46
  result = engine.resolve_gap(gap_id: gap_id)
47
47
  if result[:found]
48
- Legion::Logging.info "[epistemic_curiosity] resolved: id=#{gap_id}"
48
+ log.info "[epistemic_curiosity] resolved: id=#{gap_id}"
49
49
  else
50
- Legion::Logging.debug "[epistemic_curiosity] resolve: id=#{gap_id} not found"
50
+ log.debug "[epistemic_curiosity] resolve: id=#{gap_id} not found"
51
51
  end
52
52
  result
53
53
  end
54
54
 
55
55
  def most_urgent_gaps(limit: 5, **)
56
56
  gaps = engine.most_urgent(limit: limit)
57
- Legion::Logging.debug "[epistemic_curiosity] most_urgent: limit=#{limit} returned=#{gaps.size}"
57
+ log.debug "[epistemic_curiosity] most_urgent: limit=#{limit} returned=#{gaps.size}"
58
58
  { gaps: gaps.map(&:to_h), count: gaps.size }
59
59
  end
60
60
 
61
61
  def gaps_by_domain(domain:, **)
62
62
  gaps = engine.by_domain(domain)
63
- Legion::Logging.debug "[epistemic_curiosity] by_domain: domain=#{domain} count=#{gaps.size}"
63
+ log.debug "[epistemic_curiosity] by_domain: domain=#{domain} count=#{gaps.size}"
64
64
  { gaps: gaps.map(&:to_h), count: gaps.size, domain: domain }
65
65
  end
66
66
 
67
67
  def gaps_by_type(gap_type:, **)
68
68
  gaps = engine.by_type(gap_type)
69
- Legion::Logging.debug "[epistemic_curiosity] by_type: gap_type=#{gap_type} count=#{gaps.size}"
69
+ log.debug "[epistemic_curiosity] by_type: gap_type=#{gap_type} count=#{gaps.size}"
70
70
  { gaps: gaps.map(&:to_h), count: gaps.size, gap_type: gap_type }
71
71
  end
72
72
 
73
73
  def decay_gaps(**)
74
74
  count = engine.decay_all
75
- Legion::Logging.debug "[epistemic_curiosity] decay cycle: gaps_updated=#{count}"
75
+ log.debug "[epistemic_curiosity] decay cycle: gaps_updated=#{count}"
76
76
  { decayed: count }
77
77
  end
78
78
 
79
79
  def curiosity_report(**)
80
80
  report = engine.curiosity_report
81
- Legion::Logging.debug "[epistemic_curiosity] report: open=#{report[:open_gaps]} debt=#{report[:information_debt]}"
81
+ log.debug "[epistemic_curiosity] report: open=#{report[:open_gaps]} debt=#{report[:information_debt]}"
82
82
  report
83
83
  end
84
84
 
@@ -11,10 +11,10 @@ module Legion
11
11
  Legion::Extensions::Helpers.const_defined?(:Lex)
12
12
 
13
13
  def observe_action(action:, context: {}, **)
14
- Legion::Logging.debug "[habit] observe_action: action=#{action} context=#{context}"
14
+ log.debug "[habit] observe_action: action=#{action} context=#{context}"
15
15
  habit_store.record_action(action, context: context)
16
16
  detected = habit_store.detect_patterns
17
- Legion::Logging.info "[habit] patterns detected: #{detected.size}" unless detected.empty?
17
+ log.info "[habit] patterns detected: #{detected.size}" unless detected.empty?
18
18
  {
19
19
  recorded: true,
20
20
  action: action,
@@ -25,7 +25,7 @@ module Legion
25
25
 
26
26
  def suggest_habit(context: {}, **)
27
27
  matches = habit_store.find_matching(context: context)
28
- Legion::Logging.debug "[habit] suggest_habit: context=#{context} matches=#{matches.size}"
28
+ log.debug "[habit] suggest_habit: context=#{context} matches=#{matches.size}"
29
29
  if matches.empty?
30
30
  { suggestion: nil, reason: :no_matching_habits }
31
31
  else
@@ -43,19 +43,19 @@ module Legion
43
43
  return { error: :not_found } unless habit
44
44
 
45
45
  habit.record_execution(success: success)
46
- Legion::Logging.debug "[habit] execute_habit: id=#{id} success=#{success} maturity=#{habit.maturity}"
46
+ log.debug "[habit] execute_habit: id=#{id} success=#{success} maturity=#{habit.maturity}"
47
47
  { executed: true, habit: habit.to_h, cognitive_cost: habit.cognitive_cost }
48
48
  end
49
49
 
50
50
  def decay_habits(**)
51
51
  removed = habit_store.decay_all
52
- Legion::Logging.debug "[habit] decay_habits: removed=#{removed}"
52
+ log.debug "[habit] decay_habits: removed=#{removed}"
53
53
  { decayed: true, removed_count: removed }
54
54
  end
55
55
 
56
56
  def merge_habits(**)
57
57
  merged = habit_store.merge_similar
58
- Legion::Logging.debug "[habit] merge_habits: merged=#{merged}"
58
+ log.debug "[habit] merge_habits: merged=#{merged}"
59
59
  { merged_count: merged }
60
60
  end
61
61
 
@@ -65,7 +65,7 @@ module Legion
65
65
 
66
66
  def habit_repertoire(maturity: nil, limit: 20, **)
67
67
  habits = maturity ? habit_store.by_maturity(maturity.to_sym) : habit_store.habits.values
68
- Legion::Logging.debug "[habit] habit_repertoire: maturity=#{maturity} total=#{habits.size}"
68
+ log.debug "[habit] habit_repertoire: maturity=#{maturity} total=#{habits.size}"
69
69
  {
70
70
  habits: habits.sort_by { |h| -h.strength }.first(limit).map(&:to_h),
71
71
  total: habits.size
@@ -11,14 +11,14 @@ module Legion
11
11
  Legion::Extensions::Helpers.const_defined?(:Lex)
12
12
 
13
13
  def activate_unit(id:, level: 1.0, domain: :general, **)
14
- Legion::Logging.debug "[hebbian] activate: id=#{id} level=#{level}"
14
+ log.debug "[hebbian] activate: id=#{id} level=#{level}"
15
15
  network.add_unit(id: id, domain: domain)
16
16
  unit = network.activate_unit(id: id, level: level)
17
17
  { success: true, unit: unit.to_h, assemblies: network.assembly_count }
18
18
  end
19
19
 
20
20
  def co_activate_units(ids:, level: 1.0, **)
21
- Legion::Logging.debug "[hebbian] co_activate: ids=#{ids}"
21
+ log.debug "[hebbian] co_activate: ids=#{ids}"
22
22
  results = network.co_activate(ids: ids, level: level)
23
23
  { success: true, units: results, assemblies: network.assembly_count }
24
24
  end
@@ -27,19 +27,19 @@ module Legion
27
27
  w = network.query_weight(from: from, to: to)
28
28
  label = Helpers::Constants::WEIGHT_LABELS.each { |range, l| break l if range.cover?(w) }
29
29
  label = :nascent unless label.is_a?(Symbol)
30
- Legion::Logging.debug "[hebbian] weight: #{from}->#{to} = #{w}"
30
+ log.debug "[hebbian] weight: #{from}->#{to} = #{w}"
31
31
  { success: true, from: from, to: to, weight: w.round(4), label: label }
32
32
  end
33
33
 
34
34
  def list_assemblies(**)
35
35
  assemblies = network.assemblies.values.map(&:to_h)
36
- Legion::Logging.debug "[hebbian] list_assemblies: #{assemblies.size}"
36
+ log.debug "[hebbian] list_assemblies: #{assemblies.size}"
37
37
  { success: true, assemblies: assemblies, count: assemblies.size }
38
38
  end
39
39
 
40
40
  def query_assembly(id:, **)
41
41
  asm = network.query_assembly(id: id.to_sym)
42
- Legion::Logging.debug "[hebbian] query_assembly: id=#{id} found=#{!asm.nil?}"
42
+ log.debug "[hebbian] query_assembly: id=#{id} found=#{!asm.nil?}"
43
43
  if asm
44
44
  { success: true, assembly: asm.to_h }
45
45
  else
@@ -48,7 +48,7 @@ module Legion
48
48
  end
49
49
 
50
50
  def pattern_complete(partial_ids:, **)
51
- Legion::Logging.debug "[hebbian] pattern_complete: partial=#{partial_ids}"
51
+ log.debug "[hebbian] pattern_complete: partial=#{partial_ids}"
52
52
  result = network.pattern_complete(partial_ids: partial_ids)
53
53
  if result
54
54
  { success: true, completion: result }
@@ -59,24 +59,24 @@ module Legion
59
59
 
60
60
  def strongest_units(limit: 10, **)
61
61
  units = network.strongest_units(limit.to_i)
62
- Legion::Logging.debug "[hebbian] strongest_units: #{units.size}"
62
+ log.debug "[hebbian] strongest_units: #{units.size}"
63
63
  { success: true, units: units }
64
64
  end
65
65
 
66
66
  def assemblies_for(unit_id:, **)
67
67
  asms = network.assemblies_containing(unit_id: unit_id).map(&:to_h)
68
- Legion::Logging.debug "[hebbian] assemblies_for: unit=#{unit_id} count=#{asms.size}"
68
+ log.debug "[hebbian] assemblies_for: unit=#{unit_id} count=#{asms.size}"
69
69
  { success: true, assemblies: asms, count: asms.size }
70
70
  end
71
71
 
72
72
  def update_hebbian(**)
73
- Legion::Logging.debug '[hebbian] decay tick'
73
+ log.debug '[hebbian] decay tick'
74
74
  network.decay_all
75
75
  { success: true, units: network.unit_count, assemblies: network.assembly_count }
76
76
  end
77
77
 
78
78
  def hebbian_stats(**)
79
- Legion::Logging.debug '[hebbian] stats'
79
+ log.debug '[hebbian] stats'
80
80
  { success: true, stats: network.to_h }
81
81
  end
82
82
 
@@ -14,7 +14,7 @@ module Legion
14
14
  rate_model.record_prediction(domain: domain, correct: correct)
15
15
  rate = rate_model.rate_for(domain)
16
16
  accuracy = rate_model.accuracy_for(domain)
17
- Legion::Logging.debug "[learning_rate] prediction: domain=#{domain} correct=#{correct} rate=#{rate.round(3)} accuracy=#{accuracy.round(3)}"
17
+ log.debug "[learning_rate] prediction: domain=#{domain} correct=#{correct} rate=#{rate.round(3)} accuracy=#{accuracy.round(3)}"
18
18
  {
19
19
  success: true,
20
20
  domain: domain,
@@ -27,14 +27,14 @@ module Legion
27
27
  def record_surprise(magnitude:, domain: :general, **)
28
28
  rate_model.record_surprise(domain: domain, magnitude: magnitude)
29
29
  rate = rate_model.rate_for(domain)
30
- Legion::Logging.debug "[learning_rate] surprise: domain=#{domain} magnitude=#{magnitude.round(3)} rate=#{rate.round(3)}"
30
+ log.debug "[learning_rate] surprise: domain=#{domain} magnitude=#{magnitude.round(3)} rate=#{rate.round(3)}"
31
31
  { success: true, domain: domain, rate: rate, label: rate_model.label_for(domain) }
32
32
  end
33
33
 
34
34
  def record_error(magnitude:, domain: :general, **)
35
35
  rate_model.record_error(domain: domain, magnitude: magnitude)
36
36
  rate = rate_model.rate_for(domain)
37
- Legion::Logging.debug "[learning_rate] error: domain=#{domain} magnitude=#{magnitude.round(3)} rate=#{rate.round(3)}"
37
+ log.debug "[learning_rate] error: domain=#{domain} magnitude=#{magnitude.round(3)} rate=#{rate.round(3)}"
38
38
  { success: true, domain: domain, rate: rate, label: rate_model.label_for(domain) }
39
39
  end
40
40
 
@@ -63,7 +63,7 @@ module Legion
63
63
  def update_learning_rate(**)
64
64
  rate_model.decay
65
65
  overall = rate_model.overall_rate
66
- Legion::Logging.debug "[learning_rate] tick: domains=#{rate_model.domain_count} overall=#{overall.round(3)}"
66
+ log.debug "[learning_rate] tick: domains=#{rate_model.domain_count} overall=#{overall.round(3)}"
67
67
  { success: true, domain_count: rate_model.domain_count, overall_rate: overall }
68
68
  end
69
69
 
@@ -14,77 +14,77 @@ module Legion
14
14
  related_domains: [], **)
15
15
  result = engine.create_domain(name: name, learning_rate: learning_rate, related_domains: related_domains)
16
16
  if result.is_a?(Hash) && result[:error]
17
- Legion::Logging.warn "[meta_learning] create_domain failed: #{result[:error]}"
17
+ log.warn "[meta_learning] create_domain failed: #{result[:error]}"
18
18
  return result
19
19
  end
20
20
 
21
- Legion::Logging.debug "[meta_learning] domain created: #{result.name} id=#{result.id[0..7]}"
21
+ log.debug "[meta_learning] domain created: #{result.name} id=#{result.id[0..7]}"
22
22
  result.to_h
23
23
  end
24
24
 
25
25
  def register_learning_strategy(name:, strategy_type:, **)
26
26
  result = engine.create_strategy(name: name, strategy_type: strategy_type)
27
27
  if result.is_a?(Hash) && result[:error]
28
- Legion::Logging.warn "[meta_learning] create_strategy failed: #{result[:error]}"
28
+ log.warn "[meta_learning] create_strategy failed: #{result[:error]}"
29
29
  return result
30
30
  end
31
31
 
32
- Legion::Logging.debug "[meta_learning] strategy registered: #{result.name} type=#{result.strategy_type}"
32
+ log.debug "[meta_learning] strategy registered: #{result.name} type=#{result.strategy_type}"
33
33
  result.to_h
34
34
  end
35
35
 
36
36
  def record_learning_episode(domain_id:, success:, strategy_id: nil, **)
37
37
  result = engine.record_episode(domain_id: domain_id, strategy_id: strategy_id, success: success)
38
38
  if result.is_a?(Hash) && result[:error]
39
- Legion::Logging.warn "[meta_learning] record_episode failed: #{result[:error]}"
39
+ log.warn "[meta_learning] record_episode failed: #{result[:error]}"
40
40
  return result
41
41
  end
42
42
 
43
- Legion::Logging.debug "[meta_learning] episode recorded domain=#{result[:domain_name]} " \
44
- "success=#{success} proficiency=#{result[:proficiency].round(4)}"
43
+ log.debug "[meta_learning] episode recorded domain=#{result[:domain_name]} " \
44
+ "success=#{success} proficiency=#{result[:proficiency].round(4)}"
45
45
  result
46
46
  end
47
47
 
48
48
  def recommend_learning_strategy(domain_id:, **)
49
49
  result = engine.recommend_strategy(domain_id: domain_id)
50
- Legion::Logging.debug "[meta_learning] strategy recommendation domain=#{domain_id[0..7]} " \
51
- "recommendation=#{result[:recommendation]}"
50
+ log.debug "[meta_learning] strategy recommendation domain=#{domain_id[0..7]} " \
51
+ "recommendation=#{result[:recommendation]}"
52
52
  result
53
53
  end
54
54
 
55
55
  def check_transfer_learning(source_domain_id:, target_domain_id:, **)
56
56
  result = engine.transfer_check(source_domain_id: source_domain_id, target_domain_id: target_domain_id)
57
- Legion::Logging.debug "[meta_learning] transfer check eligible=#{result[:eligible]}"
57
+ log.debug "[meta_learning] transfer check eligible=#{result[:eligible]}"
58
58
  result
59
59
  end
60
60
 
61
61
  def apply_transfer_bonus(source_domain_id:, target_domain_id:, **)
62
62
  result = engine.apply_transfer(source_domain_id: source_domain_id, target_domain_id: target_domain_id)
63
- Legion::Logging.info "[meta_learning] transfer applied=#{result[:applied]}"
63
+ log.info "[meta_learning] transfer applied=#{result[:applied]}"
64
64
  result
65
65
  end
66
66
 
67
67
  def learning_domain_ranking(limit: 10, **)
68
68
  ranking = engine.domain_ranking(limit: limit)
69
- Legion::Logging.debug "[meta_learning] domain ranking returned #{ranking.size} domains"
69
+ log.debug "[meta_learning] domain ranking returned #{ranking.size} domains"
70
70
  { ranking: ranking, count: ranking.size }
71
71
  end
72
72
 
73
73
  def learning_strategy_ranking(limit: 10, **)
74
74
  ranking = engine.strategy_ranking(limit: limit)
75
- Legion::Logging.debug "[meta_learning] strategy ranking returned #{ranking.size} strategies"
75
+ log.debug "[meta_learning] strategy ranking returned #{ranking.size} strategies"
76
76
  { ranking: ranking, count: ranking.size }
77
77
  end
78
78
 
79
79
  def learning_curve_report(domain_id:, **)
80
80
  result = engine.learning_curve(domain_id: domain_id)
81
81
  if result.is_a?(Hash) && result[:error]
82
- Legion::Logging.warn "[meta_learning] learning_curve failed: #{result[:error]}"
82
+ log.warn "[meta_learning] learning_curve failed: #{result[:error]}"
83
83
  return result
84
84
  end
85
85
 
86
- Legion::Logging.debug "[meta_learning] learning curve domain=#{result[:domain]} " \
87
- "episodes=#{result[:curve].size}"
86
+ log.debug "[meta_learning] learning curve domain=#{result[:domain]} " \
87
+ "episodes=#{result[:curve].size}"
88
88
  result
89
89
  end
90
90
 
@@ -92,15 +92,15 @@ module Legion
92
92
  adapt_result = engine.adapt_rates
93
93
  prune_result = engine.prune_stale_domains
94
94
  stats = engine.to_h
95
- Legion::Logging.info "[meta_learning] update: adapted=#{adapt_result[:count]} " \
96
- "pruned=#{prune_result[:pruned]} domains=#{stats[:domain_count]}"
95
+ log.info "[meta_learning] update: adapted=#{adapt_result[:count]} " \
96
+ "pruned=#{prune_result[:pruned]} domains=#{stats[:domain_count]}"
97
97
  { adapt: adapt_result, prune: prune_result, stats: stats }
98
98
  end
99
99
 
100
100
  def meta_learning_stats(**)
101
101
  stats = engine.to_h
102
- Legion::Logging.debug "[meta_learning] stats domains=#{stats[:domain_count]} " \
103
- "strategies=#{stats[:strategy_count]} efficiency=#{stats[:overall_efficiency]}"
102
+ log.debug "[meta_learning] stats domains=#{stats[:domain_count]} " \
103
+ "strategies=#{stats[:strategy_count]} efficiency=#{stats[:overall_efficiency]}"
104
104
  stats
105
105
  end
106
106
 
@@ -13,9 +13,9 @@ module Legion
13
13
  def register_preference_option(label:, domain: :general, **)
14
14
  result = preference_engine.register_option(label: label, domain: domain)
15
15
  if result[:error]
16
- Legion::Logging.warn "[preference_learning] register failed: #{result[:error]}"
16
+ log.warn "[preference_learning] register failed: #{result[:error]}"
17
17
  else
18
- Legion::Logging.debug "[preference_learning] registered option id=#{result[:id]} label=#{label} domain=#{domain}"
18
+ log.debug "[preference_learning] registered option id=#{result[:id]} label=#{label} domain=#{domain}"
19
19
  end
20
20
  result
21
21
  end
@@ -23,9 +23,9 @@ module Legion
23
23
  def record_preference_comparison(winner_id:, loser_id:, **)
24
24
  result = preference_engine.record_comparison(winner_id: winner_id, loser_id: loser_id)
25
25
  if result[:error]
26
- Legion::Logging.warn "[preference_learning] comparison failed: #{result[:error]}"
26
+ log.warn "[preference_learning] comparison failed: #{result[:error]}"
27
27
  else
28
- Legion::Logging.info "[preference_learning] comparison: winner=#{winner_id} loser=#{loser_id} total=#{result[:comparisons]}"
28
+ log.info "[preference_learning] comparison: winner=#{winner_id} loser=#{loser_id} total=#{result[:comparisons]}"
29
29
  end
30
30
  result
31
31
  end
@@ -33,35 +33,35 @@ module Legion
33
33
  def predict_preference_outcome(option_a_id:, option_b_id:, **)
34
34
  result = preference_engine.predict_preference(option_a_id: option_a_id, option_b_id: option_b_id)
35
35
  if result[:error]
36
- Legion::Logging.warn "[preference_learning] predict failed: #{result[:error]}"
36
+ log.warn "[preference_learning] predict failed: #{result[:error]}"
37
37
  else
38
- Legion::Logging.debug "[preference_learning] predict: preferred=#{result[:preferred_label]} confidence=#{result[:confidence].round(2)}"
38
+ log.debug "[preference_learning] predict: preferred=#{result[:preferred_label]} confidence=#{result[:confidence].round(2)}"
39
39
  end
40
40
  result
41
41
  end
42
42
 
43
43
  def top_preferences_report(domain: nil, limit: 5, **)
44
44
  options = preference_engine.top_preferences(domain: domain, limit: limit)
45
- Legion::Logging.debug "[preference_learning] top #{limit} preferences domain=#{domain.inspect} count=#{options.size}"
45
+ log.debug "[preference_learning] top #{limit} preferences domain=#{domain.inspect} count=#{options.size}"
46
46
  { domain: domain, limit: limit, options: options }
47
47
  end
48
48
 
49
49
  def preference_stability_report(**)
50
50
  stability = preference_engine.preference_stability
51
51
  label = stability < 0.1 ? :stable : :variable
52
- Legion::Logging.debug "[preference_learning] stability=#{stability.round(4)} label=#{label}"
52
+ log.debug "[preference_learning] stability=#{stability.round(4)} label=#{label}"
53
53
  { stability: stability, label: label }
54
54
  end
55
55
 
56
56
  def update_preference_learning(**)
57
57
  count = preference_engine.decay_all
58
- Legion::Logging.debug "[preference_learning] decay cycle: options_updated=#{count}"
58
+ log.debug "[preference_learning] decay cycle: options_updated=#{count}"
59
59
  { decayed: count }
60
60
  end
61
61
 
62
62
  def preference_learning_stats(**)
63
63
  engine_hash = preference_engine.to_h
64
- Legion::Logging.debug "[preference_learning] stats: total_options=#{engine_hash[:total_options]} comparisons=#{engine_hash[:comparisons]}"
64
+ log.debug "[preference_learning] stats: total_options=#{engine_hash[:total_options]} comparisons=#{engine_hash[:comparisons]}"
65
65
  engine_hash.merge(stability_label: preference_engine_stability_label)
66
66
  end
67
67
 
@@ -12,8 +12,8 @@ module Legion
12
12
 
13
13
  def create_skill(name:, domain:, **)
14
14
  skill = engine.create_skill(name: name, domain: domain)
15
- Legion::Logging.debug "[procedural_learning] created skill=#{name} " \
16
- "domain=#{domain} id=#{skill.id[0..7]}"
15
+ log.debug "[procedural_learning] created skill=#{name} " \
16
+ "domain=#{domain} id=#{skill.id[0..7]}"
17
17
  { success: true, skill_id: skill.id, name: name, domain: domain,
18
18
  proficiency: skill.proficiency, stage: skill.stage }
19
19
  end
@@ -26,59 +26,59 @@ module Legion
26
26
 
27
27
  return result unless result.is_a?(Helpers::Production)
28
28
 
29
- Legion::Logging.debug '[procedural_learning] production added ' \
30
- "skill=#{skill_id[0..7]} condition=#{condition}"
29
+ log.debug '[procedural_learning] production added ' \
30
+ "skill=#{skill_id[0..7]} condition=#{condition}"
31
31
  { success: true, production_id: result.id, skill_id: skill_id }
32
32
  end
33
33
 
34
34
  def practice_skill(skill_id:, success:, **)
35
35
  result = engine.practice_skill(skill_id: skill_id, success: success)
36
- Legion::Logging.debug "[procedural_learning] practice skill=#{skill_id[0..7]} " \
37
- "success=#{success} proficiency=#{result[:proficiency]&.round(3)}"
36
+ log.debug "[procedural_learning] practice skill=#{skill_id[0..7]} " \
37
+ "success=#{success} proficiency=#{result[:proficiency]&.round(3)}"
38
38
  result
39
39
  end
40
40
 
41
41
  def execute_production(production_id:, success:, **)
42
42
  result = engine.execute_production(production_id: production_id, success: success)
43
- Legion::Logging.debug "[procedural_learning] execute production=#{production_id[0..7]} " \
44
- "success=#{success}"
43
+ log.debug "[procedural_learning] execute production=#{production_id[0..7]} " \
44
+ "success=#{success}"
45
45
  result
46
46
  end
47
47
 
48
48
  def skill_assessment(skill_id:, **)
49
49
  result = engine.skill_assessment(skill_id: skill_id)
50
- Legion::Logging.debug "[procedural_learning] assessment skill=#{skill_id[0..7]}"
50
+ log.debug "[procedural_learning] assessment skill=#{skill_id[0..7]}"
51
51
  result
52
52
  end
53
53
 
54
54
  def compiled_skills(**)
55
55
  skills = engine.compiled_skills
56
- Legion::Logging.debug "[procedural_learning] compiled count=#{skills.size}"
56
+ log.debug "[procedural_learning] compiled count=#{skills.size}"
57
57
  { success: true, skills: skills.map(&:to_h), count: skills.size }
58
58
  end
59
59
 
60
60
  def autonomous_skills(**)
61
61
  skills = engine.autonomous_skills
62
- Legion::Logging.debug "[procedural_learning] autonomous count=#{skills.size}"
62
+ log.debug "[procedural_learning] autonomous count=#{skills.size}"
63
63
  { success: true, skills: skills.map(&:to_h), count: skills.size }
64
64
  end
65
65
 
66
66
  def most_practiced_skills(limit: 5, **)
67
67
  skills = engine.most_practiced(limit: limit)
68
- Legion::Logging.debug "[procedural_learning] most_practiced limit=#{limit}"
68
+ log.debug "[procedural_learning] most_practiced limit=#{limit}"
69
69
  { success: true, skills: skills.map(&:to_h), count: skills.size }
70
70
  end
71
71
 
72
72
  def update_procedural_learning(**)
73
73
  engine.decay_all
74
74
  pruned = engine.prune_stale
75
- Legion::Logging.debug "[procedural_learning] decay+prune pruned=#{pruned}"
75
+ log.debug "[procedural_learning] decay+prune pruned=#{pruned}"
76
76
  { success: true, pruned: pruned }
77
77
  end
78
78
 
79
79
  def procedural_learning_stats(**)
80
80
  stats = engine.to_h
81
- Legion::Logging.debug "[procedural_learning] stats total=#{stats[:total_skills]}"
81
+ log.debug "[procedural_learning] stats total=#{stats[:total_skills]}"
82
82
  { success: true }.merge(stats)
83
83
  end
84
84
 
@@ -13,83 +13,83 @@ module Legion
13
13
  def create_scaffold(skill_name:, domain:, competence: nil, **)
14
14
  comp = competence || Helpers::Constants::DEFAULT_COMPETENCE
15
15
  scaffold = engine.create_scaffold(skill_name: skill_name, domain: domain, competence: comp)
16
- Legion::Logging.debug "[cognitive_scaffolding] created: skill=#{skill_name} domain=#{domain} " \
17
- "competence=#{scaffold.competence.round(2)} zone=#{scaffold.current_zone}"
16
+ log.debug "[cognitive_scaffolding] created: skill=#{skill_name} domain=#{domain} " \
17
+ "competence=#{scaffold.competence.round(2)} zone=#{scaffold.current_zone}"
18
18
  { success: true, scaffold: scaffold.to_h }
19
19
  end
20
20
 
21
21
  def attempt_scaffolded_task(scaffold_id:, difficulty:, success:, **)
22
22
  scaffold = engine.attempt_scaffolded_task(scaffold_id: scaffold_id, difficulty: difficulty, success: success)
23
23
  unless scaffold
24
- Legion::Logging.debug "[cognitive_scaffolding] attempt: scaffold_id=#{scaffold_id} not found"
24
+ log.debug "[cognitive_scaffolding] attempt: scaffold_id=#{scaffold_id} not found"
25
25
  return { success: false, reason: :not_found, scaffold_id: scaffold_id }
26
26
  end
27
27
 
28
- Legion::Logging.debug "[cognitive_scaffolding] attempt: skill=#{scaffold.skill_name} " \
29
- "difficulty=#{difficulty.round(2)} success=#{success} " \
30
- "competence=#{scaffold.competence.round(2)} zone=#{scaffold.current_zone}"
28
+ log.debug "[cognitive_scaffolding] attempt: skill=#{scaffold.skill_name} " \
29
+ "difficulty=#{difficulty.round(2)} success=#{success} " \
30
+ "competence=#{scaffold.competence.round(2)} zone=#{scaffold.current_zone}"
31
31
  { success: true, scaffold: scaffold.to_h }
32
32
  end
33
33
 
34
34
  def recommend_scaffolded_task(scaffold_id:, **)
35
35
  recommendation = engine.recommend_task(scaffold_id: scaffold_id)
36
36
  unless recommendation
37
- Legion::Logging.debug "[cognitive_scaffolding] recommend: scaffold_id=#{scaffold_id} not found"
37
+ log.debug "[cognitive_scaffolding] recommend: scaffold_id=#{scaffold_id} not found"
38
38
  return { success: false, reason: :not_found, scaffold_id: scaffold_id }
39
39
  end
40
40
 
41
- Legion::Logging.debug "[cognitive_scaffolding] recommend: difficulty=#{recommendation[:difficulty].round(2)} " \
42
- "support=#{recommendation[:support_level]} zone=#{recommendation[:zone]}"
41
+ log.debug "[cognitive_scaffolding] recommend: difficulty=#{recommendation[:difficulty].round(2)} " \
42
+ "support=#{recommendation[:support_level]} zone=#{recommendation[:zone]}"
43
43
  { success: true, recommendation: recommendation }
44
44
  end
45
45
 
46
46
  def mastered_scaffolded_skills(**)
47
47
  skills = engine.mastered_skills
48
- Legion::Logging.debug "[cognitive_scaffolding] mastered: count=#{skills.size}"
48
+ log.debug "[cognitive_scaffolding] mastered: count=#{skills.size}"
49
49
  { success: true, skills: skills.map(&:to_h), count: skills.size }
50
50
  end
51
51
 
52
52
  def zpd_skills(**)
53
53
  skills = engine.zpd_skills
54
- Legion::Logging.debug "[cognitive_scaffolding] zpd: count=#{skills.size}"
54
+ log.debug "[cognitive_scaffolding] zpd: count=#{skills.size}"
55
55
  { success: true, skills: skills.map(&:to_h), count: skills.size }
56
56
  end
57
57
 
58
58
  def domain_scaffolds(domain:, **)
59
59
  scaffolds = engine.by_domain(domain: domain)
60
- Legion::Logging.debug "[cognitive_scaffolding] domain: domain=#{domain} count=#{scaffolds.size}"
60
+ log.debug "[cognitive_scaffolding] domain: domain=#{domain} count=#{scaffolds.size}"
61
61
  { success: true, domain: domain, scaffolds: scaffolds.map(&:to_h), count: scaffolds.size }
62
62
  end
63
63
 
64
64
  def adjust_scaffold_support(scaffold_id:, direction:, **)
65
65
  scaffold = engine.adjust_support(scaffold_id: scaffold_id, direction: direction)
66
66
  unless scaffold
67
- Legion::Logging.debug "[cognitive_scaffolding] adjust_support: scaffold_id=#{scaffold_id} not found"
67
+ log.debug "[cognitive_scaffolding] adjust_support: scaffold_id=#{scaffold_id} not found"
68
68
  return { success: false, reason: :not_found, scaffold_id: scaffold_id }
69
69
  end
70
70
 
71
- Legion::Logging.debug "[cognitive_scaffolding] adjust_support: skill=#{scaffold.skill_name} " \
72
- "direction=#{direction} support=#{scaffold.support_level}"
71
+ log.debug "[cognitive_scaffolding] adjust_support: skill=#{scaffold.skill_name} " \
72
+ "direction=#{direction} support=#{scaffold.support_level}"
73
73
  { success: true, scaffold: scaffold.to_h }
74
74
  end
75
75
 
76
76
  def overall_scaffolded_competence(**)
77
77
  overall = engine.overall_competence
78
- Legion::Logging.debug "[cognitive_scaffolding] overall_competence: #{overall.round(3)}"
78
+ log.debug "[cognitive_scaffolding] overall_competence: #{overall.round(3)}"
79
79
  { success: true, overall_competence: overall.round(4) }
80
80
  end
81
81
 
82
82
  def update_cognitive_scaffolding(**)
83
83
  count = engine.decay_all
84
84
  overall = engine.overall_competence
85
- Legion::Logging.debug "[cognitive_scaffolding] decay: scaffolds=#{count} overall=#{overall.round(3)}"
85
+ log.debug "[cognitive_scaffolding] decay: scaffolds=#{count} overall=#{overall.round(3)}"
86
86
  { success: true, action: :decay, scaffold_count: count, overall_competence: overall.round(4) }
87
87
  end
88
88
 
89
89
  def cognitive_scaffolding_stats(**)
90
90
  stats = engine.to_h
91
- Legion::Logging.debug "[cognitive_scaffolding] stats: total=#{stats[:total_scaffolds]} " \
92
- "mastered=#{stats[:mastered_count]} zpd=#{stats[:zpd_count]}"
91
+ log.debug "[cognitive_scaffolding] stats: total=#{stats[:total_scaffolds]} " \
92
+ "mastered=#{stats[:mastered_count]} zpd=#{stats[:zpd_count]}"
93
93
  { success: true, stats: stats }
94
94
  end
95
95
 
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Agentic
6
6
  module Learning
7
- VERSION = '0.1.1'
7
+ VERSION = '0.1.2'
8
8
  end
9
9
  end
10
10
  end
data/spec/spec_helper.rb CHANGED
@@ -1,41 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/setup'
4
+ require 'legion/logging'
5
+ require 'legion/settings'
6
+ require 'legion/cache/helper'
7
+ require 'legion/crypt/helper'
8
+ require 'legion/data/helper'
9
+ require 'legion/json/helper'
10
+ require 'legion/transport'
4
11
 
5
12
  module Legion
6
- module Logging
7
- def self.debug(_msg); end
8
- def self.info(_msg); end
9
- def self.warn(_msg); end
10
- def self.error(_msg); end
11
- def self.fatal(_msg); end
12
- end
13
-
14
13
  module Extensions
15
- module Core
16
- def self.extended(_base); end
17
- end
18
-
19
14
  module Helpers
20
15
  module Lex
21
- def self.included(_base); end
16
+ include Legion::Logging::Helper
17
+ include Legion::Settings::Helper
18
+ include Legion::Cache::Helper
19
+ include Legion::Crypt::Helper
20
+ include Legion::Data::Helper
21
+ include Legion::JSON::Helper
22
+ include Legion::Transport::Helper
22
23
  end
23
24
  end
24
- end
25
- end
26
25
 
27
- # rubocop:disable Lint/EmptyClass, Style/OneClassPerFile
28
- module Legion
29
- module Extensions
30
26
  module Actors
31
- class Every; end
32
- class Once; end
27
+ class Every
28
+ include Helpers::Lex
29
+ end
30
+
31
+ class Once
32
+ include Helpers::Lex
33
+ end
33
34
  end
34
35
  end
35
36
  end
36
37
  $LOADED_FEATURES << 'legion/extensions/actors/every'
37
38
  $LOADED_FEATURES << 'legion/extensions/actors/once'
38
- # rubocop:enable Lint/EmptyClass, Style/OneClassPerFile
39
39
 
40
40
  require 'legion/extensions/agentic/learning'
41
41
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-agentic-learning
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -9,6 +9,104 @@ bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: legion-cache
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: 1.3.11
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 1.3.11
26
+ - !ruby/object:Gem::Dependency
27
+ name: legion-crypt
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.4.9
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 1.4.9
40
+ - !ruby/object:Gem::Dependency
41
+ name: legion-data
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.4.17
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.4.17
54
+ - !ruby/object:Gem::Dependency
55
+ name: legion-json
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 1.2.1
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 1.2.1
68
+ - !ruby/object:Gem::Dependency
69
+ name: legion-logging
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 1.3.2
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: 1.3.2
82
+ - !ruby/object:Gem::Dependency
83
+ name: legion-settings
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 1.3.14
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: 1.3.14
96
+ - !ruby/object:Gem::Dependency
97
+ name: legion-transport
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 1.3.9
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: 1.3.9
12
110
  - !ruby/object:Gem::Dependency
13
111
  name: rspec
14
112
  requirement: !ruby/object:Gem::Requirement