Class: PromptWarden::CostCalculator
- Inherits:
-
Object
- Object
- PromptWarden::CostCalculator
- Defined in:
- lib/prompt_warden/cost_calculator.rb
Constant Summary collapse
- MODEL_PRICING =
Model pricing (per 1K tokens) - updated as of 2024
{ # OpenAI Models 'gpt-4o' => { input: 0.0025, output: 0.01 }, 'gpt-4o-mini' => { input: 0.00015, output: 0.0006 }, 'gpt-4-turbo' => { input: 0.01, output: 0.03 }, 'gpt-4' => { input: 0.03, output: 0.06 }, 'gpt-3.5-turbo' => { input: 0.0005, output: 0.0015 }, # Anthropic Models 'claude-3-opus-20240229' => { input: 0.015, output: 0.075 }, 'claude-3-sonnet-20240229' => { input: 0.003, output: 0.015 }, 'claude-3-haiku-20240307' => { input: 0.00025, output: 0.00125 }, 'claude-3-5-sonnet-20241022' => { input: 0.003, output: 0.015 }, # Default fallback 'default' => { input: 0.001, output: 0.002 } }.freeze
Class Method Summary collapse
- .calculate_cost(prompt:, model:, response_tokens: nil) ⇒ Object
- .count_tokens(text, model = nil) ⇒ Object
- .estimate_output_tokens(prompt, model) ⇒ Object
- .get_model_pricing(model) ⇒ Object
Class Method Details
.calculate_cost(prompt:, model:, response_tokens: nil) ⇒ Object
27 28 29 30 31 32 33 34 35 36 |
# File 'lib/prompt_warden/cost_calculator.rb', line 27 def calculate_cost(prompt:, model:, response_tokens: nil) input_tokens = count_tokens(prompt, model) output_tokens = response_tokens || estimate_output_tokens(prompt, model) pricing = get_model_pricing(model) input_cost = (input_tokens / 1000.0) * pricing[:input] output_cost = (output_tokens / 1000.0) * pricing[:output] (input_cost + output_cost).round(6) end |
.count_tokens(text, model = nil) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/prompt_warden/cost_calculator.rb', line 38 def count_tokens(text, model = nil) return 0 if text.nil? || text.empty? # Use tiktoken for OpenAI models if available if model&.start_with?('gpt-') && defined?(Tiktoken) count_tokens_tiktoken(text, model) else # Fallback to approximate counting count_tokens_approximate(text) end end |
.estimate_output_tokens(prompt, model) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/prompt_warden/cost_calculator.rb', line 50 def estimate_output_tokens(prompt, model) return 0 if prompt.nil? || prompt.empty? # Rough estimation based on prompt length and model base_tokens = prompt.length / 4 # ~4 chars per token # Adjust based on model type case model when /gpt-4o/ (base_tokens * 0.8).round # More efficient when /claude-3-opus/ (base_tokens * 1.2).round # More verbose when /claude-3-sonnet/ (base_tokens * 1.0).round # Standard when /claude-3-haiku/ (base_tokens * 0.7).round # Concise else base_tokens.round end end |
.get_model_pricing(model) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/prompt_warden/cost_calculator.rb', line 71 def get_model_pricing(model) return MODEL_PRICING['default'] unless model # Try exact match first return MODEL_PRICING[model] if MODEL_PRICING[model] # Try partial matches for model variants MODEL_PRICING.each do |key, pricing| next if key == 'default' return pricing if model.include?(key.split('-').first) || key.include?(model.split('-').first) end MODEL_PRICING['default'] end |