lex-mind-growth 0.1.4 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40f7d638167956b7c52bd79a6946c7489ad677e2cf8ed0afd095530cf907ad08
4
- data.tar.gz: 9054302975661892f60a91fa9d3b41eae764e8c48509d480b2242cc213b737c0
3
+ metadata.gz: 3749e6e3fd39af6abe591e437da33b0c159db29b6e3463bd96dfb46f17b65d47
4
+ data.tar.gz: c702f090f36a6279fcded74bc19fccfa16cf8149d549d2603d0d38ed8b706432
5
5
  SHA512:
6
- metadata.gz: e966570dcfdf4bd5b5e0d6ff1b176772e62d0cbe77d6f25cdb88dec1afe091fbf0a77791084476f1423b93407ef3ff1f4733af8c713241ef982331faff7974c2
7
- data.tar.gz: c07d864de3b898050838da167d1ec9e65424291df54af05a0628ba46821591899e84898a45f406f4edc1131c90c93bd0c4da4ff779903cde73f3db54ac2a07b7
6
+ metadata.gz: 5a70ad32a8ca26d122eae4d6e176d3d680f8943c08fa9c74379e3e03bbc99f1f7663b1b0abf6ecb5ef3d06f997107fd2c3d04d48ab32306f458a78419f92e39d
7
+ data.tar.gz: 9861dfcd32bad6bcb08b398be0a1a1fc3e3f564e2cb8d17a58cb30cdd43218d1ce1600c7d2f0af559f38c0ce5868f639e14fb59f8dc00fd6ac13b551770cb197
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module MindGrowth
6
+ module Helpers
7
+ module PhaseAllocator
8
+ # Maps cognitive categories to GAIA tick phases
9
+ CATEGORY_PHASE_MAP = {
10
+ perception: :sensory_processing,
11
+ attention: :sensory_processing,
12
+ emotion: :emotional_evaluation,
13
+ affect: :emotional_evaluation,
14
+ memory: :memory_retrieval,
15
+ knowledge: :knowledge_retrieval,
16
+ identity: :identity_entropy_check,
17
+ cognition: :working_memory_integration,
18
+ reasoning: :working_memory_integration,
19
+ safety: :procedural_check,
20
+ defense: :procedural_check,
21
+ prediction: :prediction_engine,
22
+ inference: :prediction_engine,
23
+ communication: :mesh_interface,
24
+ social: :mesh_interface,
25
+ coordination: :mesh_interface,
26
+ motivation: :action_selection,
27
+ executive: :action_selection,
28
+ learning: :memory_consolidation,
29
+ consolidation: :memory_consolidation,
30
+ introspection: :post_tick_reflection,
31
+ self: :post_tick_reflection,
32
+ reflection: :post_tick_reflection
33
+ }.freeze
34
+
35
+ # Dream cycle phase mappings
36
+ DREAM_PHASE_MAP = {
37
+ memory: :memory_audit,
38
+ association: :association_walk,
39
+ conflict: :contradiction_resolution,
40
+ curiosity: :agenda_formation,
41
+ consolidation: :consolidation_commit,
42
+ knowledge: :knowledge_promotion,
43
+ reflection: :dream_reflection,
44
+ narrative: :dream_narration
45
+ }.freeze
46
+
47
+ # Maps method name substrings to inferred GAIA phases for unknown categories
48
+ METHOD_INFERENCE_MAP = [
49
+ [%w[filter sense detect], :sensory_processing],
50
+ [%w[predict forecast estimate], :prediction_engine],
51
+ [%w[reflect evaluate assess], :post_tick_reflection],
52
+ [%w[store retrieve recall], :memory_retrieval],
53
+ [%w[decide select choose], :action_selection]
54
+ ].freeze
55
+
56
+ module_function
57
+
58
+ def allocate_phase(category:, runner_methods: [])
59
+ category_sym = category.to_s.downcase.to_sym
60
+
61
+ # Check active phases first
62
+ phase = CATEGORY_PHASE_MAP[category_sym]
63
+ return { phase: phase, cycle: :active, confidence: :high } if phase
64
+
65
+ # Try to infer from runner method names
66
+ inferred = infer_from_methods(runner_methods)
67
+ return inferred if inferred
68
+
69
+ # Default to working_memory_integration (safest catch-all)
70
+ { phase: :working_memory_integration, cycle: :active, confidence: :low }
71
+ end
72
+
73
+ def allocate_dream_phase(category:)
74
+ category_sym = category.to_s.downcase.to_sym
75
+ phase = DREAM_PHASE_MAP[category_sym]
76
+ return { phase: phase, cycle: :dream, confidence: :high } if phase
77
+
78
+ nil
79
+ end
80
+
81
+ def infer_from_methods(methods)
82
+ method_names = methods.map(&:to_s)
83
+ match = METHOD_INFERENCE_MAP.find do |keywords, _phase|
84
+ method_names.any? { |m| keywords.any? { |kw| m.include?(kw) } }
85
+ end
86
+ return nil unless match
87
+
88
+ { phase: match[1], cycle: :active, confidence: :medium }
89
+ end
90
+
91
+ def valid_phase?(phase)
92
+ CATEGORY_PHASE_MAP.values.include?(phase) || DREAM_PHASE_MAP.values.include?(phase)
93
+ end
94
+
95
+ def phases_for_category(category)
96
+ category_sym = category.to_s.downcase.to_sym
97
+ results = []
98
+ results << CATEGORY_PHASE_MAP[category_sym] if CATEGORY_PHASE_MAP.key?(category_sym)
99
+ results << DREAM_PHASE_MAP[category_sym] if DREAM_PHASE_MAP.key?(category_sym)
100
+ results.compact
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module MindGrowth
6
+ module Runners
7
+ module IntegrationTester
8
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
9
+ Legion::Extensions::Helpers.const_defined?(:Lex)
10
+
11
+ extend self
12
+
13
+ TICK_BUDGET_MS = 5000
14
+
15
+ def test_extension_in_tick(ext_module:, runner_module:, fn:, phase:, test_args: {}, **) # rubocop:disable Naming/MethodParameterName
16
+ return { success: false, reason: :gaia_not_available } unless gaia_available?
17
+
18
+ runner_class = resolve_runner_class(ext_module, runner_module)
19
+ return { success: false, reason: :runner_not_found } unless runner_class
20
+
21
+ # Test 1: Method exists and is callable
22
+ method_check = test_method_callable(runner_class, fn)
23
+ return method_check unless method_check[:success]
24
+
25
+ # Test 2: Method returns valid response hash
26
+ response_check = test_valid_response(runner_class, fn, test_args)
27
+ return response_check unless response_check[:success]
28
+
29
+ # Test 3: Method completes within budget
30
+ perf_check = test_performance(runner_class, fn, test_args)
31
+
32
+ {
33
+ success: true,
34
+ method_callable: method_check[:success],
35
+ valid_response: response_check[:success],
36
+ performance: perf_check,
37
+ phase: phase
38
+ }
39
+ rescue StandardError => e
40
+ { success: false, reason: :exception, error: e.message }
41
+ end
42
+
43
+ def benchmark_tick(with_extension: nil, iterations: 5, **)
44
+ return { success: false, reason: :gaia_not_available } unless gaia_available?
45
+
46
+ timings = iterations.times.map do
47
+ start = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
48
+ Legion::Gaia.heartbeat if Legion::Gaia.respond_to?(:heartbeat)
49
+ finish = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
50
+ ((finish - start) * 1000).round(2)
51
+ end
52
+
53
+ {
54
+ success: true,
55
+ with_extension: with_extension,
56
+ iterations: iterations,
57
+ avg_ms: (timings.sum / timings.size).round(2),
58
+ max_ms: timings.max,
59
+ min_ms: timings.min,
60
+ within_budget: timings.max <= TICK_BUDGET_MS
61
+ }
62
+ rescue StandardError => e
63
+ { success: false, reason: :benchmark_failed, error: e.message }
64
+ end
65
+
66
+ private
67
+
68
+ def gaia_available?
69
+ defined?(Legion::Gaia)
70
+ end
71
+
72
+ def resolve_runner_class(ext_module, runner_module)
73
+ return nil unless defined?(Legion::Gaia::PhaseWiring)
74
+
75
+ Legion::Gaia::PhaseWiring.resolve_runner_class(ext_module.to_sym, runner_module.to_sym)
76
+ end
77
+
78
+ def test_method_callable(runner_class, fn) # rubocop:disable Naming/MethodParameterName
79
+ if runner_class.method_defined?(fn) || runner_class.respond_to?(fn)
80
+ { success: true, method: fn }
81
+ else
82
+ { success: false, reason: :method_not_defined, method: fn }
83
+ end
84
+ end
85
+
86
+ def test_valid_response(runner_class, fn, args) # rubocop:disable Naming/MethodParameterName
87
+ host = Object.new.extend(runner_class)
88
+ result = host.send(fn, **args)
89
+
90
+ if result.is_a?(Hash)
91
+ { success: true, response_type: :hash, keys: result.keys }
92
+ elsif result.nil?
93
+ { success: true, response_type: :nil }
94
+ else
95
+ { success: true, response_type: result.class.name }
96
+ end
97
+ rescue StandardError => e
98
+ { success: false, reason: :invocation_error, error: e.message }
99
+ end
100
+
101
+ def test_performance(runner_class, fn, args) # rubocop:disable Naming/MethodParameterName
102
+ host = Object.new.extend(runner_class)
103
+ start = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
104
+ host.send(fn, **args)
105
+ finish = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
106
+ duration_ms = ((finish - start) * 1000).round(2)
107
+
108
+ { duration_ms: duration_ms, within_budget: duration_ms <= TICK_BUDGET_MS }
109
+ rescue StandardError => e
110
+ { duration_ms: nil, error: e.message, within_budget: false }
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module MindGrowth
6
+ module Runners
7
+ module Wirer
8
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
9
+ Legion::Extensions::Helpers.const_defined?(:Lex)
10
+
11
+ extend self
12
+
13
+ def analyze_fit(extension_name:, category:, runner_module: nil, runner_methods: [], **) # rubocop:disable Lint/UnusedMethodArgument
14
+ allocation = Helpers::PhaseAllocator.allocate_phase(
15
+ category: category,
16
+ runner_methods: runner_methods
17
+ )
18
+
19
+ dream_allocation = Helpers::PhaseAllocator.allocate_dream_phase(category: category)
20
+
21
+ {
22
+ success: true,
23
+ extension: extension_name,
24
+ active_phase: allocation,
25
+ dream_phase: dream_allocation,
26
+ recommendation: build_recommendation(allocation, dream_allocation)
27
+ }
28
+ end
29
+
30
+ def wire_extension(extension_name:, ext_module:, runner_module:, fn:, phase:, **) # rubocop:disable Naming/MethodParameterName
31
+ return { success: false, reason: :gaia_not_available } unless gaia_available?
32
+ return { success: false, reason: :invalid_phase } unless Helpers::PhaseAllocator.valid_phase?(phase)
33
+
34
+ # Verify the runner class exists and has the method
35
+ runner_class = resolve_runner(ext_module: ext_module, runner_module: runner_module)
36
+ return { success: false, reason: :runner_not_found } unless runner_class
37
+
38
+ return { success: false, reason: :method_not_found, method: fn } unless runner_class.method_defined?(fn) || runner_class.respond_to?(fn)
39
+
40
+ # Record the wiring in our registry
41
+ wiring_registry[extension_name] = {
42
+ ext_module: ext_module,
43
+ runner_module: runner_module,
44
+ fn: fn,
45
+ phase: phase,
46
+ wired_at: Time.now,
47
+ enabled: true
48
+ }
49
+
50
+ # Trigger GAIA rediscovery to pick up the new wiring
51
+ rediscover_result = trigger_rediscovery
52
+
53
+ {
54
+ success: true,
55
+ extension: extension_name,
56
+ phase: phase,
57
+ fn: fn,
58
+ rediscovery: rediscover_result
59
+ }
60
+ end
61
+
62
+ def unwire_extension(extension_name:, **)
63
+ entry = wiring_registry.delete(extension_name)
64
+ return { success: false, reason: :not_wired } unless entry
65
+
66
+ trigger_rediscovery
67
+
68
+ { success: true, extension: extension_name, unwired_phase: entry[:phase] }
69
+ end
70
+
71
+ def disable_extension(extension_name:, **)
72
+ entry = wiring_registry[extension_name]
73
+ return { success: false, reason: :not_wired } unless entry
74
+
75
+ entry[:enabled] = false
76
+ { success: true, extension: extension_name, status: :disabled }
77
+ end
78
+
79
+ def enable_extension(extension_name:, **)
80
+ entry = wiring_registry[extension_name]
81
+ return { success: false, reason: :not_wired } unless entry
82
+
83
+ entry[:enabled] = true
84
+ trigger_rediscovery
85
+ { success: true, extension: extension_name, status: :enabled }
86
+ end
87
+
88
+ def wiring_status(**)
89
+ {
90
+ success: true,
91
+ wired_count: wiring_registry.size,
92
+ enabled_count: wiring_registry.count { |_, v| v[:enabled] },
93
+ extensions: wiring_registry.transform_values { |v| v.slice(:phase, :fn, :enabled, :wired_at) }
94
+ }
95
+ end
96
+
97
+ def rewire_all(**)
98
+ return { success: false, reason: :gaia_not_available } unless gaia_available?
99
+
100
+ result = trigger_rediscovery
101
+ { success: true, rediscovery: result }
102
+ end
103
+
104
+ private
105
+
106
+ def gaia_available?
107
+ defined?(Legion::Gaia) && Legion::Gaia.respond_to?(:registry)
108
+ end
109
+
110
+ def resolve_runner(ext_module:, runner_module:)
111
+ return nil unless defined?(Legion::Gaia::PhaseWiring)
112
+
113
+ Legion::Gaia::PhaseWiring.resolve_runner_class(ext_module.to_sym, runner_module.to_sym)
114
+ end
115
+
116
+ def trigger_rediscovery
117
+ return { rediscovered: false, reason: :gaia_not_available } unless gaia_available?
118
+
119
+ Legion::Gaia.registry.rediscover
120
+ rescue StandardError => e
121
+ { rediscovered: false, error: e.message }
122
+ end
123
+
124
+ def wiring_registry
125
+ @wiring_registry ||= {}
126
+ end
127
+
128
+ def build_recommendation(active_alloc, dream_alloc)
129
+ parts = []
130
+ parts << case active_alloc[:confidence]
131
+ when :high
132
+ "Wire to #{active_alloc[:phase]} (high confidence)"
133
+ when :medium
134
+ "Suggest #{active_alloc[:phase]} (medium confidence, verify manually)"
135
+ else
136
+ "Default to #{active_alloc[:phase]} (low confidence, manual review recommended)"
137
+ end
138
+ parts << "Also wire dream phase: #{dream_alloc[:phase]}" if dream_alloc
139
+ parts.join('. ')
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -3,7 +3,7 @@
3
3
  module Legion
4
4
  module Extensions
5
5
  module MindGrowth
6
- VERSION = '0.1.4'
6
+ VERSION = '0.1.5'
7
7
  end
8
8
  end
9
9
  end
@@ -9,11 +9,14 @@ require 'legion/extensions/mind_growth/helpers/proposal_store'
9
9
  require 'legion/extensions/mind_growth/helpers/cognitive_models'
10
10
  require 'legion/extensions/mind_growth/helpers/build_pipeline'
11
11
  require 'legion/extensions/mind_growth/helpers/fitness_evaluator'
12
+ require 'legion/extensions/mind_growth/helpers/phase_allocator'
12
13
  require 'legion/extensions/mind_growth/runners/proposer'
13
14
  require 'legion/extensions/mind_growth/runners/analyzer'
14
15
  require 'legion/extensions/mind_growth/runners/builder'
15
16
  require 'legion/extensions/mind_growth/runners/validator'
16
17
  require 'legion/extensions/mind_growth/runners/orchestrator'
18
+ require 'legion/extensions/mind_growth/runners/wirer'
19
+ require 'legion/extensions/mind_growth/runners/integration_tester'
17
20
  require 'legion/extensions/mind_growth/client'
18
21
 
19
22
  module Legion