@rulvar/cli 1.120.0 → 1.121.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/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { r as runCli, t as processIo } from "./io-Dh-lBbqe.js";
2
+ import { r as runCli, t as processIo } from "./io-CsvU0Iog.js";
3
3
  import { sanitizeTerminalText } from "@rulvar/core";
4
4
  import { inspect } from "node:util";
5
5
  //#region src/cli.ts
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CreateEngineOptions, Engine, JournalStore, KeyDeriver, LeasableStore, ModelRef, PreflightInput, RunHandle, RunMeta, RunOutcome, Usage, Workflow, WorkflowEvent, WorkflowRegistry } from "@rulvar/core";
1
+ import { CreateEngineOptions, Engine, JournalStore, KeyDeriver, LeasableStore, ModelRef, PreflightInput, Pricing, RunHandle, RunMeta, RunOutcome, Usage, Workflow, WorkflowEvent, WorkflowRegistry } from "@rulvar/core";
2
2
 
3
3
  //#region src/io.d.ts
4
4
  interface CliIo {
@@ -166,6 +166,13 @@ interface AssembledCli {
166
166
  /** The journal-fold price function (table wins over caps). */
167
167
  priceUsd: (servedBy: ModelRef, usage: Usage) => number | undefined;
168
168
  /**
169
+ * The resolved pricing row behind priceUsd (table wins over caps),
170
+ * surfaced for the provenance renderers (RV814): the invoice names
171
+ * each priced model's `ratesVerifiedAt` with its age, and the row is
172
+ * where the date lives.
173
+ */
174
+ pricingOf: (servedBy: ModelRef) => Pricing | undefined;
175
+ /**
169
176
  * The deployment's argsHash salt (engineOptions.security, RV-217),
170
177
  * surfaced so the CLI resume args gate hashes supplied --args the
171
178
  * same way the engine hashed the genesis args.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as loadCliConfig, a as invoiceCommand, c as runCommand, d as reportOutcome, f as strictExitCode, g as assembleEngine, h as DEFAULT_STORE_DIR, i as inspectCommand, l as runsLsCommand, m as renderEventLine, n as HELP, o as preflightCommand, p as attachProgress, r as runCli, s as resumeCommand, t as processIo, u as driveRun, v as loadWorkflowModule, y as looksLikeFile } from "./io-Dh-lBbqe.js";
1
+ import { _ as loadCliConfig, a as invoiceCommand, c as runCommand, d as reportOutcome, f as strictExitCode, g as assembleEngine, h as DEFAULT_STORE_DIR, i as inspectCommand, l as runsLsCommand, m as renderEventLine, n as HELP, o as preflightCommand, p as attachProgress, r as runCli, s as resumeCommand, t as processIo, u as driveRun, v as loadWorkflowModule, y as looksLikeFile } from "./io-CsvU0Iog.js";
2
2
  import { ConfigError, InvalidResolutionError, JournalCompatibilityError, LeaseHeldError, Replayer, RulvarError, buildDeriverRegistry, compileSecretMasker, costReportFromJournal, journalPricingSnapshot, maskSecrets, normalizeEntry, readRunMeta, scanJournalCompatibility, validateSchemaSpec } from "@rulvar/core";
3
3
  //#region src/server.ts
4
4
  /**
@@ -105,9 +105,12 @@ function assembleEngine(options) {
105
105
  }
106
106
  });
107
107
  const byId = new Map(adapters.map((adapter) => [adapter.id, adapter]));
108
- const priceUsd = (servedBy, usage) => {
108
+ const pricingOf = (servedBy) => {
109
109
  const { adapterId, model } = parseModelRef(servedBy);
110
- const pricing = resolvePricing(servedBy, engineOptions.pricing, byId.get(adapterId)?.caps(model).pricing);
110
+ return resolvePricing(servedBy, engineOptions.pricing, byId.get(adapterId)?.caps(model).pricing);
111
+ };
112
+ const priceUsd = (servedBy, usage) => {
113
+ const pricing = pricingOf(servedBy);
111
114
  return pricing === void 0 ? void 0 : priceUsdOf(pricing, usage);
112
115
  };
113
116
  const argsHashSalt = engineOptions.security?.argsHashSalt;
@@ -117,6 +120,7 @@ function assembleEngine(options) {
117
120
  store,
118
121
  workflows,
119
122
  priceUsd,
123
+ pricingOf,
120
124
  ...argsHashSalt === void 0 ? {} : { argsHashSalt },
121
125
  ...currentPricingVersion === void 0 ? {} : { currentPricingVersion }
122
126
  };
@@ -1185,6 +1189,8 @@ async function invoiceCommand(argv, context) {
1185
1189
  context.io.out(`rows: ${invoice.rows.length} (reconciliation failures: ${invoice.reconciliationFailures}${invoice.usageUnknownRows === void 0 ? "" : `; usage unknown: ${invoice.usageUnknownRows}`})`);
1186
1190
  context.io.out(`pricing basis: ${invoice.pricingBasis} ` + (invoice.rowUsdNonAdditive ? "(row usd is non-additive: an aggregate-priced remainder or legacy entry is in the fold; allocatedUsd sums to gross)" : "(rows are additive: every provider call priced per request; allocatedUsd agrees and sums to gross)"));
1187
1191
  context.io.out(snapshot === void 0 ? "pricing rates: current table (no snapshot in the journal)" : "pricing rates: run-settle pins composed with the current table" + pinVersionsSuffix(snapshot, assembled.currentPricingVersion));
1192
+ const verified = ratesVerifiedLine(invoice, snapshot, assembled.pricingOf, Date.now());
1193
+ if (verified !== void 0) context.io.out(verified);
1188
1194
  for (const row of invoice.rows) {
1189
1195
  const usd = row.usd === void 0 ? "unpriced" : `$${row.usd.toFixed(4)}`;
1190
1196
  const tokens = row.usage.inputTokens + row.usage.outputTokens;
@@ -1215,6 +1221,37 @@ function pinVersionsSuffix(snapshot, currentPricingVersion) {
1215
1221
  if (currentPricingVersion !== void 0) parts.push(`current ${currentPricingVersion}`);
1216
1222
  return parts.length === 0 ? "" : ` (${parts.join("; ")})`;
1217
1223
  }
1224
+ /**
1225
+ * ` (age Nd)` for an ISO date against the wall clock; empty when the
1226
+ * date does not parse or lies in the future (a malformed or clock-skewed
1227
+ * stamp renders as the bare date, never as a negative age).
1228
+ */
1229
+ function ageSuffixOf(date, nowMs) {
1230
+ const parsed = Date.parse(date);
1231
+ if (!Number.isFinite(parsed) || parsed > nowMs) return "";
1232
+ return ` (age ${String(Math.floor((nowMs - parsed) / 864e5))}d)`;
1233
+ }
1234
+ /**
1235
+ * `rates verified: <model> <date> (age Nd), <model> no date` over the
1236
+ * models the invoice rows name (RV814). Per model, the date is the
1237
+ * LAST settle pin's row when the journal pins one, because those are
1238
+ * the rates that priced settled history whatever today's table says; a
1239
+ * model outside the pins reads the current table's row. A pinned row
1240
+ * without a stamp is honestly `no date`, never today's table date.
1241
+ * Undefined when no applicable row names a date: journals priced under
1242
+ * pre-stamp tables keep their historical output byte for byte.
1243
+ */
1244
+ function ratesVerifiedLine(invoice, snapshot, pricingOf, nowMs) {
1245
+ const dated = [...new Set(invoice.rows.map((row) => row.servedBy))].sort().map((model) => {
1246
+ const pinRow = snapshot?.rows.find((row) => row.model === model);
1247
+ return {
1248
+ model,
1249
+ date: pinRow !== void 0 ? pinRow.rates.ratesVerifiedAt : pricingOf(model)?.ratesVerifiedAt
1250
+ };
1251
+ });
1252
+ if (!dated.some((entry) => entry.date !== void 0)) return;
1253
+ return `rates verified: ${dated.map(({ model, date }) => date === void 0 ? `${model} no date` : `${model} ${date}${ageSuffixOf(date, nowMs)}`).join(", ")}`;
1254
+ }
1218
1255
  function renderPreflight(report, io) {
1219
1256
  io.out("preflight: effective limits and admission projection (zero provider dispatches)");
1220
1257
  const perProvider = report.concurrency.perProvider;
@@ -1229,7 +1266,7 @@ function renderPreflight(report, io) {
1229
1266
  io.out(`quota: ${report.quota.configured ? "configured" : "none"}` + (report.quota.tenant === void 0 ? "" : ` tenant=${report.quota.tenant}`) + (report.quota.rules === void 0 ? "" : ` rules=${report.quota.rules}`));
1230
1267
  io.out(`run limits: ${JSON.stringify(report.runLimits)}`);
1231
1268
  for (const spawn of report.spawns) {
1232
- io.out(`spawn '${spawn.label}' role=${spawn.role} x${spawn.count} servedBy=${spawn.servedBy ?? "UNROUTED"}${spawn.unpriced === true ? " (unpriced)" : ""} reserve=${usdOf(spawn.admissionReserveUsd)} (${spawn.reserveSource})` + (spawn.maxOutputTokensPerTurn === void 0 ? "" : ` maxOutput=${spawn.maxOutputTokensPerTurn}`) + (spawn.turnFloorUsd === void 0 ? "" : ` turnFloor=${usdOf(spawn.turnFloorUsd)}`) + ` toolCallCeiling=${spawn.executedToolCallCeiling ?? "unlimited"} projectedTurns=${spawn.projectedProviderTurns}`);
1269
+ io.out(`spawn '${spawn.label}' role=${spawn.role} x${spawn.count} servedBy=${spawn.servedBy ?? "UNROUTED"}${spawn.unpriced === true ? " (unpriced)" : ""}` + (spawn.ratesVerifiedAt === void 0 ? "" : ` ratesVerified=${spawn.ratesVerifiedAt}${ageSuffixOf(spawn.ratesVerifiedAt, Date.now())}`) + ` reserve=${usdOf(spawn.admissionReserveUsd)} (${spawn.reserveSource})` + (spawn.maxOutputTokensPerTurn === void 0 ? "" : ` maxOutput=${spawn.maxOutputTokensPerTurn}`) + (spawn.turnFloorUsd === void 0 ? "" : ` turnFloor=${usdOf(spawn.turnFloorUsd)}`) + ` toolCallCeiling=${spawn.executedToolCallCeiling ?? "unlimited"} projectedTurns=${spawn.projectedProviderTurns}`);
1233
1270
  io.out(` limits: ${JSON.stringify(spawn.limits)}`);
1234
1271
  for (const row of spawn.toolCeilings) {
1235
1272
  if (row.tool === "(any)" && row.ceiling === null) continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulvar/cli",
3
- "version": "1.120.0",
3
+ "version": "1.121.0",
4
4
  "description": "Rulvar shell: run/resume/runs/inspect/plan/kb commands, TUI progress, createServer, createWorker, OTel exporter.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -22,17 +22,17 @@
22
22
  "access": "public"
23
23
  },
24
24
  "dependencies": {
25
- "@rulvar/core": "1.120.0"
25
+ "@rulvar/core": "1.121.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^22.20.1",
29
29
  "tsdown": "^0.22.14",
30
30
  "typescript": "~6.0.3",
31
- "@rulvar/store-sqlite": "1.120.0",
32
- "@rulvar/testing": "1.120.0",
33
- "@rulvar/evals": "1.120.0",
34
- "@rulvar/plan": "1.120.0",
35
- "@rulvar/planner": "1.120.0"
31
+ "@rulvar/testing": "1.121.0",
32
+ "@rulvar/store-sqlite": "1.121.0",
33
+ "@rulvar/planner": "1.121.0",
34
+ "@rulvar/plan": "1.121.0",
35
+ "@rulvar/evals": "1.121.0"
36
36
  },
37
37
  "bin": {
38
38
  "rulvar": "./dist/cli.js"