lex-apollo 0.4.6 → 0.4.8

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 (26) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/lib/legion/extensions/apollo/actors/writeback_store.rb +26 -0
  4. data/lib/legion/extensions/apollo/actors/writeback_vectorize.rb +50 -0
  5. data/lib/legion/extensions/apollo/helpers/capability.rb +68 -0
  6. data/lib/legion/extensions/apollo/helpers/tag_normalizer.rb +36 -0
  7. data/lib/legion/extensions/apollo/helpers/writeback.rb +157 -0
  8. data/lib/legion/extensions/apollo/runners/knowledge.rb +29 -6
  9. data/lib/legion/extensions/apollo/runners/maintenance.rb +0 -1
  10. data/lib/legion/extensions/apollo/transport/messages/writeback.rb +48 -0
  11. data/lib/legion/extensions/apollo/transport/queues/writeback_store.rb +23 -0
  12. data/lib/legion/extensions/apollo/transport/queues/writeback_vectorize.rb +23 -0
  13. data/lib/legion/extensions/apollo/version.rb +1 -1
  14. data/lib/legion/extensions/apollo.rb +6 -0
  15. data/spec/legion/extensions/apollo/actors/writeback_store_spec.rb +42 -0
  16. data/spec/legion/extensions/apollo/actors/writeback_vectorize_spec.rb +102 -0
  17. data/spec/legion/extensions/apollo/helpers/capability_spec.rb +56 -0
  18. data/spec/legion/extensions/apollo/helpers/tag_normalizer_spec.rb +62 -0
  19. data/spec/legion/extensions/apollo/helpers/writeback_spec.rb +96 -0
  20. data/spec/legion/extensions/apollo/runners/knowledge_spec.rb +73 -11
  21. data/spec/legion/extensions/apollo/runners/maintenance_spec.rb +0 -1
  22. data/spec/legion/extensions/apollo/runners/request_spec.rb +14 -8
  23. data/spec/legion/extensions/apollo/transport/messages/writeback_spec.rb +87 -0
  24. metadata +15 -3
  25. data/lib/legion/extensions/apollo/helpers/embedding.rb +0 -104
  26. data/spec/legion/extensions/apollo/helpers/embedding_spec.rb +0 -127
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-apollo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 0.4.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -153,14 +153,18 @@ files:
153
153
  - lib/legion/extensions/apollo/actors/gas_subscriber.rb
154
154
  - lib/legion/extensions/apollo/actors/ingest.rb
155
155
  - lib/legion/extensions/apollo/actors/query_responder.rb
156
+ - lib/legion/extensions/apollo/actors/writeback_store.rb
157
+ - lib/legion/extensions/apollo/actors/writeback_vectorize.rb
156
158
  - lib/legion/extensions/apollo/api.rb
157
159
  - lib/legion/extensions/apollo/client.rb
158
160
  - lib/legion/extensions/apollo/gaia_integration.rb
161
+ - lib/legion/extensions/apollo/helpers/capability.rb
159
162
  - lib/legion/extensions/apollo/helpers/confidence.rb
160
- - lib/legion/extensions/apollo/helpers/embedding.rb
161
163
  - lib/legion/extensions/apollo/helpers/entity_watchdog.rb
162
164
  - lib/legion/extensions/apollo/helpers/graph_query.rb
163
165
  - lib/legion/extensions/apollo/helpers/similarity.rb
166
+ - lib/legion/extensions/apollo/helpers/tag_normalizer.rb
167
+ - lib/legion/extensions/apollo/helpers/writeback.rb
164
168
  - lib/legion/extensions/apollo/runners/entity_extractor.rb
165
169
  - lib/legion/extensions/apollo/runners/expertise.rb
166
170
  - lib/legion/extensions/apollo/runners/gas.rb
@@ -172,24 +176,31 @@ files:
172
176
  - lib/legion/extensions/apollo/transport/exchanges/llm_audit.rb
173
177
  - lib/legion/extensions/apollo/transport/messages/ingest.rb
174
178
  - lib/legion/extensions/apollo/transport/messages/query.rb
179
+ - lib/legion/extensions/apollo/transport/messages/writeback.rb
175
180
  - lib/legion/extensions/apollo/transport/queues/gas.rb
176
181
  - lib/legion/extensions/apollo/transport/queues/ingest.rb
177
182
  - lib/legion/extensions/apollo/transport/queues/query.rb
183
+ - lib/legion/extensions/apollo/transport/queues/writeback_store.rb
184
+ - lib/legion/extensions/apollo/transport/queues/writeback_vectorize.rb
178
185
  - lib/legion/extensions/apollo/version.rb
179
186
  - spec/legion/extensions/apollo/actors/decay_spec.rb
180
187
  - spec/legion/extensions/apollo/actors/entity_watchdog_spec.rb
181
188
  - spec/legion/extensions/apollo/actors/expertise_aggregator_spec.rb
182
189
  - spec/legion/extensions/apollo/actors/gas_subscriber_spec.rb
183
190
  - spec/legion/extensions/apollo/actors/ingest_spec.rb
191
+ - spec/legion/extensions/apollo/actors/writeback_store_spec.rb
192
+ - spec/legion/extensions/apollo/actors/writeback_vectorize_spec.rb
184
193
  - spec/legion/extensions/apollo/api_spec.rb
185
194
  - spec/legion/extensions/apollo/client_spec.rb
186
195
  - spec/legion/extensions/apollo/contradiction_spec.rb
187
196
  - spec/legion/extensions/apollo/gaia_integration_spec.rb
197
+ - spec/legion/extensions/apollo/helpers/capability_spec.rb
188
198
  - spec/legion/extensions/apollo/helpers/confidence_spec.rb
189
- - spec/legion/extensions/apollo/helpers/embedding_spec.rb
190
199
  - spec/legion/extensions/apollo/helpers/entity_watchdog_spec.rb
191
200
  - spec/legion/extensions/apollo/helpers/graph_query_spec.rb
192
201
  - spec/legion/extensions/apollo/helpers/similarity_spec.rb
202
+ - spec/legion/extensions/apollo/helpers/tag_normalizer_spec.rb
203
+ - spec/legion/extensions/apollo/helpers/writeback_spec.rb
193
204
  - spec/legion/extensions/apollo/runners/decay_cycle_spec.rb
194
205
  - spec/legion/extensions/apollo/runners/entity_extractor_spec.rb
195
206
  - spec/legion/extensions/apollo/runners/expertise_spec.rb
@@ -202,6 +213,7 @@ files:
202
213
  - spec/legion/extensions/apollo/runners/request_spec.rb
203
214
  - spec/legion/extensions/apollo/transport/messages/ingest_spec.rb
204
215
  - spec/legion/extensions/apollo/transport/messages/query_spec.rb
216
+ - spec/legion/extensions/apollo/transport/messages/writeback_spec.rb
205
217
  - spec/spec_helper.rb
206
218
  homepage: https://github.com/LegionIO/lex-apollo
207
219
  licenses:
@@ -1,104 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Legion
4
- module Extensions
5
- module Apollo
6
- module Helpers
7
- module Embedding
8
- DEFAULT_DIMENSION = 1024
9
-
10
- LOCAL_EMBEDDING_MODELS = %w[mxbai-embed-large bge-large snowflake-arctic-embed].freeze
11
-
12
- module_function
13
-
14
- def generate(text:, **)
15
- unless defined?(Legion::LLM) && Legion::LLM.started?
16
- Legion::Logging.debug('[apollo] embedding fallback: LLM not started') if defined?(Legion::Logging)
17
- return zero_vector
18
- end
19
-
20
- local_model = detect_local_model
21
- vector = if local_model
22
- ollama_embed(text, local_model)
23
- else
24
- opts = cloud_embedding_opts
25
- result = Legion::LLM.embed(text, **opts)
26
- result.is_a?(Hash) ? result[:vector] : result
27
- end
28
-
29
- if vector.is_a?(Array) && vector.any?
30
- @dimension = vector.size
31
- vector
32
- else
33
- Legion::Logging.warn('[apollo] embedding fallback: LLM returned no vector') if defined?(Legion::Logging)
34
- zero_vector
35
- end
36
- end
37
-
38
- def dimension
39
- @dimension || configured_dimension
40
- end
41
-
42
- def configured_dimension
43
- return DEFAULT_DIMENSION unless defined?(Legion::Settings) && !Legion::Settings[:apollo].nil?
44
-
45
- Legion::Settings[:apollo].dig(:embedding, :dimension) || DEFAULT_DIMENSION
46
- rescue StandardError
47
- DEFAULT_DIMENSION
48
- end
49
-
50
- def ollama_embed(text, model)
51
- require 'faraday'
52
- base_url = ollama_base_url
53
- Legion::Logging.debug("[apollo] embedding via local Ollama: #{model}") if defined?(Legion::Logging)
54
- conn = Faraday.new(url: base_url) { |f| f.options.timeout = 10 }
55
- response = conn.post('/api/embed', { model: model, input: text }.to_json,
56
- 'Content-Type' => 'application/json')
57
- return nil unless response.success?
58
-
59
- parsed = ::JSON.parse(response.body)
60
- parsed['embeddings']&.first
61
- rescue StandardError => e
62
- Legion::Logging.warn("[apollo] local Ollama embed failed: #{e.message}") if defined?(Legion::Logging)
63
- nil
64
- end
65
-
66
- def ollama_base_url
67
- return 'http://localhost:11434' unless defined?(Legion::Settings)
68
-
69
- Legion::Settings[:llm].dig(:providers, :ollama, :base_url) || 'http://localhost:11434'
70
- rescue StandardError
71
- 'http://localhost:11434'
72
- end
73
-
74
- def cloud_embedding_opts
75
- return {} unless defined?(Legion::Settings) && !Legion::Settings[:apollo].nil?
76
-
77
- embedding = Legion::Settings[:apollo][:embedding] || {}
78
- opts = {}
79
- opts[:provider] = embedding[:provider].to_sym if embedding[:provider]
80
- opts[:model] = embedding[:model] if embedding[:model]
81
- opts
82
- rescue StandardError
83
- {}
84
- end
85
-
86
- def detect_local_model
87
- return nil unless defined?(Legion::LLM::Discovery::Ollama)
88
-
89
- LOCAL_EMBEDDING_MODELS.find do |m|
90
- Legion::LLM::Discovery::Ollama.model_available?(m) ||
91
- Legion::LLM::Discovery::Ollama.model_available?("#{m}:latest")
92
- end
93
- rescue StandardError
94
- nil
95
- end
96
-
97
- def zero_vector
98
- Array.new(dimension, 0.0)
99
- end
100
- end
101
- end
102
- end
103
- end
104
- end
@@ -1,127 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'legion/extensions/apollo/helpers/embedding'
5
-
6
- RSpec.describe Legion::Extensions::Apollo::Helpers::Embedding do
7
- describe '.generate' do
8
- context 'when Legion::LLM is not defined' do
9
- before do
10
- hide_const('Legion::LLM') if defined?(Legion::LLM)
11
- end
12
-
13
- it 'returns a zero vector of the correct dimension' do
14
- result = described_class.generate(text: 'hello world')
15
- expect(result).to eq(Array.new(1024, 0.0))
16
- expect(result.size).to eq(1024)
17
- end
18
- end
19
-
20
- context 'when Legion::LLM is defined but not started' do
21
- before do
22
- stub_const('Legion::LLM', Module.new { def self.started? = false })
23
- end
24
-
25
- it 'returns a zero vector' do
26
- result = described_class.generate(text: 'hello world')
27
- expect(result).to eq(Array.new(1024, 0.0))
28
- end
29
- end
30
-
31
- context 'when Legion::LLM is available and started' do
32
- let(:mock_vector) { Array.new(1024) { rand(-1.0..1.0) } }
33
-
34
- before do
35
- llm = Module.new do
36
- define_method(:started?) { true }
37
- define_method(:embed) { |_text, **| nil }
38
- extend self
39
- end
40
- stub_const('Legion::LLM', llm)
41
- allow(Legion::LLM).to receive(:embed).and_return({ vector: mock_vector, model: 'text-embedding-3-small' })
42
- end
43
-
44
- it 'returns the vector from the LLM response hash' do
45
- result = described_class.generate(text: 'hello world')
46
- expect(result).to eq(mock_vector)
47
- expect(Legion::LLM).to have_received(:embed).with('hello world', **{})
48
- end
49
- end
50
-
51
- context 'when Legion::LLM returns a short embedding' do
52
- before do
53
- llm = Module.new do
54
- define_method(:started?) { true }
55
- define_method(:embed) { |_text, **| nil }
56
- extend self
57
- end
58
- stub_const('Legion::LLM', llm)
59
- allow(Legion::LLM).to receive(:embed).and_return({ vector: [0.1, 0.2], model: 'test' })
60
- end
61
-
62
- it 'accepts the embedding and updates dimension' do
63
- result = described_class.generate(text: 'hello world')
64
- expect(result).to eq([0.1, 0.2])
65
- expect(described_class.dimension).to eq(2)
66
- end
67
- end
68
-
69
- context 'when Legion::LLM returns nil vector' do
70
- before do
71
- llm = Module.new do
72
- define_method(:started?) { true }
73
- define_method(:embed) { |_text, **| nil }
74
- extend self
75
- end
76
- stub_const('Legion::LLM', llm)
77
- allow(Legion::LLM).to receive(:embed).and_return({ vector: nil, model: 'test', error: 'failed' })
78
- end
79
-
80
- it 'returns a zero vector as fallback' do
81
- result = described_class.generate(text: 'hello world')
82
- expect(result).to be_an(Array)
83
- expect(result.all?(&:zero?)).to be true
84
- end
85
- end
86
-
87
- context 'when Legion::LLM returns nil' do
88
- before do
89
- llm = Module.new do
90
- define_method(:started?) { true }
91
- define_method(:embed) { |_text, **| nil }
92
- extend self
93
- end
94
- stub_const('Legion::LLM', llm)
95
- allow(Legion::LLM).to receive(:embed).and_return(nil)
96
- end
97
-
98
- it 'returns a zero vector as fallback' do
99
- result = described_class.generate(text: 'hello world')
100
- expect(result).to be_an(Array)
101
- expect(result.all?(&:zero?)).to be true
102
- end
103
- end
104
- end
105
-
106
- describe '.configured_dimension' do
107
- context 'when Settings has apollo.embedding.dimension' do
108
- before do
109
- stub_const('Legion::Settings', { apollo: { embedding: { dimension: 768 } } })
110
- end
111
-
112
- it 'returns the configured dimension' do
113
- expect(described_class.configured_dimension).to eq(768)
114
- end
115
- end
116
-
117
- context 'when Settings has no apollo key' do
118
- before do
119
- stub_const('Legion::Settings', { apollo: nil })
120
- end
121
-
122
- it 'returns the default dimension' do
123
- expect(described_class.configured_dimension).to eq(1024)
124
- end
125
- end
126
- end
127
- end