lex-somatic-marker 0.1.0

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.
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/somatic_marker/client'
4
+
5
+ RSpec.describe Legion::Extensions::SomaticMarker::Runners::SomaticMarker do
6
+ let(:client) { Legion::Extensions::SomaticMarker::Client.new }
7
+
8
+ describe '#register_marker' do
9
+ it 'returns success: true with marker hash' do
10
+ result = client.register_marker(action: :deploy, domain: :ops, valence: 0.7)
11
+ expect(result[:success]).to be true
12
+ expect(result[:marker]).to include(:id, :action, :domain, :valence)
13
+ end
14
+
15
+ it 'returns success: false on error' do
16
+ allow(client).to receive(:store).and_raise(StandardError, 'boom')
17
+ result = client.register_marker(action: :deploy, domain: :ops, valence: 0.7)
18
+ expect(result[:success]).to be false
19
+ expect(result[:error]).to eq('boom')
20
+ end
21
+
22
+ it 'accepts extra keyword args via **' do
23
+ result = client.register_marker(action: :deploy, domain: :ops, valence: 0.5, extra: 'ignored')
24
+ expect(result[:success]).to be true
25
+ end
26
+ end
27
+
28
+ describe '#evaluate_option' do
29
+ it 'returns success: true with signal' do
30
+ result = client.evaluate_option(action: :deploy, domain: :ops)
31
+ expect(result[:success]).to be true
32
+ expect(result[:signal]).to be_a(Symbol)
33
+ end
34
+
35
+ it 'returns neutral when no markers exist' do
36
+ result = client.evaluate_option(action: :unknown_action, domain: :unknown_domain)
37
+ expect(result[:signal]).to eq(:neutral)
38
+ end
39
+
40
+ it 'returns approach after registering positive marker' do
41
+ client.register_marker(action: :submit, domain: :forms, valence: 0.9)
42
+ result = client.evaluate_option(action: :submit, domain: :forms)
43
+ expect(result[:signal]).to eq(:approach)
44
+ end
45
+ end
46
+
47
+ describe '#make_decision' do
48
+ it 'returns success: true with ranked options' do
49
+ client.register_marker(action: :approve, domain: :risk, valence: 0.8)
50
+ client.register_marker(action: :reject, domain: :risk, valence: -0.8)
51
+
52
+ result = client.make_decision(options: %i[approve reject], domain: :risk)
53
+ expect(result[:success]).to be true
54
+ expect(result[:decision][:ranked]).to be_an(Array)
55
+ expect(result[:decision][:ranked].first[:action]).to eq(:approve)
56
+ end
57
+
58
+ it 'ranks by valence descending' do
59
+ client.register_marker(action: :high, domain: :d, valence: 0.9)
60
+ client.register_marker(action: :low, domain: :d, valence: -0.5)
61
+
62
+ result = client.make_decision(options: %i[high low neutral], domain: :d)
63
+ valences = result[:decision][:ranked].map { |r| r[:valence] }
64
+ expect(valences).to eq(valences.sort.reverse)
65
+ end
66
+
67
+ it 'returns success: false on error' do
68
+ allow(client).to receive(:store).and_raise(StandardError, 'store_error')
69
+ result = client.make_decision(options: %i[a b], domain: :d)
70
+ expect(result[:success]).to be false
71
+ end
72
+ end
73
+
74
+ describe '#reinforce' do
75
+ it 'returns success: true when marker found' do
76
+ reg = client.register_marker(action: :deploy, domain: :ops, valence: 0.0)
77
+ result = client.reinforce(marker_id: reg[:marker][:id], outcome_valence: 1.0)
78
+ expect(result[:success]).to be true
79
+ expect(result[:marker][:valence]).to be > 0.0
80
+ end
81
+
82
+ it 'returns success: false when marker not found' do
83
+ result = client.reinforce(marker_id: 'nonexistent', outcome_valence: 0.5)
84
+ expect(result[:success]).to be false
85
+ expect(result[:error]).to include('not found')
86
+ end
87
+ end
88
+
89
+ describe '#update_body' do
90
+ it 'returns success: true with updated body state' do
91
+ result = client.update_body(arousal: 0.8, tension: 0.7)
92
+ expect(result[:success]).to be true
93
+ expect(result[:body_state][:arousal]).to eq(0.8)
94
+ expect(result[:body_state][:tension]).to eq(0.7)
95
+ end
96
+
97
+ it 'accepts nil values without error' do
98
+ result = client.update_body(arousal: nil, tension: nil)
99
+ expect(result[:success]).to be true
100
+ end
101
+ end
102
+
103
+ describe '#body_state' do
104
+ it 'returns success: true with body state hash' do
105
+ result = client.body_state
106
+ expect(result[:success]).to be true
107
+ expect(result[:body_state]).to include(:arousal, :tension, :comfort, :gut_signal)
108
+ end
109
+
110
+ it 'reflects updates made via update_body' do
111
+ client.update_body(comfort: 0.9)
112
+ result = client.body_state
113
+ expect(result[:body_state][:comfort]).to eq(0.9)
114
+ end
115
+ end
116
+
117
+ describe '#markers_for_action' do
118
+ it 'returns success: true with marker list' do
119
+ client.register_marker(action: :click, domain: :ui, valence: 0.3)
120
+ result = client.markers_for_action(action: :click, domain: :ui)
121
+ expect(result[:success]).to be true
122
+ expect(result[:count]).to eq(1)
123
+ expect(result[:markers].first[:action]).to eq(:click)
124
+ end
125
+
126
+ it 'returns empty list for unknown action' do
127
+ result = client.markers_for_action(action: :unknown, domain: :unknown)
128
+ expect(result[:success]).to be true
129
+ expect(result[:count]).to eq(0)
130
+ expect(result[:markers]).to be_empty
131
+ end
132
+ end
133
+
134
+ describe '#recent_decisions' do
135
+ it 'returns success: true with decision list' do
136
+ client.make_decision(options: %i[go stop], domain: :ops)
137
+ result = client.recent_decisions
138
+ expect(result[:success]).to be true
139
+ expect(result[:count]).to eq(1)
140
+ expect(result[:decisions]).to be_an(Array)
141
+ end
142
+
143
+ it 'respects the limit parameter' do
144
+ 5.times { client.make_decision(options: %i[go stop], domain: :ops) }
145
+ result = client.recent_decisions(limit: 3)
146
+ expect(result[:count]).to eq(3)
147
+ end
148
+ end
149
+
150
+ describe '#update_somatic_markers' do
151
+ it 'returns success: true with decay stats' do
152
+ client.register_marker(action: :deploy, domain: :ops, valence: 0.5)
153
+ result = client.update_somatic_markers
154
+ expect(result[:success]).to be true
155
+ expect(result).to have_key(:markers_decayed)
156
+ expect(result).to have_key(:markers_removed)
157
+ end
158
+
159
+ it 'returns success: false on error' do
160
+ allow(client).to receive(:store).and_raise(StandardError, 'decay_error')
161
+ result = client.update_somatic_markers
162
+ expect(result[:success]).to be false
163
+ end
164
+ end
165
+
166
+ describe '#somatic_marker_stats' do
167
+ it 'returns success: true with stats' do
168
+ client.register_marker(action: :deploy, domain: :ops, valence: 0.5)
169
+ result = client.somatic_marker_stats
170
+ expect(result[:success]).to be true
171
+ expect(result[:marker_count]).to eq(1)
172
+ expect(result[:decision_count]).to eq(0)
173
+ end
174
+
175
+ it 'reflects decision count after decisions' do
176
+ client.make_decision(options: %i[go stop], domain: :ops)
177
+ result = client.somatic_marker_stats
178
+ expect(result[:decision_count]).to eq(1)
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Helpers
8
+ module Lex; end
9
+ end
10
+
11
+ module Actors
12
+ class Every
13
+ def initialize(*); end
14
+ end
15
+ end
16
+ end
17
+
18
+ module Logging
19
+ def self.debug(_msg); end
20
+ def self.info(_msg); end
21
+ def self.warn(_msg); end
22
+ def self.error(_msg); end
23
+ end
24
+ end
25
+
26
+ require 'legion/extensions/somatic_marker'
27
+ require 'legion/extensions/somatic_marker/client'
28
+
29
+ RSpec.configure do |config|
30
+ config.example_status_persistence_file_path = '.rspec_status'
31
+ config.disable_monkey_patching!
32
+ config.expect_with(:rspec) { |c| c.syntax = :expect }
33
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-somatic-marker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Esity
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: legion-gaia
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ description: Damasio's Somatic Marker Hypothesis for brain-modeled agentic AI decision-making
27
+ email:
28
+ - matthewdiverson@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - Gemfile
34
+ - LICENSE
35
+ - README.md
36
+ - lex-somatic-marker.gemspec
37
+ - lib/legion/extensions/somatic_marker.rb
38
+ - lib/legion/extensions/somatic_marker/actors/decay.rb
39
+ - lib/legion/extensions/somatic_marker/client.rb
40
+ - lib/legion/extensions/somatic_marker/helpers/body_state.rb
41
+ - lib/legion/extensions/somatic_marker/helpers/constants.rb
42
+ - lib/legion/extensions/somatic_marker/helpers/marker_store.rb
43
+ - lib/legion/extensions/somatic_marker/helpers/somatic_marker.rb
44
+ - lib/legion/extensions/somatic_marker/runners/somatic_marker.rb
45
+ - lib/legion/extensions/somatic_marker/version.rb
46
+ - spec/legion/extensions/somatic_marker/client_spec.rb
47
+ - spec/legion/extensions/somatic_marker/helpers/body_state_spec.rb
48
+ - spec/legion/extensions/somatic_marker/helpers/marker_store_spec.rb
49
+ - spec/legion/extensions/somatic_marker/helpers/somatic_marker_spec.rb
50
+ - spec/legion/extensions/somatic_marker/runners/somatic_marker_spec.rb
51
+ - spec/spec_helper.rb
52
+ homepage: https://github.com/LegionIO/lex-somatic-marker
53
+ licenses:
54
+ - MIT
55
+ metadata:
56
+ homepage_uri: https://github.com/LegionIO/lex-somatic-marker
57
+ source_code_uri: https://github.com/LegionIO/lex-somatic-marker
58
+ documentation_uri: https://github.com/LegionIO/lex-somatic-marker
59
+ changelog_uri: https://github.com/LegionIO/lex-somatic-marker
60
+ bug_tracker_uri: https://github.com/LegionIO/lex-somatic-marker/issues
61
+ rubygems_mfa_required: 'true'
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '3.4'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubygems_version: 3.6.9
77
+ specification_version: 4
78
+ summary: LEX Somatic Marker
79
+ test_files: []