149 lines
4.5 KiB
Ruby
149 lines
4.5 KiB
Ruby
# frozen_string_literal: true
|
|
module DiscourseAi
|
|
module Completions
|
|
class Report
|
|
UNKNOWN_FEATURE = "unknown"
|
|
USER_LIMIT = 50
|
|
|
|
attr_reader :start_date, :end_date, :base_query
|
|
|
|
def initialize(start_date: 30.days.ago, end_date: Time.current)
|
|
@start_date = start_date.beginning_of_day
|
|
@end_date = end_date.end_of_day
|
|
@base_query = AiApiAuditLog.where(created_at: @start_date..@end_date)
|
|
end
|
|
|
|
def total_tokens
|
|
stats.total_tokens || 0
|
|
end
|
|
|
|
def total_cached_tokens
|
|
stats.total_cached_tokens || 0
|
|
end
|
|
|
|
def total_request_tokens
|
|
stats.total_request_tokens || 0
|
|
end
|
|
|
|
def total_response_tokens
|
|
stats.total_response_tokens || 0
|
|
end
|
|
|
|
def total_requests
|
|
stats.total_requests || 0
|
|
end
|
|
|
|
def stats
|
|
@stats ||=
|
|
base_query.select(
|
|
"COUNT(*) as total_requests",
|
|
"SUM(COALESCE(request_tokens + response_tokens, 0)) as total_tokens",
|
|
"SUM(COALESCE(cached_tokens,0)) as total_cached_tokens",
|
|
"SUM(COALESCE(request_tokens,0)) as total_request_tokens",
|
|
"SUM(COALESCE(response_tokens,0)) as total_response_tokens",
|
|
)[
|
|
0
|
|
]
|
|
end
|
|
|
|
def guess_period(period = nil)
|
|
period = nil if %i[day month hour].include?(period)
|
|
period ||
|
|
case @end_date - @start_date
|
|
when 0..3.days
|
|
:hour
|
|
when 3.days..90.days
|
|
:day
|
|
else
|
|
:month
|
|
end
|
|
end
|
|
|
|
def tokens_by_period(period = nil)
|
|
period = guess_period(period)
|
|
base_query
|
|
.group("DATE_TRUNC('#{period}', created_at)")
|
|
.order("DATE_TRUNC('#{period}', created_at)")
|
|
.select(
|
|
"DATE_TRUNC('#{period}', created_at) as period",
|
|
"SUM(COALESCE(request_tokens + response_tokens, 0)) as total_tokens",
|
|
"SUM(COALESCE(cached_tokens,0)) as total_cached_tokens",
|
|
"SUM(COALESCE(request_tokens,0)) as total_request_tokens",
|
|
"SUM(COALESCE(response_tokens,0)) as total_response_tokens",
|
|
)
|
|
end
|
|
|
|
def user_breakdown
|
|
base_query
|
|
.joins(:user)
|
|
.group(:user_id, "users.username", "users.uploaded_avatar_id")
|
|
.order("usage_count DESC")
|
|
.limit(USER_LIMIT)
|
|
.select(
|
|
"users.username",
|
|
"users.uploaded_avatar_id",
|
|
"COUNT(*) as usage_count",
|
|
"SUM(COALESCE(request_tokens + response_tokens, 0)) as total_tokens",
|
|
"SUM(COALESCE(cached_tokens,0)) as total_cached_tokens",
|
|
"SUM(COALESCE(request_tokens,0)) as total_request_tokens",
|
|
"SUM(COALESCE(response_tokens,0)) as total_response_tokens",
|
|
)
|
|
end
|
|
|
|
def feature_breakdown
|
|
base_query
|
|
.group(:feature_name)
|
|
.order("usage_count DESC")
|
|
.select(
|
|
"case when coalesce(feature_name, '') = '' then '#{UNKNOWN_FEATURE}' else feature_name end as feature_name",
|
|
"COUNT(*) as usage_count",
|
|
"SUM(COALESCE(request_tokens + response_tokens, 0)) as total_tokens",
|
|
"SUM(COALESCE(cached_tokens,0)) as total_cached_tokens",
|
|
"SUM(COALESCE(request_tokens,0)) as total_request_tokens",
|
|
"SUM(COALESCE(response_tokens,0)) as total_response_tokens",
|
|
)
|
|
end
|
|
|
|
def model_breakdown
|
|
base_query
|
|
.group(:language_model)
|
|
.order("usage_count DESC")
|
|
.select(
|
|
"language_model as llm",
|
|
"COUNT(*) as usage_count",
|
|
"SUM(COALESCE(request_tokens + response_tokens, 0)) as total_tokens",
|
|
"SUM(COALESCE(cached_tokens,0)) as total_cached_tokens",
|
|
"SUM(COALESCE(request_tokens,0)) as total_request_tokens",
|
|
"SUM(COALESCE(response_tokens,0)) as total_response_tokens",
|
|
)
|
|
end
|
|
|
|
def tokens_per_hour
|
|
tokens_by_period(:hour)
|
|
end
|
|
|
|
def tokens_per_day
|
|
tokens_by_period(:day)
|
|
end
|
|
|
|
def tokens_per_month
|
|
tokens_by_period(:month)
|
|
end
|
|
|
|
def filter_by_feature(feature_name)
|
|
if feature_name == UNKNOWN_FEATURE
|
|
@base_query = base_query.where("coalesce(feature_name, '') = ''")
|
|
else
|
|
@base_query = base_query.where(feature_name: feature_name)
|
|
end
|
|
self
|
|
end
|
|
|
|
def filter_by_model(model_name)
|
|
@base_query = base_query.where(language_model: model_name)
|
|
self
|
|
end
|
|
end
|
|
end
|
|
end
|