Module: HTM::LongTermMemory::VectorSearch

Included in:
HTM::LongTermMemory
Defined in:
lib/htm/long_term_memory/vector_search.rb

Overview

Vector similarity search using pgvector

Performs semantic search by:

  1. Generating query embedding client-side

  2. Using pgvector cosine distance for similarity ranking

  3. Supporting timeframe and metadata filtering

Results are cached for performance.

Security: All queries use parameterized placeholders to prevent SQL injection.

Constant Summary collapse

MAX_VECTOR_LIMIT =

Maximum results to prevent DoS via unbounded queries

1000

Instance Method Summary collapse

Instance Method Details

#search(timeframe:, query:, limit:, embedding_service:, metadata: {}) ⇒ Array<Hash>

Vector similarity search

Parameters:

  • timeframe (nil, Range, Array<Range>)

    Time range(s) to search (nil = no filter)

  • query (String)

    Search query

  • limit (Integer)

    Maximum results (capped at MAX_VECTOR_LIMIT)

  • embedding_service (Object)

    Service to generate embeddings

  • metadata (Hash) (defaults to: {})

    Filter by metadata fields (default: {})

Returns:

  • (Array<Hash>)

    Matching nodes



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/htm/long_term_memory/vector_search.rb', line 29

def search(timeframe:, query:, limit:, embedding_service:, metadata: {})
  # Enforce limit to prevent DoS
  safe_limit = limit.to_i.clamp(1, MAX_VECTOR_LIMIT)

  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  result = @cache.fetch(:search, timeframe, query, safe_limit, ) do
    search_uncached(
      timeframe: timeframe,
      query: query,
      limit: safe_limit,
      embedding_service: embedding_service,
      metadata: 
    )
  end
  elapsed_ms = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) * 1000).round
  HTM::Telemetry.search_latency.record(elapsed_ms, attributes: { 'strategy' => 'vector' })
  result
end