@praeviso/code-env-switch 0.1.4 → 0.1.5
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 +17 -0
- package/README_zh.md +17 -0
- package/bin/commands/list.js +44 -2
- package/bin/statusline/format.js +6 -9
- package/bin/statusline/index.js +46 -8
- package/bin/statusline/input.js +9 -91
- package/bin/statusline/usage/claude.js +181 -0
- package/bin/statusline/usage/codex.js +168 -0
- package/bin/statusline/usage.js +20 -76
- package/bin/usage/index.js +396 -41
- package/bin/usage/pricing.js +303 -0
- package/code-env.example.json +55 -0
- package/package.json +1 -1
- package/src/commands/list.ts +74 -4
- package/src/statusline/format.ts +9 -10
- package/src/statusline/index.ts +74 -24
- package/src/statusline/input.ts +13 -154
- package/src/statusline/types.ts +6 -0
- package/src/statusline/usage/claude.ts +299 -0
- package/src/statusline/usage/codex.ts +263 -0
- package/src/statusline/usage.ts +24 -119
- package/src/types.ts +23 -0
- package/src/usage/index.ts +519 -35
- package/src/usage/pricing.ts +323 -0
- package/PLAN.md +0 -33
package/README.md
CHANGED
|
@@ -217,6 +217,17 @@ If nothing is found, `codenv add` writes to `~/.config/code-env/config.json`.
|
|
|
217
217
|
"type": "command",
|
|
218
218
|
"padding": 0
|
|
219
219
|
},
|
|
220
|
+
"pricing": {
|
|
221
|
+
"models": {
|
|
222
|
+
"Claude Sonnet 4.5": {
|
|
223
|
+
"input": 3.0,
|
|
224
|
+
"output": 15.0,
|
|
225
|
+
"cacheWrite": 3.75,
|
|
226
|
+
"cacheRead": 0.3,
|
|
227
|
+
"description": "Balanced performance and speed for daily use."
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
},
|
|
220
231
|
"profiles": {
|
|
221
232
|
"p_a1b2c3": {
|
|
222
233
|
"name": "primary",
|
|
@@ -247,10 +258,16 @@ Notes:
|
|
|
247
258
|
- `type`: string; statusLine type (default: `command`).
|
|
248
259
|
- `padding`: number; statusLine padding (default: 0).
|
|
249
260
|
- `settingsPath`: optional; override `~/.claude/settings.json` (also supports `CODE_ENV_CLAUDE_SETTINGS_PATH`).
|
|
261
|
+
- `pricing`: optional; model pricing (USD per 1M tokens) used to convert token usage to dollar amounts in the status line.
|
|
262
|
+
- `models`: map of model name to pricing. Keys are matched case/format-insensitively.
|
|
263
|
+
- `input`/`output`/`cacheRead`/`cacheWrite`: token rates.
|
|
264
|
+
- Cost display uses the profile pricing model if set; otherwise the status line model label. No breakdown => no cost.
|
|
250
265
|
- `name`: human-facing profile name shown in `codenv list` and used by `codenv use <name>`.
|
|
251
266
|
- `type`: optional; `codex` or `claude` (alias `cc`) for `codenv use <type> <name>` matching.
|
|
252
267
|
- `note`: shown in `codenv list`.
|
|
253
268
|
- `removeFiles`: optional; `codenv use` emits `rm -f` for each path. Codex profiles also remove `~/.codex/auth.json`.
|
|
269
|
+
- `pricing` (profile): optional; per-profile pricing override. Supports `model` plus `input`/`output`/`cacheRead`/`cacheWrite`.
|
|
270
|
+
- `multiplier`: optional; scale pricing (number).
|
|
254
271
|
- `ANTHROPIC_AUTH_TOKEN`: when `ANTHROPIC_API_KEY` is set, `codenv use` also exports `ANTHROPIC_AUTH_TOKEN` with the same value.
|
|
255
272
|
- `commands`: optional; emitted as-is in the switch script.
|
|
256
273
|
|
package/README_zh.md
CHANGED
|
@@ -216,6 +216,17 @@ codenv use codex primary | source
|
|
|
216
216
|
"type": "command",
|
|
217
217
|
"padding": 0
|
|
218
218
|
},
|
|
219
|
+
"pricing": {
|
|
220
|
+
"models": {
|
|
221
|
+
"Claude Sonnet 4.5": {
|
|
222
|
+
"input": 3.0,
|
|
223
|
+
"output": 15.0,
|
|
224
|
+
"cacheWrite": 3.75,
|
|
225
|
+
"cacheRead": 0.3,
|
|
226
|
+
"description": "平衡性能与速度,适合日常使用"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
},
|
|
219
230
|
"profiles": {
|
|
220
231
|
"p_a1b2c3": {
|
|
221
232
|
"name": "primary",
|
|
@@ -246,10 +257,16 @@ codenv use codex primary | source
|
|
|
246
257
|
- `type`:字符串;statusLine 类型(默认 `command`)。
|
|
247
258
|
- `padding`:数字;statusLine padding(默认 0)。
|
|
248
259
|
- `settingsPath`:可选;覆盖 `~/.claude/settings.json`(也可用 `CODE_ENV_CLAUDE_SETTINGS_PATH`)。
|
|
260
|
+
- `pricing`:可选;模型价格(美元 / 1M tokens),用于在状态栏将 token 用量换算为美元额度。
|
|
261
|
+
- `models`:模型名称到价格的映射(匹配时忽略大小写与格式差异)。
|
|
262
|
+
- `input`/`output`/`cacheRead`/`cacheWrite`:输入/输出/缓存价格。
|
|
263
|
+
- 优先使用 profile 中指定的 `model`,否则使用状态栏输入的模型名称;无拆分则不显示金额。
|
|
249
264
|
- `name`:用于展示的 profile 名称,`codenv list` 与 `codenv use <name>` 会使用它。
|
|
250
265
|
- `type`:可选,`codex` 或 `claude`(别名 `cc`),便于用 `codenv use <type> <name>` 匹配。
|
|
251
266
|
- `note`:显示在 `codenv list` 输出中。
|
|
252
267
|
- `removeFiles`:可选;`codenv use` 会输出对应 `rm -f`。Codex profile 还会删除 `~/.codex/auth.json`。
|
|
268
|
+
- `pricing`(profile 内):可选;为单个 profile 覆盖价格。支持 `model` 以及 `input`/`output`/`cacheRead`/`cacheWrite`。
|
|
269
|
+
- `multiplier`:可选;倍率(数字)。
|
|
253
270
|
- `ANTHROPIC_AUTH_TOKEN`:当设置了 `ANTHROPIC_API_KEY` 时,`codenv use` 会自动以同样的值导出 `ANTHROPIC_AUTH_TOKEN`。
|
|
254
271
|
- `commands`:可选;原样输出到切换脚本中。
|
|
255
272
|
|
package/bin/commands/list.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.printList = printList;
|
|
|
4
4
|
const display_1 = require("../profile/display");
|
|
5
5
|
const defaults_1 = require("../config/defaults");
|
|
6
6
|
const usage_1 = require("../usage");
|
|
7
|
+
const pricing_1 = require("../usage/pricing");
|
|
7
8
|
function printList(config, configPath) {
|
|
8
9
|
const rows = (0, display_1.buildListRows)(config, defaults_1.getResolvedDefaultProfileKeys);
|
|
9
10
|
if (rows.length === 0) {
|
|
@@ -12,6 +13,7 @@ function printList(config, configPath) {
|
|
|
12
13
|
}
|
|
13
14
|
try {
|
|
14
15
|
const usageTotals = (0, usage_1.readUsageTotalsIndex)(config, configPath, true);
|
|
16
|
+
const usageCosts = (0, usage_1.readUsageCostIndex)(config, configPath, false);
|
|
15
17
|
if (usageTotals) {
|
|
16
18
|
for (const row of rows) {
|
|
17
19
|
if (!row.usageType)
|
|
@@ -23,6 +25,19 @@ function printList(config, configPath) {
|
|
|
23
25
|
row.totalTokens = usage.total;
|
|
24
26
|
}
|
|
25
27
|
}
|
|
28
|
+
if (usageCosts) {
|
|
29
|
+
for (const row of rows) {
|
|
30
|
+
if (!row.usageType)
|
|
31
|
+
continue;
|
|
32
|
+
const cost = (0, usage_1.resolveUsageCostForProfile)(usageCosts, row.usageType, row.key, row.name);
|
|
33
|
+
if (!cost)
|
|
34
|
+
continue;
|
|
35
|
+
row.todayCost = cost.today;
|
|
36
|
+
row.totalCost = cost.total;
|
|
37
|
+
row.todayBilledTokens = cost.todayTokens;
|
|
38
|
+
row.totalBilledTokens = cost.totalTokens;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
26
41
|
}
|
|
27
42
|
catch {
|
|
28
43
|
// ignore usage sync errors
|
|
@@ -32,8 +47,14 @@ function printList(config, configPath) {
|
|
|
32
47
|
const headerToday = "TODAY";
|
|
33
48
|
const headerTotal = "TOTAL";
|
|
34
49
|
const headerNote = "NOTE";
|
|
35
|
-
const todayTexts = rows.map((row) =>
|
|
36
|
-
|
|
50
|
+
const todayTexts = rows.map((row) => {
|
|
51
|
+
var _a, _b;
|
|
52
|
+
return formatUsageWithCost(row.todayTokens, (_a = row.todayBilledTokens) !== null && _a !== void 0 ? _a : null, (_b = row.todayCost) !== null && _b !== void 0 ? _b : null);
|
|
53
|
+
});
|
|
54
|
+
const totalTexts = rows.map((row) => {
|
|
55
|
+
var _a, _b;
|
|
56
|
+
return formatUsageWithCost(row.totalTokens, (_a = row.totalBilledTokens) !== null && _a !== void 0 ? _a : null, (_b = row.totalCost) !== null && _b !== void 0 ? _b : null);
|
|
57
|
+
});
|
|
37
58
|
const nameWidth = Math.max(headerName.length, ...rows.map((row) => row.name.length));
|
|
38
59
|
const typeWidth = Math.max(headerType.length, ...rows.map((row) => row.type.length));
|
|
39
60
|
const todayWidth = Math.max(headerToday.length, ...todayTexts.map((v) => v.length));
|
|
@@ -55,3 +76,24 @@ function printList(config, configPath) {
|
|
|
55
76
|
}
|
|
56
77
|
}
|
|
57
78
|
}
|
|
79
|
+
function formatUsageWithCost(tokens, billedTokens, cost) {
|
|
80
|
+
const tokenText = (0, usage_1.formatTokenCount)(tokens !== null && tokens !== void 0 ? tokens : null);
|
|
81
|
+
if (tokenText === "-")
|
|
82
|
+
return tokenText;
|
|
83
|
+
if (cost === null || !Number.isFinite(cost))
|
|
84
|
+
return tokenText;
|
|
85
|
+
if (tokens === null || tokens === undefined || !Number.isFinite(tokens)) {
|
|
86
|
+
return tokenText;
|
|
87
|
+
}
|
|
88
|
+
if (billedTokens === null || !Number.isFinite(billedTokens)) {
|
|
89
|
+
return `${tokenText} (${(0, pricing_1.formatUsdAmount)(cost)})`;
|
|
90
|
+
}
|
|
91
|
+
if (billedTokens >= tokens) {
|
|
92
|
+
return `${tokenText} (${(0, pricing_1.formatUsdAmount)(cost)})`;
|
|
93
|
+
}
|
|
94
|
+
const billedText = (0, usage_1.formatTokenCount)(billedTokens);
|
|
95
|
+
if (billedText === "-") {
|
|
96
|
+
return `${tokenText} (${(0, pricing_1.formatUsdAmount)(cost)})`;
|
|
97
|
+
}
|
|
98
|
+
return `${tokenText} (billed ${billedText}, ${(0, pricing_1.formatUsdAmount)(cost)})`;
|
|
99
|
+
}
|
package/bin/statusline/format.js
CHANGED
|
@@ -8,6 +8,7 @@ exports.formatContextSegment = formatContextSegment;
|
|
|
8
8
|
exports.formatContextUsedSegment = formatContextUsedSegment;
|
|
9
9
|
exports.formatModeSegment = formatModeSegment;
|
|
10
10
|
const usage_1 = require("../usage");
|
|
11
|
+
const pricing_1 = require("../usage/pricing");
|
|
11
12
|
const style_1 = require("./style");
|
|
12
13
|
const path = require("path");
|
|
13
14
|
function getCwdSegment(cwd) {
|
|
@@ -17,16 +18,12 @@ function getCwdSegment(cwd) {
|
|
|
17
18
|
const segment = `${style_1.ICON_CWD} ${base}`;
|
|
18
19
|
return (0, style_1.dim)(segment);
|
|
19
20
|
}
|
|
20
|
-
function formatUsageSegment(
|
|
21
|
-
|
|
22
|
-
if (!usage)
|
|
21
|
+
function formatUsageSegment(todayCost, sessionCost) {
|
|
22
|
+
if (todayCost === null && sessionCost === null)
|
|
23
23
|
return null;
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (today === null)
|
|
28
|
-
return null;
|
|
29
|
-
const text = `Today ${(0, usage_1.formatTokenCount)(today)}`;
|
|
24
|
+
const todayText = `T ${(0, pricing_1.formatUsdAmount)(todayCost)}`;
|
|
25
|
+
const sessionText = `S ${(0, pricing_1.formatUsdAmount)(sessionCost)}`;
|
|
26
|
+
const text = `${todayText} / ${sessionText}`;
|
|
30
27
|
return (0, style_1.colorize)(`${style_1.ICON_USAGE} ${text}`, "33");
|
|
31
28
|
}
|
|
32
29
|
function formatModelSegment(model, provider) {
|
package/bin/statusline/index.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.buildStatuslineResult = buildStatuslineResult;
|
|
4
4
|
const type_1 = require("../profile/type");
|
|
5
5
|
const usage_1 = require("../usage");
|
|
6
|
+
const pricing_1 = require("../usage/pricing");
|
|
6
7
|
const debug_1 = require("./debug");
|
|
7
8
|
const format_1 = require("./format");
|
|
8
9
|
const git_1 = require("./git");
|
|
@@ -37,8 +38,10 @@ function buildStatuslineResult(args, config, configPath) {
|
|
|
37
38
|
}
|
|
38
39
|
const cwd = (0, utils_1.firstNonEmpty)(args.cwd, process.env.CODE_ENV_CWD, (0, input_1.getWorkspaceDir)(stdinInput), stdinInput ? stdinInput.cwd : null, process.cwd());
|
|
39
40
|
const sessionId = (0, input_1.getSessionId)(stdinInput);
|
|
40
|
-
const stdinUsageTotals = (0, usage_2.getUsageTotalsFromInput)(stdinInput);
|
|
41
41
|
const usageType = (0, type_1.normalizeType)(type || "");
|
|
42
|
+
const stdinUsageTotals = (0, usage_2.getUsageTotalsFromInput)(stdinInput, usageType);
|
|
43
|
+
const model = (0, utils_1.firstNonEmpty)(args.model, process.env.CODE_ENV_MODEL, (0, input_1.getModelFromInput)(stdinInput));
|
|
44
|
+
const modelProvider = (0, utils_1.firstNonEmpty)(process.env.CODE_ENV_MODEL_PROVIDER, (0, input_1.getModelProviderFromInput)(stdinInput));
|
|
42
45
|
(0, debug_1.appendStatuslineDebug)(configPath, {
|
|
43
46
|
timestamp: new Date().toISOString(),
|
|
44
47
|
typeCandidate,
|
|
@@ -68,27 +71,31 @@ function buildStatuslineResult(args, config, configPath) {
|
|
|
68
71
|
input: stdinInput,
|
|
69
72
|
});
|
|
70
73
|
if (args.syncUsage && sessionId && stdinUsageTotals) {
|
|
71
|
-
(0, usage_1.syncUsageFromStatuslineInput)(config, configPath, usageType, profileKey, profileName, sessionId, stdinUsageTotals, cwd);
|
|
74
|
+
(0, usage_1.syncUsageFromStatuslineInput)(config, configPath, usageType, profileKey, profileName, sessionId, stdinUsageTotals, cwd, model);
|
|
72
75
|
}
|
|
73
|
-
const model = (0, utils_1.firstNonEmpty)(args.model, process.env.CODE_ENV_MODEL, (0, input_1.getModelFromInput)(stdinInput));
|
|
74
|
-
const modelProvider = (0, utils_1.firstNonEmpty)(process.env.CODE_ENV_MODEL_PROVIDER, (0, input_1.getModelProviderFromInput)(stdinInput));
|
|
75
76
|
const usage = {
|
|
76
77
|
todayTokens: (0, utils_1.firstNumber)(args.usageToday, process.env.CODE_ENV_USAGE_TODAY),
|
|
77
78
|
totalTokens: (0, utils_1.firstNumber)(args.usageTotal, process.env.CODE_ENV_USAGE_TOTAL),
|
|
78
79
|
inputTokens: (0, utils_1.firstNumber)(args.usageInput, process.env.CODE_ENV_USAGE_INPUT),
|
|
79
80
|
outputTokens: (0, utils_1.firstNumber)(args.usageOutput, process.env.CODE_ENV_USAGE_OUTPUT),
|
|
81
|
+
cacheReadTokens: null,
|
|
82
|
+
cacheWriteTokens: null,
|
|
80
83
|
};
|
|
81
84
|
const hasExplicitUsage = usage.todayTokens !== null ||
|
|
82
85
|
usage.totalTokens !== null ||
|
|
83
86
|
usage.inputTokens !== null ||
|
|
84
87
|
usage.outputTokens !== null;
|
|
85
|
-
const stdinUsage = (0, usage_2.normalizeInputUsage)((0, input_1.getInputUsage)(stdinInput));
|
|
88
|
+
const stdinUsage = (0, usage_2.normalizeInputUsage)((0, input_1.getInputUsage)(stdinInput, usageType));
|
|
89
|
+
const recordsUsage = (0, usage_2.resolveUsageFromRecords)(config, configPath, type, profileKey, profileName, args.syncUsage);
|
|
86
90
|
let finalUsage = hasExplicitUsage ? usage : null;
|
|
91
|
+
if (!finalUsage && args.syncUsage && recordsUsage) {
|
|
92
|
+
finalUsage = recordsUsage;
|
|
93
|
+
}
|
|
87
94
|
if (!finalUsage) {
|
|
88
95
|
finalUsage = stdinUsage;
|
|
89
96
|
}
|
|
90
|
-
if (!finalUsage) {
|
|
91
|
-
finalUsage =
|
|
97
|
+
if (!finalUsage && recordsUsage) {
|
|
98
|
+
finalUsage = recordsUsage;
|
|
92
99
|
}
|
|
93
100
|
let gitStatus = (0, git_1.getGitStatus)(cwd);
|
|
94
101
|
if (!gitStatus) {
|
|
@@ -103,7 +110,38 @@ function buildStatuslineResult(args, config, configPath) {
|
|
|
103
110
|
const gitSegment = (0, git_1.formatGitSegment)(gitStatus);
|
|
104
111
|
const profileSegment = (0, format_1.formatProfileSegment)(type, profileKey, profileName);
|
|
105
112
|
const modelSegment = (0, format_1.formatModelSegment)(model, modelProvider);
|
|
106
|
-
|
|
113
|
+
let profile = profileKey && config.profiles ? config.profiles[profileKey] : null;
|
|
114
|
+
if (!profile && profileName && config.profiles) {
|
|
115
|
+
const matches = Object.entries(config.profiles).find(([key, entry]) => {
|
|
116
|
+
const displayName = (0, type_1.getProfileDisplayName)(key, entry);
|
|
117
|
+
return (displayName === profileName ||
|
|
118
|
+
entry.name === profileName ||
|
|
119
|
+
key === profileName);
|
|
120
|
+
});
|
|
121
|
+
if (matches)
|
|
122
|
+
profile = matches[1];
|
|
123
|
+
}
|
|
124
|
+
const sessionUsage = hasExplicitUsage ? usage : stdinUsage;
|
|
125
|
+
const pricing = (0, pricing_1.resolvePricingForProfile)(config, profile || null, model);
|
|
126
|
+
let sessionCost = null;
|
|
127
|
+
if (hasExplicitUsage) {
|
|
128
|
+
sessionCost = sessionUsage
|
|
129
|
+
? (0, pricing_1.calculateUsageCost)(sessionUsage, pricing)
|
|
130
|
+
: null;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
const sessionCostFromRecords = sessionId
|
|
134
|
+
? (0, usage_1.readUsageSessionCost)(config, configPath, type, sessionId, args.syncUsage)
|
|
135
|
+
: null;
|
|
136
|
+
sessionCost =
|
|
137
|
+
sessionCostFromRecords !== null && sessionCostFromRecords !== void 0 ? sessionCostFromRecords : (sessionUsage ? (0, pricing_1.calculateUsageCost)(sessionUsage, pricing) : null);
|
|
138
|
+
}
|
|
139
|
+
const costIndex = (0, usage_1.readUsageCostIndex)(config, configPath, args.syncUsage);
|
|
140
|
+
const costTotals = costIndex
|
|
141
|
+
? (0, usage_1.resolveUsageCostForProfile)(costIndex, type, profileKey, profileName)
|
|
142
|
+
: null;
|
|
143
|
+
const todayCost = costTotals ? costTotals.today : null;
|
|
144
|
+
const usageSegment = (0, format_1.formatUsageSegment)(todayCost, sessionCost);
|
|
107
145
|
const contextLeft = (0, input_1.getContextLeftPercent)(stdinInput, type);
|
|
108
146
|
const contextSegment = (0, format_1.formatContextSegment)(contextLeft);
|
|
109
147
|
const contextUsedTokens = (0, input_1.getContextUsedTokens)(stdinInput);
|
package/bin/statusline/input.js
CHANGED
|
@@ -17,6 +17,8 @@ const fs = require("fs");
|
|
|
17
17
|
const constants_1 = require("../constants");
|
|
18
18
|
const type_1 = require("../profile/type");
|
|
19
19
|
const utils_1 = require("./utils");
|
|
20
|
+
const claude_1 = require("./usage/claude");
|
|
21
|
+
const codex_1 = require("./usage/codex");
|
|
20
22
|
function readStdinJson() {
|
|
21
23
|
if (process.stdin.isTTY)
|
|
22
24
|
return null;
|
|
@@ -92,101 +94,17 @@ function getInputProfile(input) {
|
|
|
92
94
|
return null;
|
|
93
95
|
return input.profile;
|
|
94
96
|
}
|
|
95
|
-
function getInputUsage(input) {
|
|
96
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
97
|
+
function getInputUsage(input, type) {
|
|
97
98
|
if (!input)
|
|
98
99
|
return null;
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
const normalized = normalizeTypeValue(type);
|
|
101
|
+
if (normalized === "codex") {
|
|
102
|
+
return (0, codex_1.getCodexInputUsage)(input);
|
|
101
103
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (typeof tokenUsage === "number") {
|
|
105
|
-
return {
|
|
106
|
-
todayTokens: null,
|
|
107
|
-
totalTokens: (0, utils_1.coerceNumber)(tokenUsage),
|
|
108
|
-
inputTokens: null,
|
|
109
|
-
outputTokens: null,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
if ((0, utils_1.isRecord)(tokenUsage)) {
|
|
113
|
-
const record = tokenUsage;
|
|
114
|
-
const todayTokens = (_a = (0, utils_1.firstNumber)(record.todayTokens, record.today, record.today_tokens, record.daily, record.daily_tokens)) !== null && _a !== void 0 ? _a : null;
|
|
115
|
-
const totalTokens = (_b = (0, utils_1.firstNumber)(record.totalTokens, record.total, record.total_tokens)) !== null && _b !== void 0 ? _b : null;
|
|
116
|
-
const inputTokens = (_c = (0, utils_1.firstNumber)(record.inputTokens, record.input, record.input_tokens)) !== null && _c !== void 0 ? _c : null;
|
|
117
|
-
const outputTokens = (_d = (0, utils_1.firstNumber)(record.outputTokens, record.output, record.output_tokens)) !== null && _d !== void 0 ? _d : null;
|
|
118
|
-
const cacheRead = (_e = (0, utils_1.firstNumber)(record.cache_read_input_tokens, record.cacheReadInputTokens, record.cache_read, record.cacheRead)) !== null && _e !== void 0 ? _e : null;
|
|
119
|
-
const cacheWrite = (_f = (0, utils_1.firstNumber)(record.cache_creation_input_tokens, record.cacheCreationInputTokens, record.cache_write_input_tokens, record.cacheWriteInputTokens, record.cache_write, record.cacheWrite)) !== null && _f !== void 0 ? _f : null;
|
|
120
|
-
if (todayTokens === null &&
|
|
121
|
-
totalTokens === null &&
|
|
122
|
-
inputTokens === null &&
|
|
123
|
-
outputTokens === null &&
|
|
124
|
-
cacheRead === null &&
|
|
125
|
-
cacheWrite === null) {
|
|
126
|
-
return null;
|
|
127
|
-
}
|
|
128
|
-
const hasCacheTokens = cacheRead !== null || cacheWrite !== null;
|
|
129
|
-
const computedTotal = hasCacheTokens
|
|
130
|
-
? (inputTokens || 0) +
|
|
131
|
-
(outputTokens || 0) +
|
|
132
|
-
(cacheRead || 0) +
|
|
133
|
-
(cacheWrite || 0)
|
|
134
|
-
: null;
|
|
135
|
-
const resolvedTodayTokens = hasCacheTokens
|
|
136
|
-
? (_g = todayTokens !== null && todayTokens !== void 0 ? todayTokens : totalTokens) !== null && _g !== void 0 ? _g : computedTotal
|
|
137
|
-
: todayTokens;
|
|
138
|
-
return {
|
|
139
|
-
todayTokens: resolvedTodayTokens,
|
|
140
|
-
totalTokens: totalTokens !== null && totalTokens !== void 0 ? totalTokens : null,
|
|
141
|
-
inputTokens,
|
|
142
|
-
outputTokens,
|
|
143
|
-
};
|
|
144
|
-
}
|
|
104
|
+
if (normalized === "claude") {
|
|
105
|
+
return (0, claude_1.getClaudeInputUsage)(input);
|
|
145
106
|
}
|
|
146
|
-
|
|
147
|
-
? input.context_window
|
|
148
|
-
: (0, utils_1.isRecord)(input.contextWindow)
|
|
149
|
-
? input.contextWindow
|
|
150
|
-
: null;
|
|
151
|
-
if (!contextWindow)
|
|
152
|
-
return null;
|
|
153
|
-
const totalInputTokens = (_h = (0, utils_1.firstNumber)(contextWindow.total_input_tokens, contextWindow.totalInputTokens)) !== null && _h !== void 0 ? _h : null;
|
|
154
|
-
const totalOutputTokens = (_j = (0, utils_1.firstNumber)(contextWindow.total_output_tokens, contextWindow.totalOutputTokens)) !== null && _j !== void 0 ? _j : null;
|
|
155
|
-
if (totalInputTokens !== null || totalOutputTokens !== null) {
|
|
156
|
-
return {
|
|
157
|
-
todayTokens: null,
|
|
158
|
-
totalTokens: null,
|
|
159
|
-
inputTokens: totalInputTokens,
|
|
160
|
-
outputTokens: totalOutputTokens,
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
const currentUsage = (0, utils_1.isRecord)(contextWindow.current_usage)
|
|
164
|
-
? contextWindow.current_usage
|
|
165
|
-
: (0, utils_1.isRecord)(contextWindow.currentUsage)
|
|
166
|
-
? contextWindow.currentUsage
|
|
167
|
-
: null;
|
|
168
|
-
if (!currentUsage)
|
|
169
|
-
return null;
|
|
170
|
-
const inputTokens = (_k = (0, utils_1.firstNumber)(currentUsage.input_tokens, currentUsage.inputTokens)) !== null && _k !== void 0 ? _k : null;
|
|
171
|
-
const outputTokens = (_l = (0, utils_1.firstNumber)(currentUsage.output_tokens, currentUsage.outputTokens)) !== null && _l !== void 0 ? _l : null;
|
|
172
|
-
const cacheRead = (_m = (0, utils_1.firstNumber)(currentUsage.cache_read_input_tokens, currentUsage.cacheReadInputTokens)) !== null && _m !== void 0 ? _m : null;
|
|
173
|
-
const cacheWrite = (_o = (0, utils_1.firstNumber)(currentUsage.cache_creation_input_tokens, currentUsage.cacheCreationInputTokens)) !== null && _o !== void 0 ? _o : null;
|
|
174
|
-
if (inputTokens === null &&
|
|
175
|
-
outputTokens === null &&
|
|
176
|
-
cacheRead === null &&
|
|
177
|
-
cacheWrite === null) {
|
|
178
|
-
return null;
|
|
179
|
-
}
|
|
180
|
-
const totalTokens = (inputTokens || 0) +
|
|
181
|
-
(outputTokens || 0) +
|
|
182
|
-
(cacheRead || 0) +
|
|
183
|
-
(cacheWrite || 0);
|
|
184
|
-
return {
|
|
185
|
-
todayTokens: totalTokens,
|
|
186
|
-
totalTokens: null,
|
|
187
|
-
inputTokens,
|
|
188
|
-
outputTokens,
|
|
189
|
-
};
|
|
107
|
+
return (0, codex_1.getCodexInputUsage)(input) || (0, claude_1.getClaudeInputUsage)(input);
|
|
190
108
|
}
|
|
191
109
|
function getSessionId(input) {
|
|
192
110
|
if (!input)
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getClaudeUsageTotalsFromInput = getClaudeUsageTotalsFromInput;
|
|
4
|
+
exports.getClaudeInputUsage = getClaudeInputUsage;
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
function resolveContextWindow(input) {
|
|
7
|
+
if ((0, utils_1.isRecord)(input.context_window)) {
|
|
8
|
+
return input.context_window;
|
|
9
|
+
}
|
|
10
|
+
if ((0, utils_1.isRecord)(input.contextWindow)) {
|
|
11
|
+
return input.contextWindow;
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
function resolveCurrentUsage(contextWindow) {
|
|
16
|
+
if ((0, utils_1.isRecord)(contextWindow.current_usage)) {
|
|
17
|
+
return contextWindow.current_usage;
|
|
18
|
+
}
|
|
19
|
+
if ((0, utils_1.isRecord)(contextWindow.currentUsage)) {
|
|
20
|
+
return contextWindow.currentUsage;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
function parseClaudeUsageTotalsRecord(record) {
|
|
25
|
+
var _a, _b, _c, _d, _e;
|
|
26
|
+
const inputTokens = (_a = (0, utils_1.firstNumber)(record.inputTokens, record.input, record.input_tokens)) !== null && _a !== void 0 ? _a : null;
|
|
27
|
+
const outputTokens = (_b = (0, utils_1.firstNumber)(record.outputTokens, record.output, record.output_tokens)) !== null && _b !== void 0 ? _b : null;
|
|
28
|
+
const cacheRead = (_c = (0, utils_1.firstNumber)(record.cache_read_input_tokens, record.cacheReadInputTokens, record.cache_read, record.cacheRead)) !== null && _c !== void 0 ? _c : null;
|
|
29
|
+
const cacheWrite = (_d = (0, utils_1.firstNumber)(record.cache_creation_input_tokens, record.cacheCreationInputTokens, record.cache_write_input_tokens, record.cacheWriteInputTokens, record.cache_write, record.cacheWrite)) !== null && _d !== void 0 ? _d : null;
|
|
30
|
+
const totalTokens = (_e = (0, utils_1.firstNumber)(record.totalTokens, record.total, record.total_tokens)) !== null && _e !== void 0 ? _e : null;
|
|
31
|
+
let computedTotal = null;
|
|
32
|
+
if (inputTokens !== null ||
|
|
33
|
+
outputTokens !== null ||
|
|
34
|
+
cacheRead !== null ||
|
|
35
|
+
cacheWrite !== null) {
|
|
36
|
+
computedTotal =
|
|
37
|
+
(inputTokens || 0) +
|
|
38
|
+
(outputTokens || 0) +
|
|
39
|
+
(cacheRead || 0) +
|
|
40
|
+
(cacheWrite || 0);
|
|
41
|
+
}
|
|
42
|
+
const resolvedTotal = totalTokens !== null && totalTokens !== void 0 ? totalTokens : computedTotal;
|
|
43
|
+
if (inputTokens === null &&
|
|
44
|
+
outputTokens === null &&
|
|
45
|
+
cacheRead === null &&
|
|
46
|
+
cacheWrite === null &&
|
|
47
|
+
resolvedTotal === null) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
inputTokens,
|
|
52
|
+
outputTokens,
|
|
53
|
+
cacheReadTokens: cacheRead,
|
|
54
|
+
cacheWriteTokens: cacheWrite,
|
|
55
|
+
totalTokens: resolvedTotal,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function parseClaudeInputUsageRecord(record) {
|
|
59
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
60
|
+
const todayTokens = (_a = (0, utils_1.firstNumber)(record.todayTokens, record.today, record.today_tokens, record.daily, record.daily_tokens)) !== null && _a !== void 0 ? _a : null;
|
|
61
|
+
const totalTokens = (_b = (0, utils_1.firstNumber)(record.totalTokens, record.total, record.total_tokens)) !== null && _b !== void 0 ? _b : null;
|
|
62
|
+
const inputTokens = (_c = (0, utils_1.firstNumber)(record.inputTokens, record.input, record.input_tokens)) !== null && _c !== void 0 ? _c : null;
|
|
63
|
+
const outputTokens = (_d = (0, utils_1.firstNumber)(record.outputTokens, record.output, record.output_tokens)) !== null && _d !== void 0 ? _d : null;
|
|
64
|
+
const cacheRead = (_e = (0, utils_1.firstNumber)(record.cache_read_input_tokens, record.cacheReadInputTokens, record.cache_read, record.cacheRead)) !== null && _e !== void 0 ? _e : null;
|
|
65
|
+
const cacheWrite = (_f = (0, utils_1.firstNumber)(record.cache_creation_input_tokens, record.cacheCreationInputTokens, record.cache_write_input_tokens, record.cacheWriteInputTokens, record.cache_write, record.cacheWrite)) !== null && _f !== void 0 ? _f : null;
|
|
66
|
+
if (todayTokens === null &&
|
|
67
|
+
totalTokens === null &&
|
|
68
|
+
inputTokens === null &&
|
|
69
|
+
outputTokens === null &&
|
|
70
|
+
cacheRead === null &&
|
|
71
|
+
cacheWrite === null) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const hasCacheTokens = cacheRead !== null || cacheWrite !== null;
|
|
75
|
+
const computedTotal = hasCacheTokens
|
|
76
|
+
? (inputTokens || 0) +
|
|
77
|
+
(outputTokens || 0) +
|
|
78
|
+
(cacheRead || 0) +
|
|
79
|
+
(cacheWrite || 0)
|
|
80
|
+
: null;
|
|
81
|
+
const resolvedTodayTokens = hasCacheTokens
|
|
82
|
+
? (_g = todayTokens !== null && todayTokens !== void 0 ? todayTokens : totalTokens) !== null && _g !== void 0 ? _g : computedTotal
|
|
83
|
+
: todayTokens;
|
|
84
|
+
return {
|
|
85
|
+
todayTokens: resolvedTodayTokens,
|
|
86
|
+
totalTokens: totalTokens !== null && totalTokens !== void 0 ? totalTokens : null,
|
|
87
|
+
inputTokens,
|
|
88
|
+
outputTokens,
|
|
89
|
+
cacheReadTokens: cacheRead,
|
|
90
|
+
cacheWriteTokens: cacheWrite,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function parseTotalsFromContextWindow(contextWindow) {
|
|
94
|
+
var _a, _b, _c, _d;
|
|
95
|
+
const inputTokens = (_a = (0, utils_1.firstNumber)(contextWindow.total_input_tokens, contextWindow.totalInputTokens)) !== null && _a !== void 0 ? _a : null;
|
|
96
|
+
const outputTokens = (_b = (0, utils_1.firstNumber)(contextWindow.total_output_tokens, contextWindow.totalOutputTokens)) !== null && _b !== void 0 ? _b : null;
|
|
97
|
+
if (inputTokens === null && outputTokens === null)
|
|
98
|
+
return null;
|
|
99
|
+
const currentUsage = resolveCurrentUsage(contextWindow);
|
|
100
|
+
const cacheRead = currentUsage
|
|
101
|
+
? (_c = (0, utils_1.firstNumber)(currentUsage.cache_read_input_tokens, currentUsage.cacheReadInputTokens)) !== null && _c !== void 0 ? _c : null
|
|
102
|
+
: null;
|
|
103
|
+
const cacheWrite = currentUsage
|
|
104
|
+
? (_d = (0, utils_1.firstNumber)(currentUsage.cache_creation_input_tokens, currentUsage.cacheCreationInputTokens)) !== null && _d !== void 0 ? _d : null
|
|
105
|
+
: null;
|
|
106
|
+
const totalTokens = (inputTokens || 0) +
|
|
107
|
+
(outputTokens || 0) +
|
|
108
|
+
(cacheRead || 0) +
|
|
109
|
+
(cacheWrite || 0);
|
|
110
|
+
return {
|
|
111
|
+
inputTokens,
|
|
112
|
+
outputTokens,
|
|
113
|
+
cacheReadTokens: cacheRead,
|
|
114
|
+
cacheWriteTokens: cacheWrite,
|
|
115
|
+
totalTokens,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function getClaudeUsageTotalsFromInput(input) {
|
|
119
|
+
if (!input)
|
|
120
|
+
return null;
|
|
121
|
+
const contextWindow = resolveContextWindow(input);
|
|
122
|
+
if (contextWindow) {
|
|
123
|
+
const totals = parseTotalsFromContextWindow(contextWindow);
|
|
124
|
+
if (totals)
|
|
125
|
+
return totals;
|
|
126
|
+
}
|
|
127
|
+
if ((0, utils_1.isRecord)(input.usage)) {
|
|
128
|
+
return parseClaudeUsageTotalsRecord(input.usage);
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
function getClaudeInputUsage(input) {
|
|
133
|
+
var _a, _b, _c, _d;
|
|
134
|
+
if (!input)
|
|
135
|
+
return null;
|
|
136
|
+
if ((0, utils_1.isRecord)(input.usage)) {
|
|
137
|
+
const parsed = parseClaudeInputUsageRecord(input.usage);
|
|
138
|
+
if (parsed)
|
|
139
|
+
return parsed;
|
|
140
|
+
return input.usage;
|
|
141
|
+
}
|
|
142
|
+
const contextWindow = resolveContextWindow(input);
|
|
143
|
+
if (!contextWindow)
|
|
144
|
+
return null;
|
|
145
|
+
const totals = parseTotalsFromContextWindow(contextWindow);
|
|
146
|
+
if (totals) {
|
|
147
|
+
return {
|
|
148
|
+
todayTokens: null,
|
|
149
|
+
totalTokens: null,
|
|
150
|
+
inputTokens: totals.inputTokens,
|
|
151
|
+
outputTokens: totals.outputTokens,
|
|
152
|
+
cacheReadTokens: totals.cacheReadTokens,
|
|
153
|
+
cacheWriteTokens: totals.cacheWriteTokens,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
const currentUsage = resolveCurrentUsage(contextWindow);
|
|
157
|
+
if (!currentUsage)
|
|
158
|
+
return null;
|
|
159
|
+
const inputTokens = (_a = (0, utils_1.firstNumber)(currentUsage.input_tokens, currentUsage.inputTokens)) !== null && _a !== void 0 ? _a : null;
|
|
160
|
+
const outputTokens = (_b = (0, utils_1.firstNumber)(currentUsage.output_tokens, currentUsage.outputTokens)) !== null && _b !== void 0 ? _b : null;
|
|
161
|
+
const cacheRead = (_c = (0, utils_1.firstNumber)(currentUsage.cache_read_input_tokens, currentUsage.cacheReadInputTokens)) !== null && _c !== void 0 ? _c : null;
|
|
162
|
+
const cacheWrite = (_d = (0, utils_1.firstNumber)(currentUsage.cache_creation_input_tokens, currentUsage.cacheCreationInputTokens)) !== null && _d !== void 0 ? _d : null;
|
|
163
|
+
if (inputTokens === null &&
|
|
164
|
+
outputTokens === null &&
|
|
165
|
+
cacheRead === null &&
|
|
166
|
+
cacheWrite === null) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
const totalTokens = (inputTokens || 0) +
|
|
170
|
+
(outputTokens || 0) +
|
|
171
|
+
(cacheRead || 0) +
|
|
172
|
+
(cacheWrite || 0);
|
|
173
|
+
return {
|
|
174
|
+
todayTokens: totalTokens,
|
|
175
|
+
totalTokens: null,
|
|
176
|
+
inputTokens,
|
|
177
|
+
outputTokens,
|
|
178
|
+
cacheReadTokens: cacheRead,
|
|
179
|
+
cacheWriteTokens: cacheWrite,
|
|
180
|
+
};
|
|
181
|
+
}
|