lex-agentic-integration 0.1.6 → 0.1.7

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 +9 -0
  3. data/lib/legion/extensions/agentic/integration/labyrinth/runners/cognitive_labyrinth.rb +2 -3
  4. data/lib/legion/extensions/agentic/integration/mosaic/runners/cognitive_mosaic.rb +13 -7
  5. data/lib/legion/extensions/agentic/integration/mycelium/runners/cognitive_mycelium.rb +7 -3
  6. data/lib/legion/extensions/agentic/integration/phenomenal_binding/runners/phenomenal_binding.rb +9 -3
  7. data/lib/legion/extensions/agentic/integration/qualia/runners/qualia.rb +2 -1
  8. data/lib/legion/extensions/agentic/integration/tapestry/helpers/loom_engine.rb +1 -1
  9. data/lib/legion/extensions/agentic/integration/tapestry/helpers/tapestry.rb +12 -7
  10. data/lib/legion/extensions/agentic/integration/tapestry/helpers/{thread.rb → thread_strand.rb} +1 -1
  11. data/lib/legion/extensions/agentic/integration/tapestry/runners/cognitive_tapestry.rb +9 -5
  12. data/lib/legion/extensions/agentic/integration/tapestry.rb +1 -1
  13. data/lib/legion/extensions/agentic/integration/tessellation/runners/cognitive_tessellation.rb +2 -1
  14. data/lib/legion/extensions/agentic/integration/version.rb +1 -1
  15. data/spec/legion/extensions/agentic/integration/mosaic/runners/cognitive_mosaic_spec.rb +22 -16
  16. data/spec/legion/extensions/agentic/integration/mycelium/runners/cognitive_mycelium_spec.rb +22 -17
  17. data/spec/legion/extensions/agentic/integration/tapestry/helpers/loom_engine_spec.rb +3 -3
  18. data/spec/legion/extensions/agentic/integration/tapestry/helpers/tapestry_spec.rb +1 -1
  19. data/spec/legion/extensions/agentic/integration/tapestry/helpers/{thread_spec.rb → thread_strand_spec.rb} +1 -1
  20. data/spec/legion/extensions/agentic/integration/tapestry/runners/cognitive_tapestry_spec.rb +36 -31
  21. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd18609f94c33ed5bd6e39e0761d071c52eaeda9a3c943d7b852cef3ea2aca9d
4
- data.tar.gz: 51b7fae44fd51d62908c447f334f39bcae2722f46f74d0804d251ac8bd32bbe1
3
+ metadata.gz: 44af35cef10d0f6915b1bce2703f54330dc0bf92f7e3314c79956bc548577adb
4
+ data.tar.gz: 77b8502f617e09062c298ae4e32e86a1290b6be6d178ff3e910c39407a6ae1bf
5
5
  SHA512:
6
- metadata.gz: fce716d00a57fc8b4696b7d2a0ca3b1845bfcaf9a9acb9011b5a366391431b09058b8cfb419559dd189f5edfd663385f87b605890328c33fa4ef5e48b3934d76
7
- data.tar.gz: 78b9dcd521a5b86079ad9d31f78f855e5919409e054cb21c2528d37a807e3f7d26c5c35c827669e9012704244105ae079afee1ba1dfcd4958c6fbfb23e26aed5
6
+ metadata.gz: 520e41ef7be1d87dab9608baf81d15927f41af29e1b35bf1c50b2332fbafc1e891142a2ddb210f660eea0bd57921b9b85ffe22a550ba21bc06abcc1b492fb3d5
7
+ data.tar.gz: 6897020483d937060caf2c4e50aa7b413f8e8fb49f9259aa45c5785f1566c0d1bcaab2a214893ea528b07d172f715989f509e4b20b03947851018353b64a9357
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.7] - 2026-06-01
4
+ ### Fixed
5
+ - Nil dereference in `PhenomenalBinding::Runners::PhenomenalBinding#register_stream` — guard against `nil` return from `engine.register_stream` when stream_type is invalid; returns `{ status: :rejected, reason: :unknown_stream_type }` instead of crashing on `.salience`
6
+ - `Tapestry::Helpers::Tapestry#age!` and `#repair!` were no-op stubs that accepted params but did nothing — now `age!` frays thread strength via a `@decay_factor` (returned as a float) and `repair!` boosts it; `to_h` includes `decay_factor`
7
+ - `Tapestry::Helpers::Thread` class renamed to `ThreadStrand` to avoid shadowing Ruby's built-in `Thread` constant; all internal references updated
8
+ - Removed `extend self` from `Tapestry::Runners::CognitiveTapestry`, `Labyrinth::Runners::CognitiveLabyrinth`, `Mosaic::Runners::CognitiveMosaic`, and `Mycelium::Runners::CognitiveMycelium` — standardized to instance-module pattern (`include Lex` + private `engine`/`resolve_engine`) matching all other sub-module runners
9
+ - Standardized `include Legion::Extensions::Helpers::Lex` guard to use `const_defined?` double-check (matches project-wide pattern) in mosaic and mycelium runners
10
+ - Updated corresponding runner specs to use `runner_host = Object.new.tap { |o| o.extend(described_class) }` pattern instead of module-level calls
11
+
3
12
  ## [0.1.6] - 2026-04-22
4
13
  ### Fixed
5
14
  - ThreadWalker actor now calls `follow_thread` (navigation) instead of `list_labyrinths` (read-only query)
@@ -7,9 +7,8 @@ module Legion
7
7
  module Labyrinth
8
8
  module Runners
9
9
  module CognitiveLabyrinth
10
- extend self
11
-
12
- include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex, false)
13
12
 
14
13
  def create_labyrinth(name:, domain: nil, labyrinth_id: nil, engine: nil, **)
15
14
  raise ArgumentError, 'name is required' if name.nil? || name.to_s.strip.empty?
@@ -7,7 +7,8 @@ module Legion
7
7
  module Mosaic
8
8
  module Runners
9
9
  module CognitiveMosaic
10
- extend self
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex, false)
11
12
 
12
13
  def create_tessera(material:, domain:, content:,
13
14
  color: nil, fit_quality: nil, engine: nil, **)
@@ -15,6 +16,7 @@ module Legion
15
16
  t = eng.create_tessera(material: material, domain: domain,
16
17
  content: content, color: color,
17
18
  fit_quality: fit_quality)
19
+ log.debug("[cognitive_mosaic] create_tessera: material=#{material} domain=#{domain}")
18
20
  { success: true, tessera: t.to_h }
19
21
  rescue ArgumentError => e
20
22
  { success: false, error: e.message }
@@ -25,6 +27,7 @@ module Legion
25
27
  eng = resolve_engine(engine)
26
28
  m = eng.create_mosaic(name: name, pattern_category: pattern_category,
27
29
  capacity: capacity, grout_strength: grout_strength)
30
+ log.debug("[cognitive_mosaic] create_mosaic: name=#{name} pattern=#{pattern_category}")
28
31
  { success: true, mosaic: m.to_h }
29
32
  rescue ArgumentError => e
30
33
  { success: false, error: e.message }
@@ -32,8 +35,9 @@ module Legion
32
35
 
33
36
  def place_tessera(tessera_id:, mosaic_id:, engine: nil, **)
34
37
  eng = resolve_engine(engine)
35
- t = eng.place_tessera(tessera_id: tessera_id, mosaic_id: mosaic_id)
36
- { success: true, tessera: t.to_h }
38
+ eng.place_tessera(tessera_id: tessera_id, mosaic_id: mosaic_id)
39
+ log.debug("[cognitive_mosaic] place_tessera: tessera=#{tessera_id[0..7]} mosaic=#{mosaic_id[0..7]}")
40
+ { success: true }
37
41
  rescue ArgumentError => e
38
42
  { success: false, error: e.message }
39
43
  end
@@ -42,22 +46,24 @@ module Legion
42
46
  eng = resolve_engine(engine)
43
47
  results = eng.all_tesserae
44
48
  results = results.select { |t| t.material == material.to_sym } if material
49
+ log.debug("[cognitive_mosaic] list_tesserae: count=#{results.size}")
45
50
  { success: true, tesserae: results.map(&:to_h), count: results.size }
46
51
  end
47
52
 
48
53
  def list_mosaics(engine: nil, **)
49
54
  eng = resolve_engine(engine)
50
- { success: true, mosaics: eng.all_mosaics.map(&:to_h),
51
- count: eng.all_mosaics.size }
55
+ mosaics = eng.all_mosaics
56
+ log.debug("[cognitive_mosaic] list_mosaics: count=#{mosaics.size}")
57
+ { success: true, mosaics: mosaics.map(&:to_h),
58
+ count: mosaics.size }
52
59
  end
53
60
 
54
61
  def mosaic_status(engine: nil, **)
55
62
  eng = resolve_engine(engine)
63
+ log.debug('[cognitive_mosaic] mosaic_status')
56
64
  { success: true, report: eng.mosaic_report }
57
65
  end
58
66
 
59
- include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
60
-
61
67
  private
62
68
 
63
69
  def resolve_engine(engine)
@@ -7,7 +7,8 @@ module Legion
7
7
  module Mycelium
8
8
  module Runners
9
9
  module CognitiveMycelium
10
- extend self
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex, false)
11
12
 
12
13
  def create_node(node_type:, domain:, content:,
13
14
  nutrient_level: 0.5, engine: nil, **)
@@ -15,6 +16,7 @@ module Legion
15
16
  node = eng.create_node(node_type: node_type, domain: domain,
16
17
  content: content,
17
18
  nutrient_level: nutrient_level)
19
+ log.debug("[cognitive_mycelium] create_node: type=#{node_type} domain=#{domain}")
18
20
  { success: true, node: node.to_h }
19
21
  rescue ArgumentError => e
20
22
  { success: false, error: e.message }
@@ -26,6 +28,7 @@ module Legion
26
28
  hypha = eng.connect(source_id: source_id, target_id: target_id,
27
29
  nutrient_type: nutrient_type,
28
30
  strength: strength)
31
+ log.debug("[cognitive_mycelium] connect: source=#{source_id[0..7]} target=#{target_id[0..7]}")
29
32
  { success: true, hypha: hypha.to_h }
30
33
  rescue ArgumentError => e
31
34
  { success: false, error: e.message }
@@ -34,6 +37,7 @@ module Legion
34
37
  def transfer_nutrients(hypha_id:, engine: nil, **)
35
38
  eng = resolve_engine(engine)
36
39
  result = eng.transfer_nutrients(hypha_id: hypha_id)
40
+ log.debug("[cognitive_mycelium] transfer_nutrients: hypha_id=#{hypha_id[0..7]}")
37
41
  { success: true }.merge(result)
38
42
  rescue ArgumentError => e
39
43
  { success: false, error: e.message }
@@ -43,6 +47,7 @@ module Legion
43
47
  eng = resolve_engine(engine)
44
48
  body = eng.fruit!(node_id: node_id, fruiting_type: fruiting_type,
45
49
  content: content)
50
+ log.debug("[cognitive_mycelium] fruit: node_id=#{node_id[0..7]} type=#{fruiting_type}")
46
51
  { success: true, fruiting_body: body.to_h }
47
52
  rescue ArgumentError => e
48
53
  { success: false, error: e.message }
@@ -50,11 +55,10 @@ module Legion
50
55
 
51
56
  def network_status(engine: nil, **)
52
57
  eng = resolve_engine(engine)
58
+ log.debug('[cognitive_mycelium] network_status')
53
59
  { success: true, report: eng.network_report }
54
60
  end
55
61
 
56
- include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
57
-
58
62
  private
59
63
 
60
64
  def resolve_engine(engine)
@@ -18,9 +18,15 @@ module Legion
18
18
  salience: salience,
19
19
  domain: domain
20
20
  )
21
- log.debug("[phenomenal_binding] register_stream: type=#{stream_type} " \
22
- "salience=#{stream.salience.round(2)} domain=#{domain}")
23
- { status: :registered, stream: stream.to_h }
21
+ if stream.nil?
22
+ log.debug("[phenomenal_binding] register_stream rejected: type=#{stream_type.inspect} " \
23
+ '(unknown stream_type)')
24
+ { status: :rejected, reason: :unknown_stream_type, stream_type: stream_type }
25
+ else
26
+ log.debug("[phenomenal_binding] register_stream: type=#{stream_type} " \
27
+ "salience=#{stream.salience.round(2)} domain=#{domain}")
28
+ { status: :registered, stream: stream.to_h }
29
+ end
24
30
  end
25
31
 
26
32
  def create_binding(stream_ids:, binding_type:, attention_weight: 0.5, **)
@@ -7,7 +7,8 @@ module Legion
7
7
  module Qualia
8
8
  module Runners
9
9
  module Qualia
10
- include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex, false)
11
12
 
12
13
  def create_quale(content:, modality: :abstract, quality: :smooth, texture: :fluid, vividness: nil,
13
14
  valence: nil, engine: nil, **)
@@ -16,7 +16,7 @@ module Legion
16
16
  strength: nil, color: nil)
17
17
  raise ArgumentError, 'thread limit reached' if @threads.size >= Constants::MAX_THREADS
18
18
 
19
- t = Helpers::Thread.new(
19
+ t = Helpers::ThreadStrand.new(
20
20
  thread_type: thread_type,
21
21
  domain: domain,
22
22
  content: content,
@@ -7,16 +7,18 @@ module Legion
7
7
  module Tapestry
8
8
  module Helpers
9
9
  class Tapestry
10
- attr_reader :id, :name, :pattern, :capacity, :thread_ids, :created_at
10
+ attr_reader :id, :name, :pattern, :capacity, :thread_ids, :created_at,
11
+ :decay_factor
11
12
 
12
13
  def initialize(name:, pattern:, capacity: 50)
13
14
  validate_pattern!(pattern)
14
- @id = SecureRandom.uuid
15
- @name = name.to_s
16
- @pattern = pattern.to_sym
17
- @capacity = capacity.to_i.clamp(1, 500)
18
- @thread_ids = []
19
- @created_at = Time.now.utc
15
+ @id = SecureRandom.uuid
16
+ @name = name.to_s
17
+ @pattern = pattern.to_sym
18
+ @capacity = capacity.to_i.clamp(1, 500)
19
+ @thread_ids = []
20
+ @created_at = Time.now.utc
21
+ @decay_factor = 0.0
20
22
  end
21
23
 
22
24
  def weave_thread(thread_id)
@@ -50,10 +52,12 @@ module Legion
50
52
  end
51
53
 
52
54
  def age!(fray_rate: Constants::FRAY_RATE)
55
+ @decay_factor = (@decay_factor + fray_rate.abs).clamp(0.0, 1.0).round(10)
53
56
  fray_rate
54
57
  end
55
58
 
56
59
  def repair!(boost: 0.1)
60
+ @decay_factor = (@decay_factor - boost.abs).clamp(0.0, 1.0).round(10)
57
61
  boost
58
62
  end
59
63
 
@@ -110,6 +114,7 @@ module Legion
110
114
  empty: empty?,
111
115
  fraying: fraying?(threads),
112
116
  masterwork: masterwork?(threads),
117
+ decay_factor: decay_factor,
113
118
  thread_ids: @thread_ids.dup,
114
119
  created_at: @created_at
115
120
  }
@@ -6,7 +6,7 @@ module Legion
6
6
  module Integration
7
7
  module Tapestry
8
8
  module Helpers
9
- class Thread
9
+ class ThreadStrand
10
10
  attr_reader :id, :thread_type, :domain, :content,
11
11
  :color, :created_at, :tapestry_id
12
12
  attr_accessor :strength
@@ -7,9 +7,8 @@ module Legion
7
7
  module Tapestry
8
8
  module Runners
9
9
  module CognitiveTapestry
10
- extend self
11
-
12
- include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex, false)
13
12
 
14
13
  def spin_thread(thread_type:, domain:, content:,
15
14
  strength: nil, color: nil, engine: nil, **)
@@ -21,6 +20,7 @@ module Legion
21
20
  strength: strength,
22
21
  color: color
23
22
  )
23
+ log.debug("[cognitive_tapestry] spin_thread: type=#{thread_type} domain=#{domain}")
24
24
  { success: true, thread: t.to_h }
25
25
  rescue ArgumentError => e
26
26
  { success: false, error: e.message }
@@ -30,6 +30,7 @@ module Legion
30
30
  eng = resolve_engine(engine)
31
31
  tap = eng.create_tapestry(name: name, pattern: pattern, capacity: capacity)
32
32
  threads_arr = eng.all_threads
33
+ log.debug("[cognitive_tapestry] create_tapestry: name=#{name} pattern=#{pattern}")
33
34
  { success: true, tapestry: tap.to_h(threads_arr) }
34
35
  rescue ArgumentError => e
35
36
  { success: false, error: e.message }
@@ -37,8 +38,9 @@ module Legion
37
38
 
38
39
  def weave(thread_id:, tapestry_id:, engine: nil, **)
39
40
  eng = resolve_engine(engine)
40
- t = eng.weave(thread_id: thread_id, tapestry_id: tapestry_id)
41
- { success: true, thread: t.to_h }
41
+ eng.weave(thread_id: thread_id, tapestry_id: tapestry_id)
42
+ log.debug("[cognitive_tapestry] weave: thread_id=#{thread_id[0..7]} tapestry_id=#{tapestry_id[0..7]}")
43
+ { success: true }
42
44
  rescue ArgumentError => e
43
45
  { success: false, error: e.message }
44
46
  end
@@ -51,6 +53,7 @@ module Legion
51
53
  results = results.select { |tap| tap.pattern == pattern.to_sym } if pattern
52
54
  results = results.select { |tap| tap.fraying?(threads_arr) } if fraying_only
53
55
 
56
+ log.debug("[cognitive_tapestry] list_tapestries: count=#{results.size}")
54
57
  {
55
58
  success: true,
56
59
  tapestries: results.map { |tap| tap.to_h(threads_arr) },
@@ -60,6 +63,7 @@ module Legion
60
63
 
61
64
  def loom_status(engine: nil, **)
62
65
  eng = resolve_engine(engine)
66
+ log.debug('[cognitive_tapestry] loom_status')
63
67
  { success: true, report: eng.tapestry_report }
64
68
  end
65
69
 
@@ -4,7 +4,7 @@ require 'securerandom'
4
4
 
5
5
  require_relative 'tapestry/version'
6
6
  require_relative 'tapestry/helpers/constants'
7
- require_relative 'tapestry/helpers/thread'
7
+ require_relative 'tapestry/helpers/thread_strand'
8
8
  require_relative 'tapestry/helpers/tapestry'
9
9
  require_relative 'tapestry/helpers/loom_engine'
10
10
  require_relative 'tapestry/runners/cognitive_tapestry'
@@ -7,7 +7,8 @@ module Legion
7
7
  module Tessellation
8
8
  module Runners
9
9
  module CognitiveTessellation
10
- include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex, false)
11
12
 
12
13
  def create_tile(tile_type:, shape:, domain:, coverage: nil, fit_score: nil, engine: nil, **)
13
14
  eng = engine || @default_engine
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Agentic
6
6
  module Integration
7
- VERSION = '0.1.6'
7
+ VERSION = '0.1.7'
8
8
  end
9
9
  end
10
10
  end
@@ -3,9 +3,15 @@
3
3
  RSpec.describe Legion::Extensions::Agentic::Integration::Mosaic::Runners::CognitiveMosaic do
4
4
  let(:engine) { Legion::Extensions::Agentic::Integration::Mosaic::Helpers::MosaicEngine.new }
5
5
 
6
- describe '.create_tessera' do
6
+ let(:runner_host) do
7
+ host = Object.new
8
+ host.extend(described_class)
9
+ host
10
+ end
11
+
12
+ describe '#create_tessera' do
7
13
  it 'returns success' do
8
- result = described_class.create_tessera(
14
+ result = runner_host.create_tessera(
9
15
  material: :glass, domain: :reasoning, content: 'test', engine: engine
10
16
  )
11
17
  expect(result[:success]).to be true
@@ -13,16 +19,16 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Mosaic::Runners::Cognit
13
19
  end
14
20
 
15
21
  it 'returns failure for invalid material' do
16
- result = described_class.create_tessera(
22
+ result = runner_host.create_tessera(
17
23
  material: :plasma, domain: :x, content: 'y', engine: engine
18
24
  )
19
25
  expect(result[:success]).to be false
20
26
  end
21
27
  end
22
28
 
23
- describe '.create_mosaic' do
29
+ describe '#create_mosaic' do
24
30
  it 'returns success' do
25
- result = described_class.create_mosaic(
31
+ result = runner_host.create_mosaic(
26
32
  name: 'test', pattern_category: :geometric, engine: engine
27
33
  )
28
34
  expect(result[:success]).to be true
@@ -30,57 +36,57 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Mosaic::Runners::Cognit
30
36
  end
31
37
 
32
38
  it 'returns failure for invalid pattern' do
33
- result = described_class.create_mosaic(
39
+ result = runner_host.create_mosaic(
34
40
  name: 'x', pattern_category: :random, engine: engine
35
41
  )
36
42
  expect(result[:success]).to be false
37
43
  end
38
44
  end
39
45
 
40
- describe '.place_tessera' do
46
+ describe '#place_tessera' do
41
47
  it 'places tessera successfully' do
42
48
  t = engine.create_tessera(material: :stone, domain: :x, content: 'a')
43
49
  m = engine.create_mosaic(name: 'wall', pattern_category: :organic)
44
- result = described_class.place_tessera(
50
+ result = runner_host.place_tessera(
45
51
  tessera_id: t.id, mosaic_id: m.id, engine: engine
46
52
  )
47
53
  expect(result[:success]).to be true
48
54
  end
49
55
 
50
56
  it 'returns failure for missing tessera' do
51
- result = described_class.place_tessera(
57
+ result = runner_host.place_tessera(
52
58
  tessera_id: 'nope', mosaic_id: 'nope', engine: engine
53
59
  )
54
60
  expect(result[:success]).to be false
55
61
  end
56
62
  end
57
63
 
58
- describe '.list_tesserae' do
64
+ describe '#list_tesserae' do
59
65
  it 'returns all tesserae' do
60
66
  engine.create_tessera(material: :glass, domain: :x, content: 'a')
61
- result = described_class.list_tesserae(engine: engine)
67
+ result = runner_host.list_tesserae(engine: engine)
62
68
  expect(result[:count]).to eq(1)
63
69
  end
64
70
 
65
71
  it 'filters by material' do
66
72
  engine.create_tessera(material: :glass, domain: :x, content: 'a')
67
73
  engine.create_tessera(material: :stone, domain: :x, content: 'b')
68
- result = described_class.list_tesserae(engine: engine, material: :glass)
74
+ result = runner_host.list_tesserae(engine: engine, material: :glass)
69
75
  expect(result[:count]).to eq(1)
70
76
  end
71
77
  end
72
78
 
73
- describe '.list_mosaics' do
79
+ describe '#list_mosaics' do
74
80
  it 'returns all mosaics' do
75
81
  engine.create_mosaic(name: 'a', pattern_category: :geometric)
76
- result = described_class.list_mosaics(engine: engine)
82
+ result = runner_host.list_mosaics(engine: engine)
77
83
  expect(result[:count]).to eq(1)
78
84
  end
79
85
  end
80
86
 
81
- describe '.mosaic_status' do
87
+ describe '#mosaic_status' do
82
88
  it 'returns report' do
83
- result = described_class.mosaic_status(engine: engine)
89
+ result = runner_host.mosaic_status(engine: engine)
84
90
  expect(result[:success]).to be true
85
91
  expect(result[:report]).to have_key(:total_tesserae)
86
92
  end
@@ -2,42 +2,47 @@
2
2
 
3
3
  RSpec.describe Legion::Extensions::Agentic::Integration::Mycelium::Runners::CognitiveMycelium do
4
4
  let(:engine) { Legion::Extensions::Agentic::Integration::Mycelium::Helpers::MyceliumEngine.new }
5
- let(:runner) { described_class }
6
5
 
7
- describe '.create_node' do
6
+ let(:runner_host) do
7
+ host = Object.new
8
+ host.extend(described_class)
9
+ host
10
+ end
11
+
12
+ describe '#create_node' do
8
13
  it 'succeeds' do
9
- result = runner.create_node(node_type: :knowledge_cluster,
10
- domain: :semantic, content: 'test',
11
- engine: engine)
14
+ result = runner_host.create_node(node_type: :knowledge_cluster,
15
+ domain: :semantic, content: 'test',
16
+ engine: engine)
12
17
  expect(result[:success]).to be true
13
18
  expect(result[:node][:node_type]).to eq :knowledge_cluster
14
19
  end
15
20
 
16
21
  it 'returns failure for invalid type' do
17
- result = runner.create_node(node_type: :bogus, domain: :x,
18
- content: 'x', engine: engine)
22
+ result = runner_host.create_node(node_type: :bogus, domain: :x,
23
+ content: 'x', engine: engine)
19
24
  expect(result[:success]).to be false
20
25
  end
21
26
  end
22
27
 
23
- describe '.connect' do
28
+ describe '#connect' do
24
29
  it 'creates connection' do
25
30
  n1 = engine.create_node(node_type: :knowledge_cluster,
26
31
  domain: :semantic, content: 'a')
27
32
  n2 = engine.create_node(node_type: :skill_node, domain: :procedural,
28
33
  content: 'b')
29
- result = runner.connect(source_id: n1.id, target_id: n2.id,
30
- nutrient_type: :information, engine: engine)
34
+ result = runner_host.connect(source_id: n1.id, target_id: n2.id,
35
+ nutrient_type: :information, engine: engine)
31
36
  expect(result[:success]).to be true
32
37
  end
33
38
  end
34
39
 
35
- describe '.fruit' do
40
+ describe '#fruit' do
36
41
  it 'creates fruiting body' do
37
42
  n = engine.create_node(node_type: :creative_node, domain: :creative,
38
43
  content: 'ripe', nutrient_level: 0.9)
39
- result = runner.fruit(node_id: n.id, fruiting_type: :insight,
40
- content: 'eureka', engine: engine)
44
+ result = runner_host.fruit(node_id: n.id, fruiting_type: :insight,
45
+ content: 'eureka', engine: engine)
41
46
  expect(result[:success]).to be true
42
47
  expect(result[:fruiting_body][:fruiting_type]).to eq :insight
43
48
  end
@@ -45,15 +50,15 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Mycelium::Runners::Cogn
45
50
  it 'returns failure when not ready' do
46
51
  n = engine.create_node(node_type: :creative_node, domain: :creative,
47
52
  content: 'x', nutrient_level: 0.2)
48
- result = runner.fruit(node_id: n.id, fruiting_type: :insight,
49
- content: 'x', engine: engine)
53
+ result = runner_host.fruit(node_id: n.id, fruiting_type: :insight,
54
+ content: 'x', engine: engine)
50
55
  expect(result[:success]).to be false
51
56
  end
52
57
  end
53
58
 
54
- describe '.network_status' do
59
+ describe '#network_status' do
55
60
  it 'returns report' do
56
- result = runner.network_status(engine: engine)
61
+ result = runner_host.network_status(engine: engine)
57
62
  expect(result[:success]).to be true
58
63
  expect(result[:report]).to be_a Hash
59
64
  end
@@ -13,7 +13,7 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Helpers::Loom
13
13
 
14
14
  describe '#spin_thread' do
15
15
  it 'returns a Thread instance' do
16
- expect(spin).to be_a(Legion::Extensions::Agentic::Integration::Tapestry::Helpers::Thread)
16
+ expect(spin).to be_a(Legion::Extensions::Agentic::Integration::Tapestry::Helpers::ThreadStrand)
17
17
  end
18
18
 
19
19
  it 'stores the thread internally' do
@@ -63,7 +63,7 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Helpers::Loom
63
63
 
64
64
  it 'returns the Thread' do
65
65
  result = engine.weave(thread_id: t.id, tapestry_id: tap.id)
66
- expect(result).to be_a(Legion::Extensions::Agentic::Integration::Tapestry::Helpers::Thread)
66
+ expect(result).to be_a(Legion::Extensions::Agentic::Integration::Tapestry::Helpers::ThreadStrand)
67
67
  end
68
68
 
69
69
  it 'marks the thread as woven' do
@@ -111,7 +111,7 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Helpers::Loom
111
111
 
112
112
  it 'returns the Thread' do
113
113
  result = engine.unravel(thread_id: t.id, tapestry_id: tap.id)
114
- expect(result).to be_a(Legion::Extensions::Agentic::Integration::Tapestry::Helpers::Thread)
114
+ expect(result).to be_a(Legion::Extensions::Agentic::Integration::Tapestry::Helpers::ThreadStrand)
115
115
  end
116
116
 
117
117
  it 'marks thread as loose' do
@@ -5,7 +5,7 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Helpers::Tape
5
5
  described_class.new(name: 'life story', pattern: :brocade, capacity: 10)
6
6
  end
7
7
 
8
- let(:thread_klass) { Legion::Extensions::Agentic::Integration::Tapestry::Helpers::Thread }
8
+ let(:thread_klass) { Legion::Extensions::Agentic::Integration::Tapestry::Helpers::ThreadStrand }
9
9
 
10
10
  def make_thread(type: :experience, strength: 0.5)
11
11
  thread_klass.new(thread_type: type, domain: :reasoning, content: 'event', strength: strength)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Helpers::Thread do
3
+ RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Helpers::ThreadStrand do
4
4
  subject(:thread) do
5
5
  described_class.new(thread_type: :experience, domain: :reasoning, content: 'a past event')
6
6
  end
@@ -3,9 +3,15 @@
3
3
  RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Runners::CognitiveTapestry do
4
4
  let(:engine) { Legion::Extensions::Agentic::Integration::Tapestry::Helpers::LoomEngine.new }
5
5
 
6
- describe '.spin_thread' do
6
+ let(:runner_host) do
7
+ host = Object.new
8
+ host.extend(described_class)
9
+ host
10
+ end
11
+
12
+ describe '#spin_thread' do
7
13
  it 'returns success with thread hash' do
8
- result = described_class.spin_thread(
14
+ result = runner_host.spin_thread(
9
15
  thread_type: :experience, domain: :test, content: 'something happened',
10
16
  engine: engine
11
17
  )
@@ -14,7 +20,7 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Runners::Cogn
14
20
  end
15
21
 
16
22
  it 'returns failure for invalid thread_type' do
17
- result = described_class.spin_thread(
23
+ result = runner_host.spin_thread(
18
24
  thread_type: :bogus, domain: :x, content: 'y', engine: engine
19
25
  )
20
26
  expect(result[:success]).to be false
@@ -22,7 +28,7 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Runners::Cogn
22
28
  end
23
29
 
24
30
  it 'accepts optional strength and color' do
25
- result = described_class.spin_thread(
31
+ result = runner_host.spin_thread(
26
32
  thread_type: :belief, domain: :x, content: 'core belief',
27
33
  strength: 0.8, color: :amber, engine: engine
28
34
  )
@@ -33,7 +39,7 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Runners::Cogn
33
39
 
34
40
  it 'absorbs extra keyword args via **' do
35
41
  expect do
36
- described_class.spin_thread(
42
+ runner_host.spin_thread(
37
43
  thread_type: :memory, domain: :x, content: 'y',
38
44
  engine: engine, unknown_key: 'ignored'
39
45
  )
@@ -41,9 +47,9 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Runners::Cogn
41
47
  end
42
48
  end
43
49
 
44
- describe '.create_tapestry' do
50
+ describe '#create_tapestry' do
45
51
  it 'returns success with tapestry hash' do
46
- result = described_class.create_tapestry(
52
+ result = runner_host.create_tapestry(
47
53
  name: 'my story', pattern: :brocade, engine: engine
48
54
  )
49
55
  expect(result[:success]).to be true
@@ -52,14 +58,14 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Runners::Cogn
52
58
  end
53
59
 
54
60
  it 'returns failure for invalid pattern' do
55
- result = described_class.create_tapestry(
61
+ result = runner_host.create_tapestry(
56
62
  name: 'x', pattern: :hexagonal, engine: engine
57
63
  )
58
64
  expect(result[:success]).to be false
59
65
  end
60
66
 
61
67
  it 'accepts custom capacity' do
62
- result = described_class.create_tapestry(
68
+ result = runner_host.create_tapestry(
63
69
  name: 'limited', pattern: :plain, capacity: 5, engine: engine
64
70
  )
65
71
  expect(result[:success]).to be true
@@ -67,32 +73,31 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Runners::Cogn
67
73
  end
68
74
  end
69
75
 
70
- describe '.weave' do
76
+ describe '#weave' do
71
77
  let(:thread_result) do
72
- described_class.spin_thread(thread_type: :narrative, domain: :x, content: 'a', engine: engine)
78
+ runner_host.spin_thread(thread_type: :narrative, domain: :x, content: 'a', engine: engine)
73
79
  end
74
80
  let(:tapestry_result) do
75
- described_class.create_tapestry(name: 'canvas', pattern: :satin, engine: engine)
81
+ runner_host.create_tapestry(name: 'canvas', pattern: :satin, engine: engine)
76
82
  end
77
83
 
78
84
  it 'successfully weaves thread into tapestry' do
79
- result = described_class.weave(
85
+ result = runner_host.weave(
80
86
  thread_id: thread_result[:thread][:id],
81
87
  tapestry_id: tapestry_result[:tapestry][:id],
82
88
  engine: engine
83
89
  )
84
90
  expect(result[:success]).to be true
85
- expect(result[:thread][:woven]).to be true
86
91
  end
87
92
 
88
93
  it 'returns failure when thread is already woven' do
89
- first_tap = described_class.create_tapestry(name: 'first', pattern: :plain, engine: engine)
90
- described_class.weave(
94
+ first_tap = runner_host.create_tapestry(name: 'first', pattern: :plain, engine: engine)
95
+ runner_host.weave(
91
96
  thread_id: thread_result[:thread][:id],
92
97
  tapestry_id: first_tap[:tapestry][:id],
93
98
  engine: engine
94
99
  )
95
- result = described_class.weave(
100
+ result = runner_host.weave(
96
101
  thread_id: thread_result[:thread][:id],
97
102
  tapestry_id: tapestry_result[:tapestry][:id],
98
103
  engine: engine
@@ -102,34 +107,34 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Runners::Cogn
102
107
  end
103
108
 
104
109
  it 'returns failure for unknown thread_id' do
105
- result = described_class.weave(
110
+ result = runner_host.weave(
106
111
  thread_id: 'nonexistent', tapestry_id: tapestry_result[:tapestry][:id], engine: engine
107
112
  )
108
113
  expect(result[:success]).to be false
109
114
  end
110
115
 
111
116
  it 'returns failure for unknown tapestry_id' do
112
- result = described_class.weave(
117
+ result = runner_host.weave(
113
118
  thread_id: thread_result[:thread][:id], tapestry_id: 'nonexistent', engine: engine
114
119
  )
115
120
  expect(result[:success]).to be false
116
121
  end
117
122
  end
118
123
 
119
- describe '.list_tapestries' do
124
+ describe '#list_tapestries' do
120
125
  before do
121
- described_class.create_tapestry(name: 'plain one', pattern: :plain, engine: engine)
122
- described_class.create_tapestry(name: 'twill one', pattern: :twill, engine: engine)
126
+ runner_host.create_tapestry(name: 'plain one', pattern: :plain, engine: engine)
127
+ runner_host.create_tapestry(name: 'twill one', pattern: :twill, engine: engine)
123
128
  end
124
129
 
125
130
  it 'returns all tapestries when no filter' do
126
- result = described_class.list_tapestries(engine: engine)
131
+ result = runner_host.list_tapestries(engine: engine)
127
132
  expect(result[:success]).to be true
128
133
  expect(result[:count]).to eq(2)
129
134
  end
130
135
 
131
136
  it 'filters by pattern' do
132
- result = described_class.list_tapestries(engine: engine, pattern: :plain)
137
+ result = runner_host.list_tapestries(engine: engine, pattern: :plain)
133
138
  expect(result[:count]).to eq(1)
134
139
  expect(result[:tapestries].first[:pattern]).to eq(:plain)
135
140
  end
@@ -138,33 +143,33 @@ RSpec.describe Legion::Extensions::Agentic::Integration::Tapestry::Runners::Cogn
138
143
  weak_t = engine.spin_thread(thread_type: :emotion, domain: :x, content: 'y', strength: 0.05)
139
144
  tap3 = engine.create_tapestry(name: 'fragile', pattern: :satin, capacity: 5)
140
145
  engine.weave(thread_id: weak_t.id, tapestry_id: tap3.id)
141
- result = described_class.list_tapestries(engine: engine, fraying_only: true)
146
+ result = runner_host.list_tapestries(engine: engine, fraying_only: true)
142
147
  expect(result[:count]).to be >= 1
143
148
  end
144
149
 
145
150
  it 'returns empty array when no match' do
146
- result = described_class.list_tapestries(engine: engine, pattern: :brocade)
151
+ result = runner_host.list_tapestries(engine: engine, pattern: :brocade)
147
152
  expect(result[:count]).to eq(0)
148
153
  expect(result[:tapestries]).to be_empty
149
154
  end
150
155
  end
151
156
 
152
- describe '.loom_status' do
157
+ describe '#loom_status' do
153
158
  it 'returns success with report' do
154
- result = described_class.loom_status(engine: engine)
159
+ result = runner_host.loom_status(engine: engine)
155
160
  expect(result[:success]).to be true
156
161
  expect(result[:report]).to have_key(:total_threads)
157
162
  expect(result[:report]).to have_key(:total_tapestries)
158
163
  end
159
164
 
160
165
  it 'report includes loose_count' do
161
- described_class.spin_thread(thread_type: :belief, domain: :x, content: 'y', engine: engine)
162
- result = described_class.loom_status(engine: engine)
166
+ runner_host.spin_thread(thread_type: :belief, domain: :x, content: 'y', engine: engine)
167
+ result = runner_host.loom_status(engine: engine)
163
168
  expect(result[:report][:loose_count]).to eq(1)
164
169
  end
165
170
 
166
171
  it 'report includes fraying_count' do
167
- result = described_class.loom_status(engine: engine)
172
+ result = runner_host.loom_status(engine: engine)
168
173
  expect(result[:report]).to have_key(:fraying_count)
169
174
  end
170
175
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-agentic-integration
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -296,7 +296,7 @@ files:
296
296
  - lib/legion/extensions/agentic/integration/tapestry/helpers/constants.rb
297
297
  - lib/legion/extensions/agentic/integration/tapestry/helpers/loom_engine.rb
298
298
  - lib/legion/extensions/agentic/integration/tapestry/helpers/tapestry.rb
299
- - lib/legion/extensions/agentic/integration/tapestry/helpers/thread.rb
299
+ - lib/legion/extensions/agentic/integration/tapestry/helpers/thread_strand.rb
300
300
  - lib/legion/extensions/agentic/integration/tapestry/runners/cognitive_tapestry.rb
301
301
  - lib/legion/extensions/agentic/integration/tapestry/version.rb
302
302
  - lib/legion/extensions/agentic/integration/tessellation.rb
@@ -395,7 +395,7 @@ files:
395
395
  - spec/legion/extensions/agentic/integration/tapestry/helpers/constants_spec.rb
396
396
  - spec/legion/extensions/agentic/integration/tapestry/helpers/loom_engine_spec.rb
397
397
  - spec/legion/extensions/agentic/integration/tapestry/helpers/tapestry_spec.rb
398
- - spec/legion/extensions/agentic/integration/tapestry/helpers/thread_spec.rb
398
+ - spec/legion/extensions/agentic/integration/tapestry/helpers/thread_strand_spec.rb
399
399
  - spec/legion/extensions/agentic/integration/tapestry/runners/cognitive_tapestry_spec.rb
400
400
  - spec/legion/extensions/agentic/integration/tessellation/client_spec.rb
401
401
  - spec/legion/extensions/agentic/integration/tessellation/helpers/mosaic_spec.rb