trainfabric 0.1.30 → 0.1.31

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/README.md CHANGED
@@ -30,7 +30,7 @@ trainfabric projects:create --name <name>
30
30
  trainfabric projects:delete <projectId>
31
31
  trainfabric datasets:upload ./train.jsonl --project <projectId>
32
32
  trainfabric runs:quote --summary --project <projectId> --dataset <datasetId> --model llama-3-8b
33
- trainfabric runs:create --yes --quote <quoteId> --project <projectId> --dataset <datasetId> --model llama-3-8b
33
+ trainfabric runs:create --yes --quote <quoteId>
34
34
  trainfabric runs:watch <runId> --timeout 30m
35
35
  trainfabric runs:cost-breakdown <runId> --summary
36
36
  ```
package/dist/index.cjs CHANGED
@@ -8478,15 +8478,6 @@ var RunHandle = class {
8478
8478
  this.snapshot = detail.run;
8479
8479
  if (["completed", "failed", "canceled", "terminated"].includes(detail.run.status)) {
8480
8480
  this.close();
8481
- if (detail.run.status === "failed") {
8482
- throw new Error(detail.run.failureReason ?? "Run failed.");
8483
- }
8484
- if (detail.run.status === "canceled") {
8485
- throw new Error("Run was canceled.");
8486
- }
8487
- if (detail.run.status === "terminated") {
8488
- throw new Error("Run was terminated.");
8489
- }
8490
8481
  return detail;
8491
8482
  }
8492
8483
  if (timeoutMs !== void 0 && Date.now() - startedAt > timeoutMs) {
@@ -8677,7 +8668,7 @@ var RunsClient = class extends ResourceClient {
8677
8668
  mode: selectedModeQuote.mode
8678
8669
  };
8679
8670
  }
8680
- const parsed = runCreateSchema.parse(payload);
8671
+ const parsed = input.pricingQuoteId ? payload : runCreateSchema.parse(payload);
8681
8672
  const run = await this.requestPost("/v1/runs", parsed);
8682
8673
  return new RunHandle(this.parent, run);
8683
8674
  }
@@ -8737,7 +8728,12 @@ var RuntimeClient = class extends ResourceClient {
8737
8728
  projectId: input.projectId ?? this.parent.projectId,
8738
8729
  source: input.source
8739
8730
  });
8740
- return this.requestPost("/v1/runtime/detect", payload);
8731
+ return this.requestPost("/v1/runtime/detect", payload).catch((error) => {
8732
+ if (input.source.kind === "git" && error instanceof Error && /Request failed with status 404/.test(error.message)) {
8733
+ throw new Error("Git repository could not be resolved. Check the repository URL, branch, and access permissions.");
8734
+ }
8735
+ throw error;
8736
+ });
8741
8737
  }
8742
8738
  build(input) {
8743
8739
  const payload = runtimeBuildCreateSchema.parse({
@@ -8899,6 +8895,7 @@ var idPatterns = {
8899
8895
  org: /^org_[A-Za-z0-9_-]+$/,
8900
8896
  pool: /^pool_[A-Za-z0-9_-]+$/,
8901
8897
  project: /^proj_[A-Za-z0-9_-]+$/,
8898
+ quote: /^quote_[A-Za-z0-9_-]+$/,
8902
8899
  run: /^run_[A-Za-z0-9_-]+$/,
8903
8900
  serviceAccount: /^svc_[A-Za-z0-9_-]+$/,
8904
8901
  supplier: /^[A-Za-z][A-Za-z0-9_-]*$/
@@ -9210,7 +9207,7 @@ function buildComputeSpec(options) {
9210
9207
 
9211
9208
  // src/index.ts
9212
9209
  var DEFAULT_TRAINFABRIC_API_URL2 = "https://api.trainfabric.com";
9213
- var CLI_VERSION = "0.1.30";
9210
+ var CLI_VERSION = "0.1.31";
9214
9211
  var CONFIG_DIR = import_node_path3.default.join(import_node_os2.default.homedir(), ".trainfabric");
9215
9212
  var CONFIG_PATH = import_node_path3.default.join(CONFIG_DIR, "config.json");
9216
9213
  var FALLBACK_SECRET_PATH = import_node_path3.default.join(CONFIG_DIR, "session.enc");
@@ -9557,23 +9554,43 @@ function requireProjectId(options, config) {
9557
9554
  }
9558
9555
  function buildRunInput(options, config = loadConfig()) {
9559
9556
  const sourceOptions = buildSourceOptions(options);
9560
- return {
9561
- projectId: requireProjectId(options, config),
9557
+ const quoteId = options.quote === void 0 ? void 0 : normalizeId(options.quote, "quote", "Pricing quote ID");
9558
+ if (!quoteId && !options.dataset) {
9559
+ throw new Error("Dataset is required unless --quote is provided.");
9560
+ }
9561
+ if (!quoteId && !options.model) {
9562
+ throw new Error("Model is required unless --quote is provided.");
9563
+ }
9564
+ const projectId = normalizeOptionalId(options.project ?? config.projectId, "project", "Project ID");
9565
+ if (!quoteId && !projectId) {
9566
+ throw new Error("Project is required. Pass --project <projectId> or run `trainfabric config:set-project <projectId>`.");
9567
+ }
9568
+ const input = {
9562
9569
  task: "sft",
9563
9570
  method: "lora",
9564
- baseModel: normalizeBaseModel(options.model),
9565
- datasetId: normalizeId(options.dataset, "dataset", "Dataset ID"),
9571
+ pricingQuoteId: quoteId,
9566
9572
  evalDatasetId: normalizeOptionalId(options.eval, "dataset", "Eval dataset ID"),
9567
- pricingQuoteId: options.quote,
9568
9573
  ...sourceOptions,
9569
- mode: normalizeTrainingMode(options.mode),
9570
- compute: buildComputeSpec(options),
9571
- hyperparameters: {
9574
+ mode: normalizeTrainingMode(options.mode)
9575
+ };
9576
+ if (projectId) {
9577
+ input.projectId = projectId;
9578
+ }
9579
+ if (options.model) {
9580
+ input.baseModel = normalizeBaseModel(options.model);
9581
+ }
9582
+ if (options.dataset) {
9583
+ input.datasetId = normalizeId(options.dataset, "dataset", "Dataset ID");
9584
+ }
9585
+ if (!quoteId) {
9586
+ input.compute = buildComputeSpec(options);
9587
+ input.hyperparameters = {
9572
9588
  epochs: normalizeEpochs(options.epochs),
9573
9589
  lr: normalizeLearningRate(options.lr),
9574
9590
  batchSize: "auto"
9575
- }
9576
- };
9591
+ };
9592
+ }
9593
+ return input;
9577
9594
  }
9578
9595
  function assertQuoteOptions(bundle, options) {
9579
9596
  if (bundle.quotes.length > 0) {
@@ -9872,7 +9889,7 @@ program2.command("datasets:upload").argument("<file>").option("--project <projec
9872
9889
  });
9873
9890
  printJson(dataset);
9874
9891
  });
9875
- 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) => {
9892
+ program2.command("runs:create").option("--project <projectId>").option("--dataset <datasetId>").option("--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").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) => {
9876
9893
  const config = loadConfig();
9877
9894
  const runInput = buildRunInput(options, config);
9878
9895
  if (!options.yes) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trainfabric",
3
- "version": "0.1.30",
3
+ "version": "0.1.31",
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",