Class: LlmCostTracker::Billing::LineItem

Inherits:
Data
  • Object
show all
Defined in:
lib/llm_cost_tracker/billing/line_item.rb,
lib/llm_cost_tracker/billing/line_item.rb

Constant Summary collapse

USD =
"USD"
OPTIONAL_ATTRIBUTES =
%i[
  pricing_basis
  price_key
  price_source
  price_source_version
  provider_field
  provider_item_id
].freeze
SYMBOL_ATTRIBUTES =
%i[
  kind
  direction
  modality
  cache_state
  unit
  pricing_basis
  price_source
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#cache_stateObject (readonly)

Returns the value of attribute cache_state

Returns:

  • (Object)

    the current value of cache_state



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def cache_state
  @cache_state
end

#costObject (readonly)

Returns the value of attribute cost

Returns:

  • (Object)

    the current value of cost



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def cost
  @cost
end

#cost_statusObject (readonly)

Returns the value of attribute cost_status

Returns:

  • (Object)

    the current value of cost_status



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def cost_status
  @cost_status
end

#currencyObject (readonly)

Returns the value of attribute currency

Returns:

  • (Object)

    the current value of currency



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def currency
  @currency
end

#detailsObject (readonly)

Returns the value of attribute details

Returns:

  • (Object)

    the current value of details



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def details
  @details
end

#directionObject (readonly)

Returns the value of attribute direction

Returns:

  • (Object)

    the current value of direction



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def direction
  @direction
end

#kindObject (readonly)

Returns the value of attribute kind

Returns:

  • (Object)

    the current value of kind



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def kind
  @kind
end

#modalityObject (readonly)

Returns the value of attribute modality

Returns:

  • (Object)

    the current value of modality



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def modality
  @modality
end

#price_keyObject (readonly)

Returns the value of attribute price_key

Returns:

  • (Object)

    the current value of price_key



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def price_key
  @price_key
end

#price_sourceObject (readonly)

Returns the value of attribute price_source

Returns:

  • (Object)

    the current value of price_source



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def price_source
  @price_source
end

#price_source_versionObject (readonly)

Returns the value of attribute price_source_version

Returns:

  • (Object)

    the current value of price_source_version



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def price_source_version
  @price_source_version
end

#pricing_basisObject (readonly)

Returns the value of attribute pricing_basis

Returns:

  • (Object)

    the current value of pricing_basis



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def pricing_basis
  @pricing_basis
end

#provider_fieldObject (readonly)

Returns the value of attribute provider_field

Returns:

  • (Object)

    the current value of provider_field



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def provider_field
  @provider_field
end

#provider_item_idObject (readonly)

Returns the value of attribute provider_item_id

Returns:

  • (Object)

    the current value of provider_item_id



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def provider_item_id
  @provider_item_id
end

#quantityObject (readonly)

Returns the value of attribute quantity

Returns:

  • (Object)

    the current value of quantity



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def quantity
  @quantity
end

#rate_amountObject (readonly)

Returns the value of attribute rate_amount

Returns:

  • (Object)

    the current value of rate_amount



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def rate_amount
  @rate_amount
end

#rate_quantityObject (readonly)

Returns the value of attribute rate_quantity

Returns:

  • (Object)

    the current value of rate_quantity



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def rate_quantity
  @rate_quantity
end

#unitObject (readonly)

Returns the value of attribute unit

Returns:

  • (Object)

    the current value of unit



10
11
12
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 10

def unit
  @unit
end

Class Method Details

.build(attributes) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 51

def self.build(attributes)
  attributes = attributes.to_h
  component = component_for(attributes)
  normalized = {
    kind: symbol_or_nil(attributes[:kind]) || component&.kind,
    direction: symbol_or_nil(attributes[:direction]) || component&.direction,
    modality: symbol_or_nil(attributes[:modality]) || component&.modality,
    cache_state: symbol_or_nil(attributes[:cache_state]) || component&.cache_state,
    quantity: decimal_or_zero(attributes[:quantity]),
    unit: symbol_or_nil(attributes[:unit]) || component&.unit,
    rate_amount: decimal_or_nil(attributes[:rate_amount]),
    rate_quantity: decimal_or_nil(attributes[:rate_quantity]) || BigDecimal("1"),
    cost: decimal_or_nil(attributes[:cost]),
    currency: attributes[:currency] || USD,
    cost_status: cost_status_for(attributes),
    details: attributes[:details] || {}
  }.merge(optional_attributes_for(attributes))

  new(**normalized)
end

.from_token_usage(token_usage) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 72

def self.from_token_usage(token_usage)
  return [] unless token_usage

  Components::TOKEN_PRICED.filter_map do |component|
    quantity = token_usage.public_send(component.token_key)
    next unless quantity.positive?

    new(
      kind: component.kind,
      direction: component.direction,
      modality: component.modality,
      cache_state: component.cache_state,
      quantity: BigDecimal(quantity.to_s),
      unit: component.unit,
      rate_amount: nil,
      rate_quantity: BigDecimal("1"),
      cost: nil,
      currency: USD,
      cost_status: CostStatus::UNKNOWN,
      pricing_basis: nil,
      price_key: nil,
      price_source: nil,
      price_source_version: nil,
      provider_field: nil,
      provider_item_id: nil,
      details: {}
    )
  end
end

Instance Method Details

#apply_rate(rate) ⇒ Object



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 166

def apply_rate(rate)
  rate_amount = rate.fetch(:amount)
  rate_quantity = rate.fetch(:quantity)
  applied_cost = (quantity / rate_quantity) * rate_amount
  with(
    rate_amount: rate_amount,
    rate_quantity: rate_quantity,
    cost: applied_cost,
    currency: rate.fetch(:currency),
    cost_status: applied_cost.zero? ? CostStatus::FREE : CostStatus::COMPLETE,
    price_key: rate.fetch(:source_key),
    price_source: rate.fetch(:source),
    price_source_version: rate.fetch(:source_version)
  )
end

#billable?Boolean

Returns:

  • (Boolean)


146
147
148
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 146

def billable?
  quantity.positive?
end

#cost_valueObject



162
163
164
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 162

def cost_value
  cost || BigDecimal("0")
end

#priced?Boolean

Returns:

  • (Boolean)


150
151
152
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 150

def priced?
  [CostStatus::COMPLETE, CostStatus::FREE].include?(cost_status)
end

#to_hObject



182
183
184
185
186
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 182

def to_h
  super.transform_values do |value|
    value.is_a?(BigDecimal) ? value.to_s("F") : value
  end
end

#token?Boolean

Returns:

  • (Boolean)


158
159
160
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 158

def token?
  unit == :token
end

#unpriced?Boolean

Returns:

  • (Boolean)


154
155
156
# File 'lib/llm_cost_tracker/billing/line_item.rb', line 154

def unpriced?
  cost_status == CostStatus::UNKNOWN
end