trainfabric 0.1.73 → 0.1.74

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.
Files changed (2) hide show
  1. package/dist/index.cjs +35 -2
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -9255,6 +9255,7 @@ var INTERCONNECT_TYPES = /* @__PURE__ */ new Set(["pcie", "nvlink"]);
9255
9255
  var BASE_MODELS = new Set(baseModels);
9256
9256
  var TRAINING_MODES = new Set(trainingModes);
9257
9257
  var MAX_MIN_GPU_MEMORY_GB = 192;
9258
+ var MIN_PROFILED_QUOTE_MAX_COST_USD = 1;
9258
9259
  function normalizePositiveInteger(value, label, fallback, max) {
9259
9260
  const parsed = Number(value ?? String(fallback));
9260
9261
  if (!Number.isInteger(parsed) || parsed <= 0) {
@@ -9324,6 +9325,9 @@ function normalizeMaxCost(maxCost) {
9324
9325
  if (!Number.isFinite(parsed) || parsed <= 0 || parsed > 1e5) {
9325
9326
  throw new Error("Max cost must be a positive USD amount up to 100000.");
9326
9327
  }
9328
+ if (parsed < MIN_PROFILED_QUOTE_MAX_COST_USD) {
9329
+ throw new Error(`Max cost is below the minimum profiled quote floor of $${MIN_PROFILED_QUOTE_MAX_COST_USD.toFixed(2)}. Increase --max-cost before running quote profiling.`);
9330
+ }
9327
9331
  return Number(parsed.toFixed(2));
9328
9332
  }
9329
9333
  function buildComputeSpec(options) {
@@ -9367,7 +9371,7 @@ function buildComputeSpec(options) {
9367
9371
 
9368
9372
  // src/index.ts
9369
9373
  var DEFAULT_TRAINFABRIC_API_URL2 = "https://api.trainfabric.com";
9370
- var CLI_VERSION = "0.1.73";
9374
+ var CLI_VERSION = "0.1.74";
9371
9375
  var CONFIG_DIR = import_node_path3.default.join(import_node_os2.default.homedir(), ".trainfabric");
9372
9376
  var CONFIG_PATH = import_node_path3.default.join(CONFIG_DIR, "config.json");
9373
9377
  var FALLBACK_SECRET_PATH = import_node_path3.default.join(CONFIG_DIR, "session.enc");
@@ -9729,6 +9733,26 @@ function printUsageSummary(usage) {
9729
9733
  console.log(` ${item.label}: ${formatUsd(item.amountUsd)} - ${item.description}`);
9730
9734
  }
9731
9735
  }
9736
+ function summarizeUsageRecords(usage) {
9737
+ const sumMetric = (metric) => Number(
9738
+ usage.filter((record) => record.metric === metric).reduce((sum, record) => sum + record.quantity, 0).toFixed(6)
9739
+ );
9740
+ const customerChargeUsd = sumMetric("customer_charge_usd");
9741
+ const infraCostUsd = sumMetric("infra_cost_usd");
9742
+ const marginUsd = sumMetric("margin_usd");
9743
+ return {
9744
+ billableUnit: "normalized_tflop_seconds",
9745
+ normalizedTflopSeconds: sumMetric("normalized_tflop_seconds"),
9746
+ reservedGpuSeconds: sumMetric("reserved_gpu_seconds"),
9747
+ customerChargeUsd,
9748
+ usageChargeUsd: customerChargeUsd,
9749
+ infraCostUsd,
9750
+ supplierComputeCostUsd: sumMetric("supplier_compute_cost_usd"),
9751
+ dataPlaneCostUsd: sumMetric("data_plane_cost_usd"),
9752
+ marginUsd,
9753
+ marginRatio: customerChargeUsd > 0 ? Number((marginUsd / customerChargeUsd).toFixed(6)) : 0
9754
+ };
9755
+ }
9732
9756
  function printInvoiceSummary(invoices) {
9733
9757
  if (invoices.length === 0) {
9734
9758
  console.log("No invoices found.");
@@ -10321,7 +10345,13 @@ program2.command("runtime:detect").option("--project <projectId>").option("--rep
10321
10345
  }
10322
10346
  printJson(redactInlineSource(detection));
10323
10347
  });
10324
- program2.command("runtime:build").option("--json", "print raw JSON output; this is the default").option("--project <projectId>").requiredOption("--detection <detectionId>").description("Build or reuse a cached runtime image from a runtime detection").action(async (options) => {
10348
+ program2.command("runtime:build").option("--json", "print raw JSON output; this is the default").option("--project <projectId>").addOption(new Option("--repo <path>").hideHelp()).addOption(new Option("--git <url>").hideHelp()).addOption(new Option("--branch <branch>").hideHelp()).option("--detection <detectionId>").description("Build or reuse a cached runtime image from a runtime detection").action(async (options) => {
10349
+ if (options.repo || options.git || options.branch) {
10350
+ throw new Error("runtime:build requires --detection. Run runtime:detect --repo or --git first, then pass the returned detection ID.");
10351
+ }
10352
+ if (!options.detection) {
10353
+ throw new Error("Runtime detection ID is required. Run runtime:detect first, then pass --detection <detectionId>.");
10354
+ }
10325
10355
  const config = loadConfig();
10326
10356
  printJson(
10327
10357
  redactInlineSource(
@@ -10464,11 +10494,14 @@ program2.command("billing:usage").option("--json", "print raw JSON output; this
10464
10494
  return;
10465
10495
  }
10466
10496
  const usage = await client.billing.getUsage(unit);
10497
+ const totals = summarizeUsageRecords(usage);
10467
10498
  printJson({
10468
10499
  recordCount: usage.length,
10469
10500
  responseShape: "usage_summary",
10470
10501
  runId: null,
10471
10502
  unit: unit ?? "all",
10503
+ ...totals,
10504
+ usageTotals: totals,
10472
10505
  usage
10473
10506
  });
10474
10507
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trainfabric",
3
- "version": "0.1.73",
3
+ "version": "0.1.74",
4
4
  "description": "Trainfabric CLI for launching GPU training jobs on the hosted Trainfabric backend.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",