lex-cognitive-control 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c1de8aff56a2e7595c43898c5be6dad98608ee3d6ddbcb23e100700c54d0bc83
4
+ data.tar.gz: ff3b7fb5e6eabf9ba94f8c0dc9c2ce0165bbffc045776651189ff6ca97ea60d6
5
+ SHA512:
6
+ metadata.gz: 588b9b7b395a0a32a0daa14b02b5f92bb6f37fde9baa1330e26e01a25e5476bbf68b418e054356d18c411929c61f56e068d83303877b0c662f0ce1be2dd73e8a
7
+ data.tar.gz: b2bf9c9f8efc0f0572c958e072cc24301e0180030e8d0a4a2cabcc59ae502f6a97b5896d94f541c86fb68f165b4b99f3b751327a1ad542a68b4d788ed53c25ff
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveControl
6
+ class Client
7
+ include Runners::CognitiveControl
8
+
9
+ def initialize(controller: nil)
10
+ @controller = controller || Helpers::Controller.new
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveControl
6
+ module Helpers
7
+ module Constants
8
+ MAX_GOALS = 20
9
+ MAX_POLICIES = 50
10
+ MAX_HISTORY = 200
11
+
12
+ DEFAULT_EFFORT = 0.5
13
+ EFFORT_FLOOR = 0.1
14
+ EFFORT_CEILING = 1.0
15
+ EFFORT_DECAY = 0.02
16
+ EFFORT_RECOVERY = 0.03
17
+
18
+ AUTOMATIC_THRESHOLD = 0.3
19
+ CONTROLLED_THRESHOLD = 0.6
20
+ OVERRIDE_THRESHOLD = 0.8
21
+
22
+ CONFLICT_BOOST = 0.2
23
+ ERROR_BOOST = 0.15
24
+ NOVELTY_BOOST = 0.1
25
+ ADAPTATION_ALPHA = 0.1
26
+
27
+ CONTROL_MODES = %i[automatic controlled override].freeze
28
+ GOAL_STATES = %i[active suspended completed abandoned].freeze
29
+
30
+ EFFORT_LABELS = {
31
+ (0.8..) => :maximal,
32
+ (0.6...0.8) => :effortful,
33
+ (0.4...0.6) => :moderate,
34
+ (0.2...0.4) => :low,
35
+ (..0.2) => :automatic
36
+ }.freeze
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveControl
6
+ module Helpers
7
+ class ControlSignal
8
+ include Constants
9
+
10
+ attr_reader :effort_level, :conflict_detected, :error_detected,
11
+ :novelty_detected
12
+
13
+ def initialize
14
+ @effort_level = DEFAULT_EFFORT
15
+ @conflict_detected = false
16
+ @error_detected = false
17
+ @novelty_detected = false
18
+ end
19
+
20
+ def detect_conflict
21
+ @conflict_detected = true
22
+ @effort_level = [@effort_level + CONFLICT_BOOST, EFFORT_CEILING].min
23
+ end
24
+
25
+ def detect_error
26
+ @error_detected = true
27
+ @effort_level = [@effort_level + ERROR_BOOST, EFFORT_CEILING].min
28
+ end
29
+
30
+ def detect_novelty
31
+ @novelty_detected = true
32
+ @effort_level = [@effort_level + NOVELTY_BOOST, EFFORT_CEILING].min
33
+ end
34
+
35
+ def reset_detections
36
+ @conflict_detected = false
37
+ @error_detected = false
38
+ @novelty_detected = false
39
+ end
40
+
41
+ def mode
42
+ return :override if @effort_level >= OVERRIDE_THRESHOLD
43
+ return :controlled if @effort_level >= CONTROLLED_THRESHOLD
44
+
45
+ :automatic
46
+ end
47
+
48
+ def effort_label
49
+ EFFORT_LABELS.each { |range, lbl| return lbl if range.cover?(@effort_level) }
50
+ :automatic
51
+ end
52
+
53
+ def decay
54
+ @effort_level = [@effort_level - EFFORT_DECAY, EFFORT_FLOOR].max
55
+ end
56
+
57
+ def recover(amount: EFFORT_RECOVERY)
58
+ @effort_level = [@effort_level + amount, EFFORT_CEILING].min
59
+ end
60
+
61
+ def to_h
62
+ {
63
+ effort_level: @effort_level.round(4),
64
+ mode: mode,
65
+ effort_label: effort_label,
66
+ conflict_detected: @conflict_detected,
67
+ error_detected: @error_detected,
68
+ novelty_detected: @novelty_detected
69
+ }
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveControl
6
+ module Helpers
7
+ class Controller
8
+ include Constants
9
+
10
+ attr_reader :goals, :signal, :history
11
+
12
+ def initialize
13
+ @goals = {}
14
+ @counter = 0
15
+ @signal = ControlSignal.new
16
+ @history = []
17
+ end
18
+
19
+ def set_goal(description:, domain: :general, priority: 0.5)
20
+ return nil if @goals.size >= MAX_GOALS
21
+
22
+ @counter += 1
23
+ goal_id = :"goal_#{@counter}"
24
+ goal = Goal.new(id: goal_id, description: description, domain: domain, priority: priority)
25
+ @goals[goal_id] = goal
26
+ goal
27
+ end
28
+
29
+ def advance_goal(goal_id:, amount: 0.1)
30
+ goal = @goals[goal_id]
31
+ return nil unless goal
32
+
33
+ goal.advance(amount: amount)
34
+ end
35
+
36
+ def suspend_goal(goal_id:)
37
+ goal = @goals[goal_id]
38
+ return nil unless goal
39
+
40
+ goal.suspend!
41
+ end
42
+
43
+ def resume_goal(goal_id:)
44
+ goal = @goals[goal_id]
45
+ return nil unless goal
46
+
47
+ goal.resume!
48
+ end
49
+
50
+ def abandon_goal(goal_id:)
51
+ goal = @goals[goal_id]
52
+ return nil unless goal
53
+
54
+ goal.abandon!
55
+ end
56
+
57
+ def evaluate_control_demand(conflict: false, error: false, novelty: false)
58
+ @signal.reset_detections
59
+ @signal.detect_conflict if conflict
60
+ @signal.detect_error if error
61
+ @signal.detect_novelty if novelty
62
+ record_evaluation
63
+ @signal.to_h
64
+ end
65
+
66
+ def current_mode
67
+ @signal.mode
68
+ end
69
+
70
+ def should_override?
71
+ @signal.mode == :override
72
+ end
73
+
74
+ def should_control?
75
+ %i[controlled override].include?(@signal.mode)
76
+ end
77
+
78
+ def active_goals
79
+ @goals.values.select(&:active?).sort_by { |g| -g.priority }.map(&:to_h)
80
+ end
81
+
82
+ def top_goal
83
+ active = @goals.values.select(&:active?)
84
+ return nil if active.empty?
85
+
86
+ active.max_by(&:priority).to_h
87
+ end
88
+
89
+ def goal_conflict?
90
+ active = @goals.values.select(&:active?)
91
+ return false if active.size < 2
92
+
93
+ priorities = active.map(&:priority)
94
+ (priorities.max - priorities.min) < 0.2 && active.size > 1
95
+ end
96
+
97
+ def tick
98
+ @signal.decay
99
+ check_goal_conflicts
100
+ @signal.to_h
101
+ end
102
+
103
+ def to_h
104
+ {
105
+ goal_count: @goals.size,
106
+ active_goals: @goals.values.count(&:active?),
107
+ effort_level: @signal.effort_level.round(4),
108
+ mode: current_mode,
109
+ effort_label: @signal.effort_label,
110
+ goal_conflict: goal_conflict?,
111
+ history_size: @history.size
112
+ }
113
+ end
114
+
115
+ private
116
+
117
+ def check_goal_conflicts
118
+ @signal.detect_conflict if goal_conflict?
119
+ end
120
+
121
+ def record_evaluation
122
+ @history << {
123
+ mode: @signal.mode,
124
+ effort: @signal.effort_level.round(4),
125
+ conflict: @signal.conflict_detected,
126
+ error: @signal.error_detected,
127
+ novelty: @signal.novelty_detected,
128
+ at: Time.now.utc
129
+ }
130
+ @history.shift while @history.size > MAX_HISTORY
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveControl
6
+ module Helpers
7
+ class Goal
8
+ include Constants
9
+
10
+ attr_reader :id, :description, :domain, :priority, :state, :progress, :created_at
11
+
12
+ def initialize(id:, description:, domain: :general, priority: 0.5)
13
+ @id = id
14
+ @description = description
15
+ @domain = domain
16
+ @priority = priority.to_f.clamp(0.0, 1.0)
17
+ @state = :active
18
+ @progress = 0.0
19
+ @created_at = Time.now.utc
20
+ end
21
+
22
+ def advance(amount: 0.1)
23
+ return nil unless @state == :active
24
+
25
+ @progress = [@progress + amount, 1.0].min
26
+ complete! if @progress >= 1.0
27
+ @progress
28
+ end
29
+
30
+ def complete!
31
+ @state = :completed
32
+ end
33
+
34
+ def suspend!
35
+ @state = :suspended if @state == :active
36
+ end
37
+
38
+ def resume!
39
+ @state = :active if @state == :suspended
40
+ end
41
+
42
+ def abandon!
43
+ @state = :abandoned unless @state == :completed
44
+ end
45
+
46
+ def active?
47
+ @state == :active
48
+ end
49
+
50
+ def completed?
51
+ @state == :completed
52
+ end
53
+
54
+ def to_h
55
+ {
56
+ id: @id,
57
+ description: @description,
58
+ domain: @domain,
59
+ priority: @priority.round(4),
60
+ state: @state,
61
+ progress: @progress.round(4)
62
+ }
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveControl
6
+ module Runners
7
+ module CognitiveControl
8
+ include Helpers::Constants
9
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
10
+
11
+ def set_control_goal(description:, domain: :general, priority: 0.5, **)
12
+ goal = controller.set_goal(description: description, domain: domain, priority: priority)
13
+ return { success: false, reason: :limit_reached } unless goal
14
+
15
+ { success: true, goal_id: goal.id, priority: goal.priority }
16
+ end
17
+
18
+ def advance_control_goal(goal_id:, amount: 0.1, **)
19
+ result = controller.advance_goal(goal_id: goal_id, amount: amount)
20
+ return { success: false, reason: :not_found } unless result
21
+
22
+ { success: true, goal_id: goal_id, progress: result.round(4) }
23
+ end
24
+
25
+ def suspend_control_goal(goal_id:, **)
26
+ controller.suspend_goal(goal_id: goal_id)
27
+ { success: true, goal_id: goal_id }
28
+ end
29
+
30
+ def evaluate_control(conflict: false, error: false, novelty: false, **)
31
+ result = controller.evaluate_control_demand(conflict: conflict, error: error, novelty: novelty)
32
+ { success: true }.merge(result)
33
+ end
34
+
35
+ def current_control_mode(**)
36
+ { success: true, mode: controller.current_mode, should_override: controller.should_override?,
37
+ should_control: controller.should_control? }
38
+ end
39
+
40
+ def active_control_goals(**)
41
+ goals = controller.active_goals
42
+ { success: true, goals: goals, count: goals.size }
43
+ end
44
+
45
+ def top_control_goal(**)
46
+ goal = controller.top_goal
47
+ return { success: false, reason: :no_active_goals } unless goal
48
+
49
+ { success: true }.merge(goal)
50
+ end
51
+
52
+ def update_cognitive_control(**)
53
+ result = controller.tick
54
+ { success: true }.merge(result)
55
+ end
56
+
57
+ def cognitive_control_stats(**)
58
+ { success: true }.merge(controller.to_h)
59
+ end
60
+
61
+ private
62
+
63
+ def controller
64
+ @controller ||= Helpers::Controller.new
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveControl
6
+ VERSION = '0.1.0'
7
+ end
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-cognitive-control
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: Cognitive control for LegionIO — automatic vs. controlled processing,
27
+ goal management, and effort allocation
28
+ email:
29
+ - matthewdiverson@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - lib/legion/extensions/cognitive_control/client.rb
35
+ - lib/legion/extensions/cognitive_control/helpers/constants.rb
36
+ - lib/legion/extensions/cognitive_control/helpers/control_signal.rb
37
+ - lib/legion/extensions/cognitive_control/helpers/controller.rb
38
+ - lib/legion/extensions/cognitive_control/helpers/goal.rb
39
+ - lib/legion/extensions/cognitive_control/runners/cognitive_control.rb
40
+ - lib/legion/extensions/cognitive_control/version.rb
41
+ homepage: https://github.com/LegionIO/lex-cognitive-control
42
+ licenses:
43
+ - MIT
44
+ metadata:
45
+ homepage_uri: https://github.com/LegionIO/lex-cognitive-control
46
+ source_code_uri: https://github.com/LegionIO/lex-cognitive-control
47
+ documentation_uri: https://github.com/LegionIO/lex-cognitive-control/blob/master/README.md
48
+ changelog_uri: https://github.com/LegionIO/lex-cognitive-control/blob/master/CHANGELOG.md
49
+ bug_tracker_uri: https://github.com/LegionIO/lex-cognitive-control/issues
50
+ rubygems_mfa_required: 'true'
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '3.4'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubygems_version: 3.6.9
66
+ specification_version: 4
67
+ summary: Cognitive control meta-controller for LegionIO
68
+ test_files: []