Module: RobotLab::Robot::HistorySearch

Included in:
RobotLab::Robot
Defined in:
lib/robot_lab/robot/history_search.rb

Overview

Semantic search over a robot’s conversation history.

Scores each message in @chat.messages against the query using stemmed term-frequency cosine similarity (via the classifier gem). Returns the top-N messages ranked by relevance.

Requires the optional ‘classifier’ gem (~> 2.3).

Examples:

results = robot.search_history("quarterly revenue", limit: 3)
results.each do |r|
  puts "[#{r.role}] (score #{r.score.round(3)}) #{r.text}"
end

Defined Under Namespace

Classes: HistoryResult

Constant Summary collapse

MIN_SCORE_LENGTH =

Minimum text length (characters) for a message to be considered.

20

Instance Method Summary collapse

Instance Method Details

#search_history(query, limit: 5) ⇒ Array<HistoryResult>

Search the robot’s conversation history for messages relevant to query.

Parameters:

  • query (String)

    natural-language search query

  • limit (Integer) (defaults to: 5)

    maximum number of results to return (default 5)

Returns:

Raises:



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/robot_lab/robot/history_search.rb', line 31

def search_history(query, limit: 5)
  TextAnalysis.require_classifier!

  query_vec = TextAnalysis.l2_normalize(query.word_hash)
  return [] if query_vec.empty?

  results = []

  @chat.messages.each_with_index do |msg, idx|
    text = extract_history_text(msg)
    next if text.nil? || text.strip.length < MIN_SCORE_LENGTH

    vec   = TextAnalysis.l2_normalize(text.word_hash)
    score = TextAnalysis.cosine_similarity(query_vec, vec)
    next if score.zero?

    results << HistoryResult.new(text: text, role: msg.role, score: score, index: idx)
  end

  results.sort_by { |r| -r.score }.first(limit)
end