Class: RosettAi::SmartFeedback::Suggester

Inherits:
Object
  • Object
show all
Defined in:
lib/rosett_ai/smart_feedback/suggester.rb

Overview

Provides "Did you mean?" suggestions using Levenshtein distance.

Matches mistyped commands, subcommands, and flags against known candidates. Returns up to MAX_SUGGESTIONS closest matches within the distance threshold.

Author:

  • hugo

  • claude

Constant Summary collapse

MAX_SUGGESTIONS =
3
COMMAND_THRESHOLD =
2
FLAG_THRESHOLD =
3

Instance Method Summary collapse

Instance Method Details

#format_message(type, input, suggestions) ⇒ String

Format suggestion message.

Parameters:

  • type (String)

    'command', 'subcommand', or 'option'

  • input (String)

    the mistyped word

  • suggestions (Array<String>)

    suggested alternatives

Returns:

  • (String)

    formatted message



46
47
48
49
50
51
52
53
54
55
# File 'lib/rosett_ai/smart_feedback/suggester.rb', line 46

def format_message(type, input, suggestions)
  if suggestions.empty?
    "Unknown #{type} '#{input}'. Run `raictl help` for available #{type}s."
  elsif suggestions.size == 1
    "Unknown #{type} '#{input}'. Did you mean `#{suggestions.first}`?"
  else
    list = suggestions.map { |s| "`#{s}`" }.join(', ')
    "Unknown #{type} '#{input}'. Did you mean one of: #{list}?"
  end
end

#suggest(input, candidates, threshold: COMMAND_THRESHOLD) ⇒ Array<String>

Find suggestion matches for a given input.

Parameters:

  • input (String)

    the mistyped word

  • candidates (Array<String>)

    valid options

  • threshold (Integer) (defaults to: COMMAND_THRESHOLD)

    maximum edit distance

Returns:

  • (Array<String>)

    sorted suggestions (closest first)



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/rosett_ai/smart_feedback/suggester.rb', line 27

def suggest(input, candidates, threshold: COMMAND_THRESHOLD)
  input = input.to_s.downcase
  matches = candidates.filter_map do |candidate|
    candidate = candidate.to_s
    dist = levenshtein(input, candidate.downcase)
    [candidate, dist] if dist <= threshold
  end

  matches.sort_by(&:last)
    .first(MAX_SUGGESTIONS)
    .map(&:first)
end