lex-agentic-affect 0.1.12 → 0.1.14
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 +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +1 -1
- data/lib/legion/extensions/agentic/affect/emotion/actors/momentum_decay.rb +1 -1
- data/lib/legion/extensions/agentic/affect/emotion/client.rb +1 -2
- data/lib/legion/extensions/agentic/affect/emotion/runners/gut.rb +2 -2
- data/lib/legion/extensions/agentic/affect/emotion/runners/valence.rb +12 -1
- data/lib/legion/extensions/agentic/affect/empathy/actors/decay_models.rb +1 -1
- data/lib/legion/extensions/agentic/affect/fatigue/actors/update_fatigue.rb +1 -1
- data/lib/legion/extensions/agentic/affect/flow/actors/update_flow.rb +1 -1
- data/lib/legion/extensions/agentic/affect/interoception/actors/decay.rb +1 -1
- data/lib/legion/extensions/agentic/affect/mood/actors/update_mood.rb +1 -1
- data/lib/legion/extensions/agentic/affect/reappraisal/actors/auto_regulate.rb +1 -1
- data/lib/legion/extensions/agentic/affect/regulation/actors/regulate_emotion.rb +1 -1
- data/lib/legion/extensions/agentic/affect/resilience/actors/update_resilience.rb +1 -1
- data/lib/legion/extensions/agentic/affect/resonance/helpers/resonance_engine.rb +2 -4
- data/lib/legion/extensions/agentic/affect/somatic_marker/actors/decay.rb +1 -1
- data/lib/legion/extensions/agentic/affect/somatic_marker/helpers/body_state.rb +3 -3
- data/lib/legion/extensions/agentic/affect/version.rb +1 -1
- data/spec/legion/extensions/agentic/affect/emotion/runners/gut_spec.rb +22 -0
- data/spec/legion/extensions/agentic/affect/emotion/runners/valence_spec.rb +8 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9223ccb51846d7da0c831d72bc85524df797f98999541719f8ec597a13213b29
|
|
4
|
+
data.tar.gz: a0a68749e8576d34a5770818a67db14c6e1c9aafee1432f0115c809bf3285561
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c18f597848a6ac85c6f85a5d61b6b21cc431d003eddd0b273fa9908410be16941c200a1bc383b7bfca394d2cec444ce898ad3f2795705161cfe2a11fa1a9c7b0
|
|
7
|
+
data.tar.gz: 23f3308edf09101470dc0615b3dd82d9e2a7edd9faa27226f54d065933eae92831c5aa78e0d8f4c47aa1a37d33712d364b9b81213ddf8604094c0d1988e8f081
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.14] - 2026-10-29
|
|
4
|
+
### Fixed
|
|
5
|
+
- Decay emotional momentum toward rest instead of introducing synthetic valence and arousal during idle maintenance.
|
|
6
|
+
|
|
7
|
+
## [0.1.13] - 2026-05-07
|
|
8
|
+
### Fixed
|
|
9
|
+
- Valence evaluation now lazily initializes and updates domain signal counts so familiarity scoring works in runner-host usage.
|
|
10
|
+
|
|
3
11
|
## [0.1.12] - 2026-04-22
|
|
4
12
|
### Added
|
|
5
13
|
- 6 new maintenance actors: Mood::Actor::UpdateMood (60s), Flow::Actor::UpdateFlow (30s), Fatigue::Actor::UpdateFatigue (60s), Resilience::Actor::UpdateResilience (120s), Regulation::Actor::RegulateEmotion (60s), Empathy::Actor::DecayModels (300s)
|
data/README.md
CHANGED
|
@@ -8,7 +8,7 @@ module Legion
|
|
|
8
8
|
module Affect
|
|
9
9
|
module Emotion
|
|
10
10
|
module Actor
|
|
11
|
-
class MomentumDecay < Legion::Extensions::Actors::Every
|
|
11
|
+
class MomentumDecay < Legion::Extensions::Actors::Every
|
|
12
12
|
def runner_class
|
|
13
13
|
Legion::Extensions::Agentic::Affect::Emotion::Runners::Gut
|
|
14
14
|
end
|
|
@@ -19,11 +19,10 @@ module Legion
|
|
|
19
19
|
def initialize(**)
|
|
20
20
|
@emotion_baseline = Helpers::Baseline.new
|
|
21
21
|
@emotion_momentum = Helpers::Momentum.new
|
|
22
|
-
@domain_counts = Hash.new(0)
|
|
23
22
|
end
|
|
24
23
|
|
|
25
24
|
def track_domain(domain)
|
|
26
|
-
|
|
25
|
+
domain_counts[domain] += 1
|
|
27
26
|
end
|
|
28
27
|
|
|
29
28
|
private
|
|
@@ -39,9 +39,9 @@ module Legion
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def decay_momentum(**)
|
|
42
|
-
neutral =
|
|
42
|
+
neutral = Helpers::Valence.new_valence
|
|
43
43
|
momentum = emotion_momentum
|
|
44
|
-
momentum.update(neutral, 0.
|
|
44
|
+
momentum.update(neutral, 0.0)
|
|
45
45
|
stability = momentum.stability
|
|
46
46
|
|
|
47
47
|
log.debug("[emotion] momentum decay: stability=#{stability.round(2)}")
|
|
@@ -31,6 +31,7 @@ module Legion
|
|
|
31
31
|
novelty: novelty_raw, familiarity: familiarity_raw }[dim]
|
|
32
32
|
baseline.update(dim, raw)
|
|
33
33
|
end
|
|
34
|
+
record_domain_signal(domain)
|
|
34
35
|
|
|
35
36
|
magnitude = Helpers::Valence.magnitude(valence)
|
|
36
37
|
dominant = Helpers::Valence.dominant_dimension(valence)
|
|
@@ -111,6 +112,16 @@ module Legion
|
|
|
111
112
|
@emotion_baseline ||= Helpers::Baseline.new
|
|
112
113
|
end
|
|
113
114
|
|
|
115
|
+
def domain_counts
|
|
116
|
+
@domain_counts ||= Hash.new(0)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def record_domain_signal(domain)
|
|
120
|
+
return unless domain
|
|
121
|
+
|
|
122
|
+
domain_counts[domain] += 1
|
|
123
|
+
end
|
|
124
|
+
|
|
114
125
|
def compute_urgency(signal, source_type, deadline)
|
|
115
126
|
deadline_urgency = 0.0
|
|
116
127
|
if deadline
|
|
@@ -141,7 +152,7 @@ module Legion
|
|
|
141
152
|
end
|
|
142
153
|
|
|
143
154
|
def compute_familiarity(domain)
|
|
144
|
-
signal_count =
|
|
155
|
+
signal_count = domain_counts.fetch(domain, 0)
|
|
145
156
|
Helpers::Valence.clamp(signal_count.to_f / Helpers::Valence::FAMILIARITY_SATURATION)
|
|
146
157
|
end
|
|
147
158
|
end
|
|
@@ -8,7 +8,7 @@ module Legion
|
|
|
8
8
|
module Affect
|
|
9
9
|
module Empathy
|
|
10
10
|
module Actor
|
|
11
|
-
class DecayModels < Legion::Extensions::Actors::Every
|
|
11
|
+
class DecayModels < Legion::Extensions::Actors::Every
|
|
12
12
|
def runner_class
|
|
13
13
|
Legion::Extensions::Agentic::Affect::Empathy::Runners::Empathy
|
|
14
14
|
end
|
|
@@ -8,7 +8,7 @@ module Legion
|
|
|
8
8
|
module Affect
|
|
9
9
|
module Fatigue
|
|
10
10
|
module Actor
|
|
11
|
-
class UpdateFatigue < Legion::Extensions::Actors::Every
|
|
11
|
+
class UpdateFatigue < Legion::Extensions::Actors::Every
|
|
12
12
|
def runner_class
|
|
13
13
|
Legion::Extensions::Agentic::Affect::Fatigue::Runners::Fatigue
|
|
14
14
|
end
|
|
@@ -8,7 +8,7 @@ module Legion
|
|
|
8
8
|
module Affect
|
|
9
9
|
module Flow
|
|
10
10
|
module Actor
|
|
11
|
-
class UpdateFlow < Legion::Extensions::Actors::Every
|
|
11
|
+
class UpdateFlow < Legion::Extensions::Actors::Every
|
|
12
12
|
def runner_class
|
|
13
13
|
Legion::Extensions::Agentic::Affect::Flow::Runners::Flow
|
|
14
14
|
end
|
|
@@ -8,7 +8,7 @@ module Legion
|
|
|
8
8
|
module Affect
|
|
9
9
|
module Interoception
|
|
10
10
|
module Actor
|
|
11
|
-
class Decay < Legion::Extensions::Actors::Every
|
|
11
|
+
class Decay < Legion::Extensions::Actors::Every
|
|
12
12
|
def runner_class
|
|
13
13
|
Legion::Extensions::Agentic::Affect::Interoception::Runners::Interoception
|
|
14
14
|
end
|
|
@@ -8,7 +8,7 @@ module Legion
|
|
|
8
8
|
module Affect
|
|
9
9
|
module Mood
|
|
10
10
|
module Actor
|
|
11
|
-
class UpdateMood < Legion::Extensions::Actors::Every
|
|
11
|
+
class UpdateMood < Legion::Extensions::Actors::Every
|
|
12
12
|
def runner_class
|
|
13
13
|
Legion::Extensions::Agentic::Affect::Mood::Runners::Mood
|
|
14
14
|
end
|
|
@@ -8,7 +8,7 @@ module Legion
|
|
|
8
8
|
module Affect
|
|
9
9
|
module Reappraisal
|
|
10
10
|
module Actor
|
|
11
|
-
class AutoRegulate < Legion::Extensions::Actors::Every
|
|
11
|
+
class AutoRegulate < Legion::Extensions::Actors::Every
|
|
12
12
|
def runner_class
|
|
13
13
|
Legion::Extensions::Agentic::Affect::Reappraisal::Runners::CognitiveReappraisal
|
|
14
14
|
end
|
|
@@ -12,7 +12,7 @@ module Legion
|
|
|
12
12
|
# Calls update_emotional_regulation which performs skill decay — no live emotion
|
|
13
13
|
# inputs are required. regulate_emotion itself requires emotion_magnitude: and
|
|
14
14
|
# cannot be safely invoked as a background tick without a signal source.
|
|
15
|
-
class RegulateEmotion < Legion::Extensions::Actors::Every
|
|
15
|
+
class RegulateEmotion < Legion::Extensions::Actors::Every
|
|
16
16
|
def runner_class
|
|
17
17
|
Legion::Extensions::Agentic::Affect::Regulation::Runners::EmotionalRegulation
|
|
18
18
|
end
|
|
@@ -8,7 +8,7 @@ module Legion
|
|
|
8
8
|
module Affect
|
|
9
9
|
module Resilience
|
|
10
10
|
module Actor
|
|
11
|
-
class UpdateResilience < Legion::Extensions::Actors::Every
|
|
11
|
+
class UpdateResilience < Legion::Extensions::Actors::Every
|
|
12
12
|
def runner_class
|
|
13
13
|
Legion::Extensions::Agentic::Affect::Resilience::Runners::Resilience
|
|
14
14
|
end
|
|
@@ -73,10 +73,9 @@ module Legion
|
|
|
73
73
|
def resonate_with(match, normalized)
|
|
74
74
|
category = @categories[match[:id]]
|
|
75
75
|
category.update_prototype!(input: normalized)
|
|
76
|
-
# rubocop:disable Legion/HelperMigration/DirectLogging
|
|
76
|
+
# rubocop:disable-next Legion/HelperMigration/DirectLogging
|
|
77
77
|
Legion::Logging.debug("[cognitive_resonance] resonance with category #{match[:id][0..7]} " \
|
|
78
78
|
"quality=#{match[:quality].round(3)} vigilance=#{@vigilance.round(3)}")
|
|
79
|
-
# rubocop:enable Legion/HelperMigration/DirectLogging
|
|
80
79
|
{
|
|
81
80
|
outcome: :resonance,
|
|
82
81
|
category_id: match[:id],
|
|
@@ -90,10 +89,9 @@ module Legion
|
|
|
90
89
|
prune_if_full!
|
|
91
90
|
category = Category.new(prototype: normalized)
|
|
92
91
|
@categories[category.id] = category
|
|
93
|
-
# rubocop:disable Legion/HelperMigration/DirectLogging
|
|
92
|
+
# rubocop:disable-next Legion/HelperMigration/DirectLogging
|
|
94
93
|
Legion::Logging.debug("[cognitive_resonance] new category #{category.id[0..7]} " \
|
|
95
94
|
"total=#{@categories.size} vigilance=#{@vigilance.round(3)}")
|
|
96
|
-
# rubocop:enable Legion/HelperMigration/DirectLogging
|
|
97
95
|
{
|
|
98
96
|
outcome: :new_category,
|
|
99
97
|
category_id: category.id,
|
|
@@ -8,7 +8,7 @@ module Legion
|
|
|
8
8
|
module Affect
|
|
9
9
|
module SomaticMarker
|
|
10
10
|
module Actor
|
|
11
|
-
class Decay < Legion::Extensions::Actors::Every
|
|
11
|
+
class Decay < Legion::Extensions::Actors::Every
|
|
12
12
|
def runner_class
|
|
13
13
|
Legion::Extensions::Agentic::Affect::SomaticMarker::Runners::SomaticMarker
|
|
14
14
|
end
|
|
@@ -19,9 +19,9 @@ module Legion
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def update(arousal: nil, tension: nil, comfort: nil, gut_signal: nil)
|
|
22
|
-
@arousal = arousal.clamp(0.0, 1.0)
|
|
23
|
-
@tension = tension.clamp(0.0, 1.0)
|
|
24
|
-
@comfort = comfort.clamp(0.0, 1.0)
|
|
22
|
+
@arousal = arousal.clamp(0.0, 1.0) if arousal
|
|
23
|
+
@tension = tension.clamp(0.0, 1.0) if tension
|
|
24
|
+
@comfort = comfort.clamp(0.0, 1.0) if comfort
|
|
25
25
|
@gut_signal = gut_signal.clamp(-1.0, 1.0) if gut_signal
|
|
26
26
|
end
|
|
27
27
|
|
|
@@ -55,6 +55,28 @@ RSpec.describe Legion::Extensions::Agentic::Affect::Emotion::Runners::Gut do
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
describe '#decay_momentum' do
|
|
58
|
+
it 'does not generate arousal without an emotional signal' do
|
|
59
|
+
3.times { client.decay_momentum }
|
|
60
|
+
|
|
61
|
+
state = client.emotional_state[:momentum]
|
|
62
|
+
expect(state[:arousal_ema]).to eq(0.0)
|
|
63
|
+
expect(state[:valence_ema].values).to all(eq(0.0))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'reduces a low-arousal signal toward rest rather than increasing it' do
|
|
67
|
+
valence = valence_mod.new_valence(urgency: 0.1, importance: 0.1, novelty: 0.1, familiarity: 0.1)
|
|
68
|
+
client.gut_instinct(valences: [valence])
|
|
69
|
+
before = client.emotional_state[:momentum]
|
|
70
|
+
|
|
71
|
+
client.decay_momentum
|
|
72
|
+
|
|
73
|
+
after = client.emotional_state[:momentum]
|
|
74
|
+
expect(after[:arousal_ema]).to be < before[:arousal_ema]
|
|
75
|
+
valence_mod::DIMENSIONS.each do |dimension|
|
|
76
|
+
expect(after[:valence_ema][dimension]).to be < before[:valence_ema][dimension]
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
58
80
|
it 'returns decayed: true' do
|
|
59
81
|
result = client.decay_momentum
|
|
60
82
|
expect(result[:decayed]).to be true
|
|
@@ -32,6 +32,14 @@ RSpec.describe Legion::Extensions::Agentic::Affect::Emotion::Runners::Valence do
|
|
|
32
32
|
with_deadline = client.evaluate_valence(signal: {}, deadline: Time.now.utc + 60)
|
|
33
33
|
expect(with_deadline[:valence][:urgency]).to be >= no_deadline[:valence][:urgency]
|
|
34
34
|
end
|
|
35
|
+
|
|
36
|
+
it 'initializes and updates domain counts in runner-host usage' do
|
|
37
|
+
expect(client.instance_variable_get(:@domain_counts)).to be_nil
|
|
38
|
+
|
|
39
|
+
client.evaluate_valence(signal: {}, domain: :ops)
|
|
40
|
+
|
|
41
|
+
expect(client.instance_variable_get(:@domain_counts)[:ops]).to eq(1)
|
|
42
|
+
end
|
|
35
43
|
end
|
|
36
44
|
|
|
37
45
|
describe '#aggregate_valences' do
|