-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathmodels_test.ts
More file actions
136 lines (119 loc) · 3.54 KB
/
Copy pathmodels_test.ts
File metadata and controls
136 lines (119 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
61
62
63
64
65
66
67
68
69
70
71
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import { assertEquals, assertThrows } from "@std/assert"
import { ValidationError } from "@cliffy/command"
import { getCost, type Model, models, resolveModel } from "./models.ts"
const testModels: Model[] = [
{
provider: "test",
key: "vendor-alpha-pro",
id: "alpha-pro",
input: 1,
output: 1,
},
{
provider: "test",
key: "vendor-alpha-fast",
id: "alpha-fast",
input: 1,
output: 1,
},
{
provider: "test",
key: "vendor-alpha",
id: "alpha",
default: true,
input: 1,
output: 1,
},
]
function resolveTestModel(modelArg: string | undefined) {
return resolveModel(modelArg, testModels)
}
// getCost tests
Deno.test("getCost - basic calculation without caching", () => {
const model: Model = {
provider: "test",
key: "test-model",
id: "test",
input: 3, // $3 per million
output: 15, // $15 per million
}
const tokens = { input: 1000, output: 500 }
// (3 * 1000 + 15 * 500) / 1_000_000 = 10500 / 1_000_000 = 0.0105
assertEquals(getCost(model, tokens), 0.0105)
})
Deno.test("getCost - with cache hit pricing", () => {
const model: Model = {
provider: "test",
key: "test-model",
id: "test",
input: 3,
input_cached: 0.3,
output: 15,
}
const tokens = { input: 1000, input_cache_hit: 800, output: 500 }
// cached: 0.3 * 800 = 240
// uncached: 3 * (1000 - 800) = 600
// output: 15 * 500 = 7500
// total: (240 + 600 + 7500) / 1_000_000 = 0.00834
assertEquals(getCost(model, tokens), 0.00834)
})
Deno.test("getCost - cache hit but no cached pricing uses regular input price", () => {
const model: Model = {
provider: "test",
key: "test-model",
id: "test",
input: 3,
output: 15,
// no input_cached price
}
const tokens = { input: 1000, input_cache_hit: 800, output: 500 }
// Falls back to regular calculation since no input_cached price
// (3 * 1000 + 15 * 500) / 1_000_000 = 0.0105
assertEquals(getCost(model, tokens), 0.0105)
})
Deno.test("getCost - zero tokens", () => {
const model: Model = {
provider: "test",
key: "test-model",
id: "test",
input: 3,
output: 15,
}
const tokens = { input: 0, output: 0 }
assertEquals(getCost(model, tokens), 0)
})
// resolveModel tests
Deno.test("resolveModel - returns default when undefined", () => {
assertEquals(resolveTestModel(undefined), testModels[2])
})
Deno.test("resolveModel - exact match on id", () => {
assertEquals(resolveTestModel("alpha"), testModels[2])
})
Deno.test("resolveModel - exact match on key", () => {
assertEquals(resolveTestModel("vendor-alpha"), testModels[2])
})
Deno.test("resolveModel - substring match on id", () => {
assertEquals(resolveTestModel("alpha-"), testModels[0])
})
Deno.test("resolveModel - substring match on key", () => {
assertEquals(resolveTestModel("vendor-alpha-"), testModels[0])
})
Deno.test("resolveModel - case insensitive", () => {
assertEquals(resolveTestModel("ALPHA-"), testModels[0])
})
Deno.test("resolveModel - throws on unknown model", () => {
assertThrows(
() => resolveTestModel("nonexistent-model-xyz"),
ValidationError,
"not found",
)
})
Deno.test("Must have exactly one default model", () => {
assertEquals(models.filter((m) => m.default).length, 1)
})
// Modules that resolve hard-coded aliases at module scope (like
// resolveModel("flash") in summarize.ts) throw on import if catalog churn
// makes the alias stop matching. Importing them here catches that.
Deno.test("modules with hard-coded model aliases import cleanly", async () => {
await import("./summarize.ts")
})