ccusage 15.9.1 → 15.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_token-utils-WjkbrjKv.js +1 -8
- package/dist/{_types-B-1t4mxD.js → _types-C0oFKDO-.js} +497 -1082
- package/dist/calculate-cost-BDqO4yWA.js +0 -10
- package/dist/calculate-cost.d.ts +2 -2
- package/dist/calculate-cost.js +1 -1
- package/dist/{data-loader-PvTcFbip.d.ts → data-loader-B2FL7oh0.d.ts} +2 -2
- package/dist/{data-loader-D3wQxjrt.js → data-loader-B_nfl1Pr.js} +455 -1870
- package/dist/data-loader.d.ts +2 -2
- package/dist/data-loader.js +4 -4
- package/dist/debug-BoSgT8lp.js +109 -0
- package/dist/debug.js +5 -5
- package/dist/index.js +851 -2236
- package/dist/{logger-BODy31tA.js → logger-L_zzb0iT.js} +70 -267
- package/dist/logger.js +1 -1
- package/dist/{mcp-opivOm8q.js → mcp-Bqi6ayed.js} +1343 -4013
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.js +5 -5
- package/dist/{pricing-fetcher-C9P2YKDv.d.ts → pricing-fetcher-B5m_kEpz.d.ts} +1 -1
- package/dist/pricing-fetcher-ZrH9X6Xp.js +342 -0
- package/dist/pricing-fetcher.d.ts +1 -1
- package/dist/pricing-fetcher.js +3 -3
- package/dist/{prompt-lm8M58zJ.js → prompt-DsUFNEY7.js} +25 -49
- package/package.json +1 -1
- package/dist/debug-Dz_xcM_P.js +0 -162
- package/dist/pricing-fetcher-DtGb7sbF.js +0 -575
|
@@ -1,575 +0,0 @@
|
|
|
1
|
-
import { modelPricingSchema } from "./_types-B-1t4mxD.js";
|
|
2
|
-
import { logger } from "./logger-BODy31tA.js";
|
|
3
|
-
import { createRequire } from "node:module";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import F, { homedir } from "node:os";
|
|
6
|
-
var __create = Object.create;
|
|
7
|
-
var __defProp = Object.defineProperty;
|
|
8
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
11
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
|
-
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
13
|
-
var __copyProps = (to, from, except, desc) => {
|
|
14
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
15
|
-
key = keys[i];
|
|
16
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
17
|
-
get: ((k) => from[k]).bind(null, key),
|
|
18
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
return to;
|
|
22
|
-
};
|
|
23
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
24
|
-
value: mod,
|
|
25
|
-
enumerable: true
|
|
26
|
-
}) : target, mod));
|
|
27
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
28
|
-
const isFailure = (result) => "Failure" === result.type;
|
|
29
|
-
const isPromise = (value) => "object" == typeof value && null !== value && "then" in value && "function" == typeof value.then && "catch" in value && "function" == typeof value.catch;
|
|
30
|
-
const andThen = (fn) => (result) => {
|
|
31
|
-
const apply = (r) => {
|
|
32
|
-
if (isFailure(r)) return r;
|
|
33
|
-
return fn(r.value);
|
|
34
|
-
};
|
|
35
|
-
return isPromise(result) ? result.then(apply) : apply(result);
|
|
36
|
-
};
|
|
37
|
-
const andThrough = (fn) => (result) => {
|
|
38
|
-
const apply = (r) => {
|
|
39
|
-
if (isFailure(r)) return r;
|
|
40
|
-
const next = fn(r.value);
|
|
41
|
-
if (isPromise(next)) return next.then((n) => {
|
|
42
|
-
if (isFailure(n)) return n;
|
|
43
|
-
return r;
|
|
44
|
-
});
|
|
45
|
-
if (isFailure(next)) return next;
|
|
46
|
-
return r;
|
|
47
|
-
};
|
|
48
|
-
return isPromise(result) ? result.then(apply) : apply(result);
|
|
49
|
-
};
|
|
50
|
-
const isSuccess = (result) => "Success" === result.type;
|
|
51
|
-
const succeed = (...args) => {
|
|
52
|
-
const value = args[0];
|
|
53
|
-
if (void 0 === value) return { type: "Success" };
|
|
54
|
-
if (isPromise(value)) return value.then((value$1) => ({
|
|
55
|
-
type: "Success",
|
|
56
|
-
value: value$1
|
|
57
|
-
}));
|
|
58
|
-
return {
|
|
59
|
-
type: "Success",
|
|
60
|
-
value
|
|
61
|
-
};
|
|
62
|
-
};
|
|
63
|
-
const fail = (...args) => {
|
|
64
|
-
const error = args[0];
|
|
65
|
-
if (void 0 === error) return { type: "Failure" };
|
|
66
|
-
if (isPromise(error)) return error.then((error$1) => ({
|
|
67
|
-
type: "Failure",
|
|
68
|
-
error: error$1
|
|
69
|
-
}));
|
|
70
|
-
return {
|
|
71
|
-
type: "Failure",
|
|
72
|
-
error
|
|
73
|
-
};
|
|
74
|
-
};
|
|
75
|
-
const inspect = (fn) => (result) => {
|
|
76
|
-
const apply = (r) => {
|
|
77
|
-
if (isSuccess(r)) fn(r.value);
|
|
78
|
-
return r;
|
|
79
|
-
};
|
|
80
|
-
return isPromise(result) ? result.then(apply) : apply(result);
|
|
81
|
-
};
|
|
82
|
-
const inspectError = (fn) => (result) => {
|
|
83
|
-
const apply = (r) => {
|
|
84
|
-
if (isFailure(r)) fn(r.error);
|
|
85
|
-
return r;
|
|
86
|
-
};
|
|
87
|
-
return isPromise(result) ? result.then(apply) : apply(result);
|
|
88
|
-
};
|
|
89
|
-
const map = (fn) => (result) => {
|
|
90
|
-
const apply = (r) => {
|
|
91
|
-
if (isFailure(r)) return r;
|
|
92
|
-
return succeed(fn(r.value));
|
|
93
|
-
};
|
|
94
|
-
if (isPromise(result)) return result.then(apply);
|
|
95
|
-
return apply(result);
|
|
96
|
-
};
|
|
97
|
-
const orElse = (fn) => (result) => {
|
|
98
|
-
const apply = (r) => {
|
|
99
|
-
if (isSuccess(r)) return r;
|
|
100
|
-
return fn(r.error);
|
|
101
|
-
};
|
|
102
|
-
return isPromise(result) ? result.then(apply) : apply(result);
|
|
103
|
-
};
|
|
104
|
-
const pipe = (value, ...functions) => {
|
|
105
|
-
let next = value;
|
|
106
|
-
for (const func of functions) next = func(next);
|
|
107
|
-
return next;
|
|
108
|
-
};
|
|
109
|
-
const try_ = (options) => {
|
|
110
|
-
if (isPromise(options.try)) {
|
|
111
|
-
if ("safe" in options && options.safe) return succeed(options.try);
|
|
112
|
-
return options.try.then((value) => succeed(value), (error) => fail(options.catch(error)));
|
|
113
|
-
}
|
|
114
|
-
return (...args) => {
|
|
115
|
-
try {
|
|
116
|
-
const output = options.try(...args);
|
|
117
|
-
if (isPromise(output)) {
|
|
118
|
-
const promise = succeed(output);
|
|
119
|
-
if ("safe" in options && options.safe) return promise;
|
|
120
|
-
return promise.catch((error) => fail(options.catch(error)));
|
|
121
|
-
}
|
|
122
|
-
return succeed(output);
|
|
123
|
-
} catch (error) {
|
|
124
|
-
if ("safe" in options && options.safe) throw error;
|
|
125
|
-
return fail(options.catch(error));
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
};
|
|
129
|
-
const homeDirectory = F.homedir();
|
|
130
|
-
const { env } = process;
|
|
131
|
-
const xdgData = env.XDG_DATA_HOME || (homeDirectory ? path.join(homeDirectory, ".local", "share") : void 0);
|
|
132
|
-
const xdgConfig = env.XDG_CONFIG_HOME || (homeDirectory ? path.join(homeDirectory, ".config") : void 0);
|
|
133
|
-
const xdgState = env.XDG_STATE_HOME || (homeDirectory ? path.join(homeDirectory, ".local", "state") : void 0);
|
|
134
|
-
const xdgCache = env.XDG_CACHE_HOME || (homeDirectory ? path.join(homeDirectory, ".cache") : void 0);
|
|
135
|
-
const xdgRuntime = env.XDG_RUNTIME_DIR || void 0;
|
|
136
|
-
const xdgDataDirectories = (env.XDG_DATA_DIRS || "/usr/local/share/:/usr/share/").split(":");
|
|
137
|
-
if (xdgData) xdgDataDirectories.unshift(xdgData);
|
|
138
|
-
const xdgConfigDirectories = (env.XDG_CONFIG_DIRS || "/etc/xdg").split(":");
|
|
139
|
-
if (xdgConfig) xdgConfigDirectories.unshift(xdgConfig);
|
|
140
|
-
/**
|
|
141
|
-
* URL for LiteLLM's model pricing and context window data
|
|
142
|
-
*/
|
|
143
|
-
const LITELLM_PRICING_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
|
|
144
|
-
/**
|
|
145
|
-
* Default number of recent days to include when filtering blocks
|
|
146
|
-
* Used in both session blocks and commands for consistent behavior
|
|
147
|
-
*/
|
|
148
|
-
const DEFAULT_RECENT_DAYS = 3;
|
|
149
|
-
/**
|
|
150
|
-
* Threshold percentage for showing usage warnings in blocks command (80%)
|
|
151
|
-
* When usage exceeds this percentage of limits, warnings are displayed
|
|
152
|
-
*/
|
|
153
|
-
const BLOCKS_WARNING_THRESHOLD = .8;
|
|
154
|
-
/**
|
|
155
|
-
* Terminal width threshold for switching to compact display mode in blocks command
|
|
156
|
-
* Below this width, tables use more compact formatting
|
|
157
|
-
*/
|
|
158
|
-
const BLOCKS_COMPACT_WIDTH_THRESHOLD = 120;
|
|
159
|
-
/**
|
|
160
|
-
* Default terminal width when stdout.columns is not available in blocks command
|
|
161
|
-
* Used as fallback for responsive table formatting
|
|
162
|
-
*/
|
|
163
|
-
const BLOCKS_DEFAULT_TERMINAL_WIDTH = 120;
|
|
164
|
-
/**
|
|
165
|
-
* Threshold percentage for considering costs as matching (0.1% tolerance)
|
|
166
|
-
* Used in debug cost validation to allow for minor calculation differences
|
|
167
|
-
*/
|
|
168
|
-
const DEBUG_MATCH_THRESHOLD_PERCENT = .1;
|
|
169
|
-
/**
|
|
170
|
-
* User's home directory path
|
|
171
|
-
* Centralized access to OS home directory for consistent path building
|
|
172
|
-
*/
|
|
173
|
-
const USER_HOME_DIR = homedir();
|
|
174
|
-
/**
|
|
175
|
-
* XDG config directory path
|
|
176
|
-
* Uses XDG_CONFIG_HOME if set, otherwise falls back to ~/.config
|
|
177
|
-
*/
|
|
178
|
-
const XDG_CONFIG_DIR = xdgConfig ?? `${USER_HOME_DIR}/.config`;
|
|
179
|
-
/**
|
|
180
|
-
* Default Claude data directory path (~/.claude)
|
|
181
|
-
* Used as base path for loading usage data from JSONL files
|
|
182
|
-
*/
|
|
183
|
-
const DEFAULT_CLAUDE_CODE_PATH = ".claude";
|
|
184
|
-
/**
|
|
185
|
-
* Default Claude data directory path using XDG config directory
|
|
186
|
-
* Uses XDG_CONFIG_HOME if set, otherwise falls back to ~/.config/claude
|
|
187
|
-
*/
|
|
188
|
-
const DEFAULT_CLAUDE_CONFIG_PATH = `${XDG_CONFIG_DIR}/claude`;
|
|
189
|
-
/**
|
|
190
|
-
* Environment variable for specifying multiple Claude data directories
|
|
191
|
-
* Supports comma-separated paths for multiple locations
|
|
192
|
-
*/
|
|
193
|
-
const CLAUDE_CONFIG_DIR_ENV = "CLAUDE_CONFIG_DIR";
|
|
194
|
-
/**
|
|
195
|
-
* Environment variable for custom project name aliases
|
|
196
|
-
*
|
|
197
|
-
* Allows users to configure readable display names for cryptic or long project directory names.
|
|
198
|
-
* This is particularly useful for:
|
|
199
|
-
* - UUID-based project directories generated by Claude Code
|
|
200
|
-
* - Long path-based project names that are hard to read in tables
|
|
201
|
-
* - Custom branding of project names for organizational consistency
|
|
202
|
-
*
|
|
203
|
-
* Format: "raw-name=alias,another-name=other-alias"
|
|
204
|
-
* Example: "a2cd99ed-a586-4fe4-8f59-b0026409ec09=My Project,long-project-name=Short"
|
|
205
|
-
*
|
|
206
|
-
* Environment variable approach is used because:
|
|
207
|
-
* - No config file needed - simple and lightweight configuration
|
|
208
|
-
* - Works in any shell/environment without file management
|
|
209
|
-
* - Easy to set temporarily for specific invocations
|
|
210
|
-
* - Follows Unix conventions for tool configuration
|
|
211
|
-
* - Doesn't require file system permissions or config directory setup
|
|
212
|
-
*
|
|
213
|
-
* Used to override display names for project directories in all output formats.
|
|
214
|
-
*/
|
|
215
|
-
const PROJECT_ALIASES_ENV = "CCUSAGE_PROJECT_ALIASES";
|
|
216
|
-
/**
|
|
217
|
-
* Claude projects directory name within the data directory
|
|
218
|
-
* Contains subdirectories for each project with usage data
|
|
219
|
-
*/
|
|
220
|
-
const CLAUDE_PROJECTS_DIR_NAME = "projects";
|
|
221
|
-
/**
|
|
222
|
-
* JSONL file glob pattern for finding usage data files
|
|
223
|
-
* Used to recursively find all JSONL files in project directories
|
|
224
|
-
*/
|
|
225
|
-
const USAGE_DATA_GLOB_PATTERN = "**/*.jsonl";
|
|
226
|
-
/**
|
|
227
|
-
* Default port for MCP server HTTP transport
|
|
228
|
-
* Used when no port is specified for MCP server communication
|
|
229
|
-
*/
|
|
230
|
-
const MCP_DEFAULT_PORT = 8080;
|
|
231
|
-
/**
|
|
232
|
-
* Default refresh interval in seconds for live monitoring mode
|
|
233
|
-
* Used in blocks command for real-time updates
|
|
234
|
-
*/
|
|
235
|
-
const DEFAULT_REFRESH_INTERVAL_SECONDS = 1;
|
|
236
|
-
/**
|
|
237
|
-
* Minimum refresh interval in seconds for live monitoring mode
|
|
238
|
-
* Prevents too-frequent updates that could impact performance
|
|
239
|
-
*/
|
|
240
|
-
const MIN_REFRESH_INTERVAL_SECONDS = 1;
|
|
241
|
-
/**
|
|
242
|
-
* Maximum refresh interval in seconds for live monitoring mode
|
|
243
|
-
* Prevents too-slow updates that reduce monitoring effectiveness
|
|
244
|
-
*/
|
|
245
|
-
const MAX_REFRESH_INTERVAL_SECONDS = 60;
|
|
246
|
-
/**
|
|
247
|
-
* Frame rate limit for live monitoring (16ms = ~60fps)
|
|
248
|
-
* Prevents terminal flickering and excessive CPU usage during rapid updates
|
|
249
|
-
*/
|
|
250
|
-
const MIN_RENDER_INTERVAL_MS = 16;
|
|
251
|
-
/**
|
|
252
|
-
* Burn rate thresholds for indicator display (tokens per minute)
|
|
253
|
-
*/
|
|
254
|
-
const BURN_RATE_THRESHOLDS = {
|
|
255
|
-
HIGH: 1e3,
|
|
256
|
-
MODERATE: 500
|
|
257
|
-
};
|
|
258
|
-
/**
|
|
259
|
-
* Days of the week for weekly aggregation
|
|
260
|
-
*/
|
|
261
|
-
const WEEK_DAYS = [
|
|
262
|
-
"sunday",
|
|
263
|
-
"monday",
|
|
264
|
-
"tuesday",
|
|
265
|
-
"wednesday",
|
|
266
|
-
"thursday",
|
|
267
|
-
"friday",
|
|
268
|
-
"saturday"
|
|
269
|
-
];
|
|
270
|
-
var require_usingCtx = __commonJSMin((exports, module) => {
|
|
271
|
-
function _usingCtx() {
|
|
272
|
-
var r = "function" == typeof SuppressedError ? SuppressedError : function(r$1, e$1) {
|
|
273
|
-
var n$1 = Error();
|
|
274
|
-
return n$1.name = "SuppressedError", n$1.error = r$1, n$1.suppressed = e$1, n$1;
|
|
275
|
-
}, e = {}, n = [];
|
|
276
|
-
function using(r$1, e$1) {
|
|
277
|
-
if (null != e$1) {
|
|
278
|
-
if (Object(e$1) !== e$1) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
|
|
279
|
-
if (r$1) var o = e$1[Symbol.asyncDispose || Symbol["for"]("Symbol.asyncDispose")];
|
|
280
|
-
if (void 0 === o && (o = e$1[Symbol.dispose || Symbol["for"]("Symbol.dispose")], r$1)) var t = o;
|
|
281
|
-
if ("function" != typeof o) throw new TypeError("Object is not disposable.");
|
|
282
|
-
t && (o = function o$1() {
|
|
283
|
-
try {
|
|
284
|
-
t.call(e$1);
|
|
285
|
-
} catch (r$2) {
|
|
286
|
-
return Promise.reject(r$2);
|
|
287
|
-
}
|
|
288
|
-
}), n.push({
|
|
289
|
-
v: e$1,
|
|
290
|
-
d: o,
|
|
291
|
-
a: r$1
|
|
292
|
-
});
|
|
293
|
-
} else r$1 && n.push({
|
|
294
|
-
d: e$1,
|
|
295
|
-
a: r$1
|
|
296
|
-
});
|
|
297
|
-
return e$1;
|
|
298
|
-
}
|
|
299
|
-
return {
|
|
300
|
-
e,
|
|
301
|
-
u: using.bind(null, !1),
|
|
302
|
-
a: using.bind(null, !0),
|
|
303
|
-
d: function d() {
|
|
304
|
-
var o, t = this.e, s = 0;
|
|
305
|
-
function next() {
|
|
306
|
-
for (; o = n.pop();) try {
|
|
307
|
-
if (!o.a && 1 === s) return s = 0, n.push(o), Promise.resolve().then(next);
|
|
308
|
-
if (o.d) {
|
|
309
|
-
var r$1 = o.d.call(o.v);
|
|
310
|
-
if (o.a) return s |= 2, Promise.resolve(r$1).then(next, err);
|
|
311
|
-
} else s |= 1;
|
|
312
|
-
} catch (r$2) {
|
|
313
|
-
return err(r$2);
|
|
314
|
-
}
|
|
315
|
-
if (1 === s) return t !== e ? Promise.reject(t) : Promise.resolve();
|
|
316
|
-
if (t !== e) throw t;
|
|
317
|
-
}
|
|
318
|
-
function err(n$1) {
|
|
319
|
-
return t = t !== e ? new r(n$1, t) : n$1, next();
|
|
320
|
-
}
|
|
321
|
-
return next();
|
|
322
|
-
}
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
module.exports = _usingCtx, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
|
326
|
-
});
|
|
327
|
-
var import_usingCtx = __toESM(require_usingCtx(), 1);
|
|
328
|
-
/**
|
|
329
|
-
* Fetches and caches model pricing information from LiteLLM
|
|
330
|
-
* Implements Disposable pattern for automatic resource cleanup
|
|
331
|
-
*/
|
|
332
|
-
var PricingFetcher = class {
|
|
333
|
-
cachedPricing = null;
|
|
334
|
-
offline;
|
|
335
|
-
/**
|
|
336
|
-
* Creates a new PricingFetcher instance
|
|
337
|
-
* @param offline - Whether to use pre-fetched pricing data instead of fetching from API
|
|
338
|
-
*/
|
|
339
|
-
constructor(offline = false) {
|
|
340
|
-
this.offline = offline;
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* Implements Disposable interface for automatic cleanup
|
|
344
|
-
*/
|
|
345
|
-
[Symbol.dispose]() {
|
|
346
|
-
this.clearCache();
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* Clears the cached pricing data
|
|
350
|
-
*/
|
|
351
|
-
clearCache() {
|
|
352
|
-
this.cachedPricing = null;
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Loads offline pricing data from pre-fetched cache
|
|
356
|
-
* @returns Map of model names to pricing information
|
|
357
|
-
*/
|
|
358
|
-
loadOfflinePricing = try_({
|
|
359
|
-
try: async () => {
|
|
360
|
-
const pricing = new Map(Object.entries({
|
|
361
|
-
"claude-3-haiku-20240307": {
|
|
362
|
-
"input_cost_per_token": 25e-8,
|
|
363
|
-
"output_cost_per_token": 125e-8,
|
|
364
|
-
"cache_creation_input_token_cost": 3e-7,
|
|
365
|
-
"cache_read_input_token_cost": 3e-8
|
|
366
|
-
},
|
|
367
|
-
"claude-3-5-haiku-20241022": {
|
|
368
|
-
"input_cost_per_token": 8e-7,
|
|
369
|
-
"output_cost_per_token": 4e-6,
|
|
370
|
-
"cache_creation_input_token_cost": 1e-6,
|
|
371
|
-
"cache_read_input_token_cost": 8e-8
|
|
372
|
-
},
|
|
373
|
-
"claude-3-5-haiku-latest": {
|
|
374
|
-
"input_cost_per_token": 1e-6,
|
|
375
|
-
"output_cost_per_token": 5e-6,
|
|
376
|
-
"cache_creation_input_token_cost": 125e-8,
|
|
377
|
-
"cache_read_input_token_cost": 1e-7
|
|
378
|
-
},
|
|
379
|
-
"claude-3-opus-latest": {
|
|
380
|
-
"input_cost_per_token": 15e-6,
|
|
381
|
-
"output_cost_per_token": 75e-6,
|
|
382
|
-
"cache_creation_input_token_cost": 1875e-8,
|
|
383
|
-
"cache_read_input_token_cost": 15e-7
|
|
384
|
-
},
|
|
385
|
-
"claude-3-opus-20240229": {
|
|
386
|
-
"input_cost_per_token": 15e-6,
|
|
387
|
-
"output_cost_per_token": 75e-6,
|
|
388
|
-
"cache_creation_input_token_cost": 1875e-8,
|
|
389
|
-
"cache_read_input_token_cost": 15e-7
|
|
390
|
-
},
|
|
391
|
-
"claude-3-5-sonnet-latest": {
|
|
392
|
-
"input_cost_per_token": 3e-6,
|
|
393
|
-
"output_cost_per_token": 15e-6,
|
|
394
|
-
"cache_creation_input_token_cost": 375e-8,
|
|
395
|
-
"cache_read_input_token_cost": 3e-7
|
|
396
|
-
},
|
|
397
|
-
"claude-3-5-sonnet-20240620": {
|
|
398
|
-
"input_cost_per_token": 3e-6,
|
|
399
|
-
"output_cost_per_token": 15e-6,
|
|
400
|
-
"cache_creation_input_token_cost": 375e-8,
|
|
401
|
-
"cache_read_input_token_cost": 3e-7
|
|
402
|
-
},
|
|
403
|
-
"claude-opus-4-20250514": {
|
|
404
|
-
"input_cost_per_token": 15e-6,
|
|
405
|
-
"output_cost_per_token": 75e-6,
|
|
406
|
-
"cache_creation_input_token_cost": 1875e-8,
|
|
407
|
-
"cache_read_input_token_cost": 15e-7
|
|
408
|
-
},
|
|
409
|
-
"claude-opus-4-1": {
|
|
410
|
-
"input_cost_per_token": 15e-6,
|
|
411
|
-
"output_cost_per_token": 75e-6,
|
|
412
|
-
"cache_creation_input_token_cost": 1875e-8,
|
|
413
|
-
"cache_read_input_token_cost": 15e-7
|
|
414
|
-
},
|
|
415
|
-
"claude-opus-4-1-20250805": {
|
|
416
|
-
"input_cost_per_token": 15e-6,
|
|
417
|
-
"output_cost_per_token": 75e-6,
|
|
418
|
-
"cache_creation_input_token_cost": 1875e-8,
|
|
419
|
-
"cache_read_input_token_cost": 15e-7
|
|
420
|
-
},
|
|
421
|
-
"claude-sonnet-4-20250514": {
|
|
422
|
-
"input_cost_per_token": 3e-6,
|
|
423
|
-
"output_cost_per_token": 15e-6,
|
|
424
|
-
"cache_creation_input_token_cost": 375e-8,
|
|
425
|
-
"cache_read_input_token_cost": 3e-7
|
|
426
|
-
},
|
|
427
|
-
"claude-4-opus-20250514": {
|
|
428
|
-
"input_cost_per_token": 15e-6,
|
|
429
|
-
"output_cost_per_token": 75e-6,
|
|
430
|
-
"cache_creation_input_token_cost": 1875e-8,
|
|
431
|
-
"cache_read_input_token_cost": 15e-7
|
|
432
|
-
},
|
|
433
|
-
"claude-4-sonnet-20250514": {
|
|
434
|
-
"input_cost_per_token": 3e-6,
|
|
435
|
-
"output_cost_per_token": 15e-6,
|
|
436
|
-
"cache_creation_input_token_cost": 375e-8,
|
|
437
|
-
"cache_read_input_token_cost": 3e-7
|
|
438
|
-
},
|
|
439
|
-
"claude-3-7-sonnet-latest": {
|
|
440
|
-
"input_cost_per_token": 3e-6,
|
|
441
|
-
"output_cost_per_token": 15e-6,
|
|
442
|
-
"cache_creation_input_token_cost": 375e-8,
|
|
443
|
-
"cache_read_input_token_cost": 3e-7
|
|
444
|
-
},
|
|
445
|
-
"claude-3-7-sonnet-20250219": {
|
|
446
|
-
"input_cost_per_token": 3e-6,
|
|
447
|
-
"output_cost_per_token": 15e-6,
|
|
448
|
-
"cache_creation_input_token_cost": 375e-8,
|
|
449
|
-
"cache_read_input_token_cost": 3e-7
|
|
450
|
-
},
|
|
451
|
-
"claude-3-5-sonnet-20241022": {
|
|
452
|
-
"input_cost_per_token": 3e-6,
|
|
453
|
-
"output_cost_per_token": 15e-6,
|
|
454
|
-
"cache_creation_input_token_cost": 375e-8,
|
|
455
|
-
"cache_read_input_token_cost": 3e-7
|
|
456
|
-
}
|
|
457
|
-
}));
|
|
458
|
-
this.cachedPricing = pricing;
|
|
459
|
-
return pricing;
|
|
460
|
-
},
|
|
461
|
-
catch: (error) => new Error("Failed to load offline pricing data", { cause: error })
|
|
462
|
-
});
|
|
463
|
-
/**
|
|
464
|
-
* Handles fallback to offline pricing when network fetch fails
|
|
465
|
-
* @param originalError - The original error from the network fetch
|
|
466
|
-
* @returns Map of model names to pricing information
|
|
467
|
-
* @throws Error if both network fetch and fallback fail
|
|
468
|
-
*/
|
|
469
|
-
async handleFallbackToCachedPricing(originalError) {
|
|
470
|
-
logger.warn("Failed to fetch model pricing from LiteLLM, falling back to cached pricing data");
|
|
471
|
-
logger.debug("Fetch error details:", originalError);
|
|
472
|
-
return pipe(this.loadOfflinePricing(), inspect((pricing) => {
|
|
473
|
-
logger.info(`Using cached pricing data for ${pricing.size} models`);
|
|
474
|
-
}), inspectError((error) => {
|
|
475
|
-
logger.error("Failed to load cached pricing data as fallback:", error);
|
|
476
|
-
logger.error("Original fetch error:", originalError);
|
|
477
|
-
}));
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
* Ensures pricing data is loaded, either from cache or by fetching
|
|
481
|
-
* Automatically falls back to offline mode if network fetch fails
|
|
482
|
-
* @returns Map of model names to pricing information
|
|
483
|
-
*/
|
|
484
|
-
async ensurePricingLoaded() {
|
|
485
|
-
return pipe(this.cachedPricing != null ? succeed(this.cachedPricing) : fail(new Error("Cached pricing not available")), orElse(async () => {
|
|
486
|
-
if (this.offline) return this.loadOfflinePricing();
|
|
487
|
-
logger.warn("Fetching latest model pricing from LiteLLM...");
|
|
488
|
-
return pipe(try_({
|
|
489
|
-
try: fetch(LITELLM_PRICING_URL),
|
|
490
|
-
catch: (error) => new Error("Failed to fetch model pricing from LiteLLM", { cause: error })
|
|
491
|
-
}), andThrough((response) => {
|
|
492
|
-
if (!response.ok) return fail(new Error(`Failed to fetch pricing data: ${response.statusText}`));
|
|
493
|
-
return succeed();
|
|
494
|
-
}), andThen(async (response) => try_({
|
|
495
|
-
try: response.json(),
|
|
496
|
-
catch: (error) => new Error("Failed to parse pricing data", { cause: error })
|
|
497
|
-
})), map((data) => {
|
|
498
|
-
const pricing = new Map();
|
|
499
|
-
for (const [modelName, modelData] of Object.entries(data)) if (typeof modelData === "object" && modelData !== null) {
|
|
500
|
-
const parsed = modelPricingSchema.safeParse(modelData);
|
|
501
|
-
if (parsed.success) pricing.set(modelName, parsed.data);
|
|
502
|
-
}
|
|
503
|
-
return pricing;
|
|
504
|
-
}), inspect((pricing) => {
|
|
505
|
-
this.cachedPricing = pricing;
|
|
506
|
-
logger.info(`Loaded pricing for ${pricing.size} models`);
|
|
507
|
-
}), orElse(async (error) => this.handleFallbackToCachedPricing(error)));
|
|
508
|
-
}));
|
|
509
|
-
}
|
|
510
|
-
/**
|
|
511
|
-
* Fetches all available model pricing data
|
|
512
|
-
* @returns Map of model names to pricing information
|
|
513
|
-
*/
|
|
514
|
-
async fetchModelPricing() {
|
|
515
|
-
return this.ensurePricingLoaded();
|
|
516
|
-
}
|
|
517
|
-
/**
|
|
518
|
-
* Gets pricing information for a specific model with fallback matching
|
|
519
|
-
* Tries exact match first, then provider prefixes, then partial matches
|
|
520
|
-
* @param modelName - Name of the model to get pricing for
|
|
521
|
-
* @returns Model pricing information or null if not found
|
|
522
|
-
*/
|
|
523
|
-
async getModelPricing(modelName) {
|
|
524
|
-
return pipe(this.ensurePricingLoaded(), map((pricing) => {
|
|
525
|
-
const directMatch = pricing.get(modelName);
|
|
526
|
-
if (directMatch != null) return directMatch;
|
|
527
|
-
const variations = [
|
|
528
|
-
modelName,
|
|
529
|
-
`anthropic/${modelName}`,
|
|
530
|
-
`claude-3-5-${modelName}`,
|
|
531
|
-
`claude-3-${modelName}`,
|
|
532
|
-
`claude-${modelName}`
|
|
533
|
-
];
|
|
534
|
-
for (const variant of variations) {
|
|
535
|
-
const match = pricing.get(variant);
|
|
536
|
-
if (match != null) return match;
|
|
537
|
-
}
|
|
538
|
-
const lowerModel = modelName.toLowerCase();
|
|
539
|
-
for (const [key, value] of pricing) if (key.toLowerCase().includes(lowerModel) || lowerModel.includes(key.toLowerCase())) return value;
|
|
540
|
-
return null;
|
|
541
|
-
}));
|
|
542
|
-
}
|
|
543
|
-
/**
|
|
544
|
-
* Calculates the cost for given token usage and model
|
|
545
|
-
* @param tokens - Token usage breakdown
|
|
546
|
-
* @param tokens.input_tokens - Number of input tokens
|
|
547
|
-
* @param tokens.output_tokens - Number of output tokens
|
|
548
|
-
* @param tokens.cache_creation_input_tokens - Number of cache creation tokens
|
|
549
|
-
* @param tokens.cache_read_input_tokens - Number of cache read tokens
|
|
550
|
-
* @param modelName - Name of the model used
|
|
551
|
-
* @returns Total cost in USD
|
|
552
|
-
*/
|
|
553
|
-
async calculateCostFromTokens(tokens, modelName) {
|
|
554
|
-
return pipe(this.getModelPricing(modelName), map((pricing) => pricing == null ? 0 : this.calculateCostFromPricing(tokens, pricing)));
|
|
555
|
-
}
|
|
556
|
-
/**
|
|
557
|
-
* Calculates cost from token usage and pricing information
|
|
558
|
-
* @param tokens - Token usage breakdown
|
|
559
|
-
* @param tokens.input_tokens - Number of input tokens
|
|
560
|
-
* @param tokens.output_tokens - Number of output tokens
|
|
561
|
-
* @param tokens.cache_creation_input_tokens - Number of cache creation tokens
|
|
562
|
-
* @param tokens.cache_read_input_tokens - Number of cache read tokens
|
|
563
|
-
* @param pricing - Model pricing rates
|
|
564
|
-
* @returns Total cost in USD
|
|
565
|
-
*/
|
|
566
|
-
calculateCostFromPricing(tokens, pricing) {
|
|
567
|
-
let cost = 0;
|
|
568
|
-
if (pricing.input_cost_per_token != null) cost += tokens.input_tokens * pricing.input_cost_per_token;
|
|
569
|
-
if (pricing.output_cost_per_token != null) cost += tokens.output_tokens * pricing.output_cost_per_token;
|
|
570
|
-
if (tokens.cache_creation_input_tokens != null && pricing.cache_creation_input_token_cost != null) cost += tokens.cache_creation_input_tokens * pricing.cache_creation_input_token_cost;
|
|
571
|
-
if (tokens.cache_read_input_tokens != null && pricing.cache_read_input_token_cost != null) cost += tokens.cache_read_input_tokens * pricing.cache_read_input_token_cost;
|
|
572
|
-
return cost;
|
|
573
|
-
}
|
|
574
|
-
};
|
|
575
|
-
export { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, CLAUDE_CONFIG_DIR_ENV, CLAUDE_PROJECTS_DIR_NAME, DEBUG_MATCH_THRESHOLD_PERCENT, DEFAULT_CLAUDE_CODE_PATH, DEFAULT_CLAUDE_CONFIG_PATH, DEFAULT_RECENT_DAYS, DEFAULT_REFRESH_INTERVAL_SECONDS, MAX_REFRESH_INTERVAL_SECONDS, MCP_DEFAULT_PORT, MIN_REFRESH_INTERVAL_SECONDS, MIN_RENDER_INTERVAL_MS, PROJECT_ALIASES_ENV, PricingFetcher, USAGE_DATA_GLOB_PATTERN, USER_HOME_DIR, WEEK_DAYS, __commonJSMin, __require, __toESM, isFailure, isPromise, require_usingCtx, try_ };
|