@usevalt/cli 0.4.0 → 0.5.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/dist/index.js +42 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1010,7 +1010,7 @@ async function readStdin() {
|
|
|
1010
1010
|
process.stdin.setEncoding("utf-8");
|
|
1011
1011
|
process.stdin.on("data", (chunk) => chunks.push(String(chunk)));
|
|
1012
1012
|
process.stdin.on("end", () => resolve4(chunks.join("")));
|
|
1013
|
-
setTimeout(() => resolve4(chunks.join("")),
|
|
1013
|
+
setTimeout(() => resolve4(chunks.join("")), 500);
|
|
1014
1014
|
});
|
|
1015
1015
|
return data.trim() ? JSON.parse(data) : {};
|
|
1016
1016
|
} catch {
|
|
@@ -1067,13 +1067,28 @@ async function sendEvents(endpoint, apiKey, events) {
|
|
|
1067
1067
|
return false;
|
|
1068
1068
|
}
|
|
1069
1069
|
}
|
|
1070
|
+
var MODEL_PRICING = {
|
|
1071
|
+
"claude-opus-4-6": { input: 15, output: 75, cacheRead: 1.5 },
|
|
1072
|
+
"claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3 },
|
|
1073
|
+
"claude-haiku-4-5": { input: 0.8, output: 4, cacheRead: 0.08 },
|
|
1074
|
+
// Legacy model names
|
|
1075
|
+
"claude-3-5-sonnet": { input: 3, output: 15, cacheRead: 0.3 },
|
|
1076
|
+
"claude-3-5-haiku": { input: 0.8, output: 4, cacheRead: 0.08 },
|
|
1077
|
+
"claude-3-opus": { input: 15, output: 75, cacheRead: 1.5 }
|
|
1078
|
+
};
|
|
1079
|
+
function calculateCost(model, promptTokens, completionTokens, cacheReadTokens) {
|
|
1080
|
+
const pricing = MODEL_PRICING[model] ?? Object.entries(MODEL_PRICING).find(([key]) => model.startsWith(key))?.[1];
|
|
1081
|
+
if (!pricing) return 0;
|
|
1082
|
+
return promptTokens / 1e6 * pricing.input + completionTokens / 1e6 * pricing.output + cacheReadTokens / 1e6 * pricing.cacheRead;
|
|
1083
|
+
}
|
|
1070
1084
|
async function parseTranscript(transcriptPath) {
|
|
1071
1085
|
const result = {
|
|
1072
1086
|
totalCostUsd: 0,
|
|
1073
1087
|
promptTokens: 0,
|
|
1074
1088
|
completionTokens: 0,
|
|
1075
1089
|
cacheReadTokens: 0,
|
|
1076
|
-
cacheCreationTokens: 0
|
|
1090
|
+
cacheCreationTokens: 0,
|
|
1091
|
+
model: "unknown"
|
|
1077
1092
|
};
|
|
1078
1093
|
if (!existsSync3(transcriptPath)) return result;
|
|
1079
1094
|
try {
|
|
@@ -1085,11 +1100,16 @@ async function parseTranscript(transcriptPath) {
|
|
|
1085
1100
|
if (!line.trim()) continue;
|
|
1086
1101
|
try {
|
|
1087
1102
|
const entry = JSON.parse(line);
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
result.
|
|
1091
|
-
result.
|
|
1092
|
-
result.
|
|
1103
|
+
const usage = entry.message?.usage ?? entry.usage;
|
|
1104
|
+
if (usage) {
|
|
1105
|
+
result.promptTokens += usage.input_tokens ?? 0;
|
|
1106
|
+
result.completionTokens += usage.output_tokens ?? 0;
|
|
1107
|
+
result.cacheReadTokens += usage.cache_read_input_tokens ?? 0;
|
|
1108
|
+
result.cacheCreationTokens += usage.cache_creation_input_tokens ?? 0;
|
|
1109
|
+
}
|
|
1110
|
+
const model = entry.message?.model ?? entry.model;
|
|
1111
|
+
if (model && result.model === "unknown") {
|
|
1112
|
+
result.model = model;
|
|
1093
1113
|
}
|
|
1094
1114
|
if (typeof entry.costUSD === "number") {
|
|
1095
1115
|
result.totalCostUsd += entry.costUSD;
|
|
@@ -1099,6 +1119,14 @@ async function parseTranscript(transcriptPath) {
|
|
|
1099
1119
|
}
|
|
1100
1120
|
} catch {
|
|
1101
1121
|
}
|
|
1122
|
+
if (result.totalCostUsd === 0 && result.promptTokens > 0) {
|
|
1123
|
+
result.totalCostUsd = calculateCost(
|
|
1124
|
+
result.model,
|
|
1125
|
+
result.promptTokens,
|
|
1126
|
+
result.completionTokens,
|
|
1127
|
+
result.cacheReadTokens
|
|
1128
|
+
);
|
|
1129
|
+
}
|
|
1102
1130
|
return result;
|
|
1103
1131
|
}
|
|
1104
1132
|
var sessionStartCommand = new Command13("session-start").description("Hook: called when a Claude Code session starts").action(async () => {
|
|
@@ -1178,6 +1206,7 @@ var sessionEndCommand = new Command13("session-end").description("Hook: called w
|
|
|
1178
1206
|
timestamp: now.toISOString(),
|
|
1179
1207
|
duration_ms: durationMs,
|
|
1180
1208
|
tool: "claude-code",
|
|
1209
|
+
model: metrics?.model ?? session.model,
|
|
1181
1210
|
metadata: {
|
|
1182
1211
|
started_at: session.startedAt,
|
|
1183
1212
|
ended_at: now.toISOString(),
|
|
@@ -1202,22 +1231,21 @@ var sessionEndCommand = new Command13("session-end").description("Hook: called w
|
|
|
1202
1231
|
tokens_completion: metrics.completionTokens,
|
|
1203
1232
|
cost_usd: metrics.totalCostUsd,
|
|
1204
1233
|
metadata: {
|
|
1234
|
+
model: metrics.model,
|
|
1205
1235
|
cache_read_tokens: metrics.cacheReadTokens,
|
|
1206
1236
|
cache_creation_tokens: metrics.cacheCreationTokens
|
|
1207
1237
|
}
|
|
1208
1238
|
});
|
|
1209
1239
|
}
|
|
1210
|
-
|
|
1240
|
+
sendEvents(session.endpoint, session.apiKey, events).catch(() => {
|
|
1241
|
+
});
|
|
1211
1242
|
try {
|
|
1212
1243
|
unlinkSync2(SESSION_FILE);
|
|
1213
1244
|
} catch {
|
|
1214
1245
|
}
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
} else {
|
|
1219
|
-
warn("Session ended locally but failed to send to Valt.");
|
|
1220
|
-
}
|
|
1246
|
+
const costStr = metrics?.totalCostUsd ? ` $${metrics.totalCostUsd.toFixed(4)}` : "";
|
|
1247
|
+
const tokenStr = metrics?.promptTokens ? ` ${metrics.promptTokens + metrics.completionTokens} tokens` : "";
|
|
1248
|
+
success(`Valt session ended: ${session.sessionId.slice(0, 8)} (${Math.round(durationMs / 1e3)}s${costStr}${tokenStr})`);
|
|
1221
1249
|
} catch {
|
|
1222
1250
|
}
|
|
1223
1251
|
});
|