Module: LlmCostTracker::ApplicationHelper
Constant Summary
collapse
- TAG_VALUE_SUMMARY_BYTES =
80
- TAG_TOOLTIP_BYTES =
512
TokenUsageHelper::COMPONENT_LABELS, TokenUsageHelper::QUALITY_LABELS, TokenUsageHelper::STACK_CLASSES
PaginationHelper::PER_PAGE_CHOICES
DashboardFilterOptionsHelper::MAX_FILTER_OPTIONS
DashboardFilterHelper::FILTER_PARAM_KEYS, DashboardFilterHelper::STREAM_FILTER_OPTIONS
Instance Method Summary
collapse
#token_usage_quality_label, #token_usage_stack_components
#pagination_page_items
#spend_chart_svg
#calls_query_for_tag, #dashboard_filter_path
#model_filter_options, #provider_filter_options
#active_tag_filters, #any_filter_applied?, #dashboard_date_range_label
Instance Method Details
#bar_width(value, max) ⇒ Object
77
78
79
80
81
82
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 77
def bar_width(value, max)
max = max.to_f
return "0%" unless max.positive?
"#{[(value.to_f / max) * 100.0, 100.0].min.round(2)}%"
end
|
#budget_fill_modifier(percent) ⇒ Object
127
128
129
130
131
132
133
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 127
def budget_fill_modifier(percent)
percent = percent.to_f
return "lct-budget-fill--over" if percent >= 100.0
return "lct-budget-fill--warn" if percent >= 80.0
""
end
|
#calls_query_for_model(provider:, model:) ⇒ Object
139
140
141
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 139
def calls_query_for_model(provider:, model:)
current_query(provider: provider, model: model, page: nil, per: nil, format: nil)
end
|
#coverage_percent(numerator, denominator) ⇒ Object
17
18
19
20
21
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 17
def coverage_percent(numerator, denominator)
return 0.0 unless denominator.to_i.positive?
(numerator.to_f / denominator) * 100.0
end
|
#current_query(overrides = {}) ⇒ Object
135
136
137
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 135
def current_query(overrides = {})
request.query_parameters.symbolize_keys.merge(overrides)
end
|
#delta_badge(delta_percent, mode: :cost) ⇒ Object
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 58
def delta_badge(delta_percent, mode: :cost)
return { text: "n/a vs. prior", css_class: "lct-delta-badge lct-delta-neutral" } if delta_percent.nil?
rounded = delta_percent.round(1)
return { text: "0.0% vs. prior", css_class: "lct-delta-badge lct-delta-neutral" } if rounded.zero?
sign = rounded.positive? ? "+" : ""
text = "#{sign}#{format('%.1f', rounded)}% vs. prior"
css_class = if mode == :neutral
"lct-delta-badge lct-delta-neutral"
elsif rounded.positive?
"lct-delta-badge lct-delta-up"
else
"lct-delta-badge lct-delta-down"
end
{ text: text, css_class: css_class }
end
|
46
47
48
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 46
def format_date(value)
value.try(:strftime, "%Y-%m-%d %H:%M") || value.to_s
end
|
42
43
44
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 42
def format_tokens(value)
number(value)
end
|
#money(value) ⇒ Object
23
24
25
26
27
28
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 23
def money(value)
value = value.to_f
precision = value.abs < 0.01 && value != 0.0 ? 6 : 2
"$#{format("%.#{precision}f", value)}"
end
|
#number(value) ⇒ Object
38
39
40
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 38
def number(value)
number_with_delimiter(value.to_i)
end
|
#optional_money(value) ⇒ Object
30
31
32
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 30
def optional_money(value)
value.nil? ? "n/a" : money(value)
end
|
#optional_number(value) ⇒ Object
34
35
36
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 34
def optional_number(value)
value.nil? ? "n/a" : number(value)
end
|
#percent(value) ⇒ Object
54
55
56
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 54
def percent(value)
"#{format('%.1f', value.to_f)}%"
end
|
#pricing_status(call) ⇒ Object
50
51
52
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 50
def pricing_status(call)
call.total_cost.nil? ? "Unknown pricing" : "Estimated"
end
|
#safe_json(value) ⇒ Object
96
97
98
99
100
101
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 96
def safe_json(value)
parsed = value.is_a?(String) ? JSON.parse(value) : value
JSON.pretty_generate(parsed || {})
rescue JSON::ParserError, TypeError
value.to_s
end
|
#stack_segments(entries) ⇒ Object
84
85
86
87
88
89
90
91
92
93
94
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 84
def stack_segments(entries)
total = entries.sum { |entry| entry[:value].to_f }
return [] unless total.positive?
entries.filter_map do |entry|
value = entry[:value].to_f
next unless value.positive?
entry.merge(percent: (value / total) * 100.0)
end
end
|
#tag_chip_entries(tags, limit: 3) ⇒ Object
112
113
114
115
116
117
118
119
120
121
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 112
def tag_chip_entries(tags, limit: 3)
normalized = normalized_tags(tags)
return [] if normalized.empty?
visible = normalized.first(limit).map do |key, value|
{ key: key.to_s, value: tag_value_summary(value) }
end
visible << { more: normalized.size - limit } if normalized.size > limit
visible
end
|
#tag_chips_title(tags) ⇒ Object
123
124
125
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 123
def tag_chips_title(tags)
truncate_text(safe_json(tags), TAG_TOOLTIP_BYTES)
end
|
103
104
105
106
107
108
109
110
|
# File 'app/helpers/llm_cost_tracker/application_helper.rb', line 103
def tags_summary(tags, limit: 3)
tags = normalized_tags(tags)
return "(untagged)" if tags.empty?
summary = tags.first(limit).map { |key, value| "#{key}=#{tag_value_summary(value)}" }
summary << "+#{tags.size - limit}" if tags.size > limit
summary.join(", ")
end
|