trainfabric 0.1.12 → 0.1.13

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
@@ -28,7 +28,7 @@ Secrets are stored in macOS Keychain when available. Other platforms use an encr
28
28
  trainfabric projects:list
29
29
  trainfabric datasets:upload ./train.jsonl --project <projectId>
30
30
  trainfabric runs:quote --summary --project <projectId> --dataset <datasetId> --model llama-3-8b
31
- trainfabric runs:create --yes --project <projectId> --dataset <datasetId> --model llama-3-8b
31
+ trainfabric runs:create --yes --quote <quoteId> --project <projectId> --dataset <datasetId> --model llama-3-8b
32
32
  trainfabric runs:watch <runId> --timeout 30m
33
33
  trainfabric runs:cost-breakdown <runId> --summary
34
34
  ```
package/dist/index.cjs CHANGED
@@ -7975,12 +7975,6 @@ function validateChatJsonl(text) {
7975
7975
  }
7976
7976
  tokenEstimate += estimateTokens(result.data.messages.map((message) => `${message.role}:${message.content}`).join("\n"));
7977
7977
  }
7978
- if (tokenEstimate < 100) {
7979
- warnings.push({
7980
- code: "small_dataset",
7981
- message: "Dataset is valid but very small for a meaningful training run."
7982
- });
7983
- }
7984
7978
  const invalidWarnings = /* @__PURE__ */ new Set([
7985
7979
  "empty_file",
7986
7980
  "invalid_jsonl",
@@ -7988,8 +7982,15 @@ function validateChatJsonl(text) {
7988
7982
  "missing_assistant",
7989
7983
  "empty_assistant"
7990
7984
  ]);
7985
+ const isValid2 = !warnings.some((warning) => invalidWarnings.has(warning.code));
7986
+ if (tokenEstimate < 100) {
7987
+ warnings.push({
7988
+ code: "small_dataset",
7989
+ message: isValid2 ? "Dataset is valid but very small for a meaningful training run." : "Dataset is very small; fix schema errors before using it for a training run."
7990
+ });
7991
+ }
7991
7992
  return {
7992
- valid: !warnings.some((warning) => invalidWarnings.has(warning.code)),
7993
+ valid: isValid2,
7993
7994
  format: "chat_jsonl",
7994
7995
  rowCount,
7995
7996
  duplicateCount,
@@ -8921,7 +8922,7 @@ function buildComputeSpec(options) {
8921
8922
 
8922
8923
  // src/index.ts
8923
8924
  var DEFAULT_TRAINFABRIC_API_URL2 = "https://api.trainfabric.com";
8924
- var CLI_VERSION = "0.1.12";
8925
+ var CLI_VERSION = "0.1.13";
8925
8926
  var CONFIG_DIR = import_node_path3.default.join(import_node_os2.default.homedir(), ".trainfabric");
8926
8927
  var CONFIG_PATH = import_node_path3.default.join(CONFIG_DIR, "config.json");
8927
8928
  var FALLBACK_SECRET_PATH = import_node_path3.default.join(CONFIG_DIR, "session.enc");
@@ -9215,6 +9216,7 @@ function printQuoteSummary(bundle) {
9215
9216
  console.log(` data path: ${quote.dataPath ?? "auto"}`);
9216
9217
  console.log(` GPUs: ${gpuCount}`);
9217
9218
  console.log(` pool: ${quote.selectedPoolId}`);
9219
+ console.log(` launch with: --quote ${quote.id}`);
9218
9220
  }
9219
9221
  console.log("");
9220
9222
  console.log("Launch only after the customer accepts the quote. Streaming/data-plane cost is included in the estimate when the selected data path is stream, and realized usage may differ.");
@@ -9267,6 +9269,7 @@ function buildRunInput(options) {
9267
9269
  baseModel: normalizeBaseModel(options.model),
9268
9270
  datasetId: options.dataset,
9269
9271
  evalDatasetId: options.eval,
9272
+ pricingQuoteId: options.quote,
9270
9273
  ...sourceOptions,
9271
9274
  mode: options.mode,
9272
9275
  compute: buildComputeSpec(options),
@@ -9453,12 +9456,14 @@ program2.command("projects:create").requiredOption("--name <name>").option("--or
9453
9456
  printJson(await createClient(loadConfig()).projects.create({ name: options.name, organizationId: options.org }));
9454
9457
  });
9455
9458
  program2.command("datasets:validate").argument("<file>").description("Validate a local dataset file").action(async (file) => {
9456
- printJson(
9457
- await createClient(loadConfig()).datasets.validate({
9458
- path: file,
9459
- format: "chat_jsonl"
9460
- })
9461
- );
9459
+ const validation = await createClient(loadConfig()).datasets.validate({
9460
+ path: file,
9461
+ format: "chat_jsonl"
9462
+ });
9463
+ printJson(validation);
9464
+ if (!validation.valid) {
9465
+ process.exitCode = 1;
9466
+ }
9462
9467
  });
9463
9468
  program2.command("datasets:list").option("--project <projectId>").description("List datasets").action(async (options) => {
9464
9469
  printJson(await createClient(loadConfig()).datasets.list(options.project));
@@ -9476,7 +9481,7 @@ program2.command("datasets:upload").argument("<file>").option("--project <projec
9476
9481
  });
9477
9482
  printJson(dataset);
9478
9483
  });
9479
- 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("--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) => {
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) => {
9480
9485
  if (!options.yes) {
9481
9486
  throw new Error("Refusing to launch without explicit cost acceptance. Run `trainfabric runs:quote --summary ...` first, then rerun `runs:create` with --yes.");
9482
9487
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trainfabric",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
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",