Class: Braintrust::Eval::Trace
- Inherits:
-
Object
- Object
- Braintrust::Eval::Trace
- Defined in:
- lib/braintrust/eval/trace.rb
Overview
Read-only trace data accessor for scorers.
Per-case throwaway object — no global cache, no shared state. Accepts lazy (lambda) or eager (Array) span sources.
BTQL span shape (string keys from JSON):
"span_attributes" => {"type" => "llm", "name" => "Chat Completion"}
"input" => [{"role" => "user", "content" => "..."}] # flat message array
"output" => [{"message" => {"role" => "assistant", ...}}] # flat choices array
Instance Method Summary collapse
-
#initialize(spans:) ⇒ Trace
constructor
A new instance of Trace.
-
#spans(span_type: nil) ⇒ Array<Hash>
Resolve and return spans, optionally filtered by type.
-
#thread ⇒ Array<Hash>
Convenience method: extract a chronological message thread from LLM spans.
Constructor Details
#initialize(spans:) ⇒ Trace
Returns a new instance of Trace.
25 26 27 28 29 |
# File 'lib/braintrust/eval/trace.rb', line 25 def initialize(spans:) @spans_source = spans @spans_resolved = false @spans_memo = nil end |
Instance Method Details
#spans(span_type: nil) ⇒ Array<Hash>
Resolve and return spans, optionally filtered by type.
The type lives at span_attributes.type in BTQL rows (e.g. “llm”, “eval”, “task”).
39 40 41 42 43 44 45 46 47 |
# File 'lib/braintrust/eval/trace.rb', line 39 def spans(span_type: nil) resolved = resolve_spans if span_type types = Array(span_type) resolved.select { |s| types.include?(span_type_for(s)) } else resolved end end |
#thread ⇒ Array<Hash>
Convenience method: extract a chronological message thread from LLM spans.
Walks LLM spans, collects input messages (deduplicated) and output messages (always included). Returns a flat chronological array.
BTQL LLM span format:
input: flat array of messages [{"role" => "user", "content" => "..."}]
output: flat array of choices [{"message" => {"role" => "assistant", ...}}]
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/braintrust/eval/trace.rb', line 59 def thread llm_spans = spans(span_type: "llm") return [] if llm_spans.empty? seen = Set.new = [] llm_spans.each do |span| # Input: flat message array or {messages: [...]} wrapper input = span["input"] || span[:input] = (input) &.each do |msg| key = msg.hash unless seen.include?(key) seen.add(key) << msg end end # Output: flat choices array or {choices: [...]} wrapper output = span["output"] || span[:output] (output)&.each do |msg| << msg end end end |