lex-agentic-affect 0.1.7 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 74630b3aaa2366764ebb2af5fe332a6ce6b51778f2c6bcc22669348e051bf9f7
4
- data.tar.gz: a241ea19f718a589b0bb0a3ef609d7dbf16bfad7ada03cb2a29288910779a26c
3
+ metadata.gz: 304db292215662c9a10acb7c604d279ff263a747ffa410d4306020a03f2d1d69
4
+ data.tar.gz: dc50e3bcecccdd41ce18855d375576cbd52747634a8d93bd161e00ffb9c3622e
5
5
  SHA512:
6
- metadata.gz: 560024c502ab7b4b43995b330dd7b17f8f7b086c8afbcbd9c48798d895a25ada189bb3e9deb34ce606be7206cb4a6264df98940c05b811bda0c560dc11317f12
7
- data.tar.gz: fd7148b82824f8d2079bbdf8508bd9ff1031d11eb68ee00d78ca2eb52f6848dc401c0d444d976b8761224f2f7f90bb9ed8e9f6e46a85dbdd5c2056e0882b14b4
6
+ metadata.gz: f4f56f2da0be9254ca01595c8d891e8b1f8a846ccc16fa8df485c818fd2ba37fb5e888e5391085c5539fdf10f342c601963ff6a5d37e22749d986e2f16a89401
7
+ data.tar.gz: f8d3e0b229ba3b01749c1a5e5773ffe64ef3f5ac3cb67bdfea1046a2fd7ce984554d4d1af6c4dee729d25b67c14b00e5912678e7245b03c00d6b5212371a255b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.8] - 2026-03-31
4
+
5
+ ### Added
6
+ - Valence: `:partner_absence` source urgency 0.2 added to `SOURCE_URGENCY`
7
+ - Valence: `ABSENCE_BASE_IMPORTANCE`, `ABSENCE_IMPORTANCE_SCALE`, `ABSENCE_MAX_IMPORTANCE` constants for logarithmic absence scaling
8
+ - Valence helper: `absence_importance(consecutive_misses)` — logarithmic importance scaling capped at 0.7
9
+ - Valence runner: `evaluate_partner_absence(consecutive_misses:)` — generates absence valence signal (urgency 0.2, novelty 0.1, familiarity 0.8, importance scales with misses)
10
+
3
11
  ## [0.1.7] - 2026-03-31
4
12
 
5
13
  ### Added
@@ -26,9 +26,15 @@ module Legion
26
26
  direct_address: 0.8,
27
27
  mesh_priority: 0.7,
28
28
  scheduled: 0.4,
29
+ partner_absence: 0.2,
29
30
  ambient: 0.1
30
31
  }.freeze
31
32
 
33
+ # Partner absence importance scaling
34
+ ABSENCE_BASE_IMPORTANCE = 0.4
35
+ ABSENCE_IMPORTANCE_SCALE = 0.1
36
+ ABSENCE_MAX_IMPORTANCE = 0.7
37
+
32
38
  # Familiarity saturation (spec Section 3.5)
33
39
  FAMILIARITY_SATURATION = 100
34
40
 
@@ -74,6 +80,11 @@ module Legion
74
80
  clamp(total / (valences.size * MAX_MAGNITUDE))
75
81
  end
76
82
 
83
+ def absence_importance(consecutive_misses)
84
+ raw = ABSENCE_BASE_IMPORTANCE + (ABSENCE_IMPORTANCE_SCALE * Math.log(consecutive_misses + 1))
85
+ clamp(raw, 0.0, ABSENCE_MAX_IMPORTANCE)
86
+ end
87
+
77
88
  def modulate_salience(base_salience, valence)
78
89
  boost = ((valence[:urgency] * URGENCY_ATTENTION_WEIGHT) +
79
90
  (valence[:importance] * IMPORTANCE_ATTENTION_WEIGHT) +
@@ -72,6 +72,26 @@ module Legion
72
72
  { arousal: arousal }
73
73
  end
74
74
 
75
+ def evaluate_partner_absence(consecutive_misses: 1, **)
76
+ importance = Helpers::Valence.absence_importance(consecutive_misses)
77
+
78
+ valence = Helpers::Valence.new_valence(
79
+ urgency: 0.2,
80
+ importance: importance,
81
+ novelty: 0.1,
82
+ familiarity: 0.8
83
+ )
84
+
85
+ magnitude = Helpers::Valence.magnitude(valence)
86
+ dominant = Helpers::Valence.dominant_dimension(valence)
87
+
88
+ log.debug("[emotion] partner_absence: misses=#{consecutive_misses} " \
89
+ "importance=#{importance.round(2)} magnitude=#{magnitude.round(2)}")
90
+
91
+ { valence: valence, magnitude: magnitude, dominant_dimension: dominant,
92
+ event: :partner_absence, consecutive_misses: consecutive_misses }
93
+ end
94
+
75
95
  def raise_urgency_for_knowledge_vulnerability(domains_at_risk:, severity: :warning, urgency_boost: 0.3, **)
76
96
  boost = severity.to_sym == :critical ? [urgency_boost * 1.5, 1.0].min : urgency_boost.to_f
77
97
  signal = { urgency_hint: boost, domain_weight: 0.6, impact_scope: 0.5,
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Agentic
6
6
  module Affect
7
- VERSION = '0.1.7'
7
+ VERSION = '0.1.8'
8
8
  end
9
9
  end
10
10
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Agentic::Affect::Emotion::Helpers::Valence do
4
+ describe 'SOURCE_URGENCY' do
5
+ it 'includes :partner_absence with urgency 0.2' do
6
+ expect(described_class::SOURCE_URGENCY[:partner_absence]).to eq(0.2)
7
+ end
8
+ end
9
+
10
+ describe '.absence_importance' do
11
+ it 'returns base importance for a single miss' do
12
+ result = described_class.absence_importance(1)
13
+ expected = 0.4 + (0.1 * Math.log(2))
14
+ expect(result).to be_within(0.001).of(expected)
15
+ end
16
+
17
+ it 'scales logarithmically with consecutive misses' do
18
+ low = described_class.absence_importance(1)
19
+ mid = described_class.absence_importance(10)
20
+ high = described_class.absence_importance(50)
21
+ expect(mid).to be > low
22
+ expect(high).to be > mid
23
+ end
24
+
25
+ it 'caps at ABSENCE_MAX_IMPORTANCE' do
26
+ result = described_class.absence_importance(10_000)
27
+ expect(result).to eq(described_class::ABSENCE_MAX_IMPORTANCE)
28
+ end
29
+
30
+ it 'returns base importance for zero misses' do
31
+ result = described_class.absence_importance(0)
32
+ expect(result).to be_within(0.001).of(described_class::ABSENCE_BASE_IMPORTANCE)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/agentic/affect/emotion/client'
4
+
5
+ RSpec.describe Legion::Extensions::Agentic::Affect::Emotion::Runners::Valence do
6
+ let(:client) { Legion::Extensions::Agentic::Affect::Emotion::Client.new }
7
+
8
+ describe '#evaluate_partner_absence' do
9
+ it 'returns a valence with all four dimensions' do
10
+ result = client.evaluate_partner_absence(consecutive_misses: 1)
11
+ expect(result[:valence].keys).to contain_exactly(:urgency, :importance, :novelty, :familiarity)
12
+ end
13
+
14
+ it 'sets urgency to 0.2' do
15
+ result = client.evaluate_partner_absence(consecutive_misses: 1)
16
+ expect(result[:valence][:urgency]).to eq(0.2)
17
+ end
18
+
19
+ it 'sets novelty to 0.1' do
20
+ result = client.evaluate_partner_absence(consecutive_misses: 1)
21
+ expect(result[:valence][:novelty]).to eq(0.1)
22
+ end
23
+
24
+ it 'sets familiarity to 0.8' do
25
+ result = client.evaluate_partner_absence(consecutive_misses: 1)
26
+ expect(result[:valence][:familiarity]).to eq(0.8)
27
+ end
28
+
29
+ it 'tags the event as :partner_absence' do
30
+ result = client.evaluate_partner_absence(consecutive_misses: 1)
31
+ expect(result[:event]).to eq(:partner_absence)
32
+ end
33
+
34
+ it 'includes consecutive_misses in the result' do
35
+ result = client.evaluate_partner_absence(consecutive_misses: 5)
36
+ expect(result[:consecutive_misses]).to eq(5)
37
+ end
38
+
39
+ it 'returns magnitude and dominant dimension' do
40
+ result = client.evaluate_partner_absence(consecutive_misses: 1)
41
+ expect(result[:magnitude]).to be > 0.0
42
+ expect(result[:dominant_dimension]).to be_a(Symbol)
43
+ end
44
+
45
+ it 'increases importance with consecutive misses' do
46
+ low = client.evaluate_partner_absence(consecutive_misses: 1)
47
+ high = client.evaluate_partner_absence(consecutive_misses: 50)
48
+ expect(high[:valence][:importance]).to be > low[:valence][:importance]
49
+ end
50
+
51
+ it 'caps importance at ABSENCE_MAX_IMPORTANCE' do
52
+ helpers = Legion::Extensions::Agentic::Affect::Emotion::Helpers::Valence
53
+ result = client.evaluate_partner_absence(consecutive_misses: 10_000)
54
+ expect(result[:valence][:importance]).to eq(helpers::ABSENCE_MAX_IMPORTANCE)
55
+ end
56
+
57
+ it 'defaults to 1 consecutive miss' do
58
+ result = client.evaluate_partner_absence
59
+ expect(result[:consecutive_misses]).to eq(1)
60
+ end
61
+ end
62
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-agentic-affect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -312,8 +312,10 @@ files:
312
312
  - spec/legion/extensions/agentic/affect/emotion/helpers/baseline_spec.rb
313
313
  - spec/legion/extensions/agentic/affect/emotion/helpers/momentum_spec.rb
314
314
  - spec/legion/extensions/agentic/affect/emotion/helpers/valence_direct_address_spec.rb
315
+ - spec/legion/extensions/agentic/affect/emotion/helpers/valence_partner_absence_spec.rb
315
316
  - spec/legion/extensions/agentic/affect/emotion/helpers/valence_spec.rb
316
317
  - spec/legion/extensions/agentic/affect/emotion/runners/gut_spec.rb
318
+ - spec/legion/extensions/agentic/affect/emotion/runners/valence_partner_absence_spec.rb
317
319
  - spec/legion/extensions/agentic/affect/emotion/runners/valence_spec.rb
318
320
  - spec/legion/extensions/agentic/affect/empathy/client_spec.rb
319
321
  - spec/legion/extensions/agentic/affect/empathy/helpers/constants_spec.rb