Files
sure/test/models/llm_usage_test.rb
Guillem Arias 29030d648e fix(ai): attribute Bedrock model IDs to anthropic + clean nil enum
- LlmUsage.infer_provider now returns "anthropic" for Bedrock /
  Vertex shaped IDs (anthropic.* and anthropic/*), so cost-ledger
  filtering by provider stays correct even when no per-MTok rate is
  stored. Previously these IDs fell through to the "openai" default.
- AutoCategorizer drops the redundant nil sentinel from the
  category_name enum — the union type [string, null] already permits
  null, and some JSON Schema validators reject nil literals inside
  enum arrays.
2026-05-29 14:51:07 +02:00

52 lines
2.1 KiB
Ruby

require "test_helper"
class LlmUsageTest < ActiveSupport::TestCase
test "infer_provider returns anthropic for claude models" do
assert_equal "anthropic", LlmUsage.infer_provider("claude-sonnet-4-6")
assert_equal "anthropic", LlmUsage.infer_provider("claude-opus-4-7")
assert_equal "anthropic", LlmUsage.infer_provider("claude-haiku-4-5")
end
test "infer_provider still returns openai for gpt models" do
assert_equal "openai", LlmUsage.infer_provider("gpt-4.1")
assert_equal "openai", LlmUsage.infer_provider("gpt-5")
end
test "infer_provider attributes Bedrock and Vertex prefixed IDs to anthropic" do
assert_equal "anthropic", LlmUsage.infer_provider("anthropic.claude-sonnet-4-5-20250929-v1:0")
assert_equal "anthropic", LlmUsage.infer_provider("anthropic.claude-opus-4-20250514-v1:0")
assert_equal "anthropic", LlmUsage.infer_provider("anthropic/claude-3-5-sonnet@20240620")
end
test "calculate_cost returns nil for Bedrock IDs (no per-token rate stored)" do
# Bedrock bills through AWS not Anthropic — we don't store a per-MTok rate,
# but the row must still attribute to anthropic for provider filtering.
assert_nil LlmUsage.calculate_cost(
model: "anthropic.claude-sonnet-4-5-20250929-v1:0",
prompt_tokens: 1000,
completion_tokens: 500
)
end
test "calculate_cost returns Anthropic pricing for Claude models" do
cost = LlmUsage.calculate_cost(model: "claude-sonnet-4-6", prompt_tokens: 1_000_000, completion_tokens: 100_000)
# 1M input * $3/MTok + 100K output * $15/MTok = $3.00 + $1.50 = $4.50
assert_in_delta 4.5, cost, 0.0001
end
test "calculate_cost uses higher pricing for Opus" do
cost = LlmUsage.calculate_cost(model: "claude-opus-4-7", prompt_tokens: 1_000_000, completion_tokens: 0)
# 1M input * $15/MTok = $15.00
assert_in_delta 15.0, cost, 0.0001
end
test "calculate_cost uses lower pricing for Haiku" do
cost = LlmUsage.calculate_cost(model: "claude-haiku-4-5", prompt_tokens: 1_000_000, completion_tokens: 1_000_000)
# $1 in + $5 out = $6.00
assert_in_delta 6.0, cost, 0.0001
end
end