legion-apollo 0.5.2 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9320cef3392467f9819e47c9cacc3893f45ffab9570825cb5d6b270ff3ce6a67
4
- data.tar.gz: d38343aa96c9ba0b1d634f6e4d3850e22c899fe81c13550dce19809cec290a94
3
+ metadata.gz: 95c943936a3a2ac751b688b26c676197142ae6c2aa48aa3427a3dc0709cd86bd
4
+ data.tar.gz: d76f10cc2a7a4984f419489a1df52de501de6878f218f7374575e7b8893e0ad6
5
5
  SHA512:
6
- metadata.gz: 2dcaf3fc8fbf087b8e59c079e71921aebf8c53620e32d9cd8939a00981474747b78e978412d28a5c3ff4f204df01b9538f23a81c82a76a0d94afab8080219e46
7
- data.tar.gz: 8d078c7e1c727bd23b08bfdb09af0abe7581296132d715b7ed7c4c5205d4645c004f1f980af6546239961c6649e9433e66a725341e2275e3cdb2e1de7f1687a3
6
+ metadata.gz: 586271450e0c15b6b493f702b23feeec27020ab37a34ed790246e13215f501b771da84c1c49b475da148aa448791f9eb247cf1722c664ba55ba4b3082c454fea
7
+ data.tar.gz: be2de9a03d9292ce01293363285ba83bfa0eeb45de922c36fcad298576d9a5ea0c3c6c24ed519c98c4f9707e1b645516fab0ff7ca1630fa061ee294b94747b15
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.4] - 2026-05-07
4
+
5
+ ### Fixed
6
+ - Preserve distinct merged query results when local or global Apollo entries arrive without a `content_hash`.
7
+ - Detect co-located Apollo reader and writer runners by module presence so in-process routing is not skipped.
8
+
9
+ ## [0.5.3] - 2026-04-27
10
+
11
+ ### Fixed
12
+ - Preserve temporal validity windows when promoting local knowledge to global Apollo.
13
+ - Treat nil or blank `raw_content` as absent so indexed content remains the raw-content fallback.
14
+ - Ignore unparseable temporal inputs instead of storing arbitrary strings that break lexical validity comparisons.
15
+
3
16
  ## [0.5.2] - 2026-04-27
4
17
 
5
18
  ### Added
@@ -205,6 +205,8 @@ module Legion
205
205
  result = Legion::Apollo.ingest(
206
206
  content: entry[:content],
207
207
  raw_content: entry[:raw_content] || entry[:content],
208
+ valid_from: entry[:valid_from],
209
+ valid_to: entry[:valid_to],
208
210
  tags: entry_tags + ['promoted_from_local'],
209
211
  source_channel: 'local_promotion',
210
212
  submitted_by: "node:#{hostname}",
@@ -437,7 +439,7 @@ module Legion
437
439
 
438
440
  def ingest_without_lock(content:, tags:, **opts) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
439
441
  content = normalize_text_input(content)
440
- raw_content = normalize_text_input(opts.key?(:raw_content) ? opts[:raw_content] : content)
442
+ raw_content = normalize_raw_content_input(opts[:raw_content], fallback: content)
441
443
  hash = content_hash(content)
442
444
  return deduplicated_ingest(hash) if duplicate?(hash)
443
445
 
@@ -760,7 +762,16 @@ module Legion
760
762
 
761
763
  Time.parse(text).utc.strftime('%Y-%m-%dT%H:%M:%S.%LZ')
762
764
  rescue StandardError
763
- text
765
+ nil
766
+ end
767
+
768
+ def normalize_raw_content_input(value, fallback:)
769
+ if defined?(Legion::Apollo) && Legion::Apollo.respond_to?(:normalize_raw_content_input, true)
770
+ return Legion::Apollo.send(:normalize_raw_content_input, value, fallback: fallback)
771
+ end
772
+
773
+ normalized = normalize_text_input(value)
774
+ normalized.strip.empty? ? fallback : normalized
764
775
  end
765
776
 
766
777
  def normalize_tags_input(tags)
@@ -87,9 +87,8 @@ module Legion
87
87
  # TagNormalizer hard-caps to MAX_TAGS=20 internally; clamp here to make that limit explicit.
88
88
  effective_max_tags = [max_tags, Legion::Apollo::Helpers::TagNormalizer::MAX_TAGS].min
89
89
  tags = Legion::Apollo::Helpers::TagNormalizer.normalize(Array(body[:tags])).first(effective_max_tags)
90
- result = Legion::Apollo.ingest(
90
+ ingest_payload = {
91
91
  content: body[:content],
92
- raw_content: body[:raw_content],
93
92
  content_type: body[:content_type] || :observation,
94
93
  tags: tags,
95
94
  source_agent: body[:source_agent] || 'api',
@@ -109,7 +108,10 @@ module Legion
109
108
  source_hash: body[:source_hash],
110
109
  relevance_score: body[:relevance_score],
111
110
  extraction_method: body[:extraction_method]
112
- )
111
+ }
112
+ raw_content = body[:raw_content].to_s
113
+ ingest_payload[:raw_content] = body[:raw_content] unless raw_content.strip.empty?
114
+ result = Legion::Apollo.ingest(**ingest_payload)
113
115
  json_response(result, status_code: apollo_status_code(result, success_status: 201))
114
116
  end
115
117
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Legion
4
4
  module Apollo
5
- VERSION = '0.5.2'
5
+ VERSION = '0.5.4'
6
6
  end
7
7
  end
data/lib/legion/apollo.rb CHANGED
@@ -98,7 +98,7 @@ module Legion
98
98
 
99
99
  normalized_tags = normalize_tags_input(tags)
100
100
  normalized_content = normalize_text_input(content)
101
- normalized_raw_content = normalize_text_input(opts.key?(:raw_content) ? opts[:raw_content] : content)
101
+ normalized_raw_content = normalize_raw_content_input(opts[:raw_content], fallback: normalized_content)
102
102
  payload = { **opts, content: normalized_content, raw_content: normalized_raw_content, tags: normalized_tags }
103
103
  log.info do
104
104
  "Apollo ingest requested scope=#{scope} content_length=#{payload[:content].to_s.length} " \
@@ -224,8 +224,7 @@ module Legion
224
224
  def co_located_reader?
225
225
  return false unless data_available?
226
226
 
227
- defined?(Legion::Extensions::Apollo::Runners::Knowledge) &&
228
- Legion::Extensions::Apollo::Runners::Knowledge.respond_to?(:handle_query)
227
+ defined?(Legion::Extensions::Apollo::Runners::Knowledge) ? true : false
229
228
  rescue StandardError => e
230
229
  handle_exception(e, level: :debug, operation: 'apollo.co_located_reader')
231
230
  false
@@ -234,8 +233,7 @@ module Legion
234
233
  def co_located_writer?
235
234
  return false unless data_available?
236
235
 
237
- defined?(Legion::Extensions::Apollo::Runners::Knowledge) &&
238
- Legion::Extensions::Apollo::Runners::Knowledge.respond_to?(:handle_ingest)
236
+ defined?(Legion::Extensions::Apollo::Runners::Knowledge) ? true : false
239
237
  rescue StandardError => e
240
238
  handle_exception(e, level: :debug, operation: 'apollo.co_located_writer')
241
239
  false
@@ -407,7 +405,13 @@ module Legion
407
405
  end
408
406
 
409
407
  def dedup_and_rank(entries, limit:)
410
- sorted = entries
408
+ entries_with_hashes = entries.map do |e|
409
+ next e if e[:content_hash]
410
+
411
+ e.merge(content_hash: Digest::MD5.hexdigest(e[:content].to_s.strip.downcase.gsub(/\s+/, ' ')))
412
+ end
413
+
414
+ sorted = entries_with_hashes
411
415
  .sort_by { |e| -(e[:confidence] || 0) }
412
416
  .uniq { |e| e[:content_hash] }
413
417
 
@@ -509,6 +513,11 @@ module Legion
509
513
  text.delete("\u0000")
510
514
  end
511
515
 
516
+ def normalize_raw_content_input(value, fallback:)
517
+ normalized = normalize_text_input(value)
518
+ normalized.strip.empty? ? fallback : normalized
519
+ end
520
+
512
521
  def normalize_tags_input(tags)
513
522
  Legion::Apollo::Helpers::TagNormalizer.normalize(Array(tags)).first(apollo_max_tags)
514
523
  rescue StandardError => e
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: legion-apollo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity