devrage 0.5.3 → 0.5.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/dist/cli.js +95 -25
- package/dist/cli.js.map +2 -2
- package/dist/lib/adapters/codex.d.ts.map +1 -1
- package/dist/lib/adapters/codex.js +38 -4
- package/dist/lib/adapters/codex.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -569,11 +569,19 @@ function codexAdapter() {
|
|
|
569
569
|
}
|
|
570
570
|
},
|
|
571
571
|
async *usage(options) {
|
|
572
|
+
const seenUsage = /* @__PURE__ */ new Set();
|
|
572
573
|
for await (const file of discoverCodexSessionFiles(CODEX_SESSIONS_DIR)) {
|
|
573
|
-
|
|
574
|
+
for await (const record of parseCodexUsageJsonl(file.filePath, {
|
|
574
575
|
session: file.session,
|
|
575
576
|
since: options?.since
|
|
576
|
-
})
|
|
577
|
+
})) {
|
|
578
|
+
const key = codexUsageRecordKey(record);
|
|
579
|
+
if (seenUsage.has(key)) {
|
|
580
|
+
continue;
|
|
581
|
+
}
|
|
582
|
+
seenUsage.add(key);
|
|
583
|
+
yield record;
|
|
584
|
+
}
|
|
577
585
|
}
|
|
578
586
|
}
|
|
579
587
|
};
|
|
@@ -591,10 +599,15 @@ async function* discoverCodexSessionFiles(dir) {
|
|
|
591
599
|
if (entryStat.isDirectory()) {
|
|
592
600
|
yield* discoverCodexSessionFiles(fullPath);
|
|
593
601
|
} else if (entry.endsWith(".jsonl")) {
|
|
594
|
-
yield { filePath: fullPath, session: entry
|
|
602
|
+
yield { filePath: fullPath, session: sessionFromRolloutFileName(entry) };
|
|
595
603
|
}
|
|
596
604
|
}
|
|
597
605
|
}
|
|
606
|
+
function sessionFromRolloutFileName(fileName) {
|
|
607
|
+
return fileName.match(
|
|
608
|
+
/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i
|
|
609
|
+
)?.[1] ?? fileName.replace(".jsonl", "");
|
|
610
|
+
}
|
|
598
611
|
async function* parseCodexJsonl(filePath, context) {
|
|
599
612
|
const rl = createInterface2({
|
|
600
613
|
input: createReadStream2(filePath, { encoding: "utf-8" }),
|
|
@@ -655,6 +668,8 @@ async function* parseCodexUsageJsonl(filePath, context) {
|
|
|
655
668
|
let model;
|
|
656
669
|
let previousTotal = null;
|
|
657
670
|
let previousUsageSignature = null;
|
|
671
|
+
let session = context.session;
|
|
672
|
+
let sawSessionMeta = false;
|
|
658
673
|
for await (const line of rl) {
|
|
659
674
|
if (!line.trim()) {
|
|
660
675
|
continue;
|
|
@@ -662,6 +677,14 @@ async function* parseCodexUsageJsonl(filePath, context) {
|
|
|
662
677
|
try {
|
|
663
678
|
const entry = JSON.parse(line);
|
|
664
679
|
const payload = asRecord3(entry["payload"]);
|
|
680
|
+
if (entry["type"] === "session_meta") {
|
|
681
|
+
const metaSession = stringValue2(payload?.["id"]) ?? stringValue2(entry["id"]);
|
|
682
|
+
if (metaSession && !sawSessionMeta) {
|
|
683
|
+
session = metaSession;
|
|
684
|
+
sawSessionMeta = true;
|
|
685
|
+
}
|
|
686
|
+
continue;
|
|
687
|
+
}
|
|
665
688
|
if (entry["type"] === "turn_context") {
|
|
666
689
|
model = stringValue2(payload?.["model"]) ?? model;
|
|
667
690
|
continue;
|
|
@@ -710,7 +733,7 @@ async function* parseCodexUsageJsonl(filePath, context) {
|
|
|
710
733
|
provider: "openai",
|
|
711
734
|
model,
|
|
712
735
|
timestamp,
|
|
713
|
-
session
|
|
736
|
+
session,
|
|
714
737
|
inputTokens: Math.max(usage2.inputTokens - usage2.cachedInputTokens, 0),
|
|
715
738
|
outputTokens: Math.max(usage2.outputTokens - reasoningTokens, 0),
|
|
716
739
|
reasoningTokens,
|
|
@@ -721,6 +744,19 @@ async function* parseCodexUsageJsonl(filePath, context) {
|
|
|
721
744
|
}
|
|
722
745
|
}
|
|
723
746
|
}
|
|
747
|
+
function codexUsageRecordKey(record) {
|
|
748
|
+
return JSON.stringify([
|
|
749
|
+
record.session ?? "",
|
|
750
|
+
record.timestamp ?? "",
|
|
751
|
+
record.provider ?? "",
|
|
752
|
+
record.model ?? "",
|
|
753
|
+
record.inputTokens,
|
|
754
|
+
record.outputTokens,
|
|
755
|
+
record.reasoningTokens,
|
|
756
|
+
record.cacheReadTokens,
|
|
757
|
+
record.cacheWriteTokens
|
|
758
|
+
]);
|
|
759
|
+
}
|
|
724
760
|
function parseCodexTokenUsage(value) {
|
|
725
761
|
const usage2 = asRecord3(value);
|
|
726
762
|
if (!usage2) {
|
|
@@ -2430,30 +2466,49 @@ var SPINNER_MESSAGES = [
|
|
|
2430
2466
|
"Auditing your language",
|
|
2431
2467
|
"Tabulating regrets"
|
|
2432
2468
|
];
|
|
2469
|
+
var COST_SPINNER_MESSAGES = [
|
|
2470
|
+
"Loading price catalog",
|
|
2471
|
+
"Reading local usage",
|
|
2472
|
+
"Scanning transcript stores",
|
|
2473
|
+
"Crunching token counts",
|
|
2474
|
+
"Still working through local history"
|
|
2475
|
+
];
|
|
2433
2476
|
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
2434
2477
|
function createSpinner(messages = SPINNER_MESSAGES) {
|
|
2435
2478
|
let messageIdx = 0;
|
|
2436
2479
|
let dotCount = 0;
|
|
2437
2480
|
let timer = null;
|
|
2481
|
+
let messageOverride = null;
|
|
2482
|
+
function render() {
|
|
2483
|
+
dotCount = (dotCount + 1) % 4;
|
|
2484
|
+
const msg = messageOverride ?? messages[messageIdx % messages.length];
|
|
2485
|
+
const dots = ".".repeat(dotCount || 1);
|
|
2486
|
+
process.stdout.write(`\r ${c.dim}${msg}${dots}${c.reset} `);
|
|
2487
|
+
}
|
|
2438
2488
|
return {
|
|
2439
|
-
start() {
|
|
2489
|
+
start(message) {
|
|
2440
2490
|
messageIdx = Math.floor(Math.random() * messages.length);
|
|
2491
|
+
messageOverride = message ?? null;
|
|
2492
|
+
render();
|
|
2441
2493
|
timer = setInterval(() => {
|
|
2442
|
-
|
|
2443
|
-
const msg = messages[messageIdx % messages.length];
|
|
2444
|
-
const dots = ".".repeat(dotCount || 1);
|
|
2445
|
-
process.stdout.write(`\r ${c.dim}${msg}${dots}${c.reset} `);
|
|
2494
|
+
render();
|
|
2446
2495
|
}, 300);
|
|
2447
2496
|
},
|
|
2448
|
-
update() {
|
|
2449
|
-
|
|
2497
|
+
update(message) {
|
|
2498
|
+
if (message) {
|
|
2499
|
+
messageOverride = message;
|
|
2500
|
+
} else {
|
|
2501
|
+
messageOverride = null;
|
|
2502
|
+
messageIdx++;
|
|
2503
|
+
}
|
|
2504
|
+
render();
|
|
2450
2505
|
},
|
|
2451
2506
|
stop() {
|
|
2452
2507
|
if (timer) {
|
|
2453
2508
|
clearInterval(timer);
|
|
2454
2509
|
timer = null;
|
|
2455
2510
|
}
|
|
2456
|
-
process.stdout.write("\r" + " ".repeat(
|
|
2511
|
+
process.stdout.write("\r" + " ".repeat(80) + "\r");
|
|
2457
2512
|
}
|
|
2458
2513
|
};
|
|
2459
2514
|
}
|
|
@@ -2636,23 +2691,38 @@ async function cost(args) {
|
|
|
2636
2691
|
const options = parseCostArgs(args);
|
|
2637
2692
|
const adapters = options.agent ? [createAdapter(options.agent)] : allAdapters();
|
|
2638
2693
|
const costByAgent = {};
|
|
2639
|
-
const
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
}
|
|
2644
|
-
const
|
|
2645
|
-
|
|
2646
|
-
|
|
2694
|
+
const spinner = createSpinner(COST_SPINNER_MESSAGES);
|
|
2695
|
+
let totals = null;
|
|
2696
|
+
spinner.start("Loading price catalog");
|
|
2697
|
+
try {
|
|
2698
|
+
const pricing = await loadPricingCatalog({ refresh: options.refreshPrices });
|
|
2699
|
+
for (const adapter of adapters) {
|
|
2700
|
+
if (!adapter.usage) {
|
|
2701
|
+
continue;
|
|
2702
|
+
}
|
|
2703
|
+
spinner.update(`Reading ${adapter.name} usage`);
|
|
2704
|
+
const summary = await summarizeUsage(adapter.usage({ since: options.since }), pricing);
|
|
2705
|
+
if (summary.requests > 0) {
|
|
2706
|
+
costByAgent[adapter.name] = summary;
|
|
2707
|
+
}
|
|
2647
2708
|
}
|
|
2709
|
+
totals = getCostTotals(costByAgent);
|
|
2710
|
+
} finally {
|
|
2711
|
+
spinner.stop();
|
|
2648
2712
|
}
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
if (totals.entries.length === 0) {
|
|
2713
|
+
if (!totals || totals.entries.length === 0) {
|
|
2714
|
+
console.log("");
|
|
2652
2715
|
printCostCommandUnavailable(options);
|
|
2653
2716
|
return;
|
|
2654
2717
|
}
|
|
2655
|
-
|
|
2718
|
+
spinner.start("Writing cost report");
|
|
2719
|
+
let reportUrl;
|
|
2720
|
+
try {
|
|
2721
|
+
reportUrl = await writeCostHtmlReport(totals, options);
|
|
2722
|
+
} finally {
|
|
2723
|
+
spinner.stop();
|
|
2724
|
+
}
|
|
2725
|
+
console.log("");
|
|
2656
2726
|
printCostCommand(totals, options, reportUrl);
|
|
2657
2727
|
}
|
|
2658
2728
|
function printCostCommand(totals, options, reportUrl) {
|
|
@@ -3175,7 +3245,7 @@ async function main() {
|
|
|
3175
3245
|
process.exit(0);
|
|
3176
3246
|
}
|
|
3177
3247
|
if (command === "--version") {
|
|
3178
|
-
console.log("0.5.
|
|
3248
|
+
console.log("0.5.5");
|
|
3179
3249
|
process.exit(0);
|
|
3180
3250
|
}
|
|
3181
3251
|
const parsed = parseCommand(args);
|