Skip to content

Commit 68a23cc

Browse files
Bedrock specific cost calculation, including support for intelligent prompt routing
1 parent 77186e8 commit 68a23cc

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import { getCost } from "../cost"
2+
3+
describe("getCost", () => {
4+
it("should return the correct cost for Bedrock provider with invokedModelId", () => {
5+
// For 1000 tokens with 25% input (250) and 75% output (750)
6+
// Claude-3-5-sonnet: (0.003/1000 * 250) + (0.015/1000 * 750) = 0.00075 + 0.01125 = 0.012
7+
const cost = getCost("bedrock", "test prompt", "gpt-3.5-turbo", 1000, "claude-3-5-sonnet")
8+
expect(cost).toBeCloseTo(0.012, 5)
9+
})
10+
11+
it("should return 0 for Bedrock provider without invokedModelId", () => {
12+
// Since GPT models are not supported on Bedrock and we've removed the fallback,
13+
// this should return 0
14+
const cost = getCost("bedrock", "test prompt", "any-model", 1000)
15+
expect(cost).toBe(0)
16+
})
17+
18+
it("should return 0 for unknown provider", () => {
19+
const cost = getCost("unknown" as any, "test prompt", "gpt-3.5-turbo", 1000)
20+
expect(cost).toBe(0)
21+
})
22+
23+
it("should use provided input and output tokens when available", () => {
24+
// For specific input (300) and output (700) tokens
25+
// Claude-3-5-sonnet: (0.003/1000 * 300) + (0.015/1000 * 700) = 0.0009 + 0.0105 = 0.0114
26+
const cost = getCost("bedrock", "test prompt", "gpt-3.5-turbo", 1000, "claude-3-5-sonnet", 300, 700)
27+
expect(cost).toBeCloseTo(0.0114, 5)
28+
})
29+
30+
it("should handle cache write and cache read tokens", () => {
31+
// For specific input (300), output (700), cache write (200), and cache read (100) tokens
32+
// Claude-3-5-sonnet:
33+
// Input: (0.003/1000 * 300) = 0.0009
34+
// Output: (0.015/1000 * 700) = 0.0105
35+
// Cache Write: (0.00375/1000 * 200) = 0.00075
36+
// Cache Read: (0.0003/1000 * 100) = 0.00003
37+
// Total: 0.0009 + 0.0105 + 0.00075 + 0.00003 = 0.01218
38+
const cost = getCost("bedrock", "test prompt", "gpt-3.5-turbo", 1000, "claude-3-5-sonnet", 300, 700, 200, 100)
39+
expect(cost).toBeCloseTo(0.01218, 5)
40+
})
41+
42+
it("should handle models without cache pricing", () => {
43+
// For specific input (300), output (700), cache write (200), and cache read (100) tokens
44+
// Claude-3-opus:
45+
// Input: (0.015/1000 * 300) = 0.0045
46+
// Output: (0.075/1000 * 700) = 0.0525
47+
// Cache Write: (0/1000 * 200) = 0
48+
// Cache Read: (0/1000 * 100) = 0
49+
// Total: 0.0045 + 0.0525 + 0 + 0 = 0.057
50+
const cost = getCost("bedrock", "test prompt", "gpt-3.5-turbo", 1000, "claude-3-opus", 300, 700, 200, 100)
51+
expect(cost).toBeCloseTo(0.057, 5)
52+
})
53+
})
54+
55+
describe("getBedrockCost", () => {
56+
it("should return the correct cost for claude-3-5-sonnet", () => {
57+
// For 1000 tokens with 25% input (250) and 75% output (750)
58+
// Claude-3-5-sonnet: (0.003/1000 * 250) + (0.015/1000 * 750) = 0.00075 + 0.01125 = 0.012
59+
const cost = getCost("bedrock", "test prompt", "any-model", 1000, "claude-3-5-sonnet")
60+
expect(cost).toBeCloseTo(0.012, 5)
61+
})
62+
63+
// GPT model tests removed as they are not supported on Bedrock
64+
65+
it("should return 0 for unknown invokedModelId", () => {
66+
const cost = getCost("bedrock", "test prompt", "any-model", 1000, "unknown-model")
67+
expect(cost).toBe(0)
68+
})
69+
70+
it("should return 0 when invokedModelId is not provided", () => {
71+
// Since we've removed the fallback to model-based cost calculation,
72+
// this should return 0
73+
const cost = getCost("bedrock", "test prompt", "any-model", 1000)
74+
expect(cost).toBe(0)
75+
})
76+
77+
it("should handle intelligent prompt router ARN format", () => {
78+
// Test with a full ARN from an intelligent prompt router
79+
// For 1000 tokens with 25% input (250) and 75% output (750)
80+
// Claude-3-5-sonnet: (0.003/1000 * 250) + (0.015/1000 * 750) = 0.00075 + 0.01125 = 0.012
81+
const cost = getCost(
82+
"bedrock",
83+
"test prompt",
84+
"custom-arn",
85+
1000,
86+
"arn:aws:bedrock:us-west-2:699475926481:inference-profile/us.anthropic.claude-3-5-sonnet-20240620-v1:0",
87+
)
88+
expect(cost).toBeCloseTo(0.012, 5)
89+
})
90+
91+
it("should return the correct cost for Amazon Nova Pro", () => {
92+
// For 1000 tokens with 25% input (250) and 75% output (750)
93+
// Amazon Nova Pro: (0.0008/1000 * 250) + (0.0032/1000 * 750) = 0.0002 + 0.0024 = 0.0026
94+
const cost = getCost("bedrock", "test prompt", "any-model", 1000, "amazon.nova-pro")
95+
expect(cost).toBeCloseTo(0.0026, 5)
96+
})
97+
98+
it("should return the correct cost for Amazon Nova Micro", () => {
99+
// For 1000 tokens with 25% input (250) and 75% output (750)
100+
// Amazon Nova Micro: (0.000035/1000 * 250) + (0.00014/1000 * 750) = 0.00000875 + 0.000105 = 0.00011375
101+
const cost = getCost("bedrock", "test prompt", "any-model", 1000, "amazon.nova-micro")
102+
expect(cost).toBeCloseTo(0.00011375, 8)
103+
})
104+
105+
it("should return the correct cost for Amazon Titan Text Express", () => {
106+
// For 1000 tokens with 25% input (250) and 75% output (750)
107+
// Amazon Titan Text Express: (0.0002/1000 * 250) + (0.0006/1000 * 750) = 0.00005 + 0.00045 = 0.0005
108+
const cost = getCost("bedrock", "test prompt", "any-model", 1000, "amazon.titan-text-express")
109+
expect(cost).toBeCloseTo(0.0005, 5)
110+
})
111+
112+
it("should return the correct cost for Amazon Titan Text Lite", () => {
113+
// For 1000 tokens with 25% input (250) and 75% output (750)
114+
// Amazon Titan Text Lite: (0.00015/1000 * 250) + (0.0002/1000 * 750) = 0.0000375 + 0.00015 = 0.0001875
115+
const cost = getCost("bedrock", "test prompt", "any-model", 1000, "amazon.titan-text-lite")
116+
expect(cost).toBeCloseTo(0.0001875, 7)
117+
})
118+
119+
it("should return the correct cost for Amazon Titan Text Embeddings", () => {
120+
// For embeddings, with the default 1:3 input/output split (250 input, 750 output)
121+
// Amazon Titan Text Embeddings: (0.0001/1000 * 250) = 0.000025
122+
// Note: Even though embeddings don't have output tokens, the getCost function
123+
// still splits tokens using a 1:3 ratio by default
124+
const cost = getCost("bedrock", "test prompt", "any-model", 1000, "amazon.titan-text-embeddings")
125+
expect(cost).toBeCloseTo(0.000025, 6)
126+
})
127+
128+
it("should return the correct cost for Llama 3.2 (11B)", () => {
129+
// For 1000 tokens with 25% input (250) and 75% output (750)
130+
// Llama 3.2 (11B): (0.00016/1000 * 250) + (0.00016/1000 * 750) = 0.00004 + 0.00012 = 0.00016
131+
const cost = getCost("bedrock", "test prompt", "any-model", 1000, "llama-3.2-11b")
132+
expect(cost).toBeCloseTo(0.00016, 6)
133+
})
134+
135+
it("should return the correct cost for Llama 3.2 (90B)", () => {
136+
// For 1000 tokens with 25% input (250) and 75% output (750)
137+
// Llama 3.2 (90B): (0.00072/1000 * 250) + (0.00072/1000 * 750) = 0.00018 + 0.00054 = 0.00072
138+
const cost = getCost("bedrock", "test prompt", "any-model", 1000, "llama-3.2-90b")
139+
expect(cost).toBeCloseTo(0.00072, 6)
140+
})
141+
142+
it("should return the correct cost for Llama 3.3 (70B)", () => {
143+
// For 1000 tokens with 25% input (250) and 75% output (750)
144+
// Llama 3.3 (70B): (0.00072/1000 * 250) + (0.00072/1000 * 750) = 0.00018 + 0.00054 = 0.00072
145+
const cost = getCost("bedrock", "test prompt", "any-model", 1000, "llama-3.3-70b")
146+
expect(cost).toBeCloseTo(0.00072, 6)
147+
})
148+
})

0 commit comments

Comments
 (0)