Class: Protege::TraceSearch

Inherits:
Object
  • Object
show all
Defined in:
app/services/protege/trace_search.rb

Overview

Console-side search over captured inference traces (see Protege::Trace) — a PORO service, the trace analog of MessageSearch.

Each free-text field narrows the Trace relation with a case-insensitive LIKE; label filters by the review verdict. Filled fields are ANDed onto the same row, so a trace matches only when it satisfies every supplied field at once. +request+/+response+ are JSON-text columns, so those terms match against the serialized JSON of the turn (the prompt/tool catalog and the produced output), not structured fields.

Matching mirrors MessageSearch: case-insensitive LIKE with sanitize_sql_like so the term's own +%+/+_+ are literals — SQLite-safe, the dashboard's database.

Constant Summary collapse

FIELD_COLUMNS =

Maps each free-text search field to the trace columns it scans. Columns are a fixed allowlist, so they are safe to interpolate into the LIKE clause (the term is always a bound param).

{
  correlation_id: %w[correlation_id],
  model:          %w[model],
  request:        %w[request],
  response:       %w[response],
  annotation:     %w[annotation]
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(correlation_id: nil, model: nil, request: nil, response: nil, annotation: nil, label: nil) ⇒ TraceSearch

Returns a new instance of TraceSearch.

Parameters:

  • correlation_id (String, nil) (defaults to: nil)

    run-id term

  • model (String, nil) (defaults to: nil)

    model term

  • request (String, nil) (defaults to: nil)

    term matched against the serialized request JSON

  • response (String, nil) (defaults to: nil)

    term matched against the serialized response JSON

  • annotation (String, nil) (defaults to: nil)

    reviewer-note term

  • label (String, nil) (defaults to: nil)

    a review verdict to filter by (ignored unless a real Trace label)



47
48
49
50
# File 'app/services/protege/trace_search.rb', line 47

def initialize(correlation_id: nil, model: nil, request: nil, response: nil, annotation: nil, label: nil)
  @column_terms = { correlation_id:, model:, request:, response:, annotation: }
  @label        = label if Trace.labels.key?(label)
end

Class Method Details

.from_params(params) ⇒ Protege::TraceSearch

Build a search from request params, reading the field keys it understands.

Parameters:

  • params (ActionController::Parameters, Hash)

    the request params

Returns:



31
32
33
34
35
36
37
38
# File 'app/services/protege/trace_search.rb', line 31

def from_params(params)
  new(correlation_id: params[:correlation_id],
      model:          params[:model],
      request:        params[:request],
      response:       params[:response],
      annotation:     params[:annotation],
      label:          params[:label])
end

Instance Method Details

#active?Boolean

Whether any field carries something to search on — a text term or a valid label.

Returns:

  • (Boolean)


55
56
57
# File 'app/services/protege/trace_search.rb', line 55

def active?
  @column_terms.values.any?(&:present?) || @label.present?
end

#resultsActiveRecord::Relation<Protege::Trace>

The matching traces, newest captured first; empty when nothing is filled.

Returns:



62
63
64
65
66
# File 'app/services/protege/trace_search.rb', line 62

def results
  return Trace.none unless active?

  trace_scope.order(created_at: :desc)
end