llm_cost_tracker 0.14.0 → 0.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +128 -0
  3. data/README.md +16 -5
  4. data/app/assets/llm_cost_tracker/application.css +16 -0
  5. data/app/controllers/llm_cost_tracker/application_controller.rb +16 -3
  6. data/app/controllers/llm_cost_tracker/calls_controller.rb +1 -3
  7. data/app/controllers/llm_cost_tracker/models_controller.rb +2 -4
  8. data/app/controllers/llm_cost_tracker/pricing_controller.rb +2 -2
  9. data/app/controllers/llm_cost_tracker/tags_controller.rb +9 -7
  10. data/app/helpers/llm_cost_tracker/application_helper.rb +5 -26
  11. data/app/helpers/llm_cost_tracker/chart_helper.rb +6 -10
  12. data/app/helpers/llm_cost_tracker/dashboard_query_helper.rb +5 -0
  13. data/app/helpers/llm_cost_tracker/token_usage_helper.rb +8 -28
  14. data/app/models/llm_cost_tracker/call.rb +10 -14
  15. data/app/services/llm_cost_tracker/dashboard/data_quality.rb +4 -15
  16. data/app/services/llm_cost_tracker/dashboard/filter.rb +29 -30
  17. data/app/services/llm_cost_tracker/dashboard/pagination.rb +2 -5
  18. data/app/services/llm_cost_tracker/dashboard/params.rb +10 -0
  19. data/app/services/llm_cost_tracker/dashboard/pricing_overview.rb +2 -1
  20. data/app/services/llm_cost_tracker/dashboard/spend_anomaly.rb +1 -1
  21. data/app/services/llm_cost_tracker/dashboard/tag_breakdown.rb +2 -3
  22. data/app/services/llm_cost_tracker/dashboard/tag_key_explorer.rb +1 -0
  23. data/app/services/llm_cost_tracker/dashboard/time_series.rb +3 -5
  24. data/app/services/llm_cost_tracker/dashboard/top_models.rb +1 -2
  25. data/app/views/llm_cost_tracker/calls/show.html.erb +8 -22
  26. data/app/views/llm_cost_tracker/data_quality/index.html.erb +1 -1
  27. data/app/views/llm_cost_tracker/shared/_bar.html.erb +1 -3
  28. data/app/views/llm_cost_tracker/shared/_filter_pill_date.html.erb +1 -4
  29. data/app/views/llm_cost_tracker/shared/_filter_pill_model.html.erb +1 -4
  30. data/app/views/llm_cost_tracker/shared/_filter_pill_provider.html.erb +1 -4
  31. data/app/views/llm_cost_tracker/shared/_filter_pill_stream.html.erb +1 -4
  32. data/app/views/llm_cost_tracker/tags/show.html.erb +8 -5
  33. data/config/routes.rb +6 -1
  34. data/lib/llm_cost_tracker/budget/per_tag.rb +21 -11
  35. data/lib/llm_cost_tracker/budget.rb +44 -55
  36. data/lib/llm_cost_tracker/capture/event_window.rb +100 -0
  37. data/lib/llm_cost_tracker/capture/sdk_payload.rb +5 -1
  38. data/lib/llm_cost_tracker/capture/sse.rb +108 -32
  39. data/lib/llm_cost_tracker/capture/stream_collector.rb +41 -81
  40. data/lib/llm_cost_tracker/capture/stream_tap.rb +57 -0
  41. data/lib/llm_cost_tracker/capture/stream_tracker.rb +14 -58
  42. data/lib/llm_cost_tracker/capture_verifier.rb +1 -7
  43. data/lib/llm_cost_tracker/charges/line_item.rb +5 -1
  44. data/lib/llm_cost_tracker/configuration/budgets.rb +1 -1
  45. data/lib/llm_cost_tracker/configuration/pricing.rb +1 -1
  46. data/lib/llm_cost_tracker/configuration.rb +5 -9
  47. data/lib/llm_cost_tracker/doctor/price_check.rb +14 -3
  48. data/lib/llm_cost_tracker/doctor/schema_check.rb +1 -2
  49. data/lib/llm_cost_tracker/doctor.rb +19 -2
  50. data/lib/llm_cost_tracker/engine.rb +0 -1
  51. data/lib/llm_cost_tracker/errors.rb +13 -0
  52. data/lib/llm_cost_tracker/event.rb +8 -0
  53. data/lib/llm_cost_tracker/generators/llm_cost_tracker/async_ingestion_generator.rb +0 -6
  54. data/lib/llm_cost_tracker/generators/llm_cost_tracker/call_rollups_generator.rb +5 -8
  55. data/lib/llm_cost_tracker/generators/llm_cost_tracker/install_generator.rb +0 -6
  56. data/lib/llm_cost_tracker/generators/llm_cost_tracker/templates/create_llm_cost_tracker_async_ingestion.rb.erb +1 -1
  57. data/lib/llm_cost_tracker/generators/llm_cost_tracker/templates/create_llm_cost_tracker_call_rollups.rb.erb +1 -1
  58. data/lib/llm_cost_tracker/generators/llm_cost_tracker/templates/create_llm_cost_tracker_calls.rb.erb +1 -1
  59. data/lib/llm_cost_tracker/generators/llm_cost_tracker/templates/initializer.rb.erb +14 -12
  60. data/lib/llm_cost_tracker/generators/llm_cost_tracker/templates/upgrade_call_rollups_provider.rb.erb +1 -1
  61. data/lib/llm_cost_tracker/generators/llm_cost_tracker/templates/upgrade_call_tags_key_value_index.rb.erb +1 -1
  62. data/lib/llm_cost_tracker/generators/llm_cost_tracker/templates/upgrade_image_tokens.rb.erb +1 -1
  63. data/lib/llm_cost_tracker/generators/llm_cost_tracker/templates/upgrade_indexes.rb.erb +1 -1
  64. data/lib/llm_cost_tracker/generators/llm_cost_tracker/templates/upgrade_per_tag_budgets.rb.erb +1 -1
  65. data/lib/llm_cost_tracker/generators/llm_cost_tracker/upgrade_call_rollups_provider_generator.rb +0 -6
  66. data/lib/llm_cost_tracker/generators/llm_cost_tracker/upgrade_call_tags_key_value_index_generator.rb +0 -6
  67. data/lib/llm_cost_tracker/generators/llm_cost_tracker/upgrade_image_tokens_generator.rb +0 -6
  68. data/lib/llm_cost_tracker/generators/llm_cost_tracker/upgrade_indexes_generator.rb +3 -8
  69. data/lib/llm_cost_tracker/generators/llm_cost_tracker/upgrade_per_tag_budgets_generator.rb +3 -8
  70. data/lib/llm_cost_tracker/ingestion/batch.rb +37 -8
  71. data/lib/llm_cost_tracker/ingestion/inbox.rb +2 -8
  72. data/lib/llm_cost_tracker/ingestion.rb +3 -1
  73. data/lib/llm_cost_tracker/integrations/anthropic.rb +70 -11
  74. data/lib/llm_cost_tracker/integrations/base.rb +56 -19
  75. data/lib/llm_cost_tracker/integrations/openai/batch_capture.rb +21 -13
  76. data/lib/llm_cost_tracker/integrations/openai/patches.rb +8 -0
  77. data/lib/llm_cost_tracker/integrations/openai.rb +42 -59
  78. data/lib/llm_cost_tracker/integrations/ruby_llm.rb +275 -75
  79. data/lib/llm_cost_tracker/integrations.rb +1 -20
  80. data/lib/llm_cost_tracker/ledger/isolation.rb +23 -0
  81. data/lib/llm_cost_tracker/ledger/period/totals.rb +16 -11
  82. data/lib/llm_cost_tracker/ledger/rollups.rb +25 -17
  83. data/lib/llm_cost_tracker/ledger/schema/adapter.rb +14 -3
  84. data/lib/llm_cost_tracker/ledger/schema/base.rb +5 -4
  85. data/lib/llm_cost_tracker/ledger/storable.rb +16 -0
  86. data/lib/llm_cost_tracker/ledger/store.rb +14 -13
  87. data/lib/llm_cost_tracker/ledger/tags/breakdown.rb +1 -5
  88. data/lib/llm_cost_tracker/ledger/tags/encoding.rb +3 -12
  89. data/lib/llm_cost_tracker/ledger/tags/query.rb +0 -2
  90. data/lib/llm_cost_tracker/ledger.rb +1 -0
  91. data/lib/llm_cost_tracker/logging.rb +3 -1
  92. data/lib/llm_cost_tracker/middleware/faraday.rb +67 -61
  93. data/lib/llm_cost_tracker/parsers.rb +12 -41
  94. data/lib/llm_cost_tracker/prices.json +3071 -249
  95. data/lib/llm_cost_tracker/pricing/backfill.rb +46 -13
  96. data/lib/llm_cost_tracker/pricing/calculation.rb +118 -75
  97. data/lib/llm_cost_tracker/pricing/effective_prices.rb +11 -10
  98. data/lib/llm_cost_tracker/pricing/estimator.rb +5 -2
  99. data/lib/llm_cost_tracker/pricing/matcher.rb +36 -22
  100. data/lib/llm_cost_tracker/pricing/mode.rb +2 -13
  101. data/lib/llm_cost_tracker/pricing/price_key.rb +5 -3
  102. data/lib/llm_cost_tracker/pricing/rate.rb +1 -0
  103. data/lib/llm_cost_tracker/pricing/registry.rb +17 -17
  104. data/lib/llm_cost_tracker/pricing/service_rates.rb +1 -8
  105. data/lib/llm_cost_tracker/pricing/sync/change_printer.rb +6 -1
  106. data/lib/llm_cost_tracker/pricing/sync/registry_diff.rb +13 -9
  107. data/lib/llm_cost_tracker/pricing/sync/snapshot_guard.rb +47 -0
  108. data/lib/llm_cost_tracker/pricing/sync.rb +38 -70
  109. data/lib/llm_cost_tracker/providers/anthropic/parser.rb +33 -3
  110. data/lib/llm_cost_tracker/providers/anthropic/response_parser.rb +11 -5
  111. data/lib/llm_cost_tracker/providers/anthropic/usage_extractor.rb +81 -12
  112. data/lib/llm_cost_tracker/providers/azure/parser.rb +22 -7
  113. data/lib/llm_cost_tracker/providers/gemini/parser.rb +175 -47
  114. data/lib/llm_cost_tracker/providers/gemini/usage_extractor.rb +13 -22
  115. data/lib/llm_cost_tracker/providers/openai/hosts.rb +1 -1
  116. data/lib/llm_cost_tracker/providers/openai/parser.rb +11 -13
  117. data/lib/llm_cost_tracker/providers/openai/response_parser.rb +101 -27
  118. data/lib/llm_cost_tracker/providers/openai/service_charges.rb +57 -40
  119. data/lib/llm_cost_tracker/providers/openai/usage_extractor.rb +24 -6
  120. data/lib/llm_cost_tracker/providers/openai_compatible/parser.rb +7 -1
  121. data/lib/llm_cost_tracker/redaction.rb +32 -0
  122. data/lib/llm_cost_tracker/report/data.rb +1 -1
  123. data/lib/llm_cost_tracker/retention.rb +1 -3
  124. data/lib/llm_cost_tracker/tags/sanitizer.rb +10 -36
  125. data/lib/llm_cost_tracker/tracker.rb +17 -10
  126. data/lib/llm_cost_tracker/usage/catalog.rb +13 -4
  127. data/lib/llm_cost_tracker/usage/dimension.rb +1 -1
  128. data/lib/llm_cost_tracker/usage/dimensions.yml +61 -0
  129. data/lib/llm_cost_tracker/version.rb +1 -1
  130. data/lib/llm_cost_tracker.rb +4 -2
  131. data/lib/tasks/llm_cost_tracker.rake +26 -21
  132. data/llm_cost_tracker.gemspec +63 -0
  133. metadata +23 -10
@@ -16,7 +16,7 @@ end
16
16
 
17
17
  # rubocop:disable-next Metrics/BlockLength
18
18
  namespace :llm_cost_tracker do
19
- desc "Install LLM Cost Tracker with dashboard and prices, migrate, and run doctor"
19
+ desc "Install LLM Cost Tracker with a local prices file, migrate, run doctor, and print dashboard mount steps"
20
20
  task :setup do
21
21
  Rails::Generators.invoke("llm_cost_tracker:install", %w[--dashboard --prices --skip])
22
22
  begin
@@ -54,7 +54,7 @@ namespace :llm_cost_tracker do
54
54
  puts LlmCostTracker::Report.generate(days: days)
55
55
  end
56
56
 
57
- desc "Recompute total_cost for calls with unknown pricing using the current price registry. " \
57
+ desc "Recompute total_cost for calls with unknown or partial pricing using the current price registry. " \
58
58
  "Use BATCH_SIZE=N to tune."
59
59
  task backfill_unknown_pricing: :environment do
60
60
  require_relative "../llm_cost_tracker/pricing/backfill"
@@ -64,7 +64,22 @@ namespace :llm_cost_tracker do
64
64
  "still unknown #{result.still_unknown}"
65
65
  end
66
66
 
67
- desc "Delete llm_cost_tracker_calls older than DAYS (default: 90). Use BATCH_SIZE=N to tune."
67
+ desc "Reprice calls tracked from FROM (and before TO, if set) at the current price registry, including " \
68
+ "calls already priced; rollups and per-tag costs move by the difference. Use BATCH_SIZE=N to tune."
69
+ task reprice: :environment do
70
+ require_relative "../llm_cost_tracker/pricing/backfill"
71
+ from = Time.zone.parse(ENV["FROM"].to_s)
72
+ abort("llm_cost_tracker: set FROM to the first day to reprice, e.g. FROM=2026-09-01") unless from
73
+ to_text = ENV["TO"].presence
74
+ to = to_text && Time.zone.parse(to_text)
75
+ abort("llm_cost_tracker: TO=#{to_text} is not a date, e.g. TO=2026-10-01") if to_text && !to
76
+ batch_size = (ENV["BATCH_SIZE"] || LlmCostTracker::Pricing::Backfill::DEFAULT_BATCH_SIZE).to_i
77
+ scope = LlmCostTracker::Pricing::Backfill.reprice_scope(from...to)
78
+ result = LlmCostTracker::Pricing::Backfill.call(scope: scope, batch_size: batch_size, reprice: true)
79
+ puts "llm_cost_tracker: examined #{result.examined} calls, repriced #{result.recomputed}"
80
+ end
81
+
82
+ desc "Delete llm_cost_tracker_calls and ingestion inbox rows older than DAYS (default: 90). Use BATCH_SIZE=N to tune."
68
83
  task prune: :environment do
69
84
  days = (ENV["DAYS"] || 90).to_i
70
85
  batch_size = (ENV["BATCH_SIZE"] || LlmCostTracker::Retention::DEFAULT_BATCH_SIZE).to_i
@@ -98,33 +113,23 @@ namespace :llm_cost_tracker do
98
113
  namespace :prices do
99
114
  desc(
100
115
  "Refresh the configured pricing file from the maintained LLM Cost Tracker price snapshot. " \
101
- "Use PREVIEW=1 to preview, URL=... to override the source, or OUTPUT=path/to/file.json."
116
+ "Review changes first with llm_cost_tracker:prices:check. Use FORCE=1 to accept suspicious price changes, " \
117
+ "URL=... to override the source, or OUTPUT=path/to/file.json."
102
118
  )
103
119
  task :refresh do
104
120
  Rake::Task["environment"].invoke if Rake::Task.task_defined?("environment")
105
121
  require_relative "../llm_cost_tracker"
106
122
 
123
+ abort("llm_cost_tracker: PREVIEW is not supported; run llm_cost_tracker:prices:check") if ENV.key?("PREVIEW")
124
+
107
125
  output_path = LlmCostTrackerTasks.price_refresh_output_path
108
126
  source_url = LlmCostTracker::Pricing::Sync.configured_remote_url
109
- preview = ENV["PREVIEW"] == "1"
110
- result = LlmCostTracker::Pricing::Sync.refresh(
111
- path: output_path,
112
- url: source_url,
113
- preview: preview
114
- )
115
-
116
- action = if preview
117
- "previewed"
118
- elsif result.written
119
- "refreshed"
120
- else
121
- "kept"
122
- end
127
+ result = LlmCostTracker::Pricing::Sync.refresh(path: output_path, url: source_url, force: ENV["FORCE"] == "1")
123
128
 
124
- puts "llm_cost_tracker: #{action} pricing file #{result.path}"
129
+ puts "llm_cost_tracker: #{result.written ? 'refreshed' : 'kept'} pricing file #{result.path}"
125
130
  puts " source: #{result.source_url}"
126
131
  puts " version: #{result.source_version.inspect}" if result.source_version
127
- LlmCostTracker::Pricing::Sync::ChangePrinter.call(result.changes)
132
+ LlmCostTracker::Pricing::Sync::ChangePrinter.call(result.changes, suspicious: result.suspicious)
128
133
  end
129
134
 
130
135
  desc "Compare the current pricing file with the maintained LLM Cost Tracker price snapshot."
@@ -139,7 +144,7 @@ namespace :llm_cost_tracker do
139
144
  puts "llm_cost_tracker: checked pricing file #{result.path}"
140
145
  puts " source: #{result.source_url}"
141
146
  puts " version: #{result.source_version.inspect}" if result.source_version
142
- LlmCostTracker::Pricing::Sync::ChangePrinter.call(result.changes)
147
+ LlmCostTracker::Pricing::Sync::ChangePrinter.call(result.changes, suspicious: result.suspicious)
143
148
  puts " pricing is up to date" if result.up_to_date
144
149
  abort("llm_cost_tracker: pricing check failed") unless result.up_to_date
145
150
  end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/llm_cost_tracker/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "llm_cost_tracker"
7
+ spec.version = LlmCostTracker::VERSION
8
+ spec.authors = ["Sergii Khomenko"]
9
+ spec.email = ["sergey@mm.st"]
10
+
11
+ spec.summary = "LLM API cost tracking for Rails applications"
12
+ spec.description = "Logs every call your Rails app makes to OpenAI, Anthropic, Gemini, RubyLLM, " \
13
+ "or an OpenAI-compatible API: tokens, cost, latency, tags. Calls go straight " \
14
+ "to the provider — no proxy. Includes price sync, budget guardrails, and a " \
15
+ "mountable dashboard."
16
+ spec.homepage = "https://github.com/sergey-homenko/llm_cost_tracker"
17
+ spec.license = "MIT"
18
+
19
+ spec.required_ruby_version = ">= 3.3.0"
20
+
21
+ spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues"
22
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
23
+ spec.metadata["source_code_uri"] = spec.homepage
24
+ spec.metadata["documentation_uri"] = "#{spec.homepage}#readme"
25
+ spec.metadata["rubygems_mfa_required"] = "true"
26
+
27
+ spec.files = Dir.chdir(__dir__) do
28
+ `git ls-files -z`.split("\x0").reject do |f|
29
+ (File.expand_path(f) == __FILE__) ||
30
+ f.start_with?("bin/",
31
+ "test/",
32
+ "spec/",
33
+ "scripts/",
34
+ "docs/",
35
+ ".git",
36
+ ".github",
37
+ "gemfiles/",
38
+ ".rubocop",
39
+ "Gemfile") ||
40
+ f == "codecov.yml"
41
+ end
42
+ end
43
+
44
+ spec.require_paths = ["lib"]
45
+
46
+ spec.add_dependency "activerecord", ">= 8.0", "< 9.0"
47
+ spec.add_dependency "activesupport", ">= 8.0", "< 9.0"
48
+ spec.add_dependency "csv", "~> 3.0"
49
+ spec.add_dependency "faraday", ">= 2.0", "< 3.0"
50
+ spec.add_dependency "railties", ">= 8.0", "< 9.0"
51
+
52
+ spec.add_development_dependency "anthropic", "~> 1.61"
53
+ spec.add_development_dependency "nokogiri", "~> 1.19"
54
+ spec.add_development_dependency "openai", "~> 0.80"
55
+ spec.add_development_dependency "pg", "~> 1.6"
56
+ spec.add_development_dependency "rake", "~> 13.0"
57
+ spec.add_development_dependency "rspec", "~> 3.0"
58
+ spec.add_development_dependency "rubocop", "~> 1.0"
59
+ spec.add_development_dependency "ruby_llm", ">= 1.16", "< 3"
60
+ spec.add_development_dependency "simplecov", "~> 0.22"
61
+ spec.add_development_dependency "simplecov-lcov", "~> 0.8"
62
+ spec.add_development_dependency "webmock", "~> 3.0"
63
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: llm_cost_tracker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.0
4
+ version: 0.14.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergii Khomenko
@@ -15,7 +15,7 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: '7.1'
18
+ version: '8.0'
19
19
  - - "<"
20
20
  - !ruby/object:Gem::Version
21
21
  version: '9.0'
@@ -25,7 +25,7 @@ dependencies:
25
25
  requirements:
26
26
  - - ">="
27
27
  - !ruby/object:Gem::Version
28
- version: '7.1'
28
+ version: '8.0'
29
29
  - - "<"
30
30
  - !ruby/object:Gem::Version
31
31
  version: '9.0'
@@ -35,7 +35,7 @@ dependencies:
35
35
  requirements:
36
36
  - - ">="
37
37
  - !ruby/object:Gem::Version
38
- version: '7.1'
38
+ version: '8.0'
39
39
  - - "<"
40
40
  - !ruby/object:Gem::Version
41
41
  version: '9.0'
@@ -45,7 +45,7 @@ dependencies:
45
45
  requirements:
46
46
  - - ">="
47
47
  - !ruby/object:Gem::Version
48
- version: '7.1'
48
+ version: '8.0'
49
49
  - - "<"
50
50
  - !ruby/object:Gem::Version
51
51
  version: '9.0'
@@ -89,7 +89,7 @@ dependencies:
89
89
  requirements:
90
90
  - - ">="
91
91
  - !ruby/object:Gem::Version
92
- version: '7.1'
92
+ version: '8.0'
93
93
  - - "<"
94
94
  - !ruby/object:Gem::Version
95
95
  version: '9.0'
@@ -99,7 +99,7 @@ dependencies:
99
99
  requirements:
100
100
  - - ">="
101
101
  - !ruby/object:Gem::Version
102
- version: '7.1'
102
+ version: '8.0'
103
103
  - - "<"
104
104
  - !ruby/object:Gem::Version
105
105
  version: '9.0'
@@ -205,16 +205,22 @@ dependencies:
205
205
  name: ruby_llm
206
206
  requirement: !ruby/object:Gem::Requirement
207
207
  requirements:
208
- - - "~>"
208
+ - - ">="
209
209
  - !ruby/object:Gem::Version
210
210
  version: '1.16'
211
+ - - "<"
212
+ - !ruby/object:Gem::Version
213
+ version: '3'
211
214
  type: :development
212
215
  prerelease: false
213
216
  version_requirements: !ruby/object:Gem::Requirement
214
217
  requirements:
215
- - - "~>"
218
+ - - ">="
216
219
  - !ruby/object:Gem::Version
217
220
  version: '1.16'
221
+ - - "<"
222
+ - !ruby/object:Gem::Version
223
+ version: '3'
218
224
  - !ruby/object:Gem::Dependency
219
225
  name: simplecov
220
226
  requirement: !ruby/object:Gem::Requirement
@@ -340,9 +346,11 @@ files:
340
346
  - lib/llm_cost_tracker/assets.rb
341
347
  - lib/llm_cost_tracker/budget.rb
342
348
  - lib/llm_cost_tracker/budget/per_tag.rb
349
+ - lib/llm_cost_tracker/capture/event_window.rb
343
350
  - lib/llm_cost_tracker/capture/sdk_payload.rb
344
351
  - lib/llm_cost_tracker/capture/sse.rb
345
352
  - lib/llm_cost_tracker/capture/stream_collector.rb
353
+ - lib/llm_cost_tracker/capture/stream_tap.rb
346
354
  - lib/llm_cost_tracker/capture/stream_tracker.rb
347
355
  - lib/llm_cost_tracker/capture_verifier.rb
348
356
  - lib/llm_cost_tracker/charges/cost.rb
@@ -399,6 +407,7 @@ files:
399
407
  - lib/llm_cost_tracker/integrations/openai/patches.rb
400
408
  - lib/llm_cost_tracker/integrations/ruby_llm.rb
401
409
  - lib/llm_cost_tracker/ledger.rb
410
+ - lib/llm_cost_tracker/ledger/isolation.rb
402
411
  - lib/llm_cost_tracker/ledger/period.rb
403
412
  - lib/llm_cost_tracker/ledger/period/totals.rb
404
413
  - lib/llm_cost_tracker/ledger/rollups.rb
@@ -411,6 +420,7 @@ files:
411
420
  - lib/llm_cost_tracker/ledger/schema/calls.rb
412
421
  - lib/llm_cost_tracker/ledger/schema/ingestion/inbox_entries.rb
413
422
  - lib/llm_cost_tracker/ledger/schema/ingestion/leases.rb
423
+ - lib/llm_cost_tracker/ledger/storable.rb
414
424
  - lib/llm_cost_tracker/ledger/store.rb
415
425
  - lib/llm_cost_tracker/ledger/tags/breakdown.rb
416
426
  - lib/llm_cost_tracker/ledger/tags/encoding.rb
@@ -436,6 +446,7 @@ files:
436
446
  - lib/llm_cost_tracker/pricing/sync/fetcher.rb
437
447
  - lib/llm_cost_tracker/pricing/sync/registry_diff.rb
438
448
  - lib/llm_cost_tracker/pricing/sync/registry_writer.rb
449
+ - lib/llm_cost_tracker/pricing/sync/snapshot_guard.rb
439
450
  - lib/llm_cost_tracker/pricing/unknown.rb
440
451
  - lib/llm_cost_tracker/providers.rb
441
452
  - lib/llm_cost_tracker/providers/anthropic/parser.rb
@@ -454,6 +465,7 @@ files:
454
465
  - lib/llm_cost_tracker/providers/openai/usage_extractor.rb
455
466
  - lib/llm_cost_tracker/providers/openai_compatible/parser.rb
456
467
  - lib/llm_cost_tracker/railtie.rb
468
+ - lib/llm_cost_tracker/redaction.rb
457
469
  - lib/llm_cost_tracker/report.rb
458
470
  - lib/llm_cost_tracker/report/data.rb
459
471
  - lib/llm_cost_tracker/report/formatter.rb
@@ -470,6 +482,7 @@ files:
470
482
  - lib/llm_cost_tracker/usage/token_usage.rb
471
483
  - lib/llm_cost_tracker/version.rb
472
484
  - lib/tasks/llm_cost_tracker.rake
485
+ - llm_cost_tracker.gemspec
473
486
  homepage: https://github.com/sergey-homenko/llm_cost_tracker
474
487
  licenses:
475
488
  - MIT
@@ -486,7 +499,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
486
499
  requirements:
487
500
  - - ">="
488
501
  - !ruby/object:Gem::Version
489
- version: 3.4.0
502
+ version: 3.3.0
490
503
  required_rubygems_version: !ruby/object:Gem::Requirement
491
504
  requirements:
492
505
  - - ">="