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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/lib/legion/extensions/apollo/actors/writeback_store.rb +26 -0
- data/lib/legion/extensions/apollo/actors/writeback_vectorize.rb +50 -0
- data/lib/legion/extensions/apollo/helpers/capability.rb +68 -0
- data/lib/legion/extensions/apollo/helpers/tag_normalizer.rb +36 -0
- data/lib/legion/extensions/apollo/helpers/writeback.rb +157 -0
- data/lib/legion/extensions/apollo/runners/knowledge.rb +29 -6
- data/lib/legion/extensions/apollo/runners/maintenance.rb +0 -1
- data/lib/legion/extensions/apollo/transport/messages/writeback.rb +48 -0
- data/lib/legion/extensions/apollo/transport/queues/writeback_store.rb +23 -0
- data/lib/legion/extensions/apollo/transport/queues/writeback_vectorize.rb +23 -0
- data/lib/legion/extensions/apollo/version.rb +1 -1
- data/lib/legion/extensions/apollo.rb +6 -0
- data/spec/legion/extensions/apollo/actors/writeback_store_spec.rb +42 -0
- data/spec/legion/extensions/apollo/actors/writeback_vectorize_spec.rb +102 -0
- data/spec/legion/extensions/apollo/helpers/capability_spec.rb +56 -0
- data/spec/legion/extensions/apollo/helpers/tag_normalizer_spec.rb +62 -0
- data/spec/legion/extensions/apollo/helpers/writeback_spec.rb +96 -0
- data/spec/legion/extensions/apollo/runners/knowledge_spec.rb +73 -11
- data/spec/legion/extensions/apollo/runners/maintenance_spec.rb +0 -1
- data/spec/legion/extensions/apollo/runners/request_spec.rb +14 -8
- data/spec/legion/extensions/apollo/transport/messages/writeback_spec.rb +87 -0
- metadata +15 -3
- data/lib/legion/extensions/apollo/helpers/embedding.rb +0 -104
- 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.
|
|
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
|