smart_rag 0.2.1 → 0.2.3

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: db8be81c26762690c4b8b4d2a3bb7c9b3081fd94ce9a05e379964df92ba78b22
4
- data.tar.gz: 47465a464dff0874022bfcfd37b7eb1115291f1af71b6d4afeb5eefc6eaf249e
3
+ metadata.gz: 126c6c21c530311732722fc39ddad72632a9fb64c6dcdb8a467665d92871f44e
4
+ data.tar.gz: '09cab17c6e5aa7cef64548ef95833e74af40ca45659e6142a4125a680c89426d'
5
5
  SHA512:
6
- metadata.gz: 68a9f3d4fffa35954489285189d49ed73cab62acd304fd441249aeffa3b454fda816f4799cfd111e2d2a4392d18f2aba4897563201c555b91c70ba7c6d25973e
7
- data.tar.gz: c3f5efc011510a414aaae99f956119f4f3446391c6352567502e4572e0eeb5df0ac5690c02f50c259293bb55733f59f492b34b5c2e3ee0a31421a223d683f7ff
6
+ metadata.gz: 30102eda862fa9d04aec069b1a0454d2b7fdef78eb5a9684e82509f096af40369e4a20982b63d9cb2672635ba3be00401e90a7beebca36dbdd76825ef453e005
7
+ data.tar.gz: 6b2b5b5f58d4168349e36f9622aa36c12948c3cdc77b9194db2eb2badb98b3a4900ee009f668b4979c334bdea051ae3d59e79d71c2b1d610f89a90f846b2a548
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.2 - 2026-09-15
4
+
5
+ ### Fixed
6
+ - 修正 gemspec 中 homepage/source_code_uri/changelog_uri 指向错误仓库地址的问题。
7
+
3
8
  ## 0.2.1 - 2026-09-15
4
9
 
5
10
  ### Changed
data/Gemfile.lock CHANGED
@@ -7,7 +7,7 @@ GIT
7
7
  PATH
8
8
  remote: .
9
9
  specs:
10
- smart_rag (0.2.1)
10
+ smart_rag (0.2.2)
11
11
  aws-sdk-s3 (~> 1.0)
12
12
  concurrent-ruby (~> 1.0)
13
13
  dotenv (~> 2.8)
@@ -381,7 +381,7 @@ CHECKSUMS
381
381
  simplecov-html (0.13.2) sha256=bd0b8e54e7c2d7685927e8d6286466359b6f16b18cb0df47b508e8d73c777246
382
382
  simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428
383
383
  smart_prompt (0.5.4) sha256=81d5e052cf05d63051a68e946e0ba25bcd280dca5e43ce96664551a33656e5bc
384
- smart_rag (0.2.1)
384
+ smart_rag (0.2.2)
385
385
  standardwebhooks (1.1.0) sha256=356ba711c14def4fb27310e4163b26bd5cccf325212c3440cabadd825e4be11f
386
386
  stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1
387
387
  tiktoken_ruby (0.0.17-x64-mingw-ucrt) sha256=8bd2f8e2c38ee9052a8cd4fc83fcb41362beb476d8885ac121125cd4dd065596
@@ -321,8 +321,15 @@ module SmartRAG
321
321
  raise e
322
322
  end
323
323
 
324
+ # Read a text file as UTF-8.
325
+ #
326
+ # File.binread returns an ASCII-8BIT string, and transcoding that to UTF-8
327
+ # with `undef: :replace, replace: ''` silently deletes every high byte —
328
+ # i.e. it deletes all non-ASCII text (CJK included). Declare the encoding
329
+ # of the bytes instead of transcoding from binary; `scrub` then replaces
330
+ # only genuinely invalid byte sequences.
324
331
  def read_text_file(file_path)
325
- normalize_text_content(File.binread(file_path))
332
+ normalize_text_content(File.read(file_path, mode: 'rb').force_encoding(Encoding::UTF_8))
326
333
  rescue StandardError => e
327
334
  @logger.error "Failed to read text file #{file_path}: #{e.message}"
328
335
  raise e
@@ -333,10 +340,16 @@ module SmartRAG
333
340
 
334
341
  normalized = content.is_a?(String) ? content.dup : content.to_s
335
342
 
336
- begin
337
- normalized = normalized.encode(Encoding::UTF_8, invalid: :replace, undef: :replace, replace: '')
338
- rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError
339
- normalized = normalized.force_encoding(Encoding::UTF_8).scrub
343
+ if normalized.encoding == Encoding::ASCII_8BIT
344
+ # Bytes of unknown encoding: reinterpret as UTF-8 instead of dropping
345
+ # everything above 0x7F.
346
+ normalized = normalized.force_encoding(Encoding::UTF_8)
347
+ elsif normalized.encoding != Encoding::UTF_8
348
+ begin
349
+ normalized = normalized.encode(Encoding::UTF_8, invalid: :replace, undef: :replace, replace: '')
350
+ rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError
351
+ normalized = normalized.force_encoding(Encoding::UTF_8)
352
+ end
340
353
  end
341
354
 
342
355
  normalized.scrub
@@ -19,6 +19,7 @@ module SmartRAG
19
19
  def execute(plan:)
20
20
  @document_metadata_cache = {}
21
21
  @section_topic_cache = {}
22
+ @document_record_cache = {}
22
23
  normalized_plan = normalize_plan(plan)
23
24
  validate_plan!(normalized_plan)
24
25
  principal = normalized_plan.delete(:_principal)
@@ -459,6 +460,15 @@ module SmartRAG
459
460
  return section.document.url if section.document.respond_to?(:url)
460
461
  end
461
462
 
463
+ # Not every search backend returns source metadata: vector search results
464
+ # carry only similarity/rank/section, so this returned nil for them. A nil
465
+ # URI matches no `source_uri_prefix`, so every candidate was rejected by
466
+ # the scope filter and semantic/hybrid plans always came back empty. The
467
+ # document row is authoritative.
468
+ document = document_record_for(extract_document_id(result, section))
469
+ stored_uri = document && document[:source_uri]
470
+ return stored_uri unless stored_uri.to_s.empty?
471
+
462
472
  nil
463
473
  end
464
474
 
@@ -471,6 +481,12 @@ module SmartRAG
471
481
  end
472
482
  end
473
483
 
484
+ # Same reasoning as extract_source_uri: prefer what was stored on the
485
+ # document over guessing from a URI a backend may not have returned.
486
+ document = document_record_for(extract_document_id(result, extract_section(result)))
487
+ stored_type = document && document[:source_type]
488
+ return stored_type unless stored_type.to_s.empty?
489
+
474
490
  return 'url' if source_uri.to_s.start_with?('http://', 'https://')
475
491
  return 'file' if source_uri.to_s.start_with?('file://', '/')
476
492
 
@@ -578,6 +594,21 @@ module SmartRAG
578
594
  nil
579
595
  end
580
596
 
597
+ # Document rows are the authoritative source for scope metadata; search
598
+ # backends do not all echo it back to the caller.
599
+ def document_record_for(document_id)
600
+ return nil if document_id.nil?
601
+ return nil unless defined?(::SmartRAG) && ::SmartRAG.respond_to?(:db) && ::SmartRAG.db
602
+
603
+ @document_record_cache ||= {}
604
+ key = document_id.to_i
605
+ return @document_record_cache[key] if @document_record_cache.key?(key)
606
+
607
+ @document_record_cache[key] = ::SmartRAG.db[:source_documents].where(id: key).first
608
+ rescue StandardError
609
+ nil
610
+ end
611
+
581
612
  def extract_vector_score(result, mode)
582
613
  return numeric_or_nil(result[:vector_score]) if result.is_a?(Hash) && result.key?(:vector_score)
583
614
  return numeric_or_nil(result[:similarity]) if mode == 'semantic' && result.is_a?(Hash) && result.key?(:similarity)
@@ -1,3 +1,3 @@
1
1
  module SmartRAG
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_rag
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - SmartRAG Team
@@ -396,13 +396,13 @@ files:
396
396
  - todo.md
397
397
  - workers/analyze_content.rb
398
398
  - workers/get_embedding.rb
399
- homepage: https://github.com/smartrag/smartrag
399
+ homepage: https://github.com/zhuangbiaowei/smart_rag
400
400
  licenses:
401
401
  - MIT
402
402
  metadata:
403
- homepage_uri: https://github.com/smartrag/smartrag
404
- source_code_uri: https://github.com/smartrag/smartrag
405
- changelog_uri: https://github.com/smartrag/smartrag/blob/main/CHANGELOG.md
403
+ homepage_uri: https://github.com/zhuangbiaowei/smart_rag
404
+ source_code_uri: https://github.com/zhuangbiaowei/smart_rag
405
+ changelog_uri: https://github.com/zhuangbiaowei/smart_rag/blob/main/CHANGELOG.md
406
406
  rdoc_options: []
407
407
  require_paths:
408
408
  - lib
@@ -417,7 +417,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
417
417
  - !ruby/object:Gem::Version
418
418
  version: '0'
419
419
  requirements: []
420
- rubygems_version: 4.0.16
420
+ rubygems_version: 4.0.20
421
421
  specification_version: 4
422
422
  summary: A hybrid RAG (Retrieval-Augmented Generation) system with vector and full-text
423
423
  search