Module: RubyLLM::Agents::DSL::Queryable

Included in:
BaseAgent
Defined in:
lib/ruby_llm/agents/dsl/queryable.rb

Overview

Adds execution querying capabilities to agent classes.

Mixed into BaseAgent via ‘extend DSL::Queryable`, making all methods available as class methods on agent classes.

Examples:

Basic queries

SupportAgent.executions.successful.recent
SupportAgent.executions.today.expensive(0.50)

Convenience methods

SupportAgent.last_run
SupportAgent.stats
SupportAgent.total_spent(since: 1.week)

Instance Method Summary collapse

Instance Method Details

#cost_by_model(since: nil) ⇒ Hash{String => Hash}

Returns cost breakdown by model for this agent.

Parameters:

  • since (ActiveSupport::Duration, nil) (defaults to: nil)

    Time window

Returns:

  • (Hash{String => Hash})

    Costs per model



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/ruby_llm/agents/dsl/queryable.rb', line 91

def cost_by_model(since: nil)
  scope = executions
  scope = scope.where("created_at > ?", since.ago) if since

  scope.group(:model_id).pluck(
    :model_id,
    Arel.sql("COUNT(*)"),
    Arel.sql("SUM(total_cost)"),
    Arel.sql("AVG(total_cost)")
  ).each_with_object({}) do |(model, count, total, avg), hash|
    hash[model] = {
      count: count,
      total_cost: total&.to_f&.round(6) || 0,
      avg_cost: avg&.to_f&.round(6) || 0
    }
  end
end

#executionsActiveRecord::Relation

Returns an ActiveRecord::Relation scoped to this agent’s executions.

Examples:

SupportAgent.executions.successful.last(5)
SupportAgent.executions.where("total_cost > ?", 0.01)

Returns:

  • (ActiveRecord::Relation)


29
30
31
# File 'lib/ruby_llm/agents/dsl/queryable.rb', line 29

def executions
  RubyLLM::Agents::Execution.by_agent(name)
end

#failures(since: 24.hours) ⇒ ActiveRecord::Relation

Returns recent failed executions.

Parameters:

  • since (ActiveSupport::Duration) (defaults to: 24.hours)

    Time window (default: 24.hours)

Returns:

  • (ActiveRecord::Relation)


46
47
48
# File 'lib/ruby_llm/agents/dsl/queryable.rb', line 46

def failures(since: 24.hours)
  executions.failed.where("created_at > ?", since.ago)
end

#last_runRubyLLM::Agents::Execution?

Returns the most recent execution for this agent.

Returns:



37
38
39
# File 'lib/ruby_llm/agents/dsl/queryable.rb', line 37

def last_run
  executions.order(created_at: :desc).first
end

#stats(since: nil) ⇒ Hash

Returns a stats summary hash for this agent.

Parameters:

  • since (ActiveSupport::Duration, nil) (defaults to: nil)

    Time window

Returns:

  • (Hash)

    Stats summary



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/ruby_llm/agents/dsl/queryable.rb', line 66

def stats(since: nil)
  scope = executions
  scope = scope.where("created_at > ?", since.ago) if since

  total = scope.count
  successful = scope.successful.count

  {
    total: total,
    successful: successful,
    failed: scope.failed.count,
    success_rate: total.zero? ? 0.0 : (successful.to_f / total * 100).round(1),
    avg_duration_ms: scope.average(:duration_ms)&.round,
    avg_cost: total.zero? ? 0 : (scope.sum(:total_cost).to_f / total).round(6),
    total_cost: scope.sum(:total_cost),
    total_tokens: scope.sum(:total_tokens),
    avg_tokens: scope.average(:total_tokens)&.round
  }
end

#total_spent(since: nil) ⇒ BigDecimal

Returns total cost spent by this agent.

Parameters:

  • since (ActiveSupport::Duration, nil) (defaults to: nil)

    Optional time window

Returns:

  • (BigDecimal)

    Total cost in USD



55
56
57
58
59
# File 'lib/ruby_llm/agents/dsl/queryable.rb', line 55

def total_spent(since: nil)
  scope = executions
  scope = scope.where("created_at > ?", since.ago) if since
  scope.sum(:total_cost)
end

#with_params(**params) ⇒ ActiveRecord::Relation

Returns executions matching specific parameter values.

Parameters:

  • params (Hash)

    Parameter key-value pairs to match

Returns:

  • (ActiveRecord::Relation)


114
115
116
117
118
119
120
# File 'lib/ruby_llm/agents/dsl/queryable.rb', line 114

def with_params(**params)
  scope = executions
  params.each do |key, value|
    scope = scope.with_parameter(key, value)
  end
  scope
end