lex-agentic-social 0.1.20 → 0.1.21

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: a649d923310d4a98480e6069c03d586585c2a27d3045c625f5c76d608b066016
4
- data.tar.gz: d5983148aebfa19722b6ae1c5c4e564bd7be94455f3838401bbbe36cdbc087fe
3
+ metadata.gz: 813631a90b8945655f76aaca3c5b8ba2bbb8b09a60126da891c1d3c6353e47a9
4
+ data.tar.gz: cc24309702a44a0a1cd7866d8b6632cce6551949079d646e6bb697f4bcd284a9
5
5
  SHA512:
6
- metadata.gz: cc6fc74f2620bc3e2cd96c2ba567f61dd0d1596127e33c75db88af80048879944d8d8719f861c7d2b9368d0d53a87f4ea2978c0c7e0e52b949f91b4168b5d650
7
- data.tar.gz: e6de6e946ebb7468dd4adf14e35e97e6104cfd13f288b7730cd1f92420764713ea0afb4ed6c3a137f2146765da060de24e0e41a70a6000a9c73148c3d904b3f8
6
+ metadata.gz: db8bafe82e2b2c3e57af811c93ca2cadbd5593d98c95c7deaef69764b55cc35ab8fd54ff3218c3ffce5bd310a002d20ec9f698058a9e90c876eb259cc347894b
7
+ data.tar.gz: 3e461b5ca49eb3d7ff2ad53c4da56c89ec9ed51f74a0cf37c13479a4a17ec57ee5c09e6a9025c07fdb7ddd744e1876ed435e8cba155cc2af47a04bb998b2e62e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.21] - 2026-07-16
4
+ ### Added
5
+ - `CalibrationStore#record_advisory` gains `applied:` kwarg to store which behavioral synapses were applied alongside the advisory.
6
+ - `CalibrationStore#evaluate_reaction` now returns `reaction_score` (Float 0.0–1.0) and `applied` hash in its result hash, enabling legion-gaia's H2 synapse grading path.
7
+ - `Calibration` runner `record_advisory_meta` accepts and passes through the `applied:` kwarg.
8
+ - `Calibration` runner `update_calibration` passes through `reaction_score` and `applied` from the store result.
9
+
3
10
  ## [0.1.20] - 2026-07-16
4
11
  ### Added
5
12
  - `CalibrationRegistry`: per-identity `CalibrationStore` instances keyed by identity string, fixing the grading-contamination bug where one interlocutor's reactions moved another's calibration weights.
@@ -28,10 +28,11 @@ module Legion
28
28
  self
29
29
  end
30
30
 
31
- def record_advisory(advisory_id:, advisory_types:)
31
+ def record_advisory(advisory_id:, advisory_types:, applied: nil)
32
32
  @last_advisory_meta = {
33
33
  advisory_id: advisory_id,
34
34
  advisory_types: Array(advisory_types).map(&:to_s),
35
+ applied: applied,
35
36
  timestamp: Time.now.utc
36
37
  }
37
38
  end
@@ -45,6 +46,7 @@ module Legion
45
46
 
46
47
  reaction_score = compute_reaction_score(observation)
47
48
  confidence = compute_confidence(observation)
49
+ applied_from_meta = @last_advisory_meta[:applied]
48
50
 
49
51
  deltas = @last_advisory_meta[:advisory_types].map do |type|
50
52
  apply_delta(type: type, reaction_score: reaction_score, confidence: confidence)
@@ -52,7 +54,7 @@ module Legion
52
54
 
53
55
  @last_advisory_meta = nil
54
56
  @dirty = true
55
- { success: true, deltas: deltas }
57
+ { success: true, deltas: deltas, reaction_score: reaction_score, applied: applied_from_meta }
56
58
  end
57
59
 
58
60
  def calibration_weights
@@ -21,11 +21,12 @@ module Legion
21
21
  result = calibration_store.evaluate_reaction(observation: observation)
22
22
  return { success: true, skipped: :no_advisory } unless result
23
23
 
24
- { success: true, deltas: result[:deltas], weights: calibration_store.calibration_weights }
24
+ { success: true, deltas: result[:deltas], weights: calibration_store.calibration_weights,
25
+ reaction_score: result[:reaction_score], applied: result[:applied] }
25
26
  end
26
27
 
27
- def record_advisory_meta(advisory_id:, advisory_types:, **)
28
- calibration_store.record_advisory(advisory_id: advisory_id, advisory_types: advisory_types)
28
+ def record_advisory_meta(advisory_id:, advisory_types:, applied: nil, **)
29
+ calibration_store.record_advisory(advisory_id: advisory_id, advisory_types: advisory_types, applied: applied)
29
30
  { success: true }
30
31
  end
31
32
 
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Agentic
6
6
  module Social
7
- VERSION = '0.1.20'
7
+ VERSION = '0.1.21'
8
8
  end
9
9
  end
10
10
  end
@@ -48,6 +48,19 @@ RSpec.describe Legion::Extensions::Agentic::Social::Calibration::Helpers::Calibr
48
48
  expect(result).not_to be_nil
49
49
  expect(result[:deltas].size).to eq(2)
50
50
  end
51
+
52
+ it 'stores applied kwarg when provided' do
53
+ applied_data = { synapse_ids: [1, 2, 3], strategy: 'tone' }
54
+ store.record_advisory(advisory_id: 'abc', advisory_types: [:tone_adjustment], applied: applied_data)
55
+ result = store.evaluate_reaction(observation: { content: 'thanks' })
56
+ expect(result[:applied]).to eq(applied_data)
57
+ end
58
+
59
+ it 'stores nil applied when not provided' do
60
+ store.record_advisory(advisory_id: 'abc', advisory_types: [:tone_adjustment])
61
+ result = store.evaluate_reaction(observation: { content: 'thanks' })
62
+ expect(result[:applied]).to be_nil
63
+ end
51
64
  end
52
65
 
53
66
  describe '#evaluate_reaction' do
@@ -90,6 +103,40 @@ RSpec.describe Legion::Extensions::Agentic::Social::Calibration::Helpers::Calibr
90
103
  store.evaluate_reaction(observation: { content: 'thanks' })
91
104
  expect(store.history['tone_adjustment']).not_to be_empty
92
105
  end
106
+
107
+ it 'returns reaction_score as a float between 0.0 and 1.0' do
108
+ result = store.evaluate_reaction(observation: { content: 'thanks' })
109
+ expect(result[:reaction_score]).to be_a(Float)
110
+ expect(result[:reaction_score]).to be_between(0.0, 1.0)
111
+ end
112
+
113
+ it 'returns applied from recorded advisory' do
114
+ store.mark_clean!
115
+ applied_data = { synapse_ids: [10, 20] }
116
+ store.record_advisory(advisory_id: 'test2', advisory_types: [:tone_adjustment], applied: applied_data)
117
+ result = store.evaluate_reaction(observation: { content: 'ok' })
118
+ expect(result[:applied]).to eq(applied_data)
119
+ end
120
+ end
121
+
122
+ context 'reaction_score signal ranges' do
123
+ it 'returns reaction_score >= 0.6 for positive feedback' do
124
+ store.record_advisory(advisory_id: 'pos', advisory_types: [:tone_adjustment])
125
+ result = store.evaluate_reaction(observation: { content: 'thanks, perfect!', direct_address: true, content_length: 50 })
126
+ expect(result[:reaction_score]).to be >= 0.6
127
+ end
128
+
129
+ it 'returns reaction_score <= 0.4 for negative feedback' do
130
+ store.record_advisory(advisory_id: 'neg', advisory_types: [:tone_adjustment])
131
+ result = store.evaluate_reaction(observation: { content: 'no, wrong, stop', content_length: 5 })
132
+ expect(result[:reaction_score]).to be <= 0.4
133
+ end
134
+
135
+ it 'returns reaction_score between 0.4 and 0.6 for neutral feedback' do
136
+ store.record_advisory(advisory_id: 'neu', advisory_types: [:tone_adjustment])
137
+ result = store.evaluate_reaction(observation: { content: 'I see', content_length: 10 })
138
+ expect(result[:reaction_score]).to be_between(0.4, 0.6)
139
+ end
93
140
  end
94
141
  end
95
142
 
@@ -22,6 +22,20 @@ RSpec.describe Legion::Extensions::Agentic::Social::Calibration::Runners::Calibr
22
22
  expect(result[:success]).to be true
23
23
  expect(result[:deltas]).not_to be_empty
24
24
  end
25
+
26
+ it 'returns reaction_score in result when advisory recorded' do
27
+ client.record_advisory_meta(advisory_id: 'test', advisory_types: [:tone_adjustment])
28
+ result = client.update_calibration(observation: { content: 'thanks', direct_address: true, content_length: 20 })
29
+ expect(result).to have_key(:reaction_score)
30
+ expect(result[:reaction_score]).to be_a(Float)
31
+ end
32
+
33
+ it 'returns applied in result when advisory recorded with applied kwarg' do
34
+ applied_data = { synapse_ids: [5, 6] }
35
+ client.record_advisory_meta(advisory_id: 'test', advisory_types: [:tone_adjustment], applied: applied_data)
36
+ result = client.update_calibration(observation: { content: 'thanks', direct_address: true, content_length: 20 })
37
+ expect(result[:applied]).to eq(applied_data)
38
+ end
25
39
  end
26
40
 
27
41
  describe '#record_advisory_meta' do
@@ -29,6 +43,15 @@ RSpec.describe Legion::Extensions::Agentic::Social::Calibration::Runners::Calibr
29
43
  result = client.record_advisory_meta(advisory_id: 'abc', advisory_types: [:partner_hint])
30
44
  expect(result[:success]).to be true
31
45
  end
46
+
47
+ it 'accepts and passes applied kwarg' do
48
+ applied_data = { synapse_ids: [1, 2], strategy: 'verbosity' }
49
+ result = client.record_advisory_meta(advisory_id: 'abc', advisory_types: [:partner_hint], applied: applied_data)
50
+ expect(result[:success]).to be true
51
+ # Verify the applied data flows through to evaluate_reaction
52
+ eval_result = client.update_calibration(observation: { content: 'thanks', content_length: 10 })
53
+ expect(eval_result[:applied]).to eq(applied_data)
54
+ end
32
55
  end
33
56
 
34
57
  describe '#detect_explicit_feedback' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-agentic-social
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.20
4
+ version: 0.1.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity