lex-cognitive-load-balancing 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: c544354dc10debe5f37d9481d770ae4d9ef9d9ff05e2f9463c7ede05ce1243bf
4
+ data.tar.gz: 6d51ca7b3e00f79ab95e6cd401c1499b78af6554dd017ef80600fd67e24d601c
5
+ SHA512:
6
+ metadata.gz: 57cc1ca0b87c2fc8d5be5d5341072cba5f8338a52dbf2c236a54b7b4ba4c27a3b71b85de72fcf2f237bb5401531663f6dc7986d911357fbceab06dcb4d7e1280
7
+ data.tar.gz: 44efcecde4666d5374e1e8abdaa3f8b3fe7ba1ada740112b2ffb0b285fa06eaa71c5a5f53a7b491f54922cde082df6d17631f6dd40837d8acd9e5ec0755ef982
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveLoadBalancing
6
+ class Client
7
+ include Runners::CognitiveLoadBalancing
8
+
9
+ def engine
10
+ @engine ||= Helpers::LoadBalancer.new
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveLoadBalancing
6
+ module Helpers
7
+ module Constants
8
+ MAX_SUBSYSTEMS = 50
9
+ MAX_TASKS = 500
10
+
11
+ DEFAULT_CAPACITY = 1.0
12
+ OVERLOAD_THRESHOLD = 0.85
13
+ UNDERLOAD_THRESHOLD = 0.2
14
+ REBALANCE_STEP = 0.1
15
+
16
+ LOAD_LABELS = {
17
+ (0.85..) => :overloaded,
18
+ (0.7...0.85) => :heavy,
19
+ (0.4...0.7) => :balanced,
20
+ (0.2...0.4) => :light,
21
+ (..0.2) => :idle
22
+ }.freeze
23
+
24
+ HEALTH_LABELS = {
25
+ (0.8..) => :excellent,
26
+ (0.6...0.8) => :good,
27
+ (0.4...0.6) => :fair,
28
+ (0.2...0.4) => :strained,
29
+ (..0.2) => :failing
30
+ }.freeze
31
+
32
+ SUBSYSTEM_TYPES = %i[
33
+ perception reasoning memory attention
34
+ language planning motor emotional
35
+ ].freeze
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveLoadBalancing
6
+ module Helpers
7
+ class LoadBalancer
8
+ include Constants
9
+
10
+ def initialize
11
+ @subsystems = {}
12
+ end
13
+
14
+ def register_subsystem(name:, subsystem_type: :general, capacity: DEFAULT_CAPACITY)
15
+ prune_if_needed
16
+ subsystem = Subsystem.new(
17
+ name: name,
18
+ subsystem_type: subsystem_type,
19
+ capacity: capacity
20
+ )
21
+ @subsystems[subsystem.id] = subsystem
22
+ subsystem
23
+ end
24
+
25
+ def assign_load(subsystem_id:, amount:)
26
+ subsystem = @subsystems[subsystem_id]
27
+ return nil unless subsystem
28
+
29
+ subsystem.add_load!(amount: amount)
30
+ end
31
+
32
+ def shed_load(subsystem_id:, amount:)
33
+ subsystem = @subsystems[subsystem_id]
34
+ return nil unless subsystem
35
+
36
+ subsystem.shed_load!(amount: amount)
37
+ end
38
+
39
+ def auto_assign(amount:, subsystem_type: nil)
40
+ candidates = if subsystem_type
41
+ @subsystems.values.select { |s| s.subsystem_type == subsystem_type.to_sym }
42
+ else
43
+ @subsystems.values
44
+ end
45
+ return nil if candidates.empty?
46
+
47
+ best = candidates.min_by(&:utilization)
48
+ best.add_load!(amount: amount)
49
+ best
50
+ end
51
+
52
+ def rebalance
53
+ overloaded = @subsystems.values.select(&:overloaded?)
54
+ underloaded = @subsystems.values.select(&:underloaded?)
55
+ transfers = 0
56
+
57
+ overloaded.each do |over|
58
+ target = underloaded.min_by(&:utilization)
59
+ break unless target
60
+
61
+ transfer_amount = [REBALANCE_STEP, over.current_load * 0.2].min
62
+ shed = over.shed_load!(amount: transfer_amount)
63
+ target.add_load!(amount: shed)
64
+ transfers += 1
65
+ end
66
+
67
+ transfers
68
+ end
69
+
70
+ def overloaded_subsystems
71
+ @subsystems.values.select(&:overloaded?)
72
+ end
73
+
74
+ def underloaded_subsystems
75
+ @subsystems.values.select(&:underloaded?)
76
+ end
77
+
78
+ def subsystems_by_type(subsystem_type:)
79
+ st = subsystem_type.to_sym
80
+ @subsystems.values.select { |s| s.subsystem_type == st }
81
+ end
82
+
83
+ def most_loaded(limit: 5)
84
+ @subsystems.values.sort_by { |s| -s.utilization }.first(limit)
85
+ end
86
+
87
+ def overall_utilization
88
+ return 0.0 if @subsystems.empty?
89
+
90
+ utils = @subsystems.values.map(&:utilization)
91
+ (utils.sum / utils.size).round(10)
92
+ end
93
+
94
+ def overall_health
95
+ return 1.0 if @subsystems.empty?
96
+
97
+ healths = @subsystems.values.map(&:health)
98
+ (healths.sum / healths.size).round(10)
99
+ end
100
+
101
+ def balance_report
102
+ {
103
+ total_subsystems: @subsystems.size,
104
+ overloaded_count: overloaded_subsystems.size,
105
+ underloaded_count: underloaded_subsystems.size,
106
+ overall_utilization: overall_utilization,
107
+ overall_health: overall_health,
108
+ most_loaded: most_loaded(limit: 3).map(&:to_h)
109
+ }
110
+ end
111
+
112
+ def to_h
113
+ {
114
+ total_subsystems: @subsystems.size,
115
+ overall_utilization: overall_utilization,
116
+ overall_health: overall_health,
117
+ overloaded_count: overloaded_subsystems.size
118
+ }
119
+ end
120
+
121
+ private
122
+
123
+ def prune_if_needed
124
+ return if @subsystems.size < MAX_SUBSYSTEMS
125
+
126
+ least_used = @subsystems.values.min_by(&:tasks_processed)
127
+ @subsystems.delete(least_used.id) if least_used
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module CognitiveLoadBalancing
8
+ module Helpers
9
+ class Subsystem
10
+ include Constants
11
+
12
+ attr_reader :id, :name, :subsystem_type, :capacity, :current_load,
13
+ :tasks_processed, :tasks_shed, :created_at
14
+
15
+ def initialize(name:, subsystem_type: :general, capacity: DEFAULT_CAPACITY)
16
+ @id = SecureRandom.uuid
17
+ @name = name
18
+ @subsystem_type = subsystem_type.to_sym
19
+ @capacity = capacity.to_f.clamp(0.1, 5.0)
20
+ @current_load = 0.0
21
+ @tasks_processed = 0
22
+ @tasks_shed = 0
23
+ @created_at = Time.now.utc
24
+ end
25
+
26
+ def utilization
27
+ return 0.0 if @capacity.zero?
28
+
29
+ (@current_load / @capacity).clamp(0.0, 1.5).round(10)
30
+ end
31
+
32
+ def load_label
33
+ match = LOAD_LABELS.find { |range, _| range.cover?(utilization) }
34
+ match ? match.last : :overloaded
35
+ end
36
+
37
+ def overloaded?
38
+ utilization >= OVERLOAD_THRESHOLD
39
+ end
40
+
41
+ def underloaded?
42
+ utilization <= UNDERLOAD_THRESHOLD
43
+ end
44
+
45
+ def health
46
+ if overloaded?
47
+ [1.0 - ((utilization - OVERLOAD_THRESHOLD) * 3), 0.0].max.round(10)
48
+ else
49
+ 1.0
50
+ end
51
+ end
52
+
53
+ def health_label
54
+ match = HEALTH_LABELS.find { |range, _| range.cover?(health) }
55
+ match ? match.last : :failing
56
+ end
57
+
58
+ def add_load!(amount:)
59
+ @current_load = (@current_load + amount.to_f).clamp(0.0, @capacity * 1.5).round(10)
60
+ @tasks_processed += 1
61
+ self
62
+ end
63
+
64
+ def shed_load!(amount:)
65
+ removed = [amount.to_f, @current_load].min
66
+ @current_load = (@current_load - removed).clamp(0.0, @capacity * 1.5).round(10)
67
+ @tasks_shed += 1
68
+ removed
69
+ end
70
+
71
+ def available_capacity
72
+ [(@capacity - @current_load), 0.0].max.round(10)
73
+ end
74
+
75
+ def to_h
76
+ {
77
+ id: @id,
78
+ name: @name,
79
+ subsystem_type: @subsystem_type,
80
+ capacity: @capacity,
81
+ current_load: @current_load,
82
+ utilization: utilization,
83
+ load_label: load_label,
84
+ overloaded: overloaded?,
85
+ health: health,
86
+ health_label: health_label,
87
+ available_capacity: available_capacity,
88
+ tasks_processed: @tasks_processed,
89
+ tasks_shed: @tasks_shed,
90
+ created_at: @created_at
91
+ }
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveLoadBalancing
6
+ module Runners
7
+ module CognitiveLoadBalancing
8
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
9
+
10
+ def register_cognitive_subsystem(name:, subsystem_type: :general,
11
+ capacity: nil, **)
12
+ cap = capacity || Helpers::Constants::DEFAULT_CAPACITY
13
+ sub = engine.register_subsystem(name: name, subsystem_type: subsystem_type,
14
+ capacity: cap)
15
+ { success: true }.merge(sub.to_h)
16
+ end
17
+
18
+ def assign_cognitive_load(subsystem_id:, amount:, **)
19
+ result = engine.assign_load(subsystem_id: subsystem_id, amount: amount)
20
+ return { success: false, error: 'subsystem not found' } unless result
21
+
22
+ { success: true }.merge(result.to_h)
23
+ end
24
+
25
+ def shed_cognitive_load(subsystem_id:, amount:, **)
26
+ result = engine.shed_load(subsystem_id: subsystem_id, amount: amount)
27
+ return { success: false, error: 'subsystem not found' } unless result
28
+
29
+ { success: true, shed: result }
30
+ end
31
+
32
+ def auto_assign_load(amount:, subsystem_type: nil, **)
33
+ result = engine.auto_assign(amount: amount, subsystem_type: subsystem_type)
34
+ return { success: false, error: 'no available subsystem' } unless result
35
+
36
+ { success: true, assigned_to: result.name }.merge(result.to_h)
37
+ end
38
+
39
+ def rebalance_cognitive_load(**)
40
+ transfers = engine.rebalance
41
+ { success: true, transfers: transfers, stats: engine.to_h }
42
+ end
43
+
44
+ def overloaded_subsystems_report(**)
45
+ subs = engine.overloaded_subsystems
46
+ { success: true, count: subs.size, subsystems: subs.map(&:to_h) }
47
+ end
48
+
49
+ def most_loaded_report(limit: 5, **)
50
+ subs = engine.most_loaded(limit: limit)
51
+ { success: true, limit: limit, subsystems: subs.map(&:to_h) }
52
+ end
53
+
54
+ def cognitive_load_balance_report(**)
55
+ engine.balance_report
56
+ end
57
+
58
+ def cognitive_load_balancing_stats(**)
59
+ engine.to_h
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveLoadBalancing
6
+ VERSION = '0.1.0'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'cognitive_load_balancing/version'
4
+ require_relative 'cognitive_load_balancing/helpers/constants'
5
+ require_relative 'cognitive_load_balancing/helpers/subsystem'
6
+ require_relative 'cognitive_load_balancing/helpers/load_balancer'
7
+ require_relative 'cognitive_load_balancing/runners/cognitive_load_balancing'
8
+ require_relative 'cognitive_load_balancing/client'
9
+
10
+ module Legion
11
+ module Extensions
12
+ module CognitiveLoadBalancing
13
+ extend Legion::Extensions::Core if defined?(Legion::Extensions::Core)
14
+ end
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-cognitive-load-balancing
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: Dynamic distribution of cognitive work across subsystems with overload
27
+ detection, auto-assignment, and rebalancing.
28
+ email:
29
+ - matthewdiverson@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - lib/legion/extensions/cognitive_load_balancing.rb
35
+ - lib/legion/extensions/cognitive_load_balancing/client.rb
36
+ - lib/legion/extensions/cognitive_load_balancing/helpers/constants.rb
37
+ - lib/legion/extensions/cognitive_load_balancing/helpers/load_balancer.rb
38
+ - lib/legion/extensions/cognitive_load_balancing/helpers/subsystem.rb
39
+ - lib/legion/extensions/cognitive_load_balancing/runners/cognitive_load_balancing.rb
40
+ - lib/legion/extensions/cognitive_load_balancing/version.rb
41
+ homepage: https://github.com/LegionIO/lex-cognitive-load-balancing
42
+ licenses:
43
+ - MIT
44
+ metadata:
45
+ homepage_uri: https://github.com/LegionIO/lex-cognitive-load-balancing
46
+ source_code_uri: https://github.com/LegionIO/lex-cognitive-load-balancing
47
+ documentation_uri: https://github.com/LegionIO/lex-cognitive-load-balancing
48
+ changelog_uri: https://github.com/LegionIO/lex-cognitive-load-balancing/blob/main/CHANGELOG.md
49
+ bug_tracker_uri: https://github.com/LegionIO/lex-cognitive-load-balancing/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 load balancing across subsystems for LegionIO
68
+ test_files: []