lex-apollo 0.4.22 → 0.4.24
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 +16 -0
- data/lib/legion/extensions/apollo/actors/corroboration_checker.rb +3 -1
- data/lib/legion/extensions/apollo/actors/decay.rb +3 -1
- data/lib/legion/extensions/apollo/actors/entity_watchdog.rb +10 -21
- data/lib/legion/extensions/apollo/actors/expertise_aggregator.rb +3 -1
- data/lib/legion/extensions/apollo/actors/gas_subscriber.rb +1 -1
- data/lib/legion/extensions/apollo/actors/ingest.rb +1 -1
- data/lib/legion/extensions/apollo/actors/query_responder.rb +1 -1
- data/lib/legion/extensions/apollo/actors/writeback_store.rb +1 -1
- data/lib/legion/extensions/apollo/actors/writeback_vectorize.rb +2 -2
- data/lib/legion/extensions/apollo/api.rb +28 -22
- data/lib/legion/extensions/apollo/gaia_integration.rb +16 -13
- data/lib/legion/extensions/apollo/helpers/capability.rb +19 -17
- data/lib/legion/extensions/apollo/helpers/confidence.rb +5 -8
- data/lib/legion/extensions/apollo/helpers/data_models.rb +61 -0
- data/lib/legion/extensions/apollo/helpers/entity_watchdog.rb +8 -15
- data/lib/legion/extensions/apollo/helpers/similarity.rb +5 -6
- data/lib/legion/extensions/apollo/helpers/writeback.rb +13 -14
- data/lib/legion/extensions/apollo/runners/expertise.rb +10 -8
- data/lib/legion/extensions/apollo/runners/gas.rb +47 -27
- data/lib/legion/extensions/apollo/runners/knowledge.rb +95 -80
- data/lib/legion/extensions/apollo/runners/maintenance.rb +7 -5
- data/lib/legion/extensions/apollo/runners/request.rb +7 -1
- data/lib/legion/extensions/apollo/version.rb +1 -1
- data/lib/legion/extensions/apollo.rb +96 -0
- data/spec/legion/extensions/apollo/actors/writeback_vectorize_spec.rb +3 -3
- data/spec/legion/extensions/apollo/api_spec.rb +20 -0
- data/spec/legion/extensions/apollo/helpers/capability_spec.rb +4 -4
- data/spec/legion/extensions/apollo/runners/gas_anticipate_spec.rb +0 -3
- data/spec/legion/extensions/apollo/runners/gas_relate_spec.rb +0 -4
- data/spec/legion/extensions/apollo/runners/gas_synthesize_spec.rb +0 -11
- data/spec/legion/extensions/apollo/runners/knowledge_spec.rb +25 -15
- data/spec/legion/extensions/apollo/runners/maintenance_spec.rb +8 -8
- data/spec/legion/extensions/apollo/runners/request_spec.rb +8 -8
- data/spec/spec_helper.rb +4 -0
- metadata +2 -1
|
@@ -12,9 +12,8 @@ module Legion
|
|
|
12
12
|
}.freeze
|
|
13
13
|
|
|
14
14
|
class << self
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
end
|
|
15
|
+
include Legion::Logging::Helper
|
|
16
|
+
include Legion::Settings::Helper
|
|
18
17
|
|
|
19
18
|
def detect_entities(text:, types: nil)
|
|
20
19
|
return [] if text.nil? || text.empty?
|
|
@@ -23,11 +22,13 @@ module Legion
|
|
|
23
22
|
entities = []
|
|
24
23
|
|
|
25
24
|
types.each do |type_sym|
|
|
26
|
-
|
|
25
|
+
entity_type = type_sym == :repository ? :repo : type_sym
|
|
26
|
+
pattern = entity_type == :concept ? concept_pattern : ENTITY_PATTERNS[entity_type]
|
|
27
27
|
next unless pattern
|
|
28
28
|
|
|
29
29
|
text.scan(pattern).each do |match|
|
|
30
|
-
entities << { type:
|
|
30
|
+
entities << { type: entity_type, value: match.strip,
|
|
31
|
+
confidence: Confidence.apollo_setting(:entity_watchdog, :detect_confidence, default: 0.5) }
|
|
31
32
|
end
|
|
32
33
|
end
|
|
33
34
|
|
|
@@ -55,11 +56,7 @@ module Legion
|
|
|
55
56
|
end
|
|
56
57
|
|
|
57
58
|
def concept_pattern
|
|
58
|
-
keywords =
|
|
59
|
-
Legion::Settings.dig(:apollo, :entity_watchdog, :concept_keywords) || []
|
|
60
|
-
else
|
|
61
|
-
[]
|
|
62
|
-
end
|
|
59
|
+
keywords = settings[:entity_watchdog][:concept_keywords]
|
|
63
60
|
return nil if keywords.empty?
|
|
64
61
|
|
|
65
62
|
Regexp.new("\\b(?:#{keywords.map { |k| Regexp.escape(k) }.join('|')})\\b", Regexp::IGNORECASE)
|
|
@@ -68,11 +65,7 @@ module Legion
|
|
|
68
65
|
private
|
|
69
66
|
|
|
70
67
|
def default_types
|
|
71
|
-
|
|
72
|
-
Legion::Settings.dig(:apollo, :entity_watchdog, :types) || %w[person service repo concept]
|
|
73
|
-
else
|
|
74
|
-
%w[person service repo concept]
|
|
75
|
-
end
|
|
68
|
+
settings[:entity_watchdog][:types]
|
|
76
69
|
end
|
|
77
70
|
|
|
78
71
|
def find_existing(_entity)
|
|
@@ -7,11 +7,10 @@ module Legion
|
|
|
7
7
|
module Apollo
|
|
8
8
|
module Helpers
|
|
9
9
|
module Similarity
|
|
10
|
-
|
|
10
|
+
extend Legion::Logging::Helper
|
|
11
|
+
extend Legion::JSON::Helper
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
Legion::Logging
|
|
14
|
-
end
|
|
13
|
+
module_function
|
|
15
14
|
|
|
16
15
|
def cosine_similarity(vec_a:, vec_b:, **)
|
|
17
16
|
vec_a = parse_vector(vec_a)
|
|
@@ -30,9 +29,9 @@ module Legion
|
|
|
30
29
|
return vec if vec.is_a?(Array)
|
|
31
30
|
return nil unless vec.is_a?(String)
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
json_parse(vec)
|
|
34
33
|
rescue StandardError => e
|
|
35
|
-
|
|
34
|
+
handle_exception(e, level: :warn, operation: 'apollo.similarity.parse_vector')
|
|
36
35
|
nil
|
|
37
36
|
end
|
|
38
37
|
|
|
@@ -8,16 +8,15 @@ module Legion
|
|
|
8
8
|
module Apollo
|
|
9
9
|
module Helpers
|
|
10
10
|
module Writeback
|
|
11
|
+
extend Legion::Logging::Helper
|
|
12
|
+
extend Legion::Settings::Helper
|
|
13
|
+
|
|
11
14
|
RESEARCH_TOOLS = %w[read_file search_files search_content run_command].freeze
|
|
12
15
|
MAX_CONTENT_LENGTH = 4000
|
|
13
16
|
MIN_CONTENT_LENGTH = 50
|
|
14
17
|
|
|
15
18
|
module_function
|
|
16
19
|
|
|
17
|
-
def log
|
|
18
|
-
Legion::Logging
|
|
19
|
-
end
|
|
20
|
-
|
|
21
20
|
def evaluate_and_route(request:, response:, enrichments: {})
|
|
22
21
|
return unless writeback_enabled?
|
|
23
22
|
return unless should_capture?(request, response, enrichments)
|
|
@@ -25,7 +24,7 @@ module Legion
|
|
|
25
24
|
payload = build_payload(request: request, response: response)
|
|
26
25
|
route_payload(payload)
|
|
27
26
|
rescue StandardError => e
|
|
28
|
-
|
|
27
|
+
handle_exception(e, level: :warn, operation: 'apollo.writeback.evaluate_and_route')
|
|
29
28
|
end
|
|
30
29
|
|
|
31
30
|
def should_capture?(_request, response, enrichments)
|
|
@@ -68,7 +67,7 @@ module Legion
|
|
|
68
67
|
can_write = Helpers::Capability.can_write?
|
|
69
68
|
|
|
70
69
|
if can_embed
|
|
71
|
-
result = Legion::LLM::Embeddings.generate(text: payload[:content])
|
|
70
|
+
result = Legion::LLM::Call::Embeddings.generate(text: payload[:content])
|
|
72
71
|
vector = result.is_a?(Hash) ? result[:vector] : result
|
|
73
72
|
payload[:embedding] = vector.is_a?(Array) && vector.any? ? vector : Array.new(1024, 0.0)
|
|
74
73
|
end
|
|
@@ -87,7 +86,7 @@ module Legion
|
|
|
87
86
|
Runners::Knowledge.handle_ingest(**payload)
|
|
88
87
|
end
|
|
89
88
|
rescue StandardError => e
|
|
90
|
-
|
|
89
|
+
handle_exception(e, level: :warn, operation: 'apollo.writeback.write_directly')
|
|
91
90
|
publish_to_transport(payload, has_embedding: !payload[:embedding].nil?)
|
|
92
91
|
end
|
|
93
92
|
|
|
@@ -98,20 +97,20 @@ module Legion
|
|
|
98
97
|
**payload, has_embedding: has_embedding
|
|
99
98
|
).publish
|
|
100
99
|
rescue StandardError => e
|
|
101
|
-
|
|
100
|
+
handle_exception(e, level: :warn, operation: 'apollo.writeback.publish_to_transport')
|
|
102
101
|
end
|
|
103
102
|
|
|
104
103
|
def writeback_enabled?
|
|
105
|
-
|
|
104
|
+
settings[:writeback][:enabled] != false
|
|
106
105
|
rescue StandardError => e
|
|
107
|
-
|
|
106
|
+
handle_exception(e, level: :warn, operation: 'apollo.writeback.writeback_enabled')
|
|
108
107
|
true
|
|
109
108
|
end
|
|
110
109
|
|
|
111
110
|
def min_content_length
|
|
112
|
-
|
|
111
|
+
settings[:writeback][:min_content_length]
|
|
113
112
|
rescue StandardError => e
|
|
114
|
-
|
|
113
|
+
handle_exception(e, level: :warn, operation: 'apollo.writeback.min_content_length')
|
|
115
114
|
MIN_CONTENT_LENGTH
|
|
116
115
|
end
|
|
117
116
|
|
|
@@ -132,7 +131,7 @@ module Legion
|
|
|
132
131
|
|
|
133
132
|
request.caller.dig(:requested_by, :identity) || 'unknown'
|
|
134
133
|
rescue StandardError => e
|
|
135
|
-
|
|
134
|
+
handle_exception(e, level: :warn, operation: 'apollo.writeback.extract_identity')
|
|
136
135
|
'unknown'
|
|
137
136
|
end
|
|
138
137
|
|
|
@@ -142,7 +141,7 @@ module Legion
|
|
|
142
141
|
user_msgs = Array(request.messages).select { |m| m[:role] == 'user' || m['role'] == 'user' }
|
|
143
142
|
(user_msgs.last || {})[:content] || ''
|
|
144
143
|
rescue StandardError => e
|
|
145
|
-
|
|
144
|
+
handle_exception(e, level: :warn, operation: 'apollo.writeback.extract_user_query')
|
|
146
145
|
''
|
|
147
146
|
end
|
|
148
147
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative '../helpers/data_models'
|
|
4
|
+
|
|
3
5
|
module Legion
|
|
4
6
|
module Extensions
|
|
5
7
|
module Apollo
|
|
@@ -18,15 +20,15 @@ module Legion
|
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
def aggregate(**)
|
|
21
|
-
unless
|
|
23
|
+
unless Helpers::DataModels.apollo_entry_available?
|
|
22
24
|
log.warn('Apollo Expertise.aggregate skipped: apollo_data_not_available')
|
|
23
25
|
return { success: false, error: 'apollo_data_not_available' }
|
|
24
26
|
end
|
|
25
27
|
|
|
26
|
-
entries =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
entries = Helpers::DataModels.apollo_entry
|
|
29
|
+
.select(:source_agent, :tags, :confidence)
|
|
30
|
+
.exclude(source_agent: nil)
|
|
31
|
+
.all
|
|
30
32
|
log.debug("Apollo Expertise.aggregate entries=#{entries.size}")
|
|
31
33
|
|
|
32
34
|
agent_set = Set.new
|
|
@@ -58,13 +60,13 @@ module Legion
|
|
|
58
60
|
def upsert_expertise_group(group)
|
|
59
61
|
count = group[:confidences].size
|
|
60
62
|
proficiency = expertise_proficiency(group[:confidences])
|
|
61
|
-
existing =
|
|
62
|
-
|
|
63
|
+
existing = Helpers::DataModels.apollo_expertise
|
|
64
|
+
.where(agent_id: group[:agent_id], domain: group[:domain]).first
|
|
63
65
|
|
|
64
66
|
if existing
|
|
65
67
|
existing.update(proficiency: proficiency, entry_count: count, last_active_at: Time.now)
|
|
66
68
|
else
|
|
67
|
-
|
|
69
|
+
Helpers::DataModels.apollo_expertise.create(
|
|
68
70
|
agent_id: group[:agent_id], domain: group[:domain],
|
|
69
71
|
proficiency: proficiency, entry_count: count, last_active_at: Time.now
|
|
70
72
|
)
|
|
@@ -6,7 +6,11 @@ module Legion
|
|
|
6
6
|
module Runners
|
|
7
7
|
module Gas
|
|
8
8
|
include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
|
|
9
|
+
include Legion::Logging::Helper
|
|
10
|
+
include Legion::JSON::Helper
|
|
9
11
|
extend Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
|
|
12
|
+
extend Legion::Logging::Helper
|
|
13
|
+
extend Legion::JSON::Helper
|
|
10
14
|
|
|
11
15
|
RELATION_TYPES = %w[
|
|
12
16
|
similar_to contradicts depends_on causes
|
|
@@ -20,7 +24,7 @@ module Legion
|
|
|
20
24
|
module_function
|
|
21
25
|
|
|
22
26
|
def json_load(str)
|
|
23
|
-
|
|
27
|
+
json_parse(str)
|
|
24
28
|
end
|
|
25
29
|
|
|
26
30
|
def relate_confidence_gate = Helpers::Confidence.apollo_setting(:gas, :relate_confidence_gate, default: RELATE_CONFIDENCE_GATE)
|
|
@@ -56,7 +60,7 @@ module Legion
|
|
|
56
60
|
log.info("GAS process complete facts=#{result[:facts]} entities=#{result[:entities]} relations=#{result[:relations]} synthesis=#{result[:synthesis]} anticipations=#{result[:anticipations]}") # rubocop:disable Layout/LineLength
|
|
57
61
|
result
|
|
58
62
|
rescue StandardError => e
|
|
59
|
-
|
|
63
|
+
handle_exception(e, level: :error, operation: 'apollo.gas.process')
|
|
60
64
|
{ phases_completed: 0, error: e.message }
|
|
61
65
|
end
|
|
62
66
|
|
|
@@ -88,7 +92,7 @@ module Legion
|
|
|
88
92
|
log.debug("GAS phase_extract success=#{result[:success]} entities=#{entities.size}")
|
|
89
93
|
entities
|
|
90
94
|
rescue StandardError => e
|
|
91
|
-
|
|
95
|
+
handle_exception(e, level: :warn, operation: 'apollo.gas.phase_extract')
|
|
92
96
|
[]
|
|
93
97
|
end
|
|
94
98
|
|
|
@@ -131,7 +135,7 @@ module Legion
|
|
|
131
135
|
log.debug("GAS phase_synthesize synthesis=#{synthesis.size}")
|
|
132
136
|
synthesis
|
|
133
137
|
rescue StandardError => e
|
|
134
|
-
|
|
138
|
+
handle_exception(e, level: :warn, operation: 'apollo.gas.phase_synthesize')
|
|
135
139
|
[]
|
|
136
140
|
end
|
|
137
141
|
|
|
@@ -155,7 +159,7 @@ module Legion
|
|
|
155
159
|
)
|
|
156
160
|
deposited += 1
|
|
157
161
|
rescue StandardError => e
|
|
158
|
-
|
|
162
|
+
handle_exception(e, level: :warn, operation: 'apollo.gas.phase_deposit_fact')
|
|
159
163
|
end
|
|
160
164
|
log.info("GAS phase_deposit deposited=#{deposited} facts=#{facts.size}")
|
|
161
165
|
{ deposited: deposited }
|
|
@@ -176,7 +180,7 @@ module Legion
|
|
|
176
180
|
log.debug("GAS phase_anticipate anticipations=#{anticipations.size}")
|
|
177
181
|
anticipations
|
|
178
182
|
rescue StandardError => e
|
|
179
|
-
|
|
183
|
+
handle_exception(e, level: :warn, operation: 'apollo.gas.phase_anticipate')
|
|
180
184
|
[]
|
|
181
185
|
end
|
|
182
186
|
|
|
@@ -188,7 +192,7 @@ module Legion
|
|
|
188
192
|
result = Runners::Knowledge.retrieve_relevant(query: fact[:content], limit: lim, min_confidence: min_conf)
|
|
189
193
|
entries.concat(result[:entries]) if result[:success] && result[:entries]&.any?
|
|
190
194
|
rescue StandardError => e
|
|
191
|
-
|
|
195
|
+
handle_exception(e, level: :warn, operation: 'apollo.gas.fetch_similar_entries')
|
|
192
196
|
next
|
|
193
197
|
end
|
|
194
198
|
unique = entries.uniq { |e| e[:id] }
|
|
@@ -204,11 +208,11 @@ module Legion
|
|
|
204
208
|
{ from_content: fact[:content], to_id: entry[:id], relation_type: 'similar_to', confidence: fb_conf }
|
|
205
209
|
end
|
|
206
210
|
rescue StandardError => e
|
|
207
|
-
|
|
211
|
+
handle_exception(e, level: :warn, operation: 'apollo.gas.classify_relation')
|
|
208
212
|
{ from_content: fact[:content], to_id: entry[:id], relation_type: 'similar_to', confidence: fallback_confidence }
|
|
209
213
|
end
|
|
210
214
|
|
|
211
|
-
def llm_classify_relation(fact, entry)
|
|
215
|
+
def llm_classify_relation(fact, entry) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
212
216
|
prompt = <<~PROMPT
|
|
213
217
|
Classify the relationship between these two knowledge entries.
|
|
214
218
|
Valid types: #{RELATION_TYPES.join(', ')}
|
|
@@ -241,9 +245,13 @@ module Legion
|
|
|
241
245
|
phase: 'gas_relate'
|
|
242
246
|
)
|
|
243
247
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
248
|
+
rels = if result.is_a?(Hash) && result[:data].is_a?(Hash)
|
|
249
|
+
result[:data][:relations] || result.dig(:data, 'relations') || []
|
|
250
|
+
else
|
|
251
|
+
content = result.respond_to?(:message) ? result.message[:content] : result.to_s
|
|
252
|
+
parsed = json_load(content)
|
|
253
|
+
parsed.is_a?(Hash) ? (parsed[:relations] || parsed['relations'] || []) : []
|
|
254
|
+
end
|
|
247
255
|
best = rels.max_by { |r| r[:confidence] || r['confidence'] || 0 }
|
|
248
256
|
|
|
249
257
|
return fallback_relation(fact, entry) unless best
|
|
@@ -254,7 +262,7 @@ module Legion
|
|
|
254
262
|
|
|
255
263
|
{ from_content: fact[:content], to_id: entry[:id], relation_type: rtype, confidence: conf }
|
|
256
264
|
rescue StandardError => e
|
|
257
|
-
|
|
265
|
+
handle_exception(e, level: :warn, operation: 'apollo.gas.llm_classify_relation')
|
|
258
266
|
fallback_relation(fact, entry)
|
|
259
267
|
end
|
|
260
268
|
|
|
@@ -298,13 +306,17 @@ module Legion
|
|
|
298
306
|
phase: 'gas_synthesize'
|
|
299
307
|
)
|
|
300
308
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
309
|
+
items = if result.is_a?(Hash) && result[:data].is_a?(Hash)
|
|
310
|
+
result[:data][:synthesis] || result.dig(:data, 'synthesis') || []
|
|
311
|
+
else
|
|
312
|
+
content = result.respond_to?(:message) ? result.message[:content] : result.to_s
|
|
313
|
+
parsed = json_load(content)
|
|
314
|
+
parsed.is_a?(Hash) ? (parsed[:synthesis] || parsed['synthesis'] || []) : []
|
|
315
|
+
end
|
|
304
316
|
|
|
305
317
|
items.map { |item| build_synthesis_entry(item, facts) }
|
|
306
318
|
rescue StandardError => e
|
|
307
|
-
|
|
319
|
+
handle_exception(e, level: :warn, operation: 'apollo.gas.llm_synthesize')
|
|
308
320
|
[]
|
|
309
321
|
end
|
|
310
322
|
|
|
@@ -354,9 +366,13 @@ module Legion
|
|
|
354
366
|
phase: 'gas_anticipate'
|
|
355
367
|
)
|
|
356
368
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
369
|
+
questions = if result.is_a?(Hash) && result[:data].is_a?(Hash)
|
|
370
|
+
result[:data][:questions] || result.dig(:data, 'questions') || []
|
|
371
|
+
else
|
|
372
|
+
content = result.respond_to?(:message) ? result.message[:content] : result.to_s
|
|
373
|
+
parsed = json_load(content)
|
|
374
|
+
parsed.is_a?(Hash) ? (parsed[:questions] || parsed['questions'] || []) : []
|
|
375
|
+
end
|
|
360
376
|
questions = questions.first(max_anticipations)
|
|
361
377
|
|
|
362
378
|
questions.map do |q|
|
|
@@ -364,7 +380,7 @@ module Legion
|
|
|
364
380
|
{ question: q }
|
|
365
381
|
end
|
|
366
382
|
rescue StandardError => e
|
|
367
|
-
|
|
383
|
+
handle_exception(e, level: :warn, operation: 'apollo.gas.llm_anticipate')
|
|
368
384
|
[]
|
|
369
385
|
end
|
|
370
386
|
|
|
@@ -377,14 +393,14 @@ module Legion
|
|
|
377
393
|
confidence: fallback_confidence
|
|
378
394
|
)
|
|
379
395
|
rescue StandardError => e
|
|
380
|
-
|
|
396
|
+
handle_exception(e, level: :warn, operation: 'apollo.gas.promote_to_pattern_store')
|
|
381
397
|
nil
|
|
382
398
|
end
|
|
383
399
|
|
|
384
400
|
def llm_available?
|
|
385
401
|
defined?(Legion::LLM::Pipeline::GaiaCaller)
|
|
386
402
|
rescue StandardError => e
|
|
387
|
-
|
|
403
|
+
handle_exception(e, level: :warn, operation: 'apollo.gas.llm_available')
|
|
388
404
|
false
|
|
389
405
|
end
|
|
390
406
|
|
|
@@ -422,9 +438,13 @@ module Legion
|
|
|
422
438
|
phase: 'gas_comprehend'
|
|
423
439
|
)
|
|
424
440
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
441
|
+
facts_array = if result.is_a?(Hash) && result[:data].is_a?(Hash)
|
|
442
|
+
result[:data][:facts] || result.dig(:data, 'facts') || []
|
|
443
|
+
else
|
|
444
|
+
content = result.respond_to?(:message) ? result.message[:content] : result.to_s
|
|
445
|
+
parsed = json_load(content)
|
|
446
|
+
parsed.is_a?(Hash) ? (parsed[:facts] || parsed['facts'] || []) : Array(parsed)
|
|
447
|
+
end
|
|
428
448
|
facts_array.map do |f|
|
|
429
449
|
{
|
|
430
450
|
content: f[:content] || f['content'],
|
|
@@ -432,7 +452,7 @@ module Legion
|
|
|
432
452
|
}
|
|
433
453
|
end
|
|
434
454
|
rescue StandardError => e
|
|
435
|
-
|
|
455
|
+
handle_exception(e, level: :warn, operation: 'apollo.gas.llm_comprehend')
|
|
436
456
|
mechanical_comprehend(messages, response)
|
|
437
457
|
end
|
|
438
458
|
end
|