lex-mind-growth 0.1.0 → 0.1.4
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 +4 -4
- data/Gemfile +4 -5
- data/lex-mind-growth.gemspec +9 -1
- data/lib/legion/extensions/mind_growth/helpers/build_pipeline.rb +10 -0
- data/lib/legion/extensions/mind_growth/runners/builder.rb +5 -2
- data/lib/legion/extensions/mind_growth/runners/orchestrator.rb +4 -3
- data/lib/legion/extensions/mind_growth/runners/proposer.rb +15 -10
- data/lib/legion/extensions/mind_growth/version.rb +1 -1
- data/spec/legion/extensions/mind_growth/helpers/build_pipeline_spec.rb +29 -0
- data/spec/spec_helper.rb +29 -7
- metadata +101 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 40f7d638167956b7c52bd79a6946c7489ad677e2cf8ed0afd095530cf907ad08
|
|
4
|
+
data.tar.gz: 9054302975661892f60a91fa9d3b41eae764e8c48509d480b2242cc213b737c0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e966570dcfdf4bd5b5e0d6ff1b176772e62d0cbe77d6f25cdb88dec1afe091fbf0a77791084476f1423b93407ef3ff1f4733af8c713241ef982331faff7974c2
|
|
7
|
+
data.tar.gz: c07d864de3b898050838da167d1ec9e65424291df54af05a0628ba46821591899e84898a45f406f4edc1131c90c93bd0c4da4ff779903cde73f3db54ac2a07b7
|
data/Gemfile
CHANGED
|
@@ -12,8 +12,7 @@ group :test do
|
|
|
12
12
|
gem 'simplecov'
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
gem 'legion-
|
|
16
|
-
gem '
|
|
17
|
-
gem 'lex-
|
|
18
|
-
|
|
19
|
-
gem 'legion-gaia', path: '../../legion-gaia'
|
|
15
|
+
gem 'legion-gaia', path: '../../legion-gaia' if File.directory?(File.expand_path('../../legion-gaia', __dir__))
|
|
16
|
+
gem 'legion-llm', path: '../../legion-llm', require: false if File.directory?(File.expand_path('../../legion-llm', __dir__))
|
|
17
|
+
gem 'lex-codegen', path: '../../extensions-core/lex-codegen', require: false if File.directory?(File.expand_path('../../extensions-core/lex-codegen', __dir__))
|
|
18
|
+
gem 'lex-exec', path: '../../extensions-core/lex-exec', require: false if File.directory?(File.expand_path('../../extensions-core/lex-exec', __dir__))
|
data/lex-mind-growth.gemspec
CHANGED
|
@@ -25,5 +25,13 @@ Gem::Specification.new do |spec|
|
|
|
25
25
|
Dir.glob('{lib,spec}/**/*') + %w[lex-mind-growth.gemspec Gemfile LICENSE]
|
|
26
26
|
end
|
|
27
27
|
spec.require_paths = ['lib']
|
|
28
|
-
spec.
|
|
28
|
+
spec.add_dependency 'legion-cache', '>= 1.3.11'
|
|
29
|
+
spec.add_dependency 'legion-crypt', '>= 1.4.9'
|
|
30
|
+
spec.add_dependency 'legion-data', '>= 1.4.17'
|
|
31
|
+
spec.add_dependency 'legion-json', '>= 1.2.1'
|
|
32
|
+
spec.add_dependency 'legion-logging', '>= 1.3.2'
|
|
33
|
+
spec.add_dependency 'legion-settings', '>= 1.3.14'
|
|
34
|
+
spec.add_dependency 'legion-transport', '>= 1.3.9'
|
|
35
|
+
|
|
36
|
+
spec.add_development_dependency 'legion-gaia', '>= 0.9.9'
|
|
29
37
|
end
|
|
@@ -21,6 +21,12 @@ module Legion
|
|
|
21
21
|
def advance!(result)
|
|
22
22
|
return if complete? || failed?
|
|
23
23
|
|
|
24
|
+
if timed_out?
|
|
25
|
+
@errors << { stage: @stage, error: 'build timeout exceeded', at: Time.now.utc }
|
|
26
|
+
@stage = :failed
|
|
27
|
+
return
|
|
28
|
+
end
|
|
29
|
+
|
|
24
30
|
if result[:success]
|
|
25
31
|
@artifacts[@stage] = result
|
|
26
32
|
next_idx = STAGES.index(@stage) + 1
|
|
@@ -40,6 +46,10 @@ module Legion
|
|
|
40
46
|
@stage == :failed
|
|
41
47
|
end
|
|
42
48
|
|
|
49
|
+
def timed_out?
|
|
50
|
+
duration_ms >= Helpers::Constants::BUILD_TIMEOUT_MS
|
|
51
|
+
end
|
|
52
|
+
|
|
43
53
|
def to_h
|
|
44
54
|
{
|
|
45
55
|
proposal_id: @proposal.id,
|
|
@@ -5,6 +5,9 @@ module Legion
|
|
|
5
5
|
module MindGrowth
|
|
6
6
|
module Runners
|
|
7
7
|
module Builder
|
|
8
|
+
include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
|
|
9
|
+
Legion::Extensions::Helpers.const_defined?(:Lex)
|
|
10
|
+
|
|
8
11
|
extend self
|
|
9
12
|
|
|
10
13
|
def build_extension(proposal_id:, base_path: nil, **)
|
|
@@ -22,7 +25,7 @@ module Legion
|
|
|
22
25
|
run_stage(pipeline, :register, -> { register_stage(proposal) }) unless pipeline.failed?
|
|
23
26
|
|
|
24
27
|
proposal.transition!(pipeline.complete? ? :passing : :build_failed)
|
|
25
|
-
|
|
28
|
+
log.info "[mind_growth:builder] #{proposal.name}: #{pipeline.stage}"
|
|
26
29
|
{ success: pipeline.complete?, pipeline: pipeline.to_h, proposal: proposal.to_h }
|
|
27
30
|
rescue ArgumentError => e
|
|
28
31
|
{ success: false, error: e.message }
|
|
@@ -178,7 +181,7 @@ module Legion
|
|
|
178
181
|
def implement_file(file_path, proposal)
|
|
179
182
|
stub_content = ::File.read(file_path)
|
|
180
183
|
|
|
181
|
-
chat = Legion::LLM.chat
|
|
184
|
+
chat = Legion::LLM.chat(caller: { extension: 'lex-mind-growth', operation: 'build' }, intent: { capability: :reasoning })
|
|
182
185
|
chat.with_instructions(implementation_instructions)
|
|
183
186
|
response = chat.ask(file_implementation_prompt(stub_content, proposal))
|
|
184
187
|
code = extract_ruby_code(response.content)
|
|
@@ -5,6 +5,9 @@ module Legion
|
|
|
5
5
|
module MindGrowth
|
|
6
6
|
module Runners
|
|
7
7
|
module Orchestrator
|
|
8
|
+
include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
|
|
9
|
+
Legion::Extensions::Helpers.const_defined?(:Lex)
|
|
10
|
+
|
|
8
11
|
extend self
|
|
9
12
|
|
|
10
13
|
def run_growth_cycle(existing_extensions: nil, base_path: nil, max_proposals: 3, force: false, **)
|
|
@@ -165,11 +168,9 @@ module Legion
|
|
|
165
168
|
end
|
|
166
169
|
|
|
167
170
|
def log_cycle_summary(trace)
|
|
168
|
-
return unless defined?(Legion::Logging)
|
|
169
|
-
|
|
170
171
|
build_step = trace[:steps].find { |s| s[:step] == :build }
|
|
171
172
|
succeeded = build_step ? build_step[:succeeded] : 0
|
|
172
|
-
|
|
173
|
+
log.info "[mind_growth:orchestrator] cycle complete: #{succeeded} extensions built"
|
|
173
174
|
end
|
|
174
175
|
end
|
|
175
176
|
end
|
|
@@ -7,13 +7,16 @@ module Legion
|
|
|
7
7
|
module MindGrowth
|
|
8
8
|
module Runners
|
|
9
9
|
module Proposer
|
|
10
|
+
include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
|
|
11
|
+
Legion::Extensions::Helpers.const_defined?(:Lex)
|
|
12
|
+
|
|
10
13
|
extend self
|
|
11
14
|
|
|
12
15
|
def analyze_gaps(existing_extensions: nil, **)
|
|
13
16
|
extensions = existing_extensions || current_extensions
|
|
14
17
|
analysis = Helpers::CognitiveModels.gap_analysis(extensions)
|
|
15
18
|
recommendations = Helpers::CognitiveModels.recommend_from_gaps(analysis)
|
|
16
|
-
|
|
19
|
+
log.debug "[mind_growth:proposer] gap analysis: #{recommendations.size} recommendations"
|
|
17
20
|
{ success: true, models: analysis, recommendations: recommendations.first(10) }
|
|
18
21
|
rescue ArgumentError => e
|
|
19
22
|
{ success: false, error: e.message }
|
|
@@ -27,7 +30,7 @@ module Legion
|
|
|
27
30
|
|
|
28
31
|
redundancy = check_redundancy(gem_name, desc)
|
|
29
32
|
if redundancy[:redundant]
|
|
30
|
-
|
|
33
|
+
log.info "[mind_growth:proposer] rejected redundant: #{gem_name} (#{redundancy[:score]})"
|
|
31
34
|
return { success: false, error: :redundant, similar_to: redundancy[:similar_to],
|
|
32
35
|
score: redundancy[:score] }
|
|
33
36
|
end
|
|
@@ -46,7 +49,7 @@ module Legion
|
|
|
46
49
|
origin: :manual
|
|
47
50
|
)
|
|
48
51
|
proposal_store.store(proposal)
|
|
49
|
-
|
|
52
|
+
log.info "[mind_growth:proposer] proposed: #{proposal.name} (#{cat})"
|
|
50
53
|
{ success: true, proposal: proposal.to_h }
|
|
51
54
|
rescue ArgumentError => e
|
|
52
55
|
{ success: false, error: e.message }
|
|
@@ -58,7 +61,7 @@ module Legion
|
|
|
58
61
|
|
|
59
62
|
eval_scores = scores || score_with_llm(proposal) || default_scores
|
|
60
63
|
proposal.evaluate!(eval_scores)
|
|
61
|
-
|
|
64
|
+
log.info "[mind_growth:proposer] evaluated #{proposal.name}: #{proposal.status}"
|
|
62
65
|
{ success: true, proposal: proposal.to_h, approved: proposal.status == :approved,
|
|
63
66
|
auto_approved: proposal.auto_approvable? }
|
|
64
67
|
rescue ArgumentError => e
|
|
@@ -114,10 +117,11 @@ module Legion
|
|
|
114
117
|
def enrich_proposal(name, category, description)
|
|
115
118
|
return {} unless llm_available?
|
|
116
119
|
|
|
117
|
-
response = Legion::LLM.chat
|
|
120
|
+
response = Legion::LLM.chat(caller: { extension: 'lex-mind-growth', operation: 'propose',
|
|
121
|
+
phase: 'capability' }).ask(enrichment_prompt(name, category, description))
|
|
118
122
|
parse_enrichment(response.content)
|
|
119
123
|
rescue StandardError => e
|
|
120
|
-
|
|
124
|
+
log.debug "[mind_growth:proposer] LLM enrichment failed: #{e.message}"
|
|
121
125
|
{}
|
|
122
126
|
end
|
|
123
127
|
|
|
@@ -158,10 +162,10 @@ module Legion
|
|
|
158
162
|
def score_with_llm(proposal)
|
|
159
163
|
return nil unless llm_available?
|
|
160
164
|
|
|
161
|
-
response = Legion::LLM.chat.ask(scoring_prompt(proposal))
|
|
165
|
+
response = Legion::LLM.chat(caller: { extension: 'lex-mind-growth', operation: 'propose', phase: 'score' }).ask(scoring_prompt(proposal))
|
|
162
166
|
parse_scores(response.content)
|
|
163
167
|
rescue StandardError => e
|
|
164
|
-
|
|
168
|
+
log.debug "[mind_growth:proposer] LLM scoring failed: #{e.message}"
|
|
165
169
|
nil
|
|
166
170
|
end
|
|
167
171
|
|
|
@@ -221,10 +225,11 @@ module Legion
|
|
|
221
225
|
return nil unless llm_available?
|
|
222
226
|
|
|
223
227
|
candidates = existing.last(20).map { |p| { name: p.name, description: p.description } }
|
|
224
|
-
response = Legion::LLM.chat
|
|
228
|
+
response = Legion::LLM.chat(caller: { extension: 'lex-mind-growth', operation: 'propose',
|
|
229
|
+
phase: 'validate' }).ask(redundancy_prompt(name, description, candidates))
|
|
225
230
|
parse_redundancy(response.content)
|
|
226
231
|
rescue StandardError => e
|
|
227
|
-
|
|
232
|
+
log.debug "[mind_growth:proposer] LLM redundancy check failed: #{e.message}"
|
|
228
233
|
nil
|
|
229
234
|
end
|
|
230
235
|
|
|
@@ -118,6 +118,35 @@ RSpec.describe Legion::Extensions::MindGrowth::Helpers::BuildPipeline do
|
|
|
118
118
|
end
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
+
describe '#timed_out?' do
|
|
122
|
+
it 'returns false when within time budget' do
|
|
123
|
+
expect(pipeline.timed_out?).to be false
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it 'returns true when duration exceeds BUILD_TIMEOUT_MS' do
|
|
127
|
+
pipeline.instance_variable_set(:@started_at, Time.now.utc - 700)
|
|
128
|
+
expect(pipeline.timed_out?).to be true
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it 'transitions to failed on advance! when timed out' do
|
|
132
|
+
pipeline.instance_variable_set(:@started_at, Time.now.utc - 700)
|
|
133
|
+
pipeline.advance!({ success: true })
|
|
134
|
+
expect(pipeline.stage).to eq(:failed)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it 'records timeout error message' do
|
|
138
|
+
pipeline.instance_variable_set(:@started_at, Time.now.utc - 700)
|
|
139
|
+
pipeline.advance!({ success: true })
|
|
140
|
+
expect(pipeline.errors.last[:error]).to eq('build timeout exceeded')
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it 'records the stage where timeout occurred' do
|
|
144
|
+
pipeline.instance_variable_set(:@started_at, Time.now.utc - 700)
|
|
145
|
+
pipeline.advance!({ success: true })
|
|
146
|
+
expect(pipeline.errors.last[:stage]).to eq(:scaffold)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
121
150
|
describe '#complete?' do
|
|
122
151
|
it 'returns false initially' do
|
|
123
152
|
expect(pipeline.complete?).to be false
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,16 +1,38 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'bundler/setup'
|
|
4
|
+
require 'legion/logging'
|
|
5
|
+
require 'legion/settings'
|
|
6
|
+
require 'legion/cache/helper'
|
|
7
|
+
require 'legion/crypt/helper'
|
|
8
|
+
require 'legion/data/helper'
|
|
9
|
+
require 'legion/json/helper'
|
|
10
|
+
require 'legion/transport/helper'
|
|
4
11
|
|
|
5
12
|
module Legion
|
|
6
|
-
module
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
module Extensions
|
|
14
|
+
module Helpers
|
|
15
|
+
module Lex
|
|
16
|
+
include Legion::Logging::Helper
|
|
17
|
+
include Legion::Settings::Helper
|
|
18
|
+
include Legion::Cache::Helper
|
|
19
|
+
include Legion::Crypt::Helper
|
|
20
|
+
include Legion::Data::Helper
|
|
21
|
+
include Legion::JSON::Helper
|
|
22
|
+
include Legion::Transport::Helper
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module Actors
|
|
27
|
+
class Every
|
|
28
|
+
include Helpers::Lex
|
|
29
|
+
end
|
|
12
30
|
|
|
13
|
-
|
|
31
|
+
class Once
|
|
32
|
+
include Helpers::Lex
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
14
36
|
end
|
|
15
37
|
|
|
16
38
|
require 'legion/extensions/mind_growth'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lex-mind-growth
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -9,20 +9,118 @@ bindir: bin
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: legion-cache
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 1.3.11
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 1.3.11
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: legion-crypt
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 1.4.9
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 1.4.9
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: legion-data
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 1.4.17
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: 1.4.17
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: legion-json
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 1.2.1
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: 1.2.1
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: legion-logging
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: 1.3.2
|
|
75
|
+
type: :runtime
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: 1.3.2
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: legion-settings
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: 1.3.14
|
|
89
|
+
type: :runtime
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: 1.3.14
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: legion-transport
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: 1.3.9
|
|
103
|
+
type: :runtime
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: 1.3.9
|
|
12
110
|
- !ruby/object:Gem::Dependency
|
|
13
111
|
name: legion-gaia
|
|
14
112
|
requirement: !ruby/object:Gem::Requirement
|
|
15
113
|
requirements:
|
|
16
114
|
- - ">="
|
|
17
115
|
- !ruby/object:Gem::Version
|
|
18
|
-
version:
|
|
116
|
+
version: 0.9.9
|
|
19
117
|
type: :development
|
|
20
118
|
prerelease: false
|
|
21
119
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
120
|
requirements:
|
|
23
121
|
- - ">="
|
|
24
122
|
- !ruby/object:Gem::Version
|
|
25
|
-
version:
|
|
123
|
+
version: 0.9.9
|
|
26
124
|
description: Autonomous cognitive architecture expansion for LegionIO
|
|
27
125
|
email:
|
|
28
126
|
- matthewdiverson@gmail.com
|