@trazum/cli 1.31.0 → 1.33.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/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +14 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +14 -0
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/types.d.ts +29 -0
- package/dist/i18n/types.d.ts.map +1 -1
- package/dist/index.js +66 -1
- package/dist/index.js.map +1 -1
- package/dist/markdown.d.ts.map +1 -1
- package/dist/markdown.js +9 -0
- package/dist/markdown.js.map +1 -1
- package/package.json +2 -2
- package/src/i18n/en.ts +26 -0
- package/src/i18n/es.ts +26 -0
- package/src/i18n/types.ts +29 -0
- package/src/index.ts +69 -1
- package/src/markdown.ts +11 -0
package/dist/index.js
CHANGED
|
@@ -259,7 +259,7 @@ const COMMAND_FLAGS = {
|
|
|
259
259
|
],
|
|
260
260
|
check: ['max-tokens', 'level', 'exact-tokens', 'markdown-out', 'baseline'],
|
|
261
261
|
baseline: ['model', 'calls', 'output-tokens', 'cache-hit-rate', 'batch', 'exact-tokens', 'out', 'o'],
|
|
262
|
-
profile: ['json', 'pricing', 'pricing-live', 'against', 'what-if', 'markdown-out', 'csv-out', 'csv-shape', 'max-usd', 'max-growth-usd', 'max-cache-loss-usd', 'max-day-usd', 'max-session-usd', 'label', 'since', 'until'],
|
|
262
|
+
profile: ['json', 'pricing', 'pricing-live', 'against', 'what-if', 'markdown-out', 'csv-out', 'csv-shape', 'max-usd', 'max-growth-usd', 'max-cache-loss-usd', 'max-day-usd', 'max-session-usd', 'label', 'since', 'until', 'dry-run'],
|
|
263
263
|
route: ['prompt-file', 'cases', 'label', 'concurrency', 'json', 'yes', 'pricing', 'pricing-live'],
|
|
264
264
|
eval: ['cases', 'level', 'concurrency', 'export', 'out', 'o', 'model'],
|
|
265
265
|
prune: ['cases', 'concurrency', 'json', 'yes'],
|
|
@@ -1626,6 +1626,53 @@ async function commandProfile(args, config, pricing, t) {
|
|
|
1626
1626
|
}
|
|
1627
1627
|
const n = (value) => value.toLocaleString(t.numberLocale);
|
|
1628
1628
|
const pct = (share) => `${(share * 100).toFixed(1)}%`;
|
|
1629
|
+
/**
|
|
1630
|
+
* `--dry-run`: what this log could and could not answer, and no bill.
|
|
1631
|
+
*
|
|
1632
|
+
* The question somebody has *before* wiring Trazum into CI is not "what did
|
|
1633
|
+
* we spend" but "will this log support the gates I want" — and answering it
|
|
1634
|
+
* with a full report makes them read a bill to find out a field is missing.
|
|
1635
|
+
* This path states readiness per capability and produces no dollar figure
|
|
1636
|
+
* at all, so nothing here can be mistaken for spend. It also refuses to
|
|
1637
|
+
* coexist with the gates: a gate over a report that was never produced
|
|
1638
|
+
* would exit green having judged nothing.
|
|
1639
|
+
*/
|
|
1640
|
+
if (boolFlag(args, 'dry-run')) {
|
|
1641
|
+
const gateFlags = ['max-usd', 'max-growth-usd', 'max-cache-loss-usd', 'max-day-usd', 'max-session-usd'];
|
|
1642
|
+
if (gateFlags.some((flag) => typeof args.flags.get(flag) === 'string')) {
|
|
1643
|
+
throw new Error(t.profile.dryRunNoGates());
|
|
1644
|
+
}
|
|
1645
|
+
const cov = report.fieldCoverage;
|
|
1646
|
+
const parsed = cov.parsed;
|
|
1647
|
+
console.log(c.bold(t.profile.dryRunHeading()));
|
|
1648
|
+
console.log(` ${wrap(t.profile.dryRunParsed(n(parsed), n(report.skippedLines.length)), 74, ' ')}`);
|
|
1649
|
+
if (report.unpricedModels.length > 0) {
|
|
1650
|
+
console.log(` ${c.yellow('!')} ${wrap(t.profile.dryRunUnpriced(report.unpricedModels.join(', ')), 74, ' ')}`);
|
|
1651
|
+
}
|
|
1652
|
+
console.log();
|
|
1653
|
+
const can = (ok, line) => {
|
|
1654
|
+
console.log(` ${ok ? c.green('✓') : c.yellow('✗')} ${wrap(line, 74, ' ')}`);
|
|
1655
|
+
};
|
|
1656
|
+
const share = (count) => (parsed > 0 ? pct(count / parsed) : '0%');
|
|
1657
|
+
can(parsed > 0, t.profile.dryRunTotals());
|
|
1658
|
+
can(cov.label > 0, t.profile.dryRunLabels(share(cov.label)));
|
|
1659
|
+
can(cov.ts > 0, t.profile.dryRunClock(share(cov.ts)));
|
|
1660
|
+
can(cov.session > 0, t.profile.dryRunSessions(share(cov.session)));
|
|
1661
|
+
can(cov.stopReason > 0, t.profile.dryRunStopReason(share(cov.stopReason)));
|
|
1662
|
+
// "No cache traffic" is not a missing field: the split can only exist on
|
|
1663
|
+
// records that wrote, and a log that never wrote has nothing to record.
|
|
1664
|
+
if (cov.cacheWrites > 0) {
|
|
1665
|
+
can(cov.cacheTtl > 0, t.profile.dryRunCacheTtl(n(cov.cacheTtl), n(cov.cacheWrites)));
|
|
1666
|
+
}
|
|
1667
|
+
else {
|
|
1668
|
+
console.log(` ${c.dim('·')} ${wrap(t.profile.dryRunNoCacheTraffic(), 74, ' ')}`);
|
|
1669
|
+
}
|
|
1670
|
+
console.log();
|
|
1671
|
+
console.log(` ${c.dim(wrap(t.profile.dryRunFooter(), 74, ' '))}`);
|
|
1672
|
+
if (parsed === 0)
|
|
1673
|
+
process.exitCode = 1;
|
|
1674
|
+
return;
|
|
1675
|
+
}
|
|
1629
1676
|
/**
|
|
1630
1677
|
* The previous log, loaded before the output paths split so the growth gate
|
|
1631
1678
|
* exists under `--json` too — a CI step reads the JSON and trusts the exit
|
|
@@ -2717,9 +2764,27 @@ async function commandProfile(args, config, pricing, t) {
|
|
|
2717
2764
|
const line = t.profile.whatIfTotal(formatUsd(whatIf.currentUsd), formatUsd(whatIf.targetUsd), formatUsd(Math.abs(whatIf.deltaUsd)));
|
|
2718
2765
|
console.log(` ${cheaper ? c.green('→') : c.yellow('!')} ${c.bold(wrap(line, 74, ' '))}`);
|
|
2719
2766
|
console.log(` ${c.dim(wrap(cheaper ? t.profile.whatIfCheaper() : t.profile.whatIfDearer(), 74, ' '))}`);
|
|
2767
|
+
/**
|
|
2768
|
+
* The other half of the whole decision: the same move with the target's
|
|
2769
|
+
* Batch API on top. Computed against the target's rates, never by
|
|
2770
|
+
* adding two savings, and hedged the only honest way — whether these
|
|
2771
|
+
* calls can wait is not in the log.
|
|
2772
|
+
*/
|
|
2773
|
+
if (whatIf.batchOnTarget !== null) {
|
|
2774
|
+
console.log(` ${c.dim(wrap(t.profile.whatIfBatchOnTarget(formatUsd(whatIf.batchOnTarget.targetUsd), formatUsd(whatIf.targetUsd)), 74, ' '))}`);
|
|
2775
|
+
}
|
|
2720
2776
|
for (const slice of whatIf.slices.slice(0, 5)) {
|
|
2721
2777
|
const label = slice.label === UNLABELLED ? t.profile.unlabelled() : slice.label;
|
|
2722
2778
|
console.log(` ${c.dim('·')} ${c.dim(wrap(t.profile.whatIfSlice(label, slice.model, formatUsd(slice.currentUsd), formatUsd(slice.targetUsd)), 74, ' '))}`);
|
|
2779
|
+
/**
|
|
2780
|
+
* Cache traffic the target could not grant, said loudly and beside
|
|
2781
|
+
* the figure it corrects. The standard row prices cache entries the
|
|
2782
|
+
* target's minimum would refuse to create — an error that flatters
|
|
2783
|
+
* the move, which is the direction this repository refuses.
|
|
2784
|
+
*/
|
|
2785
|
+
if (slice.cacheBeyondTarget !== null) {
|
|
2786
|
+
console.log(` ${c.yellow('!')} ${c.dim(wrap(t.profile.whatIfCacheBeyond(n(slice.maxCallInputTokens), n(slice.cacheBeyondTarget.minTokens), formatUsd(slice.cacheBeyondTarget.noCacheUsd)), 74, ' '))}`);
|
|
2787
|
+
}
|
|
2723
2788
|
}
|
|
2724
2789
|
}
|
|
2725
2790
|
/**
|