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 +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/legion/extensions/agentic/social/calibration/helpers/calibration_store.rb +4 -2
- data/lib/legion/extensions/agentic/social/calibration/runners/calibration.rb +4 -3
- data/lib/legion/extensions/agentic/social/version.rb +1 -1
- data/spec/legion/extensions/agentic/social/calibration/helpers/calibration_store_spec.rb +47 -0
- data/spec/legion/extensions/agentic/social/calibration/runners/calibration_spec.rb +23 -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: 813631a90b8945655f76aaca3c5b8ba2bbb8b09a60126da891c1d3c6353e47a9
|
|
4
|
+
data.tar.gz: cc24309702a44a0a1cd7866d8b6632cce6551949079d646e6bb697f4bcd284a9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
|
@@ -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
|