|
|
@@ -1758,6 +1758,101 @@ describe("SessionNs.getUsage", () => {
|
|
|
expect(result.cost).toBe(3 + 1.5)
|
|
|
})
|
|
|
|
|
|
+ test("uses matching context cost tier before over-200k fallback", () => {
|
|
|
+ const model = createModel({
|
|
|
+ context: 1_000_000,
|
|
|
+ output: 32_000,
|
|
|
+ cost: {
|
|
|
+ input: 1,
|
|
|
+ output: 2,
|
|
|
+ cache: { read: 0.1, write: 0.5 },
|
|
|
+ tiers: [
|
|
|
+ {
|
|
|
+ input: 3,
|
|
|
+ output: 4,
|
|
|
+ cache: { read: 0.3, write: 1.5 },
|
|
|
+ tier: { type: "context", size: 200_000 },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ input: 5,
|
|
|
+ output: 6,
|
|
|
+ cache: { read: 0.5, write: 2.5 },
|
|
|
+ tier: { type: "context", size: 500_000 },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ experimentalOver200K: {
|
|
|
+ input: 100,
|
|
|
+ output: 100,
|
|
|
+ cache: { read: 100, write: 100 },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const result = SessionNs.getUsage({
|
|
|
+ model,
|
|
|
+ usage: {
|
|
|
+ inputTokens: 650_000,
|
|
|
+ outputTokens: 100_000,
|
|
|
+ totalTokens: 750_000,
|
|
|
+ inputTokenDetails: {
|
|
|
+ noCacheTokens: undefined,
|
|
|
+ cacheReadTokens: 100_000,
|
|
|
+ cacheWriteTokens: undefined,
|
|
|
+ },
|
|
|
+ outputTokenDetails: {
|
|
|
+ textTokens: undefined,
|
|
|
+ reasoningTokens: undefined,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ })
|
|
|
+
|
|
|
+ expect(result.tokens.input).toBe(550_000)
|
|
|
+ expect(result.cost).toBe(2.75 + 0.6 + 0.05)
|
|
|
+ })
|
|
|
+
|
|
|
+ test("falls back to over-200k pricing when no cost tier matches", () => {
|
|
|
+ const model = createModel({
|
|
|
+ context: 1_000_000,
|
|
|
+ output: 32_000,
|
|
|
+ cost: {
|
|
|
+ input: 1,
|
|
|
+ output: 2,
|
|
|
+ cache: { read: 0.1, write: 0.5 },
|
|
|
+ tiers: [
|
|
|
+ {
|
|
|
+ input: 5,
|
|
|
+ output: 6,
|
|
|
+ cache: { read: 0.5, write: 2.5 },
|
|
|
+ tier: { type: "context", size: 500_000 },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ experimentalOver200K: {
|
|
|
+ input: 3,
|
|
|
+ output: 4,
|
|
|
+ cache: { read: 0.3, write: 1.5 },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const result = SessionNs.getUsage({
|
|
|
+ model,
|
|
|
+ usage: {
|
|
|
+ inputTokens: 300_000,
|
|
|
+ outputTokens: 100_000,
|
|
|
+ totalTokens: 400_000,
|
|
|
+ inputTokenDetails: {
|
|
|
+ noCacheTokens: undefined,
|
|
|
+ cacheReadTokens: undefined,
|
|
|
+ cacheWriteTokens: undefined,
|
|
|
+ },
|
|
|
+ outputTokenDetails: {
|
|
|
+ textTokens: undefined,
|
|
|
+ reasoningTokens: undefined,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ })
|
|
|
+
|
|
|
+ expect(result.cost).toBe(0.9 + 0.4)
|
|
|
+ })
|
|
|
+
|
|
|
test.each(["@ai-sdk/anthropic", "@ai-sdk/amazon-bedrock", "@ai-sdk/google-vertex/anthropic"])(
|
|
|
"computes total from components for %s models",
|
|
|
(npm) => {
|