-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathllm-cost.mjs
More file actions
47 lines (42 loc) · 2.17 KB
/
Copy pathllm-cost.mjs
File metadata and controls
47 lines (42 loc) · 2.17 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
// llm-cost — estimate the USD cost of an LLM call across the four token
// classes (input, output, cache-write, cache-read). Pure calculator, no I/O.
// MIT © 2026 Gus IT LLC · https://github.com/gusitllc/luca-community
//
// Prices drift constantly — pass your own rate table. The bundled DEFAULT_RATES
// are illustrative USD-per-million-tokens and WILL go stale; treat as a starting
// point, not a source of truth.
import { pathToFileURL } from "node:url";
/** @typedef {{in:number, out:number, cacheWrite?:number, cacheRead?:number}} Rate // USD per 1M tokens */
/** Illustrative rates (USD / 1M tokens). Update to your provider's current pricing. */
export const DEFAULT_RATES = /** @type {Record<string, Rate>} */ ({
'generic-small': { in: 0.5, out: 1.5, cacheWrite: 0.6, cacheRead: 0.05 },
'generic-mid': { in: 3, out: 15, cacheWrite: 3.75, cacheRead: 0.3 },
'generic-large': { in: 15, out: 75, cacheWrite: 18.75, cacheRead: 1.5 },
});
/**
* Estimate cost in USD for a set of token counts under a rate.
* @param {{input?:number, output?:number, cacheWrite?:number, cacheRead?:number}} usage - token counts
* @param {Rate|string} rate - a Rate object, or a key into `rates`
* @param {Record<string,Rate>} [rates=DEFAULT_RATES]
* @returns {{usd:number, breakdown:Record<string,number>}}
*/
export function estimateCost(usage, rate, rates = DEFAULT_RATES) {
const r = typeof rate === 'string' ? rates[rate] : rate;
if (!r) throw new Error(`llm-cost: unknown rate "${rate}"`);
const per = (tokens, price) => ((tokens || 0) / 1_000_000) * (price || 0);
const breakdown = {
input: per(usage.input, r.in),
output: per(usage.output, r.out),
cacheWrite: per(usage.cacheWrite, r.cacheWrite),
cacheRead: per(usage.cacheRead, r.cacheRead),
};
const usd = round6(Object.values(breakdown).reduce((a, b) => a + b, 0));
return { usd, breakdown };
}
const round6 = (n) => Math.round(n * 1e6) / 1e6;
// --- self-test ---
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
const { usd } = estimateCost({ input: 1_000_000, output: 1_000_000 }, 'generic-mid');
console.assert(usd === 18, `expected 18 got ${usd}`); // 3 + 15
console.log('llm-cost OK', usd);
}