Module: Tracebook

Defined in:
lib/tracebook.rb,
lib/tracebook/config.rb,
lib/tracebook/engine.rb,
lib/tracebook/errors.rb,
lib/tracebook/version.rb,
lib/tracebook/adapters.rb,
lib/tracebook/adapters/ruby_llm.rb,
lib/tracebook/redaction/pattern.rb,
lib/tracebook/pricing/calculator.rb,
lib/tracebook/redaction/pipeline.rb,
lib/tracebook/seeds/pricing_rules.rb,
lib/generators/tracebook/install/install_generator.rb,
app/models/tracebook/comment.rb,
app/models/tracebook/chat_review.rb,
app/models/tracebook/message_cost.rb,
app/models/tracebook/pricing_rule.rb,
app/helpers/tracebook/chats_helper.rb,
app/jobs/tracebook/application_job.rb,
app/models/tracebook/application_record.rb,
app/helpers/tracebook/application_helper.rb,
app/controllers/tracebook/chats_controller.rb,
app/controllers/tracebook/comments_controller.rb,
app/controllers/tracebook/application_controller.rb

Overview

TraceBook is a Rails engine for cost tracking and review of LLM conversations.

It works as a layer on top of RubyLLM, adding:

  • Cost calculation per message based on pricing rules
  • Review workflow (approve/flag) per chat
  • Dashboard UI for monitoring LLM usage

Examples:

Configuration

Tracebook.configure do |config|
  config.chat_class = "Chat"
  config.message_class = "Message"
  config.default_currency = "USD"
  config.actor_display = ->(actor) { actor.try(:name) }
end

Cost calculation

Tracebook.calculate_cost!(message)

Defined Under Namespace

Modules: Adapters, ApplicationHelper, ChatsHelper, Generators, Pricing, Redaction, Seeds Classes: ApplicationController, ApplicationJob, ApplicationRecord, ChatReview, ChatsController, Comment, CommentsController, Config, ConfigurationError, Engine, Error, MessageCost, PricingRule

Constant Summary collapse

VERSION =
"1.0.1"

Class Method Summary collapse

Class Method Details

.calculate_cost!(message, provider:, model:, latency_ms: nil) ⇒ Tracebook::MessageCost

Calculate and store cost for a message.

Parameters:

  • message (ActiveRecord::Base)

    a message record with input_tokens, output_tokens

  • provider (String)

    provider name (e.g., "openai", "anthropic")

  • model (String)

    model identifier (e.g., "gpt-4o")

  • latency_ms (Integer, nil) (defaults to: nil)

    request duration in milliseconds

Returns:



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/tracebook.rb', line 62

def calculate_cost!(message, provider:, model:, latency_ms: nil)
  cost = Pricing::Calculator.call(
    provider: provider,
    model: model,
    input_tokens: message.input_tokens,
    output_tokens: message.output_tokens,
    occurred_at: message.created_at
  )

  MessageCost.create!(
    message: message,
    cost_input_cents: cost.input_cents,
    cost_output_cents: cost.output_cents,
    cost_total_cents: cost.total_cents,
    currency: cost.currency || config.default_currency,
    latency_ms: latency_ms
  )
end

.configObject



31
32
33
# File 'lib/tracebook.rb', line 31

def config
  @config ||= Config.new
end

.configure {|config| ... } ⇒ Object

Yields:



35
36
37
38
39
40
# File 'lib/tracebook.rb', line 35

def configure
  ensure_configurable!
  yield(config)
  finalize_configuration!
  config
end

.ensure_configurable!Object (private)

Raises:



88
89
90
91
92
# File 'lib/tracebook.rb', line 88

def ensure_configurable!
  return unless @configuration_finalized || config.finalized?

  raise ConfigurationError, "Tracebook configuration is already finalized"
end

.finalize_configuration!Object (private)



83
84
85
86
# File 'lib/tracebook.rb', line 83

def finalize_configuration!
  config.finalize!
  @configuration_finalized = true
end

.redact(text) ⇒ String

Redact PII from text using configured patterns and custom redactors.

Parameters:

  • text (String)

    the text to redact

Returns:

  • (String)

    redacted text



51
52
53
# File 'lib/tracebook.rb', line 51

def redact(text)
  config.redaction_pipeline.call(text)
end

.reset_configuration!Object



42
43
44
45
# File 'lib/tracebook.rb', line 42

def reset_configuration!
  @config = Config.new
  @configuration_finalized = false
end