Class: Locallingo::QualityChecker
- Inherits:
-
Object
- Object
- Locallingo::QualityChecker
- Defined in:
- lib/locallingo/quality_checker.rb
Overview
Checks translation quality and suggests improvements.
Static (provider-free) checks: regex rules, universal fixes, terminology, optional British-spelling drift, and a very-long-text heuristic. An optional AI pass (RubyLLM) reviews a sample for clarity/professionalism.
fix! rewrites the auto-fixable suggestions (universal fixes + British
spellings) back into the locale files, preserving case.
Constant Summary collapse
- LONG_TEXT_THRESHOLD =
200
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
-
#verbose ⇒ Object
readonly
Returns the value of attribute verbose.
Instance Method Summary collapse
-
#check(locale: nil, use_ai: false) ⇒ Object
Check all translations for a locale.
-
#check_key(key, locale, use_ai: false) ⇒ Object
Check a single key.
-
#fix!(locale: nil, dry_run: false) ⇒ Object
Auto-fix the fixable suggestions in the locale files.
-
#initialize(config: nil, root_path: nil, package: nil, verbose: false, logger: nil) ⇒ QualityChecker
constructor
A new instance of QualityChecker.
-
#suggest_improvements(keys_with_text, locale) ⇒ Object
AI suggestions for a batch of key=>text pairs.
Constructor Details
#initialize(config: nil, root_path: nil, package: nil, verbose: false, logger: nil) ⇒ QualityChecker
Returns a new instance of QualityChecker.
26 27 28 29 30 31 32 |
# File 'lib/locallingo/quality_checker.rb', line 26 def initialize(config: nil, root_path: nil, package: nil, verbose: false, logger: nil) @config = config || Configuration.load(root_path: root_path || Dir.pwd, package:) @verbose = verbose @logger = logger @provider = Providers::RubyLLM.new(provider: @config.provider) @terminology = Quality::Terminology.new(@config.terminology_setting, base_path: @config.base_path) end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
24 25 26 |
# File 'lib/locallingo/quality_checker.rb', line 24 def config @config end |
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
24 25 26 |
# File 'lib/locallingo/quality_checker.rb', line 24 def logger @logger end |
#verbose ⇒ Object (readonly)
Returns the value of attribute verbose.
24 25 26 |
# File 'lib/locallingo/quality_checker.rb', line 24 def verbose @verbose end |
Instance Method Details
#check(locale: nil, use_ai: false) ⇒ Object
Check all translations for a locale.
35 36 37 38 39 40 41 42 |
# File 'lib/locallingo/quality_checker.rb', line 35 def check(locale: nil, use_ai: false) locale ||= config.source_locale translations = load_locale_translations(locale) suggestions = translations.flat_map { |key, text| check_text(key, text, locale) } suggestions.concat(ai_sample(translations, locale)) if use_ai suggestions end |
#check_key(key, locale, use_ai: false) ⇒ Object
Check a single key.
45 46 47 48 49 50 51 52 53 |
# File 'lib/locallingo/quality_checker.rb', line 45 def check_key(key, locale, use_ai: false) translations = load_locale_translations(locale) text = translations[key] return [{ key:, error: "Key not found" }] unless text suggestions = check_text(key, text, locale) suggestions.concat(suggest_improvements({ key => text }, locale)) if use_ai suggestions end |
#fix!(locale: nil, dry_run: false) ⇒ Object
Auto-fix the fixable suggestions in the locale files. Returns
{ fixed:
57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/locallingo/quality_checker.rb', line 57 def fix!(locale: nil, dry_run: false) locale ||= config.source_locale suggestions = check(locale:) fixable = suggestions.select { |s| s[:fix] } return { fixed: 0, skipped: suggestions.size - fixable.size } if fixable.empty? changed = apply_fixes(locale, fixable) changed.each { |file, content| File.write(file, content) } unless dry_run changed.each_key { |file| log("#{dry_run ? "Would fix" : "Fixed"}: #{file}") } { fixed: changed.size, skipped: suggestions.size - fixable.size } end |
#suggest_improvements(keys_with_text, locale) ⇒ Object
AI suggestions for a batch of key=>text pairs.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/locallingo/quality_checker.rb', line 72 def suggest_improvements(keys_with_text, locale) unless @provider.credentials? warn "⚠️ No LLM credentials — skipping AI suggestions" return [] end result = @provider.chat( model: config.quality_model, instructions: quality_prompt(locale), payload: keys_with_text ) result.map do |key, suggestion| symbolized = suggestion.transform_keys(&:to_sym) symbolized[:severity] = symbolized[:severity]&.to_sym || :info { key:, text: keys_with_text[key], locale:, source: :ai, **symbolized } end rescue StandardError => e warn "⚠️ AI suggestion failed: #{e.}" [] end |