lex-agentic-attention 0.1.0 → 0.1.2

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.
Files changed (21) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/README.md +51 -3
  4. data/lib/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine.rb +2 -0
  5. data/lib/legion/extensions/agentic/attention/blindspot/version.rb +1 -1
  6. data/lib/legion/extensions/agentic/attention/feature_binding/helpers/binding_field.rb +1 -0
  7. data/lib/legion/extensions/agentic/attention/feature_binding/version.rb +1 -1
  8. data/lib/legion/extensions/agentic/attention/relevance_theory/helpers/relevance_engine.rb +3 -0
  9. data/lib/legion/extensions/agentic/attention/relevance_theory/version.rb +1 -1
  10. data/lib/legion/extensions/agentic/attention/sensory_gating/helpers/gating_engine.rb +2 -0
  11. data/lib/legion/extensions/agentic/attention/sensory_gating/version.rb +1 -1
  12. data/lib/legion/extensions/agentic/attention/switching/helpers/switching_engine.rb +2 -0
  13. data/lib/legion/extensions/agentic/attention/switching/version.rb +1 -1
  14. data/lib/legion/extensions/agentic/attention/version.rb +1 -1
  15. data/spec/legion/extensions/agentic/attention/blindspot/helpers/blindspot_engine_spec.rb +15 -0
  16. data/spec/legion/extensions/agentic/attention/feature_binding/helpers/binding_field_spec.rb +14 -0
  17. data/spec/legion/extensions/agentic/attention/relevance_theory/helpers/relevance_engine_spec.rb +28 -0
  18. data/spec/legion/extensions/agentic/attention/sensory_gating/helpers/gating_engine_spec.rb +16 -1
  19. data/spec/legion/extensions/agentic/attention/switching/attention_switching_spec.rb +1 -1
  20. data/spec/legion/extensions/agentic/attention/switching/helpers/switching_engine_spec.rb +13 -0
  21. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11316e7a48a460b4bfb317d22f335cf149e138d329df2f1ffbb91c6439915463
4
- data.tar.gz: 94a927cd12dde2ec8212462a6c504839096cb5a074945c8f89b65ebde28bf06e
3
+ metadata.gz: 689fafea8ab7532b0c71e1af0f3190fca466d853e58d3468a8833f27b24bee4f
4
+ data.tar.gz: aa609f8a51b96725bc975f19e9a902a3838be8503f2a5c4e9deb469422f88eb4
5
5
  SHA512:
6
- metadata.gz: 177772a3cf51ff7e3d799445014bf601ac106070a26a5130a12110164133cc82baa38651108eae9ea9c0cdbaec0ba2984e38ff197af6e5c3f6bba669e54ee833
7
- data.tar.gz: 80ec4fb94b4ff8129ca765ff4e90a22429cd65155f00849a7845e8e8f23159e23ed3286039db62620f9584517637e74caee81e392a42005f4c22213a6ccd1627
6
+ metadata.gz: f08ebae489ebc42ad72fa36b4f356b22c1871284c4b23479d42a01997999cee1a9880319e5f05d1e5b55aa075ed44b8f852544001d5fa96b562cdc2b846e7ddd
7
+ data.tar.gz: e525cd97878de8568104789a49c8551d134cf3e3ca1026e1bcdef82fc2d8d4f66e3f53dac36ad78469e34a4ee8359df9070203c08b6db1c38cd6cfd31d61ef1a
data/CHANGELOG.md CHANGED
@@ -2,6 +2,21 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.1.2] - 2026-03-18
6
+
7
+ ### Changed
8
+ - Enforce TASK_SET_TYPES validation in SwitchingEngine#register_task (returns nil for invalid task_type)
9
+ - Enforce INPUT_TYPES validation in RelevanceEngine#submit_input (returns nil for invalid input_type)
10
+ - Enforce EFFECT_TYPES validation in RelevanceEngine#submit_input (returns nil for invalid effect_type)
11
+ - ATTENTION_MODES and TARGET_STATES in Regulation skipped: internally computed by state machine, not external input params
12
+
13
+ ## [0.1.1] - 2026-03-18
14
+
15
+ ### Changed
16
+ - Enforce FEATURE_DIMENSIONS validation in BindingField#register_feature (returns nil for invalid dimension)
17
+ - Enforce MODALITY_TYPES validation in GatingEngine#create_filter (returns nil for invalid modality)
18
+ - Enforce DISCOVERY_METHODS validation in BlindspotEngine#register_blindspot (returns nil for invalid discovered_by)
19
+
5
20
  ## [0.1.0] - 2026-03-18
6
21
 
7
22
  ### Added
data/README.md CHANGED
@@ -1,13 +1,61 @@
1
1
  # lex-agentic-attention
2
2
 
3
- LEX agentic attention domain: focus, salience, cognitive control
3
+ Domain consolidation gem for attention, perception, and signal processing. Bundles 24 source extensions into one loadable unit under `Legion::Extensions::Agentic::Attention`.
4
4
 
5
- ## Sub-modules
5
+ ## Overview
6
6
 
7
- *(populated as extensions are consolidated)*
7
+ **Gem**: `lex-agentic-attention`
8
+ **Version**: 0.1.2
9
+ **Namespace**: `Legion::Extensions::Agentic::Attention`
10
+
11
+ ## Sub-Modules
12
+
13
+ | Sub-Module | Source Gem | Purpose |
14
+ |---|---|---|
15
+ | `Attention::Focus` | `lex-attention` | Selective attention filter — Miller's Law (7±2), habituation, goal-directed amplification |
16
+ | `Attention::Economy` | `lex-attention-economy` | Attention as scarce resource — allocation budgets, ROI tracking |
17
+ | `Attention::Regulation` | `lex-attention-regulation` | Top-down and bottom-up attention regulation |
18
+ | `Attention::Schema` | `lex-attention-schema` | Self-model of the attention system itself |
19
+ | `Attention::Spotlight` | `lex-attention-spotlight` | Spotlight metaphor — illumination radius, dimmer control |
20
+ | `Attention::Switching` | `lex-attention-switching` | Voluntary/involuntary attention shifts, switch cost tracking |
21
+ | `Attention::Blink` | `lex-attentional-blink` | Rapid succession signal suppression — temporal attention limits |
22
+ | `Attention::Telescope` | `lex-cognitive-telescope` | Long-range attentional focus |
23
+ | `Attention::Lens` | `lex-cognitive-lens` | Attentional focus shaping |
24
+ | `Attention::Prism` | `lex-cognitive-prism` | Multi-spectrum signal decomposition |
25
+ | `Attention::Lighthouse` | `lex-cognitive-lighthouse` | Beacon-based attentional guidance |
26
+ | `Attention::Blindspot` | `lex-cognitive-blindspot` | Attentional blind spots and gaps |
27
+ | `Attention::Kaleidoscope` | `lex-cognitive-kaleidoscope` | Multi-faceted attentional patterns |
28
+ | `Attention::Synesthesia` | `lex-cognitive-synesthesia` | Cross-modal attentional blending |
29
+ | `Attention::Arousal` | `lex-arousal` | Yerkes-Dodson inverted-U — optimal performance at moderate arousal |
30
+ | `Attention::Salience` | `lex-salience` | Weighted integration from eight cognitive sources |
31
+ | `Attention::SensoryGating` | `lex-sensory-gating` | Pre-attentive filtering of redundant stimuli (P50 model) |
32
+ | `Attention::SignalDetection` | `lex-signal-detection` | SDT modeling — sensitivity (d'), response bias (beta) |
33
+ | `Attention::Subliminal` | `lex-subliminal` | Below-threshold signal processing |
34
+ | `Attention::LatentInhibition` | `lex-latent-inhibition` | Learned irrelevance — reduced processing of previously irrelevant stimuli |
35
+ | `Attention::Surprise` | `lex-surprise` | Surprise signal computation from violated expectations |
36
+ | `Attention::RelevanceTheory` | `lex-relevance-theory` | Cognitive effort vs. contextual effect optimization |
37
+ | `Attention::Priming` | `lex-priming` | Prior exposure boosts related processing |
38
+ | `Attention::FeatureBinding` | `lex-feature-binding` | Binding separately-processed features into unified percepts |
39
+
40
+ ## Actors
41
+
42
+ - `Attention::FeatureBinding::Actors::Decay` — interval actor, decays bound feature groups
43
+ - `Attention::Schema::Actors::Decay` — interval actor, decays attention schema entries
8
44
 
9
45
  ## Installation
10
46
 
11
47
  ```ruby
12
48
  gem 'lex-agentic-attention'
13
49
  ```
50
+
51
+ ## Development
52
+
53
+ ```bash
54
+ bundle install
55
+ bundle exec rspec # 2288 examples, 0 failures
56
+ bundle exec rubocop # 0 offenses
57
+ ```
58
+
59
+ ## License
60
+
61
+ MIT
@@ -18,6 +18,8 @@ module Legion
18
18
  end
19
19
 
20
20
  def register_blindspot(domain:, discovered_by:, description:, severity: DEFAULT_SEVERITY)
21
+ return nil unless DISCOVERY_METHODS.include?(discovered_by.to_sym)
22
+
21
23
  prune_blindspots_if_needed
22
24
  blindspot = Blindspot.new(domain: domain, discovered_by: discovered_by,
23
25
  description: description, severity: severity)
@@ -5,7 +5,7 @@ module Legion
5
5
  module Agentic
6
6
  module Attention
7
7
  module Blindspot
8
- VERSION = '0.1.0'
8
+ VERSION = '0.1.1'
9
9
  end
10
10
  end
11
11
  end
@@ -20,6 +20,7 @@ module Legion
20
20
 
21
21
  def register_feature(id:, dimension:, value:, source: :perception, salience: 0.5)
22
22
  return @features[id] if @features.key?(id)
23
+ return nil unless FEATURE_DIMENSIONS.include?(dimension.to_sym)
23
24
  return nil if @features.size >= MAX_FEATURES
24
25
 
25
26
  @features[id] = Feature.new(id: id, dimension: dimension, value: value, source: source, salience: salience)
@@ -5,7 +5,7 @@ module Legion
5
5
  module Agentic
6
6
  module Attention
7
7
  module FeatureBinding
8
- VERSION = '0.1.0'
8
+ VERSION = '0.1.1'
9
9
  end
10
10
  end
11
11
  end
@@ -19,6 +19,9 @@ module Legion
19
19
  def submit_input(content:, input_type:, context:, cognitive_effect: DEFAULT_EFFECT,
20
20
  processing_effort: DEFAULT_EFFORT, effect_type: :new_implication,
21
21
  source_id: nil)
22
+ return nil unless INPUT_TYPES.include?(input_type.to_sym)
23
+ return nil unless EFFECT_TYPES.include?(effect_type.to_sym)
24
+
22
25
  evict_oldest if @inputs.size >= MAX_INPUTS
23
26
 
24
27
  input = CognitiveInput.new(
@@ -5,7 +5,7 @@ module Legion
5
5
  module Agentic
6
6
  module Attention
7
7
  module RelevanceTheory
8
- VERSION = '0.1.0'
8
+ VERSION = '0.1.1'
9
9
  end
10
10
  end
11
11
  end
@@ -14,6 +14,8 @@ module Legion
14
14
  end
15
15
 
16
16
  def create_filter(modality:, gate_threshold: DEFAULT_GATE_THRESHOLD)
17
+ return nil unless MODALITY_TYPES.include?(modality.to_sym)
18
+
17
19
  prune_if_needed
18
20
  filter = SensoryFilter.new(modality: modality, gate_threshold: gate_threshold)
19
21
  @filters[filter.id] = filter
@@ -5,7 +5,7 @@ module Legion
5
5
  module Agentic
6
6
  module Attention
7
7
  module SensoryGating
8
- VERSION = '0.1.0'
8
+ VERSION = '0.1.1'
9
9
  end
10
10
  end
11
11
  end
@@ -16,6 +16,8 @@ module Legion
16
16
  end
17
17
 
18
18
  def register_task(name:, task_type: :analytical, complexity: 0.5)
19
+ return nil unless TASK_SET_TYPES.include?(task_type.to_sym)
20
+
19
21
  prune_tasks_if_needed
20
22
  task = TaskSet.new(name: name, task_type: task_type, complexity: complexity)
21
23
  @task_sets[task.id] = task
@@ -5,7 +5,7 @@ module Legion
5
5
  module Agentic
6
6
  module Attention
7
7
  module Switching
8
- VERSION = '0.1.0'
8
+ VERSION = '0.1.1'
9
9
  end
10
10
  end
11
11
  end
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Agentic
6
6
  module Attention
7
- VERSION = '0.1.0'
7
+ VERSION = '0.1.2'
8
8
  end
9
9
  end
10
10
  end
@@ -18,6 +18,21 @@ RSpec.describe Legion::Extensions::Agentic::Attention::Blindspot::Helpers::Blind
18
18
  end
19
19
 
20
20
  describe '#register_blindspot' do
21
+ it 'rejects invalid discovered_by' do
22
+ result = engine.register_blindspot(
23
+ domain: :reasoning, discovered_by: :nonexistent, description: 'test'
24
+ )
25
+ expect(result).to be_nil
26
+ end
27
+
28
+ it 'accepts all valid DISCOVERY_METHODS' do
29
+ constants = Legion::Extensions::Agentic::Attention::Blindspot::Helpers::Constants
30
+ constants::DISCOVERY_METHODS.each_with_index do |method, i|
31
+ b = engine.register_blindspot(domain: :"d#{i}", discovered_by: method, description: "test #{i}")
32
+ expect(b).not_to be_nil
33
+ end
34
+ end
35
+
21
36
  it 'returns a Blindspot object' do
22
37
  expect(blindspot).to be_a(Legion::Extensions::Agentic::Attention::Blindspot::Helpers::Blindspot)
23
38
  end
@@ -24,6 +24,20 @@ RSpec.describe Legion::Extensions::Agentic::Attention::FeatureBinding::Helpers::
24
24
  expect(field.feature_count).to eq(1)
25
25
  end
26
26
 
27
+ it 'rejects invalid dimension' do
28
+ result = field.register_feature(id: 'f:bad', dimension: :nonexistent, value: :x)
29
+ expect(result).to be_nil
30
+ expect(field.feature_count).to eq(0)
31
+ end
32
+
33
+ it 'accepts all valid FEATURE_DIMENSIONS' do
34
+ constants::FEATURE_DIMENSIONS.each_with_index do |dim, i|
35
+ f = field.register_feature(id: "f:#{i}", dimension: dim, value: i)
36
+ expect(f).not_to be_nil
37
+ end
38
+ expect(field.feature_count).to eq(constants::FEATURE_DIMENSIONS.size)
39
+ end
40
+
27
41
  it 'enforces MAX_FEATURES limit' do
28
42
  constants::MAX_FEATURES.times do |i|
29
43
  field.register_feature(id: "f:#{i}", dimension: :color, value: i)
@@ -16,6 +16,34 @@ RSpec.describe Legion::Extensions::Agentic::Attention::RelevanceTheory::Helpers:
16
16
  engine.submit_input(content: 'x', input_type: :assertion, context: :c)
17
17
  expect(engine.history.last[:event]).to eq(:submitted)
18
18
  end
19
+
20
+ it 'rejects invalid input_type' do
21
+ result = engine.submit_input(content: 'test', input_type: :nonexistent_type, context: :general)
22
+ expect(result).to be_nil
23
+ end
24
+
25
+ it 'accepts all INPUT_TYPES' do
26
+ constants = Legion::Extensions::Agentic::Attention::RelevanceTheory::Helpers::Constants::INPUT_TYPES
27
+ constants.each do |val|
28
+ result = engine.submit_input(content: 'test', input_type: val, context: :general)
29
+ expect(result).not_to be_nil, "Expected #{val.inspect} to be accepted"
30
+ end
31
+ end
32
+
33
+ it 'rejects invalid effect_type' do
34
+ result = engine.submit_input(content: 'test', input_type: :assertion, context: :general,
35
+ effect_type: :nonexistent_effect)
36
+ expect(result).to be_nil
37
+ end
38
+
39
+ it 'accepts all EFFECT_TYPES' do
40
+ constants = Legion::Extensions::Agentic::Attention::RelevanceTheory::Helpers::Constants::EFFECT_TYPES
41
+ constants.each do |val|
42
+ result = engine.submit_input(content: 'test', input_type: :assertion, context: :general,
43
+ effect_type: val)
44
+ expect(result).not_to be_nil, "Expected #{val.inspect} to be accepted"
45
+ end
46
+ end
19
47
  end
20
48
 
21
49
  describe '#assess_relevance' do
@@ -14,6 +14,20 @@ RSpec.describe Legion::Extensions::Agentic::Attention::SensoryGating::Helpers::G
14
14
  filter
15
15
  expect(engine.to_h[:total_filters]).to eq(1)
16
16
  end
17
+
18
+ it 'rejects invalid modality' do
19
+ result = engine.create_filter(modality: :nonexistent)
20
+ expect(result).to be_nil
21
+ end
22
+
23
+ it 'accepts all valid MODALITY_TYPES' do
24
+ constants = Legion::Extensions::Agentic::Attention::SensoryGating::Helpers::Constants
25
+ constants::MODALITY_TYPES.each do |mod|
26
+ f = engine.create_filter(modality: mod)
27
+ expect(f).not_to be_nil
28
+ end
29
+ expect(engine.to_h[:total_filters]).to eq(constants::MODALITY_TYPES.size)
30
+ end
17
31
  end
18
32
 
19
33
  describe '#process_stimulus' do
@@ -105,7 +119,8 @@ RSpec.describe Legion::Extensions::Agentic::Attention::SensoryGating::Helpers::G
105
119
  it 'prunes oldest filter when limit reached' do
106
120
  stub_const('Legion::Extensions::Agentic::Attention::SensoryGating::Helpers::Constants::MAX_FILTERS', 3)
107
121
  eng = described_class.new
108
- 4.times { |i| eng.create_filter(modality: :"mod#{i}") }
122
+ modalities = %i[visual auditory textual semantic]
123
+ modalities.each { |m| eng.create_filter(modality: m) }
109
124
  expect(eng.to_h[:total_filters]).to eq(3)
110
125
  end
111
126
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  RSpec.describe Legion::Extensions::Agentic::Attention::Switching do
4
4
  it 'has a version number' do
5
- expect(Legion::Extensions::Agentic::Attention::Switching::VERSION).to eq('0.1.0')
5
+ expect(Legion::Extensions::Agentic::Attention::Switching::VERSION).to eq('0.1.1')
6
6
  end
7
7
  end
@@ -12,6 +12,19 @@ RSpec.describe Legion::Extensions::Agentic::Attention::Switching::Helpers::Switc
12
12
  task = engine.register_task(name: 'test')
13
13
  expect(task).to be_a(Legion::Extensions::Agentic::Attention::Switching::Helpers::TaskSet)
14
14
  end
15
+
16
+ it 'rejects invalid task_type' do
17
+ result = engine.register_task(name: 'bad', task_type: :nonexistent_type)
18
+ expect(result).to be_nil
19
+ end
20
+
21
+ it 'accepts all TASK_SET_TYPES' do
22
+ constants = Legion::Extensions::Agentic::Attention::Switching::Helpers::Constants::TASK_SET_TYPES
23
+ constants.each do |val|
24
+ result = engine.register_task(name: val.to_s, task_type: val)
25
+ expect(result).not_to be_nil, "Expected #{val.inspect} to be accepted"
26
+ end
27
+ end
15
28
  end
16
29
 
17
30
  describe '#activate_task' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-agentic-attention
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity