ccusage 16.2.5 → 17.0.0
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/README.md +20 -25
- package/config-schema.json +0 -33
- package/dist/_types-CV6z8-9_.js +583 -0
- package/dist/{calculate-cost-BDqO4yWA.js → calculate-cost-CX9KwEZt.js} +1 -1
- package/dist/calculate-cost.d.ts +1 -4
- package/dist/calculate-cost.js +2 -3
- package/dist/data-loader-DQtk3Va0.js +3733 -0
- package/dist/data-loader-D_hlygEz.d.ts +2307 -0
- package/dist/data-loader.d.ts +1 -2
- package/dist/data-loader.js +3 -5
- package/dist/debug-Bn_uiKiR.js +148 -0
- package/dist/debug.d.ts +8 -0
- package/dist/debug.js +4 -6
- package/dist/index.d.ts +0 -0
- package/dist/index.js +2838 -2065
- package/dist/{logger-wHijzbnK.js → logger-1M8m84B7.js} +179 -74
- package/dist/logger.d.ts +11 -7
- package/dist/logger.js +1 -1
- package/dist/{prompt-DsUFNEY7.js → prompt-BeRmYuGP.js} +49 -28
- package/package.json +4 -4
- package/dist/_token-utils-WjkbrjKv.js +0 -5
- package/dist/_types-DIdtMJ6V.js +0 -3076
- package/dist/data-loader-D1FVB4Lp.d.ts +0 -785
- package/dist/data-loader-abvRdQYo.js +0 -2681
- package/dist/debug-CkCfHFil.js +0 -109
- package/dist/mcp-Dz21qUWi.js +0 -6832
- package/dist/mcp.d.ts +0 -35
- package/dist/mcp.js +0 -8
- package/dist/pricing-fetcher-BtUY4dRM.js +0 -402
- package/dist/pricing-fetcher-DK8lcI1w.d.ts +0 -219
- package/dist/pricing-fetcher.d.ts +0 -2
- package/dist/pricing-fetcher.js +0 -4
package/dist/mcp.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { LoadOptions } from "./data-loader-D1FVB4Lp.js";
|
|
2
|
-
import "./pricing-fetcher-DK8lcI1w.js";
|
|
3
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
-
import { Hono } from "hono/tiny";
|
|
5
|
-
|
|
6
|
-
//#region src/mcp.d.ts
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Creates an MCP server with tools for showing usage reports.
|
|
10
|
-
* Registers tools for daily, session, monthly, and blocks usage data.
|
|
11
|
-
*
|
|
12
|
-
* @param options - Configuration options for the MCP server
|
|
13
|
-
* @param options.claudePath - Path to Claude's data directory
|
|
14
|
-
* @returns Configured MCP server instance with registered tools
|
|
15
|
-
*/
|
|
16
|
-
declare function createMcpServer(options?: LoadOptions): McpServer;
|
|
17
|
-
/**
|
|
18
|
-
* Start the MCP server with stdio transport.
|
|
19
|
-
* Used for traditional MCP client connections via standard input/output.
|
|
20
|
-
*
|
|
21
|
-
* @param server - The MCP server instance to start
|
|
22
|
-
*/
|
|
23
|
-
declare function startMcpServerStdio(server: McpServer): Promise<void>;
|
|
24
|
-
/**
|
|
25
|
-
* Create Hono app for MCP HTTP server.
|
|
26
|
-
* Provides HTTP transport support for MCP protocol using Hono framework.
|
|
27
|
-
* Handles POST requests for MCP communication and returns appropriate errors for other methods.
|
|
28
|
-
*
|
|
29
|
-
* @param options - Configuration options for the MCP server
|
|
30
|
-
* @param options.claudePath - Path to Claude's data directory
|
|
31
|
-
* @returns Configured Hono application for HTTP MCP transport
|
|
32
|
-
*/
|
|
33
|
-
declare function createMcpHttpApp(options?: LoadOptions): Hono;
|
|
34
|
-
//#endregion
|
|
35
|
-
export { createMcpHttpApp, createMcpServer, startMcpServerStdio };
|
package/dist/mcp.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import "./pricing-fetcher-BtUY4dRM.js";
|
|
2
|
-
import "./_token-utils-WjkbrjKv.js";
|
|
3
|
-
import "./_types-DIdtMJ6V.js";
|
|
4
|
-
import "./calculate-cost-BDqO4yWA.js";
|
|
5
|
-
import "./data-loader-abvRdQYo.js";
|
|
6
|
-
import "./logger-wHijzbnK.js";
|
|
7
|
-
import { createMcpHttpApp, createMcpServer, startMcpServerStdio } from "./mcp-Dz21qUWi.js";
|
|
8
|
-
export { createMcpHttpApp, createMcpServer, startMcpServerStdio };
|
|
@@ -1,402 +0,0 @@
|
|
|
1
|
-
import { modelPricingSchema } from "./_types-DIdtMJ6V.js";
|
|
2
|
-
import { logger } from "./logger-wHijzbnK.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, __defProp = Object.defineProperty, __getOwnPropDesc = Object.getOwnPropertyDescriptor, __getOwnPropNames = Object.getOwnPropertyNames, __getProtoOf = Object.getPrototypeOf, __hasOwnProp = Object.prototype.hasOwnProperty, __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __copyProps = (to, from, except, desc) => {
|
|
7
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
-
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) if (key = keys[i], !__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
9
|
-
get: ((k) => from[k]).bind(null, key),
|
|
10
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
return to;
|
|
14
|
-
}, __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
15
|
-
value: mod,
|
|
16
|
-
enumerable: true
|
|
17
|
-
}) : target, mod)), __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
18
|
-
const isFailure = (result) => "Failure" === result.type, isPromise = (value) => "object" == typeof value && null !== value && "then" in value && "function" == typeof value.then && "catch" in value && "function" == typeof value.catch, andThen = (fn) => (result) => {
|
|
19
|
-
const apply = (r) => {
|
|
20
|
-
return isFailure(r) ? r : fn(r.value);
|
|
21
|
-
};
|
|
22
|
-
return isPromise(result) ? result.then(apply) : apply(result);
|
|
23
|
-
}, andThrough = (fn) => (result) => {
|
|
24
|
-
const apply = (r) => {
|
|
25
|
-
if (isFailure(r)) return r;
|
|
26
|
-
const next = fn(r.value);
|
|
27
|
-
return isPromise(next) ? next.then((n) => {
|
|
28
|
-
return isFailure(n) ? n : r;
|
|
29
|
-
}) : isFailure(next) ? next : r;
|
|
30
|
-
};
|
|
31
|
-
return isPromise(result) ? result.then(apply) : apply(result);
|
|
32
|
-
}, isSuccess = (result) => "Success" === result.type, succeed = (...args) => {
|
|
33
|
-
if (args.length <= 0) return { type: "Success" };
|
|
34
|
-
const value = args[0];
|
|
35
|
-
return isPromise(value) ? value.then((value$1) => ({
|
|
36
|
-
type: "Success",
|
|
37
|
-
value: value$1
|
|
38
|
-
})) : {
|
|
39
|
-
type: "Success",
|
|
40
|
-
value
|
|
41
|
-
};
|
|
42
|
-
}, fail = (...args) => {
|
|
43
|
-
if (args.length <= 0) return { type: "Failure" };
|
|
44
|
-
const error = args[0];
|
|
45
|
-
return isPromise(error) ? error.then((error$1) => ({
|
|
46
|
-
type: "Failure",
|
|
47
|
-
error: error$1
|
|
48
|
-
})) : {
|
|
49
|
-
type: "Failure",
|
|
50
|
-
error
|
|
51
|
-
};
|
|
52
|
-
}, inspect = (fn) => (result) => {
|
|
53
|
-
const apply = (r) => {
|
|
54
|
-
if (isSuccess(r)) fn(r.value);
|
|
55
|
-
return r;
|
|
56
|
-
};
|
|
57
|
-
return isPromise(result) ? result.then(apply) : apply(result);
|
|
58
|
-
}, inspectError = (fn) => (result) => {
|
|
59
|
-
const apply = (r) => {
|
|
60
|
-
if (isFailure(r)) fn(r.error);
|
|
61
|
-
return r;
|
|
62
|
-
};
|
|
63
|
-
return isPromise(result) ? result.then(apply) : apply(result);
|
|
64
|
-
}, map = (fn) => (result) => {
|
|
65
|
-
const apply = (r) => {
|
|
66
|
-
return isFailure(r) ? r : succeed(fn(r.value));
|
|
67
|
-
};
|
|
68
|
-
return isPromise(result) ? result.then(apply) : apply(result);
|
|
69
|
-
}, orElse = (fn) => (result) => {
|
|
70
|
-
const apply = (r) => {
|
|
71
|
-
return isSuccess(r) ? r : fn(r.error);
|
|
72
|
-
};
|
|
73
|
-
return isPromise(result) ? result.then(apply) : apply(result);
|
|
74
|
-
}, pipe = (value, ...functions) => {
|
|
75
|
-
let next = value;
|
|
76
|
-
for (const func of functions) next = func(next);
|
|
77
|
-
return next;
|
|
78
|
-
}, try_ = (options) => {
|
|
79
|
-
return isPromise(options.try) ? "safe" in options && options.safe ? succeed(options.try) : options.try.then((value) => succeed(value), (error) => fail(options.catch(error))) : (...args) => {
|
|
80
|
-
try {
|
|
81
|
-
const output = options.try(...args);
|
|
82
|
-
if (isPromise(output)) {
|
|
83
|
-
const promise = succeed(output);
|
|
84
|
-
return "safe" in options && options.safe ? promise : promise.catch((error) => fail(options.catch(error)));
|
|
85
|
-
}
|
|
86
|
-
return succeed(output);
|
|
87
|
-
} catch (error) {
|
|
88
|
-
if ("safe" in options && options.safe) throw error;
|
|
89
|
-
return fail(options.catch(error));
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
}, homeDirectory = F.homedir(), { env } = process, xdgData = env.XDG_DATA_HOME || (homeDirectory ? path.join(homeDirectory, ".local", "share") : void 0), xdgConfig = env.XDG_CONFIG_HOME || (homeDirectory ? path.join(homeDirectory, ".config") : void 0), xdgState = env.XDG_STATE_HOME || (homeDirectory ? path.join(homeDirectory, ".local", "state") : void 0), xdgCache = env.XDG_CACHE_HOME || (homeDirectory ? path.join(homeDirectory, ".cache") : void 0), xdgRuntime = env.XDG_RUNTIME_DIR || void 0, xdgDataDirectories = (env.XDG_DATA_DIRS || "/usr/local/share/:/usr/share/").split(":");
|
|
93
|
-
if (xdgData) xdgDataDirectories.unshift(xdgData);
|
|
94
|
-
const xdgConfigDirectories = (env.XDG_CONFIG_DIRS || "/etc/xdg").split(":");
|
|
95
|
-
if (xdgConfig) xdgConfigDirectories.unshift(xdgConfig);
|
|
96
|
-
const LITELLM_PRICING_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json", DEFAULT_RECENT_DAYS = 3, BLOCKS_WARNING_THRESHOLD = .8, BLOCKS_COMPACT_WIDTH_THRESHOLD = 120, BLOCKS_DEFAULT_TERMINAL_WIDTH = 120, DEBUG_MATCH_THRESHOLD_PERCENT = .1, USER_HOME_DIR = homedir(), XDG_CONFIG_DIR = xdgConfig ?? `${USER_HOME_DIR}/.config`, DEFAULT_CLAUDE_CODE_PATH = ".claude", DEFAULT_CLAUDE_CONFIG_PATH = `${XDG_CONFIG_DIR}/claude`, CLAUDE_CONFIG_DIR_ENV = "CLAUDE_CONFIG_DIR", CLAUDE_PROJECTS_DIR_NAME = "projects", USAGE_DATA_GLOB_PATTERN = "**/*.jsonl", MCP_DEFAULT_PORT = 8080, DEFAULT_REFRESH_INTERVAL_SECONDS = 1, MIN_REFRESH_INTERVAL_SECONDS = 1, MAX_REFRESH_INTERVAL_SECONDS = 60, MIN_RENDER_INTERVAL_MS = 16, BURN_RATE_THRESHOLDS = {
|
|
97
|
-
HIGH: 1e3,
|
|
98
|
-
MODERATE: 500
|
|
99
|
-
}, DEFAULT_CONTEXT_USAGE_THRESHOLDS = {
|
|
100
|
-
LOW: 50,
|
|
101
|
-
MEDIUM: 80
|
|
102
|
-
}, WEEK_DAYS = [
|
|
103
|
-
"sunday",
|
|
104
|
-
"monday",
|
|
105
|
-
"tuesday",
|
|
106
|
-
"wednesday",
|
|
107
|
-
"thursday",
|
|
108
|
-
"friday",
|
|
109
|
-
"saturday"
|
|
110
|
-
], CONFIG_FILE_NAME = "ccusage.json", DEFAULT_LOCALE = "en-CA";
|
|
111
|
-
var require_usingCtx = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
112
|
-
function _usingCtx() {
|
|
113
|
-
var r = "function" == typeof SuppressedError ? SuppressedError : function(r$1, e$1) {
|
|
114
|
-
var n$1 = Error();
|
|
115
|
-
return n$1.name = "SuppressedError", n$1.error = r$1, n$1.suppressed = e$1, n$1;
|
|
116
|
-
}, e = {}, n = [];
|
|
117
|
-
function using(r$1, e$1) {
|
|
118
|
-
if (null != e$1) {
|
|
119
|
-
if (Object(e$1) !== e$1) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
|
|
120
|
-
if (r$1) var o = e$1[Symbol.asyncDispose || Symbol["for"]("Symbol.asyncDispose")];
|
|
121
|
-
if (void 0 === o && (o = e$1[Symbol.dispose || Symbol["for"]("Symbol.dispose")], r$1)) var t = o;
|
|
122
|
-
if ("function" != typeof o) throw new TypeError("Object is not disposable.");
|
|
123
|
-
t && (o = function o$1() {
|
|
124
|
-
try {
|
|
125
|
-
t.call(e$1);
|
|
126
|
-
} catch (r$2) {
|
|
127
|
-
return Promise.reject(r$2);
|
|
128
|
-
}
|
|
129
|
-
}), n.push({
|
|
130
|
-
v: e$1,
|
|
131
|
-
d: o,
|
|
132
|
-
a: r$1
|
|
133
|
-
});
|
|
134
|
-
} else r$1 && n.push({
|
|
135
|
-
d: e$1,
|
|
136
|
-
a: r$1
|
|
137
|
-
});
|
|
138
|
-
return e$1;
|
|
139
|
-
}
|
|
140
|
-
return {
|
|
141
|
-
e,
|
|
142
|
-
u: using.bind(null, !1),
|
|
143
|
-
a: using.bind(null, !0),
|
|
144
|
-
d: function d() {
|
|
145
|
-
var o, t = this.e, s = 0;
|
|
146
|
-
function next() {
|
|
147
|
-
for (; o = n.pop();) try {
|
|
148
|
-
if (!o.a && 1 === s) return s = 0, n.push(o), Promise.resolve().then(next);
|
|
149
|
-
if (o.d) {
|
|
150
|
-
var r$1 = o.d.call(o.v);
|
|
151
|
-
if (o.a) return s |= 2, Promise.resolve(r$1).then(next, err);
|
|
152
|
-
} else s |= 1;
|
|
153
|
-
} catch (r$2) {
|
|
154
|
-
return err(r$2);
|
|
155
|
-
}
|
|
156
|
-
if (1 === s) return t !== e ? Promise.reject(t) : Promise.resolve();
|
|
157
|
-
if (t !== e) throw t;
|
|
158
|
-
}
|
|
159
|
-
function err(n$1) {
|
|
160
|
-
return t = t !== e ? new r(n$1, t) : n$1, next();
|
|
161
|
-
}
|
|
162
|
-
return next();
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
module.exports = _usingCtx, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
|
167
|
-
})), import_usingCtx = /* @__PURE__ */ __toESM(require_usingCtx(), 1), PricingFetcher = class {
|
|
168
|
-
cachedPricing = null;
|
|
169
|
-
offline;
|
|
170
|
-
constructor(offline = false) {
|
|
171
|
-
this.offline = offline;
|
|
172
|
-
}
|
|
173
|
-
[Symbol.dispose]() {
|
|
174
|
-
this.clearCache();
|
|
175
|
-
}
|
|
176
|
-
clearCache() {
|
|
177
|
-
this.cachedPricing = null;
|
|
178
|
-
}
|
|
179
|
-
loadOfflinePricing = try_({
|
|
180
|
-
try: async () => {
|
|
181
|
-
const pricing = new Map(Object.entries({
|
|
182
|
-
"claude-3-haiku-20240307": {
|
|
183
|
-
"input_cost_per_token": 25e-8,
|
|
184
|
-
"output_cost_per_token": 125e-8,
|
|
185
|
-
"cache_creation_input_token_cost": 3e-7,
|
|
186
|
-
"cache_read_input_token_cost": 3e-8,
|
|
187
|
-
"max_tokens": 4096,
|
|
188
|
-
"max_input_tokens": 2e5,
|
|
189
|
-
"max_output_tokens": 4096
|
|
190
|
-
},
|
|
191
|
-
"claude-3-5-haiku-20241022": {
|
|
192
|
-
"input_cost_per_token": 8e-7,
|
|
193
|
-
"output_cost_per_token": 4e-6,
|
|
194
|
-
"cache_creation_input_token_cost": 1e-6,
|
|
195
|
-
"cache_read_input_token_cost": 8e-8,
|
|
196
|
-
"max_tokens": 8192,
|
|
197
|
-
"max_input_tokens": 2e5,
|
|
198
|
-
"max_output_tokens": 8192
|
|
199
|
-
},
|
|
200
|
-
"claude-3-5-haiku-latest": {
|
|
201
|
-
"input_cost_per_token": 1e-6,
|
|
202
|
-
"output_cost_per_token": 5e-6,
|
|
203
|
-
"cache_creation_input_token_cost": 125e-8,
|
|
204
|
-
"cache_read_input_token_cost": 1e-7,
|
|
205
|
-
"max_tokens": 8192,
|
|
206
|
-
"max_input_tokens": 2e5,
|
|
207
|
-
"max_output_tokens": 8192
|
|
208
|
-
},
|
|
209
|
-
"claude-3-opus-latest": {
|
|
210
|
-
"input_cost_per_token": 15e-6,
|
|
211
|
-
"output_cost_per_token": 75e-6,
|
|
212
|
-
"cache_creation_input_token_cost": 1875e-8,
|
|
213
|
-
"cache_read_input_token_cost": 15e-7,
|
|
214
|
-
"max_tokens": 4096,
|
|
215
|
-
"max_input_tokens": 2e5,
|
|
216
|
-
"max_output_tokens": 4096
|
|
217
|
-
},
|
|
218
|
-
"claude-3-opus-20240229": {
|
|
219
|
-
"input_cost_per_token": 15e-6,
|
|
220
|
-
"output_cost_per_token": 75e-6,
|
|
221
|
-
"cache_creation_input_token_cost": 1875e-8,
|
|
222
|
-
"cache_read_input_token_cost": 15e-7,
|
|
223
|
-
"max_tokens": 4096,
|
|
224
|
-
"max_input_tokens": 2e5,
|
|
225
|
-
"max_output_tokens": 4096
|
|
226
|
-
},
|
|
227
|
-
"claude-3-5-sonnet-latest": {
|
|
228
|
-
"input_cost_per_token": 3e-6,
|
|
229
|
-
"output_cost_per_token": 15e-6,
|
|
230
|
-
"cache_creation_input_token_cost": 375e-8,
|
|
231
|
-
"cache_read_input_token_cost": 3e-7,
|
|
232
|
-
"max_tokens": 8192,
|
|
233
|
-
"max_input_tokens": 2e5,
|
|
234
|
-
"max_output_tokens": 8192
|
|
235
|
-
},
|
|
236
|
-
"claude-3-5-sonnet-20240620": {
|
|
237
|
-
"input_cost_per_token": 3e-6,
|
|
238
|
-
"output_cost_per_token": 15e-6,
|
|
239
|
-
"cache_creation_input_token_cost": 375e-8,
|
|
240
|
-
"cache_read_input_token_cost": 3e-7,
|
|
241
|
-
"max_tokens": 8192,
|
|
242
|
-
"max_input_tokens": 2e5,
|
|
243
|
-
"max_output_tokens": 8192
|
|
244
|
-
},
|
|
245
|
-
"claude-opus-4-20250514": {
|
|
246
|
-
"input_cost_per_token": 15e-6,
|
|
247
|
-
"output_cost_per_token": 75e-6,
|
|
248
|
-
"cache_creation_input_token_cost": 1875e-8,
|
|
249
|
-
"cache_read_input_token_cost": 15e-7,
|
|
250
|
-
"max_tokens": 32e3,
|
|
251
|
-
"max_input_tokens": 2e5,
|
|
252
|
-
"max_output_tokens": 32e3
|
|
253
|
-
},
|
|
254
|
-
"claude-opus-4-1": {
|
|
255
|
-
"input_cost_per_token": 15e-6,
|
|
256
|
-
"output_cost_per_token": 75e-6,
|
|
257
|
-
"cache_creation_input_token_cost": 1875e-8,
|
|
258
|
-
"cache_read_input_token_cost": 15e-7,
|
|
259
|
-
"max_tokens": 32e3,
|
|
260
|
-
"max_input_tokens": 2e5,
|
|
261
|
-
"max_output_tokens": 32e3
|
|
262
|
-
},
|
|
263
|
-
"claude-opus-4-1-20250805": {
|
|
264
|
-
"input_cost_per_token": 15e-6,
|
|
265
|
-
"output_cost_per_token": 75e-6,
|
|
266
|
-
"cache_creation_input_token_cost": 1875e-8,
|
|
267
|
-
"cache_read_input_token_cost": 15e-7,
|
|
268
|
-
"max_tokens": 32e3,
|
|
269
|
-
"max_input_tokens": 2e5,
|
|
270
|
-
"max_output_tokens": 32e3
|
|
271
|
-
},
|
|
272
|
-
"claude-sonnet-4-20250514": {
|
|
273
|
-
"input_cost_per_token": 3e-6,
|
|
274
|
-
"output_cost_per_token": 15e-6,
|
|
275
|
-
"cache_creation_input_token_cost": 375e-8,
|
|
276
|
-
"cache_read_input_token_cost": 3e-7,
|
|
277
|
-
"max_tokens": 64e3,
|
|
278
|
-
"max_input_tokens": 2e5,
|
|
279
|
-
"max_output_tokens": 64e3
|
|
280
|
-
},
|
|
281
|
-
"claude-4-opus-20250514": {
|
|
282
|
-
"input_cost_per_token": 15e-6,
|
|
283
|
-
"output_cost_per_token": 75e-6,
|
|
284
|
-
"cache_creation_input_token_cost": 1875e-8,
|
|
285
|
-
"cache_read_input_token_cost": 15e-7,
|
|
286
|
-
"max_tokens": 32e3,
|
|
287
|
-
"max_input_tokens": 2e5,
|
|
288
|
-
"max_output_tokens": 32e3
|
|
289
|
-
},
|
|
290
|
-
"claude-4-sonnet-20250514": {
|
|
291
|
-
"input_cost_per_token": 3e-6,
|
|
292
|
-
"output_cost_per_token": 15e-6,
|
|
293
|
-
"cache_creation_input_token_cost": 375e-8,
|
|
294
|
-
"cache_read_input_token_cost": 3e-7,
|
|
295
|
-
"max_tokens": 1e6,
|
|
296
|
-
"max_input_tokens": 1e6,
|
|
297
|
-
"max_output_tokens": 1e6
|
|
298
|
-
},
|
|
299
|
-
"claude-3-7-sonnet-latest": {
|
|
300
|
-
"input_cost_per_token": 3e-6,
|
|
301
|
-
"output_cost_per_token": 15e-6,
|
|
302
|
-
"cache_creation_input_token_cost": 375e-8,
|
|
303
|
-
"cache_read_input_token_cost": 3e-7,
|
|
304
|
-
"max_tokens": 128e3,
|
|
305
|
-
"max_input_tokens": 2e5,
|
|
306
|
-
"max_output_tokens": 128e3
|
|
307
|
-
},
|
|
308
|
-
"claude-3-7-sonnet-20250219": {
|
|
309
|
-
"input_cost_per_token": 3e-6,
|
|
310
|
-
"output_cost_per_token": 15e-6,
|
|
311
|
-
"cache_creation_input_token_cost": 375e-8,
|
|
312
|
-
"cache_read_input_token_cost": 3e-7,
|
|
313
|
-
"max_tokens": 128e3,
|
|
314
|
-
"max_input_tokens": 2e5,
|
|
315
|
-
"max_output_tokens": 128e3
|
|
316
|
-
},
|
|
317
|
-
"claude-3-5-sonnet-20241022": {
|
|
318
|
-
"input_cost_per_token": 3e-6,
|
|
319
|
-
"output_cost_per_token": 15e-6,
|
|
320
|
-
"cache_creation_input_token_cost": 375e-8,
|
|
321
|
-
"cache_read_input_token_cost": 3e-7,
|
|
322
|
-
"max_tokens": 8192,
|
|
323
|
-
"max_input_tokens": 2e5,
|
|
324
|
-
"max_output_tokens": 8192
|
|
325
|
-
}
|
|
326
|
-
}));
|
|
327
|
-
return this.cachedPricing = pricing, pricing;
|
|
328
|
-
},
|
|
329
|
-
catch: (error) => new Error("Failed to load offline pricing data", { cause: error })
|
|
330
|
-
});
|
|
331
|
-
async handleFallbackToCachedPricing(originalError) {
|
|
332
|
-
return logger.warn("Failed to fetch model pricing from LiteLLM, falling back to cached pricing data"), logger.debug("Fetch error details:", originalError), pipe(this.loadOfflinePricing(), inspect((pricing) => {
|
|
333
|
-
logger.info(`Using cached pricing data for ${pricing.size} models`);
|
|
334
|
-
}), inspectError((error) => {
|
|
335
|
-
logger.error("Failed to load cached pricing data as fallback:", error), logger.error("Original fetch error:", originalError);
|
|
336
|
-
}));
|
|
337
|
-
}
|
|
338
|
-
async ensurePricingLoaded() {
|
|
339
|
-
return pipe(this.cachedPricing != null ? succeed(this.cachedPricing) : fail(/* @__PURE__ */ new Error("Cached pricing not available")), orElse(async () => {
|
|
340
|
-
return this.offline ? this.loadOfflinePricing() : (logger.warn("Fetching latest model pricing from LiteLLM..."), pipe(try_({
|
|
341
|
-
try: fetch(LITELLM_PRICING_URL),
|
|
342
|
-
catch: (error) => new Error("Failed to fetch model pricing from LiteLLM", { cause: error })
|
|
343
|
-
}), andThrough((response) => {
|
|
344
|
-
return response.ok ? succeed() : fail(/* @__PURE__ */ new Error(`Failed to fetch pricing data: ${response.statusText}`));
|
|
345
|
-
}), andThen(async (response) => try_({
|
|
346
|
-
try: response.json(),
|
|
347
|
-
catch: (error) => new Error("Failed to parse pricing data", { cause: error })
|
|
348
|
-
})), map((data) => {
|
|
349
|
-
const pricing = /* @__PURE__ */ new Map();
|
|
350
|
-
for (const [modelName, modelData] of Object.entries(data)) if (typeof modelData === "object" && modelData !== null) {
|
|
351
|
-
const parsed = modelPricingSchema.safeParse(modelData);
|
|
352
|
-
if (parsed.success) pricing.set(modelName, parsed.data);
|
|
353
|
-
}
|
|
354
|
-
return pricing;
|
|
355
|
-
}), inspect((pricing) => {
|
|
356
|
-
this.cachedPricing = pricing, logger.info(`Loaded pricing for ${pricing.size} models`);
|
|
357
|
-
}), orElse(async (error) => this.handleFallbackToCachedPricing(error))));
|
|
358
|
-
}));
|
|
359
|
-
}
|
|
360
|
-
async fetchModelPricing() {
|
|
361
|
-
return this.ensurePricingLoaded();
|
|
362
|
-
}
|
|
363
|
-
async getModelPricing(modelName) {
|
|
364
|
-
return pipe(this.ensurePricingLoaded(), map((pricing) => {
|
|
365
|
-
const directMatch = pricing.get(modelName);
|
|
366
|
-
if (directMatch != null) return directMatch;
|
|
367
|
-
const variations = [
|
|
368
|
-
modelName,
|
|
369
|
-
`anthropic/${modelName}`,
|
|
370
|
-
`claude-3-5-${modelName}`,
|
|
371
|
-
`claude-3-${modelName}`,
|
|
372
|
-
`claude-${modelName}`
|
|
373
|
-
];
|
|
374
|
-
for (const variant of variations) {
|
|
375
|
-
const match = pricing.get(variant);
|
|
376
|
-
if (match != null) return match;
|
|
377
|
-
}
|
|
378
|
-
const lowerModel = modelName.toLowerCase();
|
|
379
|
-
for (const [key, value] of pricing) if (key.toLowerCase().includes(lowerModel) || lowerModel.includes(key.toLowerCase())) return value;
|
|
380
|
-
return null;
|
|
381
|
-
}));
|
|
382
|
-
}
|
|
383
|
-
async getModelContextLimit(modelName) {
|
|
384
|
-
return pipe(this.getModelPricing(modelName), map((pricing) => {
|
|
385
|
-
if (pricing == null) return null;
|
|
386
|
-
const contextLimit = pricing.max_input_tokens ?? pricing.max_tokens;
|
|
387
|
-
return contextLimit ?? null;
|
|
388
|
-
}));
|
|
389
|
-
}
|
|
390
|
-
async calculateCostFromTokens(tokens, modelName) {
|
|
391
|
-
return pipe(this.getModelPricing(modelName), map((pricing) => pricing == null ? 0 : this.calculateCostFromPricing(tokens, pricing)));
|
|
392
|
-
}
|
|
393
|
-
calculateCostFromPricing(tokens, pricing) {
|
|
394
|
-
let cost = 0;
|
|
395
|
-
if (pricing.input_cost_per_token != null) cost += tokens.input_tokens * pricing.input_cost_per_token;
|
|
396
|
-
if (pricing.output_cost_per_token != null) cost += tokens.output_tokens * pricing.output_cost_per_token;
|
|
397
|
-
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;
|
|
398
|
-
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;
|
|
399
|
-
return cost;
|
|
400
|
-
}
|
|
401
|
-
};
|
|
402
|
-
export { BLOCKS_COMPACT_WIDTH_THRESHOLD, BLOCKS_DEFAULT_TERMINAL_WIDTH, BLOCKS_WARNING_THRESHOLD, BURN_RATE_THRESHOLDS, CLAUDE_CONFIG_DIR_ENV, CLAUDE_PROJECTS_DIR_NAME, CONFIG_FILE_NAME, DEBUG_MATCH_THRESHOLD_PERCENT, DEFAULT_CLAUDE_CODE_PATH, DEFAULT_CLAUDE_CONFIG_PATH, DEFAULT_CONTEXT_USAGE_THRESHOLDS, DEFAULT_LOCALE, DEFAULT_RECENT_DAYS, DEFAULT_REFRESH_INTERVAL_SECONDS, MAX_REFRESH_INTERVAL_SECONDS, MCP_DEFAULT_PORT, MIN_REFRESH_INTERVAL_SECONDS, MIN_RENDER_INTERVAL_MS, PricingFetcher, USAGE_DATA_GLOB_PATTERN, USER_HOME_DIR, WEEK_DAYS, __commonJSMin, __require, __toESM, andThen, fail, inspect, inspectError, isFailure, isPromise, isSuccess, map, pipe, require_usingCtx, succeed, try_ };
|
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { Result } from "@praha/byethrow";
|
|
3
|
-
|
|
4
|
-
//#region node_modules/type-fest/source/observable-like.d.ts
|
|
5
|
-
declare global {
|
|
6
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- It has to be an `interface` so that it can be merged.
|
|
7
|
-
interface SymbolConstructor {
|
|
8
|
-
readonly observable: symbol;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
@remarks
|
|
14
|
-
The TC39 observable proposal defines a `closed` property, but some implementations (such as xstream) do not as of 10/08/2021.
|
|
15
|
-
As well, some guidance on making an `Observable` to not include `closed` property.
|
|
16
|
-
@see https://github.com/tc39/proposal-observable/blob/master/src/Observable.js#L129-L130
|
|
17
|
-
@see https://github.com/staltz/xstream/blob/6c22580c1d84d69773ee4b0905df44ad464955b3/src/index.ts#L79-L85
|
|
18
|
-
@see https://github.com/benlesh/symbol-observable#making-an-object-observable
|
|
19
|
-
|
|
20
|
-
@category Observable
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
//#endregion
|
|
24
|
-
//#region node_modules/type-fest/source/tuple-to-union.d.ts
|
|
25
|
-
/**
|
|
26
|
-
Convert a tuple/array into a union type of its elements.
|
|
27
|
-
|
|
28
|
-
This can be useful when you have a fixed set of allowed values and want a type defining only the allowed values, but do not want to repeat yourself.
|
|
29
|
-
|
|
30
|
-
@example
|
|
31
|
-
```
|
|
32
|
-
import type {TupleToUnion} from 'type-fest';
|
|
33
|
-
|
|
34
|
-
const destinations = ['a', 'b', 'c'] as const;
|
|
35
|
-
|
|
36
|
-
type Destination = TupleToUnion<typeof destinations>;
|
|
37
|
-
//=> 'a' | 'b' | 'c'
|
|
38
|
-
|
|
39
|
-
function verifyDestination(destination: unknown): destination is Destination {
|
|
40
|
-
return destinations.includes(destination as any);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
type RequestBody = {
|
|
44
|
-
deliverTo: Destination;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
function verifyRequestBody(body: unknown): body is RequestBody {
|
|
48
|
-
const deliverTo = (body as any).deliverTo;
|
|
49
|
-
return typeof body === 'object' && body !== null && verifyDestination(deliverTo);
|
|
50
|
-
}
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Alternatively, you may use `typeof destinations[number]`. If `destinations` is a tuple, there is no difference. However if `destinations` is a string, the resulting type will the union of the characters in the string. Other types of `destinations` may result in a compile error. In comparison, TupleToUnion will return `never` if a tuple is not provided.
|
|
54
|
-
|
|
55
|
-
@example
|
|
56
|
-
```
|
|
57
|
-
const destinations = ['a', 'b', 'c'] as const;
|
|
58
|
-
|
|
59
|
-
type Destination = typeof destinations[number];
|
|
60
|
-
//=> 'a' | 'b' | 'c'
|
|
61
|
-
|
|
62
|
-
const erroringType = new Set(['a', 'b', 'c']);
|
|
63
|
-
|
|
64
|
-
type ErroringType = typeof erroringType[number];
|
|
65
|
-
//=> Type 'Set<string>' has no matching index signature for type 'number'. ts(2537)
|
|
66
|
-
|
|
67
|
-
const numberBool: { [n: number]: boolean } = { 1: true };
|
|
68
|
-
|
|
69
|
-
type NumberBool = typeof numberBool[number];
|
|
70
|
-
//=> boolean
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
@category Array
|
|
74
|
-
*/
|
|
75
|
-
type TupleToUnion<ArrayType> = ArrayType extends readonly unknown[] ? ArrayType[number] : never;
|
|
76
|
-
//#endregion
|
|
77
|
-
//#region src/_types.d.ts
|
|
78
|
-
declare const monthlyDateSchema: z.ZodBranded<z.ZodString, "MonthlyDate">;
|
|
79
|
-
declare const weeklyDateSchema: z.ZodBranded<z.ZodString, "WeeklyDate">;
|
|
80
|
-
type MonthlyDate = z.infer<typeof monthlyDateSchema>;
|
|
81
|
-
type WeeklyDate = z.infer<typeof weeklyDateSchema>;
|
|
82
|
-
type Bucket = MonthlyDate | WeeklyDate;
|
|
83
|
-
/**
|
|
84
|
-
* Available cost calculation modes
|
|
85
|
-
* - auto: Use pre-calculated costs when available, otherwise calculate from tokens
|
|
86
|
-
* - calculate: Always calculate costs from token counts using model pricing
|
|
87
|
-
* - display: Always use pre-calculated costs, show 0 for missing costs
|
|
88
|
-
*/
|
|
89
|
-
declare const CostModes: readonly ["auto", "calculate", "display"];
|
|
90
|
-
/**
|
|
91
|
-
* Union type for cost calculation modes
|
|
92
|
-
*/
|
|
93
|
-
type CostMode = TupleToUnion<typeof CostModes>;
|
|
94
|
-
/**
|
|
95
|
-
* Available sort orders for data presentation
|
|
96
|
-
*/
|
|
97
|
-
declare const SortOrders: readonly ["desc", "asc"];
|
|
98
|
-
/**
|
|
99
|
-
* Union type for sort order options
|
|
100
|
-
*/
|
|
101
|
-
type SortOrder = TupleToUnion<typeof SortOrders>;
|
|
102
|
-
/**
|
|
103
|
-
* Zod schema for model pricing information from LiteLLM
|
|
104
|
-
*/
|
|
105
|
-
declare const modelPricingSchema: z.ZodObject<{
|
|
106
|
-
input_cost_per_token: z.ZodOptional<z.ZodNumber>;
|
|
107
|
-
output_cost_per_token: z.ZodOptional<z.ZodNumber>;
|
|
108
|
-
cache_creation_input_token_cost: z.ZodOptional<z.ZodNumber>;
|
|
109
|
-
cache_read_input_token_cost: z.ZodOptional<z.ZodNumber>;
|
|
110
|
-
// Context window limits from LiteLLM data
|
|
111
|
-
max_tokens: z.ZodOptional<z.ZodNumber>;
|
|
112
|
-
max_input_tokens: z.ZodOptional<z.ZodNumber>;
|
|
113
|
-
max_output_tokens: z.ZodOptional<z.ZodNumber>;
|
|
114
|
-
}, "strip", z.ZodTypeAny, {
|
|
115
|
-
input_cost_per_token?: number | undefined;
|
|
116
|
-
output_cost_per_token?: number | undefined;
|
|
117
|
-
cache_creation_input_token_cost?: number | undefined;
|
|
118
|
-
cache_read_input_token_cost?: number | undefined;
|
|
119
|
-
max_tokens?: number | undefined;
|
|
120
|
-
max_input_tokens?: number | undefined;
|
|
121
|
-
max_output_tokens?: number | undefined;
|
|
122
|
-
}, {
|
|
123
|
-
input_cost_per_token?: number | undefined;
|
|
124
|
-
output_cost_per_token?: number | undefined;
|
|
125
|
-
cache_creation_input_token_cost?: number | undefined;
|
|
126
|
-
cache_read_input_token_cost?: number | undefined;
|
|
127
|
-
max_tokens?: number | undefined;
|
|
128
|
-
max_input_tokens?: number | undefined;
|
|
129
|
-
max_output_tokens?: number | undefined;
|
|
130
|
-
}>;
|
|
131
|
-
/**
|
|
132
|
-
* Type definition for model pricing information
|
|
133
|
-
*/
|
|
134
|
-
type ModelPricing = z.infer<typeof modelPricingSchema>;
|
|
135
|
-
/**
|
|
136
|
-
* Zod schema for Claude Code statusline hook JSON data
|
|
137
|
-
*/
|
|
138
|
-
//#endregion
|
|
139
|
-
//#region src/pricing-fetcher.d.ts
|
|
140
|
-
/**
|
|
141
|
-
* Fetches and caches model pricing information from LiteLLM
|
|
142
|
-
* Implements Disposable pattern for automatic resource cleanup
|
|
143
|
-
*/
|
|
144
|
-
declare class PricingFetcher implements Disposable {
|
|
145
|
-
private cachedPricing;
|
|
146
|
-
private readonly offline;
|
|
147
|
-
/**
|
|
148
|
-
* Creates a new PricingFetcher instance
|
|
149
|
-
* @param offline - Whether to use pre-fetched pricing data instead of fetching from API
|
|
150
|
-
*/
|
|
151
|
-
constructor(offline?: boolean);
|
|
152
|
-
/**
|
|
153
|
-
* Implements Disposable interface for automatic cleanup
|
|
154
|
-
*/
|
|
155
|
-
[Symbol.dispose](): void;
|
|
156
|
-
/**
|
|
157
|
-
* Clears the cached pricing data
|
|
158
|
-
*/
|
|
159
|
-
clearCache(): void;
|
|
160
|
-
/**
|
|
161
|
-
* Loads offline pricing data from pre-fetched cache
|
|
162
|
-
* @returns Map of model names to pricing information
|
|
163
|
-
*/
|
|
164
|
-
private loadOfflinePricing;
|
|
165
|
-
private handleFallbackToCachedPricing;
|
|
166
|
-
private ensurePricingLoaded;
|
|
167
|
-
/**
|
|
168
|
-
* Fetches all available model pricing data
|
|
169
|
-
* @returns Map of model names to pricing information
|
|
170
|
-
*/
|
|
171
|
-
fetchModelPricing(): Result.ResultAsync<Map<string, ModelPricing>, Error>;
|
|
172
|
-
/**
|
|
173
|
-
* Gets pricing information for a specific model with fallback matching
|
|
174
|
-
* Tries exact match first, then provider prefixes, then partial matches
|
|
175
|
-
* @param modelName - Name of the model to get pricing for
|
|
176
|
-
* @returns Model pricing information or null if not found
|
|
177
|
-
*/
|
|
178
|
-
getModelPricing(modelName: string): Result.ResultAsync<ModelPricing | null, Error>;
|
|
179
|
-
/**
|
|
180
|
-
* Gets context window limit for a specific model from LiteLLM data
|
|
181
|
-
* @param modelName - The model name to get context limit for
|
|
182
|
-
* @returns The context limit in tokens, or null if not found
|
|
183
|
-
*/
|
|
184
|
-
getModelContextLimit(modelName: string): Result.ResultAsync<number | null, Error>;
|
|
185
|
-
/**
|
|
186
|
-
* Calculates the cost for given token usage and model
|
|
187
|
-
* @param tokens - Token usage breakdown
|
|
188
|
-
* @param tokens.input_tokens - Number of input tokens
|
|
189
|
-
* @param tokens.output_tokens - Number of output tokens
|
|
190
|
-
* @param tokens.cache_creation_input_tokens - Number of cache creation tokens
|
|
191
|
-
* @param tokens.cache_read_input_tokens - Number of cache read tokens
|
|
192
|
-
* @param modelName - Name of the model used
|
|
193
|
-
* @returns Total cost in USD
|
|
194
|
-
*/
|
|
195
|
-
calculateCostFromTokens(tokens: {
|
|
196
|
-
input_tokens: number;
|
|
197
|
-
output_tokens: number;
|
|
198
|
-
cache_creation_input_tokens?: number;
|
|
199
|
-
cache_read_input_tokens?: number;
|
|
200
|
-
}, modelName: string): Result.ResultAsync<number, Error>;
|
|
201
|
-
/**
|
|
202
|
-
* Calculates cost from token usage and pricing information
|
|
203
|
-
* @param tokens - Token usage breakdown
|
|
204
|
-
* @param tokens.input_tokens - Number of input tokens
|
|
205
|
-
* @param tokens.output_tokens - Number of output tokens
|
|
206
|
-
* @param tokens.cache_creation_input_tokens - Number of cache creation tokens
|
|
207
|
-
* @param tokens.cache_read_input_tokens - Number of cache read tokens
|
|
208
|
-
* @param pricing - Model pricing rates
|
|
209
|
-
* @returns Total cost in USD
|
|
210
|
-
*/
|
|
211
|
-
calculateCostFromPricing(tokens: {
|
|
212
|
-
input_tokens: number;
|
|
213
|
-
output_tokens: number;
|
|
214
|
-
cache_creation_input_tokens?: number;
|
|
215
|
-
cache_read_input_tokens?: number;
|
|
216
|
-
}, pricing: ModelPricing): number;
|
|
217
|
-
}
|
|
218
|
-
//#endregion
|
|
219
|
-
export { Bucket, CostMode, PricingFetcher, SortOrder };
|
package/dist/pricing-fetcher.js
DELETED