lib/gepa/logging/experiment_tracker.rb
# frozen_string_literal: true module GEPA module Logging # Lightweight experiment tracker that records metrics locally and can fan out to user hooks. class ExperimentTracker attr_reader :events def initialize(subscribers: []) @subscribers = Array(subscribers) @events = [] end def with_subscriber(proc = nil, &block) @subscribers << (proc || block) self end def initialize_backends; end def start_run; end def log_metrics(metrics, step: nil) entry = { metrics: symbolize_keys(metrics), step: step } @events << entry @subscribers.each do |subscriber| subscriber.call(entry) rescue StandardError => e DSPy.log('gepa.experiment_tracker.error', error: e.message) end end def end_run; end def active? !@events.empty? end def each_event(&block) @events.each(&block) end private def symbolize_keys(hash) hash.each_with_object({}) do |(k, v), memo| memo[k.to_sym] = v end end end end end