Module: LlmCostTracker::Integrations::Anthropic
- Extended by:
- Base
- Defined in:
- lib/llm_cost_tracker/integrations/anthropic.rb
Defined Under Namespace
Modules: MessagesPatch
Class Method Summary
collapse
-
.inference_geo(message:, request:, usage:) ⇒ Object
-
.integration_name ⇒ Object
-
.line_item_for_server_tool(server_tool_use, component_key, count_key, provider_field) ⇒ Object
-
.minimum_version ⇒ Object
-
.patch_targets ⇒ Object
-
.pricing_mode(message:, request:, usage:) ⇒ Object
-
.record_message(message, request:, latency_ms:) ⇒ Object
-
.service_line_items_from(usage) ⇒ Object
-
.stream_pricing_mode(request) ⇒ Object
-
.token_usage(usage:, input_tokens:, output_tokens:) ⇒ Object
-
.version_constant ⇒ Object
Methods included from Base
active?, elapsed_ms, enforce_budget!, install, minimum_version, object_dig, object_value, patch_target, patch_targets, record_safely, request_params, status, stream_collector, stream_pricing_mode, track_stream, version_constant
Class Method Details
.inference_geo(message:, request:, usage:) ⇒ Object
127
128
129
130
131
|
# File 'lib/llm_cost_tracker/integrations/anthropic.rb', line 127
def inference_geo(message:, request:, usage:)
object_value(usage, :inference_geo) ||
object_value(message, :inference_geo) ||
request[:inference_geo]
end
|
.integration_name ⇒ Object
12
13
14
|
# File 'lib/llm_cost_tracker/integrations/anthropic.rb', line 12
def integration_name
:anthropic
end
|
74
75
76
77
78
79
80
81
82
83
84
85
|
# File 'lib/llm_cost_tracker/integrations/anthropic.rb', line 74
def line_item_for_server_tool(server_tool_use, component_key, count_key, provider_field)
quantity = object_value(server_tool_use, count_key).to_i
return nil if quantity.zero?
Billing::LineItem.build(
component_key: component_key,
quantity: quantity,
cost_status: Billing::CostStatus::UNKNOWN,
pricing_basis: :provider_usage,
provider_field: provider_field
)
end
|
.minimum_version ⇒ Object
16
17
18
|
# File 'lib/llm_cost_tracker/integrations/anthropic.rb', line 16
def minimum_version
"1.36.0"
end
|
.patch_targets ⇒ Object
24
25
26
27
28
29
30
31
32
33
34
|
# File 'lib/llm_cost_tracker/integrations/anthropic.rb', line 24
def patch_targets
[
patch_target("Anthropic::Resources::Messages", with: MessagesPatch, methods: %i[create stream stream_raw]),
patch_target(
"Anthropic::Resources::Beta::Messages",
with: MessagesPatch,
methods: %i[create stream stream_raw],
optional: true
)
]
end
|
.pricing_mode(message:, request:, usage:) ⇒ Object
111
112
113
114
115
116
117
118
119
120
121
|
# File 'lib/llm_cost_tracker/integrations/anthropic.rb', line 111
def pricing_mode(message:, request:, usage:)
modes = [
Pricing.normalize_mode(object_value(usage, :speed) || object_value(message, :speed) || request[:speed]),
Pricing.normalize_mode(
object_value(usage, :service_tier) || object_value(message, :service_tier) || request[:service_tier]
)
]
modes << "data_residency" if inference_geo(message: message, request: request, usage: usage).to_s == "us"
modes = modes.compact.uniq
modes.empty? ? nil : modes.join("_")
end
|
.record_message(message, request:, latency_ms:) ⇒ Object
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
# File 'lib/llm_cost_tracker/integrations/anthropic.rb', line 36
def record_message(message, request:, latency_ms:)
return unless active?
record_safely do
usage = object_value(message, :usage)
next unless usage
input_tokens = object_value(usage, :input_tokens)
output_tokens = object_value(usage, :output_tokens)
next if input_tokens.nil? && output_tokens.nil?
LlmCostTracker::Tracker.record(
capture: UsageCapture.build(
provider: "anthropic",
model: object_value(message, :model) || request[:model],
pricing_mode: pricing_mode(message: message, request: request, usage: usage),
token_usage: token_usage(usage: usage, input_tokens: input_tokens, output_tokens: output_tokens),
usage_source: :sdk_response,
provider_response_id: object_value(message, :id),
service_line_items: service_line_items_from(usage)
),
latency_ms: latency_ms
)
end
end
|
.service_line_items_from(usage) ⇒ Object
62
63
64
65
66
67
68
69
70
71
72
|
# File 'lib/llm_cost_tracker/integrations/anthropic.rb', line 62
def service_line_items_from(usage)
server_tool_use = object_value(usage, :server_tool_use)
return [] unless server_tool_use
[
line_item_for_server_tool(server_tool_use, :web_search_request, :web_search_requests,
"usage.server_tool_use.web_search_requests"),
line_item_for_server_tool(server_tool_use, :code_execution_request, :code_execution_requests,
"usage.server_tool_use.code_execution_requests")
].compact
end
|
.stream_pricing_mode(request) ⇒ Object
123
124
125
|
# File 'lib/llm_cost_tracker/integrations/anthropic.rb', line 123
def stream_pricing_mode(request)
pricing_mode(message: nil, request: request || {}, usage: nil)
end
|
.token_usage(usage:, input_tokens:, output_tokens:) ⇒ Object
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
# File 'lib/llm_cost_tracker/integrations/anthropic.rb', line 87
def token_usage(usage:, input_tokens:, output_tokens:)
cache_creation = object_value(usage, :cache_creation)
if cache_creation
cache_write_default = object_value(cache_creation, :ephemeral_5m_input_tokens).to_i
cache_write_extended = object_value(cache_creation, :ephemeral_1h_input_tokens).to_i
else
cache_write_default = object_value(usage, :cache_creation_input_tokens).to_i
cache_write_extended = 0
end
hidden_output = (
object_value(usage, :thinking_tokens, :thinking_output_tokens) ||
object_dig(usage, :output_tokens_details, :reasoning_tokens)
).to_i
TokenUsage.build(
input_tokens: input_tokens.to_i,
output_tokens: output_tokens.to_i,
cache_read_input_tokens: object_value(usage, :cache_read_input_tokens).to_i,
cache_write_input_tokens: cache_write_default,
cache_write_extended_input_tokens: cache_write_extended,
hidden_output_tokens: hidden_output
)
end
|
.version_constant ⇒ Object
20
21
22
|
# File 'lib/llm_cost_tracker/integrations/anthropic.rb', line 20
def version_constant
"Anthropic::VERSION"
end
|