trainfabric 0.1.13 → 0.1.14

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 +41 -18
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -8922,7 +8922,7 @@ function buildComputeSpec(options) {
8922
8922
 
8923
8923
  // src/index.ts
8924
8924
  var DEFAULT_TRAINFABRIC_API_URL2 = "https://api.trainfabric.com";
8925
- var CLI_VERSION = "0.1.13";
8925
+ var CLI_VERSION = "0.1.14";
8926
8926
  var CONFIG_DIR = import_node_path3.default.join(import_node_os2.default.homedir(), ".trainfabric");
8927
8927
  var CONFIG_PATH = import_node_path3.default.join(CONFIG_DIR, "config.json");
8928
8928
  var FALLBACK_SECRET_PATH = import_node_path3.default.join(CONFIG_DIR, "session.enc");
@@ -9260,10 +9260,17 @@ function visibleConfig(config) {
9260
9260
  refreshToken: config.refreshToken ? "<stored>" : void 0
9261
9261
  };
9262
9262
  }
9263
- function buildRunInput(options) {
9263
+ function requireProjectId(options, config) {
9264
+ const projectId = options.project ?? config.projectId;
9265
+ if (!projectId) {
9266
+ throw new Error("Project is required. Pass --project <projectId> or run `trainfabric config:set-project <projectId>`.");
9267
+ }
9268
+ return projectId;
9269
+ }
9270
+ function buildRunInput(options, config = loadConfig()) {
9264
9271
  const sourceOptions = buildSourceOptions(options);
9265
9272
  return {
9266
- projectId: options.project,
9273
+ projectId: requireProjectId(options, config),
9267
9274
  task: "sft",
9268
9275
  method: "lora",
9269
9276
  baseModel: normalizeBaseModel(options.model),
@@ -9300,7 +9307,16 @@ function assertQuoteOptions(bundle, options) {
9300
9307
  )}). Omit --accelerator or increase --min-memory.`
9301
9308
  );
9302
9309
  }
9303
- async function watchRun(runId, json = false, timeoutMs) {
9310
+ function filterQuoteBundleForRequestedMode(bundle, options) {
9311
+ if (!options.mode) {
9312
+ return bundle;
9313
+ }
9314
+ return {
9315
+ ...bundle,
9316
+ quotes: bundle.quotes.filter((item) => item.mode === options.mode || item.quote.mode === options.mode)
9317
+ };
9318
+ }
9319
+ async function watchRun(runId, json = false, timeoutMs, pollMs) {
9304
9320
  const handle = await createClient(loadConfig()).runs.watch(runId);
9305
9321
  if (json) {
9306
9322
  const emit = (type, payload) => printJson({ type, payload });
@@ -9337,7 +9353,7 @@ async function watchRun(runId, json = false, timeoutMs) {
9337
9353
  console.log(`[failed] ${payload.reason ?? "Run failed."}`);
9338
9354
  });
9339
9355
  }
9340
- const detail = await handle.wait({ timeoutMs });
9356
+ const detail = await handle.wait({ timeoutMs, pollMs });
9341
9357
  printJson(detail);
9342
9358
  }
9343
9359
  function parseDurationMs(value) {
@@ -9481,36 +9497,43 @@ program2.command("datasets:upload").argument("<file>").option("--project <projec
9481
9497
  });
9482
9498
  printJson(dataset);
9483
9499
  });
9484
- program2.command("runs:create").requiredOption("--project <projectId>").requiredOption("--dataset <datasetId>").requiredOption("--model <baseModel>").option("--eval <evalDatasetId>").option("--epochs <epochs>", "number of epochs", "3").option("--lr <lr>", "learning rate", "0.0002").option("--gpus <gpuCount>", "gpu count", "1").option("--nodes <nodeCount>", "node count", "1").option("--accelerator <acceleratorClass>", "optional hard accelerator constraint (for example: a10g, a100, h100)").option("--min-memory <gigabytes>", "minimum GPU memory in GB").option("--precision <precision>", "fp16_bf16, fp8, or fp32").option("--interconnect <interconnect>", "pcie or nvlink").option("--mode <mode>", "efficient, balanced, or power", "balanced").option("--quote <pricingQuoteId>", "launch the exact accepted quote id from runs:quote").option("--repo <path>", "local repo path for runtime autodetect").option("--git <url>", "git repo URL for runtime metadata").option("--branch <branch>", "git branch for runtime metadata").option("--yes", "confirm that you reviewed pricing with runs:quote --summary and accept fluctuating realized usage").description("Create a training run").action(async (options) => {
9500
+ program2.command("runs:create").option("--project <projectId>").requiredOption("--dataset <datasetId>").requiredOption("--model <baseModel>").option("--eval <evalDatasetId>").option("--epochs <epochs>", "number of epochs", "3").option("--lr <lr>", "learning rate", "0.0002").option("--gpus <gpuCount>", "gpu count", "1").option("--nodes <nodeCount>", "node count", "1").option("--accelerator <acceleratorClass>", "optional hard accelerator constraint (for example: a10g, a100, h100)").option("--min-memory <gigabytes>", "minimum GPU memory in GB").option("--precision <precision>", "fp16_bf16, fp8, or fp32").option("--interconnect <interconnect>", "pcie or nvlink").option("--mode <mode>", "efficient, balanced, or power", "balanced").option("--quote <pricingQuoteId>", "launch the exact accepted quote id from runs:quote").option("--repo <path>", "local repo path for runtime autodetect").option("--git <url>", "git repo URL for runtime metadata").option("--branch <branch>", "git branch for runtime metadata").option("--yes", "confirm that you reviewed pricing with runs:quote --summary and accept fluctuating realized usage").description("Create a training run").action(async (options) => {
9485
9501
  if (!options.yes) {
9486
9502
  throw new Error("Refusing to launch without explicit cost acceptance. Run `trainfabric runs:quote --summary ...` first, then rerun `runs:create` with --yes.");
9487
9503
  }
9488
- const client = createClient(loadConfig());
9489
- const run = await client.runs.create(buildRunInput(options));
9504
+ const config = loadConfig();
9505
+ const client = createClient(config);
9506
+ const run = await client.runs.create(buildRunInput(options, config));
9490
9507
  printJson(run.snapshot);
9491
9508
  });
9492
- program2.command("runtime:detect").requiredOption("--project <projectId>").option("--repo <path>").option("--git <url>").option("--branch <branch>").description("Detect a supported runtime from a local repo snapshot or git metadata").action(async (options) => {
9509
+ program2.command("runtime:detect").option("--project <projectId>").option("--repo <path>").option("--git <url>").option("--branch <branch>").description("Detect a supported runtime from a local repo snapshot or git metadata").action(async (options) => {
9493
9510
  const sourceOptions = buildSourceOptions(options);
9494
9511
  if (!sourceOptions.source) {
9495
9512
  throw new Error("Provide --repo or --git.");
9496
9513
  }
9514
+ const config = loadConfig();
9497
9515
  printJson(
9498
- await createClient(loadConfig()).runtime.detect({
9499
- projectId: options.project,
9516
+ await createClient(config).runtime.detect({
9517
+ projectId: requireProjectId(options, config),
9500
9518
  source: sourceOptions.source
9501
9519
  })
9502
9520
  );
9503
9521
  });
9504
- program2.command("runtime:build").requiredOption("--project <projectId>").requiredOption("--detection <detectionId>").description("Build or reuse a cached runtime image from a runtime detection").action(async (options) => {
9522
+ program2.command("runtime:build").option("--project <projectId>").requiredOption("--detection <detectionId>").description("Build or reuse a cached runtime image from a runtime detection").action(async (options) => {
9523
+ const config = loadConfig();
9505
9524
  printJson(
9506
- await createClient(loadConfig()).runtime.build({
9507
- projectId: options.project,
9525
+ await createClient(config).runtime.build({
9526
+ projectId: requireProjectId(options, config),
9508
9527
  detectionId: options.detection
9509
9528
  })
9510
9529
  );
9511
9530
  });
9512
- program2.command("runs:quote").requiredOption("--project <projectId>").requiredOption("--dataset <datasetId>").requiredOption("--model <baseModel>").option("--eval <evalDatasetId>").option("--gpus <gpuCount>", "gpu count", "1").option("--nodes <nodeCount>", "node count", "1").option("--accelerator <acceleratorClass>", "optional hard accelerator constraint (for example: a10g, a100, h100)").option("--min-memory <gigabytes>", "minimum GPU memory in GB").option("--precision <precision>", "fp16_bf16, fp8, or fp32").option("--interconnect <interconnect>", "pcie or nvlink").option("--mode <mode>", "efficient, balanced, or power").option("--repo <path>").option("--git <url>").option("--branch <branch>").option("--summary", "print a human-readable price summary instead of raw JSON").description("Preview Efficient, Balanced, and Power launch options").action(async (options) => {
9513
- const bundle = await createClient(loadConfig()).runs.quote(buildRunInput(options));
9531
+ program2.command("runs:quote").option("--project <projectId>").requiredOption("--dataset <datasetId>").requiredOption("--model <baseModel>").option("--eval <evalDatasetId>").option("--gpus <gpuCount>", "gpu count", "1").option("--nodes <nodeCount>", "node count", "1").option("--accelerator <acceleratorClass>", "optional hard accelerator constraint (for example: a10g, a100, h100)").option("--min-memory <gigabytes>", "minimum GPU memory in GB").option("--precision <precision>", "fp16_bf16, fp8, or fp32").option("--interconnect <interconnect>", "pcie or nvlink").option("--mode <mode>", "efficient, balanced, or power").option("--repo <path>").option("--git <url>").option("--branch <branch>").option("--summary", "print a human-readable price summary instead of raw JSON").description("Preview Efficient, Balanced, and Power launch options").action(async (options) => {
9532
+ const config = loadConfig();
9533
+ const bundle = filterQuoteBundleForRequestedMode(
9534
+ await createClient(config).runs.quote(buildRunInput(options, config)),
9535
+ options
9536
+ );
9514
9537
  assertQuoteOptions(bundle, options);
9515
9538
  if (options.summary) {
9516
9539
  printQuoteSummary(bundle);
@@ -9535,8 +9558,8 @@ program2.command("runs:wait").argument("<runId>").option("--timeout <duration>",
9535
9558
  })
9536
9559
  );
9537
9560
  });
9538
- program2.command("runs:watch").argument("<runId>").option("--json", "emit event output as JSON").option("--timeout <duration>", "maximum watch duration, for example 30s, 10m, or 1h").description("Stream a run until it completes").action(async (runId, options) => {
9539
- await watchRun(String(runId), Boolean(options.json), parseDurationMs(options.timeout));
9561
+ program2.command("runs:watch").argument("<runId>").option("--json", "emit event output as JSON").option("--timeout <duration>", "maximum watch duration, for example 30s, 10m, or 1h").option("--poll <duration>", "poll interval, for example 1s or 500ms").description("Stream a run until it completes").action(async (runId, options) => {
9562
+ await watchRun(String(runId), Boolean(options.json), parseDurationMs(options.timeout), parsePositiveMs(options.poll, 1e3));
9540
9563
  });
9541
9564
  program2.command("runs:usage").argument("<runId>").option("--summary", "print a human-readable cost summary instead of raw JSON").description("Fetch run usage summary").action(async (runId, options) => {
9542
9565
  const usage = await createClient(loadConfig()).runs.usage(String(runId));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trainfabric",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
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",