Class: Protege::Trace

Inherits:
ApplicationRecord show all
Defined in:
app/models/protege/trace.rb

Overview

A durable, self-contained snapshot of one inference turn (one provider API call), captured for later fine-tuning when tracing is enabled. Each row is a training example in the making: the exact request as sent (the wire conversation — resolved system prompt, history, user turn, tool catalog, attachment bytes inline) paired with the response it produced and the inference settings (+model+ + settings) that shaped it, frozen at that instant — unlike ToolUse, which stores only enough to replay against the current prompts.

Deliberately isolated and minimal: no associations, no foreign keys, and no identity columns (persona/provider) — a trace records only what affects training, plus a human review verdict. The table can be truncated or dropped without touching anything else. correlation_id + turn_index group the turns of one run for retry-safe dedup. Written only by the tracing subscriber (+Protege::Subscribers::Tracing+); reviewed and labeled in the dashboard.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.record(correlation_id:, turn_index:, **attributes) ⇒ Protege::Trace

Record one turn's snapshot. Idempotent on [correlation_id, turn_index] so a retried job (which replays the same run from turn 0) re-snapshots each turn in place rather than duplicating training rows — the same retry-safety ToolUse.record_round provides. When no correlation id is present (a run kind that carries none), rows can't be keyed for dedup, so each call simply inserts.

Parameters:

  • correlation_id (String, nil)

    the id grouping this run's turns

  • turn_index (Integer)

    this generation's turn index within the run

  • attributes (Hash)

    the snapshot columns (model, settings, request, response)

Returns:



62
63
64
65
66
67
68
# File 'app/models/protege/trace.rb', line 62

def record(correlation_id:, turn_index:, **attributes)
  return create!(correlation_id:, turn_index:, **attributes) if correlation_id.blank?

  find_or_create_by!(correlation_id:, turn_index:) do |trace|
    trace.assign_attributes(attributes)
  end
end

Instance Method Details

#apply_label(label:, annotation: nil) ⇒ void

This method returns an undefined value.

Apply a human review verdict — the label plus an optional free-text note — stamping the review time so the turn leaves the unlabeled queue.

Parameters:

  • label (String, Symbol)

    one of the label values

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

    a free-text reviewer note



48
49
50
# File 'app/models/protege/trace.rb', line 48

def apply_label(label:, annotation: nil)
  update!(label:, annotation:, reviewed_at: Time.current)
end