lex-agentic-homeostasis 0.1.6 → 0.1.8

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 (21) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/README.md +15 -9
  4. data/lib/legion/extensions/agentic/homeostasis/core/actors/regulate.rb +45 -0
  5. data/lib/legion/extensions/agentic/homeostasis/fatigue_model/actors/update.rb +45 -0
  6. data/lib/legion/extensions/agentic/homeostasis/fatigue_model/runners/cognitive_fatigue_model.rb +7 -3
  7. data/lib/legion/extensions/agentic/homeostasis/homeostasis/actors/correct.rb +45 -0
  8. data/lib/legion/extensions/agentic/homeostasis/metabolism/actors/cycle.rb +45 -0
  9. data/lib/legion/extensions/agentic/homeostasis/metabolism/runners/cognitive_metabolism.rb +26 -0
  10. data/lib/legion/extensions/agentic/homeostasis/tempo/actors/adapt.rb +1 -1
  11. data/lib/legion/extensions/agentic/homeostasis/tempo/runners/tempo.rb +17 -0
  12. data/lib/legion/extensions/agentic/homeostasis/version.rb +1 -1
  13. data/lib/legion/extensions/agentic/homeostasis.rb +12 -0
  14. data/spec/legion/extensions/agentic/homeostasis/core/actors/regulate_spec.rb +46 -0
  15. data/spec/legion/extensions/agentic/homeostasis/fatigue_model/actors/update_spec.rb +48 -0
  16. data/spec/legion/extensions/agentic/homeostasis/fatigue_model/runners/cognitive_fatigue_model_spec.rb +15 -4
  17. data/spec/legion/extensions/agentic/homeostasis/homeostasis/actors/correct_spec.rb +48 -0
  18. data/spec/legion/extensions/agentic/homeostasis/metabolism/actors/cycle_spec.rb +48 -0
  19. data/spec/legion/extensions/agentic/homeostasis/metabolism/runners/cognitive_metabolism_spec.rb +34 -0
  20. data/spec/legion/extensions/agentic/homeostasis/tempo/runners/tempo_spec.rb +26 -0
  21. metadata +9 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a85f2765a8038e69114c9e5f4e01e54bc03409f229188ec76418633b88b1a5d
4
- data.tar.gz: 00b290c436ed4cf6128372f8e05283d8bd70e97785f017a9923aa3c105feb711
3
+ metadata.gz: e70864e92a5b67a9c47778e00cd9af8675c51bfcb0fe143eadddda1ba50c8941
4
+ data.tar.gz: 7c3e45c009a7b7004620ffff85de9cc1aed3f85732037e20c214b45e9f2f02b0
5
5
  SHA512:
6
- metadata.gz: 7bfe37a1f14797eb54ad954c18d5a408c24f18e358cd0df914b015d296368acdb1d271ac8b97b6a05a09891a6ab6f699b1645c7421f5e17a62eb317bd808243f
7
- data.tar.gz: b61fe553fe79feaf680a904a503347c438cff4e2a9fd609637684b30b179582da0fa11d1838d322686dead792e11ae91bfbd58b76f8ba1b55c2037049aa3601b
6
+ metadata.gz: 82da2ce2011f8b9becb15d3ea0b0468eff393adf3aa2111d0d1fa7ad37b2bd2f8088b396a95ccef451c0a8a84bb4dccbf23b4e208a1f5fb1a44b2906523e35b4
7
+ data.tar.gz: 20d82bf609f2e3fbf1310591ab8a486d7aed2972ab45278aaf29c5e6bfc43ae134613a8e005a33c4cc6e76dde6db383deac49fb7acebc07eb32ee447b2e05e57
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.8] - 2026-04-22
4
+ ### Fixed
5
+ - Tempo Adapt actor now calls `run_tempo_adaptation` instead of read-only `tempo_report`
6
+ - CognitiveFatigueModel only rests depleted channels (below REST_THRESHOLD) instead of all channels
7
+ ### Added
8
+ - HomeostasisCore regulate actor (30s) — the cross-extension allostatic regulation cycle now fires autonomously
9
+ - CognitiveHomeostasis correct actor (30s), FatigueModel update actor (60s), Metabolism cycle actor (120s)
10
+
11
+ ## [0.1.7] - 2026-04-15
12
+ ### Changed
13
+ - Set `mcp_tools?`, `mcp_tools_deferred?`, and `transport_required?` to `false` — internal cognitive pipeline extension
14
+
3
15
  ## [0.1.6] - 2026-04-06
4
16
 
5
17
  ### Fixed
data/README.md CHANGED
@@ -5,14 +5,15 @@ Domain consolidation gem for homeostasis, self-regulation, and internal state ma
5
5
  ## Overview
6
6
 
7
7
  **Gem**: `lex-agentic-homeostasis`
8
- **Version**: 0.1.0
8
+ **Version**: 0.1.8
9
9
  **Namespace**: `Legion::Extensions::Agentic::Homeostasis`
10
10
 
11
11
  ## Sub-Modules
12
12
 
13
13
  | Sub-Module | Source Gem | Purpose |
14
14
  |---|---|---|
15
- | `Homeostasis::Homeostasis` | `lex-homeostasis` | Seven-setpoint negative feedback regulation, allostatic load |
15
+ | `Homeostasis::Core` | `lex-homeostasis` | Core regulation engine — seven setpoints, allostatic load, negative feedback |
16
+ | `Homeostasis::Homeostasis` | `lex-homeostasis` | Per-variable homeostatic tracking — create, perturb, correct cognitive variables |
16
17
  | `Homeostasis::FatigueModel` | `lex-cognitive-fatigue-model` | Cognitive resource depletion curves across session time |
17
18
  | `Homeostasis::Metabolism` | `lex-cognitive-metabolism` | Energy budget allocation and cognitive metabolic rate |
18
19
  | `Homeostasis::Rhythm` | `lex-cognitive-rhythm` | Circadian-like cognitive rhythm — sinusoidal oscillators, peak/low tide |
@@ -24,7 +25,6 @@ Domain consolidation gem for homeostasis, self-regulation, and internal state ma
24
25
  | `Homeostasis::Cocoon` | `lex-cognitive-cocoon` | Protective withdrawal and recovery state |
25
26
  | `Homeostasis::FossilFuel` | `lex-cognitive-fossil-fuel` | Stored energy from past experience |
26
27
  | `Homeostasis::Hourglass` | `lex-cognitive-hourglass` | Time-based resource depletion tracking |
27
- | `Homeostasis::Core` | `lex-homeostasis` | Core homeostasis regulation engine — seven setpoints, allostatic load, negative feedback regulator |
28
28
  | `Homeostasis::Neuromodulation` | `lex-neuromodulation` | Dopamine/serotonin/norepinephrine/acetylcholine analogs |
29
29
  | `Homeostasis::NeuralOscillation` | `lex-neural-oscillation` | Gamma/beta/alpha/theta/delta bands, cross-frequency coupling |
30
30
  | `Homeostasis::Temporal` | `lex-temporal` | Temporal reasoning — event ordering, duration estimation |
@@ -35,12 +35,18 @@ Domain consolidation gem for homeostasis, self-regulation, and internal state ma
35
35
 
36
36
  ## Actors
37
37
 
38
- - `Homeostasis::NeuralOscillation::Actors::Tick` interval actor, advances oscillation bands
39
- - `Homeostasis::Neuromodulation::Actors::Drift` — interval actor, applies neuromodulator drift
40
- - `Homeostasis::Surplus::Actors::Replenish` interval actor, replenishes cognitive surplus
41
- - `Homeostasis::Tectonics::Actors::DriftTick` interval actor, advances tectonic drift
42
- - `Homeostasis::Tempo::Actors::Adapt` interval actor, adapts processing tempo
43
- - `Homeostasis::Tide::Actors::TideCycle` runs every 60s, executes `tide_maintenance`
38
+ | Actor | Interval | What It Does |
39
+ |-------|----------|--------------|
40
+ | `Core::Actor::Regulate` | Every 30s | Runs negative-feedback regulation across all seven setpoints |
41
+ | `Homeostasis::Actor::Correct` | Every 30s | Corrects all out-of-tolerance cognitive variables |
42
+ | `FatigueModel::Actor::Update` | Every 60s | Advances fatigue depletion curve |
43
+ | `Metabolism::Actor::Cycle` | Every 120s | Runs all metabolic cycles |
44
+ | `Tempo::Actor::Adapt` | Every 60s | Adapts processing tempo to current load |
45
+ | `Tide::Actors::TideCycle` | Every 60s | Executes tidal maintenance cycle |
46
+ | `Neuromodulation::Actors::Drift` | interval | Applies neuromodulator drift |
47
+ | `NeuralOscillation::Actors::Tick` | interval | Advances oscillation bands |
48
+ | `Surplus::Actors::Replenish` | interval | Replenishes cognitive surplus |
49
+ | `Tectonics::Actors::DriftTick` | interval | Advances tectonic drift |
44
50
 
45
51
  ## Installation
46
52
 
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/actors/every'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Homeostasis
9
+ module Core
10
+ module Actor
11
+ class Regulate < Legion::Extensions::Actors::Every
12
+ def runner_class
13
+ Legion::Extensions::Agentic::Homeostasis::Core::Runners::Homeostasis
14
+ end
15
+
16
+ def runner_function
17
+ 'regulate'
18
+ end
19
+
20
+ def time
21
+ 30
22
+ end
23
+
24
+ def run_now?
25
+ false
26
+ end
27
+
28
+ def use_runner?
29
+ false
30
+ end
31
+
32
+ def check_subtask?
33
+ false
34
+ end
35
+
36
+ def generate_task?
37
+ false
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/actors/every'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Homeostasis
9
+ module FatigueModel
10
+ module Actor
11
+ class Update < Legion::Extensions::Actors::Every
12
+ def runner_class
13
+ Legion::Extensions::Agentic::Homeostasis::FatigueModel::Runners::CognitiveFatigueModel
14
+ end
15
+
16
+ def runner_function
17
+ 'update_cognitive_fatigue_model'
18
+ end
19
+
20
+ def time
21
+ 60
22
+ end
23
+
24
+ def run_now?
25
+ false
26
+ end
27
+
28
+ def use_runner?
29
+ false
30
+ end
31
+
32
+ def check_subtask?
33
+ false
34
+ end
35
+
36
+ def generate_task?
37
+ false
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -63,9 +63,13 @@ module Legion
63
63
  end
64
64
 
65
65
  def update_cognitive_fatigue_model(**)
66
- result = engine.rest_all
67
- log.info('[cognitive_fatigue] model updated: all channels rested')
68
- result
66
+ depleted = engine.channels_needing_rest
67
+ rested_channels = depleted.map { |ch| engine.rest_channel(channel_name: ch[:name]) }
68
+ log.info("[cognitive_fatigue] model updated: #{depleted.size} depleted channels rested")
69
+ { rested: depleted.size, channels: rested_channels, overall_fatigue: engine.overall_fatigue.round(4) }
70
+ rescue StandardError => e
71
+ log.error("[cognitive_fatigue] update_cognitive_fatigue_model failed: #{e.message}")
72
+ { rested: 0, channels: [], error: e.message }
69
73
  end
70
74
 
71
75
  def cognitive_fatigue_model_stats(**)
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/actors/every'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Homeostasis
9
+ module Homeostasis
10
+ module Actor
11
+ class Correct < Legion::Extensions::Actors::Every
12
+ def runner_class
13
+ Legion::Extensions::Agentic::Homeostasis::Homeostasis::Runners::CognitiveHomeostasis
14
+ end
15
+
16
+ def runner_function
17
+ 'update_cognitive_homeostasis'
18
+ end
19
+
20
+ def time
21
+ 30
22
+ end
23
+
24
+ def run_now?
25
+ false
26
+ end
27
+
28
+ def use_runner?
29
+ false
30
+ end
31
+
32
+ def check_subtask?
33
+ false
34
+ end
35
+
36
+ def generate_task?
37
+ false
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/actors/every'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Agentic
8
+ module Homeostasis
9
+ module Metabolism
10
+ module Actor
11
+ class Cycle < Legion::Extensions::Actors::Every
12
+ def runner_class
13
+ Legion::Extensions::Agentic::Homeostasis::Metabolism::Runners::CognitiveMetabolism
14
+ end
15
+
16
+ def runner_function
17
+ 'run_all_cycles'
18
+ end
19
+
20
+ def time
21
+ 120
22
+ end
23
+
24
+ def run_now?
25
+ false
26
+ end
27
+
28
+ def use_runner?
29
+ false
30
+ end
31
+
32
+ def check_subtask?
33
+ false
34
+ end
35
+
36
+ def generate_task?
37
+ false
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -73,6 +73,32 @@ module Legion
73
73
  { success: false, error: e.message }
74
74
  end
75
75
 
76
+ def run_all_cycles(**)
77
+ reserves = engine.all_reserves
78
+ if reserves.empty?
79
+ log.info('[cognitive_metabolism] run_all_cycles: no reserves to cycle')
80
+ return { success: true, cycled: 0, reserves: 0, results: [], failures: [] }
81
+ end
82
+
83
+ results = []
84
+ failures = []
85
+
86
+ reserves.each_key do |id|
87
+ result = engine.run_cycle(reserve_id: id, operations: [])
88
+ log.debug("[cognitive_metabolism] auto-cycle: reserve=#{id} state=#{result[:reserve_state]}")
89
+ results << result
90
+ rescue StandardError => e
91
+ log.error("[cognitive_metabolism] auto-cycle failed for reserve=#{id}: #{e.message}")
92
+ failures << { reserve_id: id, error: e.message }
93
+ end
94
+
95
+ log.info("[cognitive_metabolism] run_all_cycles: #{results.size}/#{reserves.size} reserves cycled")
96
+ { success: failures.empty?, cycled: results.size, reserves: reserves.size, results: results, failures: failures }
97
+ rescue StandardError => e
98
+ log.error("[cognitive_metabolism] run_all_cycles failed: #{e.message}")
99
+ { success: false, cycled: 0, reserves: 0, results: [], failures: [], error: e.message }
100
+ end
101
+
76
102
  private
77
103
 
78
104
  def engine
@@ -14,7 +14,7 @@ module Legion
14
14
  end
15
15
 
16
16
  def runner_function
17
- 'tempo_report'
17
+ 'run_tempo_adaptation'
18
18
  end
19
19
 
20
20
  def time
@@ -76,6 +76,23 @@ module Legion
76
76
  report
77
77
  end
78
78
 
79
+ def run_tempo_adaptation(**)
80
+ mismatched = tempo_engine.domains_mismatched
81
+ adapted = mismatched.filter_map do |domain|
82
+ latest = tempo_engine.records[domain]&.last
83
+ next unless latest
84
+
85
+ record = tempo_engine.adapt_tempo(domain: domain, target: latest.task_tempo_requirement)
86
+ record&.to_h
87
+ end
88
+
89
+ log.info("[cognitive_tempo] adaptation cycle: #{adapted.size}/#{mismatched.size} domains adapted")
90
+ { adapted: adapted.size, domains: mismatched.size, results: adapted }
91
+ rescue StandardError => e
92
+ log.error("[cognitive_tempo] run_tempo_adaptation failed: #{e.message}")
93
+ { adapted: 0, domains: 0, error: e.message }
94
+ end
95
+
79
96
  private
80
97
 
81
98
  def tempo_engine
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Agentic
6
6
  module Homeostasis
7
- VERSION = '0.1.6'
7
+ VERSION = '0.1.8'
8
8
  end
9
9
  end
10
10
  end
@@ -31,6 +31,18 @@ module Legion
31
31
  def self.remote_invocable?
32
32
  false
33
33
  end
34
+
35
+ def self.mcp_tools?
36
+ false
37
+ end
38
+
39
+ def self.mcp_tools_deferred?
40
+ false
41
+ end
42
+
43
+ def self.transport_required?
44
+ false
45
+ end
34
46
  end
35
47
  end
36
48
  end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Actors
6
+ class Every # rubocop:disable Lint/EmptyClass
7
+ end
8
+ end
9
+ end
10
+ end
11
+
12
+ $LOADED_FEATURES << 'legion/extensions/actors/every'
13
+
14
+ require_relative '../../../../../../../lib/legion/extensions/agentic/homeostasis/core/actors/regulate'
15
+
16
+ RSpec.describe Legion::Extensions::Agentic::Homeostasis::Core::Actor::Regulate do
17
+ subject(:actor) { described_class.new }
18
+
19
+ describe '#runner_class' do
20
+ it { expect(actor.runner_class).to eq Legion::Extensions::Agentic::Homeostasis::Core::Runners::Homeostasis }
21
+ end
22
+
23
+ describe '#runner_function' do
24
+ it { expect(actor.runner_function).to eq 'regulate' }
25
+ end
26
+
27
+ describe '#time' do
28
+ it { expect(actor.time).to eq 30 }
29
+ end
30
+
31
+ describe '#run_now?' do
32
+ it { expect(actor.run_now?).to be false }
33
+ end
34
+
35
+ describe '#use_runner?' do
36
+ it { expect(actor.use_runner?).to be false }
37
+ end
38
+
39
+ describe '#check_subtask?' do
40
+ it { expect(actor.check_subtask?).to be false }
41
+ end
42
+
43
+ describe '#generate_task?' do
44
+ it { expect(actor.generate_task?).to be false }
45
+ end
46
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Actors
6
+ class Every # rubocop:disable Lint/EmptyClass
7
+ end
8
+ end
9
+ end
10
+ end
11
+
12
+ $LOADED_FEATURES << 'legion/extensions/actors/every'
13
+
14
+ require_relative '../../../../../../../lib/legion/extensions/agentic/homeostasis/fatigue_model/actors/update'
15
+
16
+ RSpec.describe Legion::Extensions::Agentic::Homeostasis::FatigueModel::Actor::Update do
17
+ subject(:actor) { described_class.new }
18
+
19
+ describe '#runner_class' do
20
+ it do
21
+ expect(actor.runner_class).to eq Legion::Extensions::Agentic::Homeostasis::FatigueModel::Runners::CognitiveFatigueModel
22
+ end
23
+ end
24
+
25
+ describe '#runner_function' do
26
+ it { expect(actor.runner_function).to eq 'update_cognitive_fatigue_model' }
27
+ end
28
+
29
+ describe '#time' do
30
+ it { expect(actor.time).to eq 60 }
31
+ end
32
+
33
+ describe '#run_now?' do
34
+ it { expect(actor.run_now?).to be false }
35
+ end
36
+
37
+ describe '#use_runner?' do
38
+ it { expect(actor.use_runner?).to be false }
39
+ end
40
+
41
+ describe '#check_subtask?' do
42
+ it { expect(actor.check_subtask?).to be false }
43
+ end
44
+
45
+ describe '#generate_task?' do
46
+ it { expect(actor.generate_task?).to be false }
47
+ end
48
+ end
@@ -119,16 +119,27 @@ RSpec.describe Legion::Extensions::Agentic::Homeostasis::FatigueModel::Runners::
119
119
 
120
120
  describe '#update_cognitive_fatigue_model' do
121
121
  before do
122
- Legion::Extensions::Agentic::Homeostasis::FatigueModel::Helpers::Constants::CHANNELS.each do |ch|
123
- 2.times { client.process_cognitive_task(channel_name: ch) }
124
- end
122
+ # Deplete decision_making past REST_THRESHOLD (0.3) needs 12+ tasks at 0.06/task
123
+ 13.times { client.process_cognitive_task(channel_name: :decision_making) }
125
124
  end
126
125
 
127
- it 'rests all channels and returns stats' do
126
+ it 'rests depleted channels and returns stats' do
128
127
  before_fatigue = client.overall_fatigue_report[:overall_fatigue]
129
128
  result = client.update_cognitive_fatigue_model
130
129
  expect(result[:overall_fatigue]).to be > before_fatigue
131
130
  end
131
+
132
+ it 'returns rested count and channels keys' do
133
+ result = client.update_cognitive_fatigue_model
134
+ expect(result).to have_key(:rested)
135
+ expect(result).to have_key(:channels)
136
+ expect(result[:rested]).to be >= 1
137
+ end
138
+
139
+ it 'only rests channels below REST_THRESHOLD' do
140
+ result = client.update_cognitive_fatigue_model
141
+ expect(result[:rested]).to be < Legion::Extensions::Agentic::Homeostasis::FatigueModel::Helpers::Constants::CHANNELS.size
142
+ end
132
143
  end
133
144
 
134
145
  describe '#cognitive_fatigue_model_stats' do
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Actors
6
+ class Every # rubocop:disable Lint/EmptyClass
7
+ end
8
+ end
9
+ end
10
+ end
11
+
12
+ $LOADED_FEATURES << 'legion/extensions/actors/every'
13
+
14
+ require_relative '../../../../../../../lib/legion/extensions/agentic/homeostasis/homeostasis/actors/correct'
15
+
16
+ RSpec.describe Legion::Extensions::Agentic::Homeostasis::Homeostasis::Actor::Correct do
17
+ subject(:actor) { described_class.new }
18
+
19
+ describe '#runner_class' do
20
+ it do
21
+ expect(actor.runner_class).to eq Legion::Extensions::Agentic::Homeostasis::Homeostasis::Runners::CognitiveHomeostasis
22
+ end
23
+ end
24
+
25
+ describe '#runner_function' do
26
+ it { expect(actor.runner_function).to eq 'update_cognitive_homeostasis' }
27
+ end
28
+
29
+ describe '#time' do
30
+ it { expect(actor.time).to eq 30 }
31
+ end
32
+
33
+ describe '#run_now?' do
34
+ it { expect(actor.run_now?).to be false }
35
+ end
36
+
37
+ describe '#use_runner?' do
38
+ it { expect(actor.use_runner?).to be false }
39
+ end
40
+
41
+ describe '#check_subtask?' do
42
+ it { expect(actor.check_subtask?).to be false }
43
+ end
44
+
45
+ describe '#generate_task?' do
46
+ it { expect(actor.generate_task?).to be false }
47
+ end
48
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Actors
6
+ class Every # rubocop:disable Lint/EmptyClass
7
+ end
8
+ end
9
+ end
10
+ end
11
+
12
+ $LOADED_FEATURES << 'legion/extensions/actors/every'
13
+
14
+ require_relative '../../../../../../../lib/legion/extensions/agentic/homeostasis/metabolism/actors/cycle'
15
+
16
+ RSpec.describe Legion::Extensions::Agentic::Homeostasis::Metabolism::Actor::Cycle do
17
+ subject(:actor) { described_class.new }
18
+
19
+ describe '#runner_class' do
20
+ it do
21
+ expect(actor.runner_class).to eq Legion::Extensions::Agentic::Homeostasis::Metabolism::Runners::CognitiveMetabolism
22
+ end
23
+ end
24
+
25
+ describe '#runner_function' do
26
+ it { expect(actor.runner_function).to eq 'run_all_cycles' }
27
+ end
28
+
29
+ describe '#time' do
30
+ it { expect(actor.time).to eq 120 }
31
+ end
32
+
33
+ describe '#run_now?' do
34
+ it { expect(actor.run_now?).to be false }
35
+ end
36
+
37
+ describe '#use_runner?' do
38
+ it { expect(actor.use_runner?).to be false }
39
+ end
40
+
41
+ describe '#check_subtask?' do
42
+ it { expect(actor.check_subtask?).to be false }
43
+ end
44
+
45
+ describe '#generate_task?' do
46
+ it { expect(actor.generate_task?).to be false }
47
+ end
48
+ end
@@ -213,4 +213,38 @@ RSpec.describe Legion::Extensions::Agentic::Homeostasis::Metabolism::Runners::Co
213
213
  expect(result[:success]).to be false
214
214
  end
215
215
  end
216
+
217
+ describe '#run_all_cycles' do
218
+ it 'returns success: true and zero counts when no reserves exist' do
219
+ result = client.run_all_cycles
220
+ expect(result[:success]).to be true
221
+ expect(result[:cycled]).to eq(0)
222
+ expect(result[:reserves]).to eq(0)
223
+ expect(result[:results]).to eq([])
224
+ expect(result[:failures]).to eq([])
225
+ end
226
+
227
+ it 'cycles all existing reserves' do
228
+ client.create_reserve
229
+ client.create_reserve
230
+ result = client.run_all_cycles
231
+ expect(result[:reserves]).to eq(2)
232
+ expect(result[:cycled]).to eq(2)
233
+ end
234
+
235
+ it 'returns cycled count equal to reserves count on success' do
236
+ client.create_reserve
237
+ result = client.run_all_cycles
238
+ expect(result[:cycled]).to eq(result[:reserves])
239
+ end
240
+
241
+ it 'returns success: true with populated results and empty failures' do
242
+ client.create_reserve
243
+ result = client.run_all_cycles
244
+ expect(result[:success]).to be true
245
+ expect(result[:results]).to be_an(Array)
246
+ expect(result[:results].size).to eq(1)
247
+ expect(result[:failures]).to eq([])
248
+ end
249
+ end
216
250
  end
@@ -107,4 +107,30 @@ RSpec.describe Legion::Extensions::Agentic::Homeostasis::Tempo::Runners::Tempo d
107
107
  expect(report[:domains]).to include(:a, :b)
108
108
  end
109
109
  end
110
+
111
+ describe '#run_tempo_adaptation' do
112
+ it 'returns adapted and domains counts' do
113
+ result = client.run_tempo_adaptation
114
+ expect(result).to have_key(:adapted)
115
+ expect(result).to have_key(:domains)
116
+ end
117
+
118
+ it 'returns 0 adapted when no records exist' do
119
+ result = client.run_tempo_adaptation
120
+ expect(result[:adapted]).to eq(0)
121
+ expect(result[:domains]).to eq(0)
122
+ end
123
+
124
+ it 'adapts mismatched domains when records exist' do
125
+ client.record_tempo(domain: :code, current_tempo: 0.1, task_requirement: 0.9)
126
+ result = client.run_tempo_adaptation
127
+ expect(result[:adapted]).to be >= 1
128
+ end
129
+
130
+ it 'returns results array' do
131
+ client.record_tempo(domain: :analysis, current_tempo: 0.2, task_requirement: 0.8)
132
+ result = client.run_tempo_adaptation
133
+ expect(result[:results]).to be_a(Array)
134
+ end
135
+ end
110
136
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-agentic-homeostasis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -184,6 +184,7 @@ files:
184
184
  - lib/legion/extensions/agentic/homeostasis/cocoon/runners/cognitive_cocoon.rb
185
185
  - lib/legion/extensions/agentic/homeostasis/cocoon/version.rb
186
186
  - lib/legion/extensions/agentic/homeostasis/core.rb
187
+ - lib/legion/extensions/agentic/homeostasis/core/actors/regulate.rb
187
188
  - lib/legion/extensions/agentic/homeostasis/core/client.rb
188
189
  - lib/legion/extensions/agentic/homeostasis/core/helpers/allostatic_load.rb
189
190
  - lib/legion/extensions/agentic/homeostasis/core/helpers/constants.rb
@@ -192,6 +193,7 @@ files:
192
193
  - lib/legion/extensions/agentic/homeostasis/core/runners/homeostasis.rb
193
194
  - lib/legion/extensions/agentic/homeostasis/core/version.rb
194
195
  - lib/legion/extensions/agentic/homeostasis/fatigue_model.rb
196
+ - lib/legion/extensions/agentic/homeostasis/fatigue_model/actors/update.rb
195
197
  - lib/legion/extensions/agentic/homeostasis/fatigue_model/client.rb
196
198
  - lib/legion/extensions/agentic/homeostasis/fatigue_model/helpers/channel.rb
197
199
  - lib/legion/extensions/agentic/homeostasis/fatigue_model/helpers/client.rb
@@ -216,6 +218,7 @@ files:
216
218
  - lib/legion/extensions/agentic/homeostasis/furnace/runners/cognitive_furnace.rb
217
219
  - lib/legion/extensions/agentic/homeostasis/furnace/version.rb
218
220
  - lib/legion/extensions/agentic/homeostasis/homeostasis.rb
221
+ - lib/legion/extensions/agentic/homeostasis/homeostasis/actors/correct.rb
219
222
  - lib/legion/extensions/agentic/homeostasis/homeostasis/client.rb
220
223
  - lib/legion/extensions/agentic/homeostasis/homeostasis/helpers/cognitive_variable.rb
221
224
  - lib/legion/extensions/agentic/homeostasis/homeostasis/helpers/constants.rb
@@ -231,6 +234,7 @@ files:
231
234
  - lib/legion/extensions/agentic/homeostasis/hourglass/runners/cognitive_hourglass.rb
232
235
  - lib/legion/extensions/agentic/homeostasis/hourglass/version.rb
233
236
  - lib/legion/extensions/agentic/homeostasis/metabolism.rb
237
+ - lib/legion/extensions/agentic/homeostasis/metabolism/actors/cycle.rb
234
238
  - lib/legion/extensions/agentic/homeostasis/metabolism/client.rb
235
239
  - lib/legion/extensions/agentic/homeostasis/metabolism/helpers/constants.rb
236
240
  - lib/legion/extensions/agentic/homeostasis/metabolism/helpers/energy_reserve.rb
@@ -338,12 +342,14 @@ files:
338
342
  - spec/legion/extensions/agentic/homeostasis/cocoon/helpers/cocoon_spec.rb
339
343
  - spec/legion/extensions/agentic/homeostasis/cocoon/helpers/constants_spec.rb
340
344
  - spec/legion/extensions/agentic/homeostasis/cocoon/helpers/incubator_spec.rb
345
+ - spec/legion/extensions/agentic/homeostasis/core/actors/regulate_spec.rb
341
346
  - spec/legion/extensions/agentic/homeostasis/core/client_spec.rb
342
347
  - spec/legion/extensions/agentic/homeostasis/core/helpers/allostatic_load_spec.rb
343
348
  - spec/legion/extensions/agentic/homeostasis/core/helpers/constants_spec.rb
344
349
  - spec/legion/extensions/agentic/homeostasis/core/helpers/regulator_spec.rb
345
350
  - spec/legion/extensions/agentic/homeostasis/core/helpers/setpoint_spec.rb
346
351
  - spec/legion/extensions/agentic/homeostasis/core/runners/homeostasis_spec.rb
352
+ - spec/legion/extensions/agentic/homeostasis/fatigue_model/actors/update_spec.rb
347
353
  - spec/legion/extensions/agentic/homeostasis/fatigue_model/client_spec.rb
348
354
  - spec/legion/extensions/agentic/homeostasis/fatigue_model/helpers/channel_spec.rb
349
355
  - spec/legion/extensions/agentic/homeostasis/fatigue_model/helpers/constants_spec.rb
@@ -361,6 +367,7 @@ files:
361
367
  - spec/legion/extensions/agentic/homeostasis/furnace/helpers/furnace_engine_spec.rb
362
368
  - spec/legion/extensions/agentic/homeostasis/furnace/helpers/ore_spec.rb
363
369
  - spec/legion/extensions/agentic/homeostasis/furnace/runners/cognitive_furnace_spec.rb
370
+ - spec/legion/extensions/agentic/homeostasis/homeostasis/actors/correct_spec.rb
364
371
  - spec/legion/extensions/agentic/homeostasis/homeostasis/client_spec.rb
365
372
  - spec/legion/extensions/agentic/homeostasis/homeostasis/helpers/cognitive_variable_spec.rb
366
373
  - spec/legion/extensions/agentic/homeostasis/homeostasis/helpers/constants_spec.rb
@@ -372,6 +379,7 @@ files:
372
379
  - spec/legion/extensions/agentic/homeostasis/hourglass/helpers/hourglass_engine_spec.rb
373
380
  - spec/legion/extensions/agentic/homeostasis/hourglass/helpers/hourglass_spec.rb
374
381
  - spec/legion/extensions/agentic/homeostasis/hourglass/runners/cognitive_hourglass_spec.rb
382
+ - spec/legion/extensions/agentic/homeostasis/metabolism/actors/cycle_spec.rb
375
383
  - spec/legion/extensions/agentic/homeostasis/metabolism/client_spec.rb
376
384
  - spec/legion/extensions/agentic/homeostasis/metabolism/helpers/constants_spec.rb
377
385
  - spec/legion/extensions/agentic/homeostasis/metabolism/helpers/energy_reserve_spec.rb