trainfabric 0.1.44 → 0.1.46
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/index.cjs +101 -9
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -7526,6 +7526,25 @@ var NEVER = INVALID;
|
|
|
7526
7526
|
var experimentProviderIds = ["mlflow"];
|
|
7527
7527
|
var experimentTrackingModes = ["online", "offline"];
|
|
7528
7528
|
var baseModels = ["llama-3-8b", "mistral-7b", "qwen-2.5-7b"];
|
|
7529
|
+
var runStatuses = [
|
|
7530
|
+
"draft",
|
|
7531
|
+
"validating",
|
|
7532
|
+
"queued",
|
|
7533
|
+
"awaiting_capacity",
|
|
7534
|
+
"scheduled",
|
|
7535
|
+
"provisioning",
|
|
7536
|
+
"launching",
|
|
7537
|
+
"starting",
|
|
7538
|
+
"running",
|
|
7539
|
+
"checkpointing",
|
|
7540
|
+
"evaluating",
|
|
7541
|
+
"completed",
|
|
7542
|
+
"failed",
|
|
7543
|
+
"canceled",
|
|
7544
|
+
"resuming",
|
|
7545
|
+
"paused",
|
|
7546
|
+
"terminated"
|
|
7547
|
+
];
|
|
7529
7548
|
var organizationRoles = ["owner", "admin", "member", "billing"];
|
|
7530
7549
|
var apiKeyScopes = [
|
|
7531
7550
|
"org:read",
|
|
@@ -7629,6 +7648,7 @@ var runCreateSchema = external_exports.object({
|
|
|
7629
7648
|
runtimeManifestId: external_exports.string().min(1).optional(),
|
|
7630
7649
|
profileSessionId: external_exports.string().min(1).optional(),
|
|
7631
7650
|
pricingQuoteId: external_exports.string().min(1).optional(),
|
|
7651
|
+
maxCostUsd: external_exports.number().positive().max(1e5).optional(),
|
|
7632
7652
|
experimentTracking: experimentTrackingInputSchema.optional()
|
|
7633
7653
|
});
|
|
7634
7654
|
var jobProfileSchema = runCreateSchema;
|
|
@@ -7674,6 +7694,7 @@ var runQuoteSchema = external_exports.object({
|
|
|
7674
7694
|
hyperparameters: runHyperparametersSchema.optional(),
|
|
7675
7695
|
runtimeVersion: external_exports.string().min(1).optional(),
|
|
7676
7696
|
mode: external_exports.enum(trainingModes).optional(),
|
|
7697
|
+
maxCostUsd: external_exports.number().positive().max(1e5).optional(),
|
|
7677
7698
|
reservationClass: external_exports.enum(reservationClasses).optional(),
|
|
7678
7699
|
slaClass: external_exports.enum(slaClasses).optional(),
|
|
7679
7700
|
runtimeManifestId: external_exports.string().min(1).optional(),
|
|
@@ -7743,11 +7764,20 @@ var serviceAccountCreateSchema = external_exports.object({
|
|
|
7743
7764
|
scopes: external_exports.array(external_exports.enum(apiKeyScopes)).min(1)
|
|
7744
7765
|
});
|
|
7745
7766
|
var billingCheckoutSessionCreateSchema = external_exports.object({
|
|
7746
|
-
amountUsd: external_exports.number().
|
|
7767
|
+
amountUsd: external_exports.number().min(5).max(1e5).optional(),
|
|
7747
7768
|
mode: external_exports.enum(["subscription", "credits"]).default("subscription"),
|
|
7748
7769
|
planId: external_exports.enum(["hobby", "pro"]).optional(),
|
|
7749
7770
|
priceId: external_exports.string().min(1).optional()
|
|
7750
7771
|
});
|
|
7772
|
+
var couponRedeemSchema = external_exports.object({
|
|
7773
|
+
code: external_exports.string().trim().min(1).max(64)
|
|
7774
|
+
});
|
|
7775
|
+
var creditAdjustmentCreateSchema = external_exports.object({
|
|
7776
|
+
amountUsd: external_exports.number().min(-1e5).max(1e5).refine((value) => value !== 0, "Credit adjustment amount cannot be zero."),
|
|
7777
|
+
kind: external_exports.enum(["manual_adjustment", "refund_credit", "refund_debit"]),
|
|
7778
|
+
reason: external_exports.string().trim().min(1).max(500),
|
|
7779
|
+
sourceId: external_exports.string().trim().min(1).max(128).optional()
|
|
7780
|
+
});
|
|
7751
7781
|
var treasuryCounterpartyCreateSchema = external_exports.object({
|
|
7752
7782
|
providerId: external_exports.enum(treasuryProviderIds).default("mercury"),
|
|
7753
7783
|
name: external_exports.string().min(1),
|
|
@@ -8594,6 +8624,10 @@ function encodeRunId(runId) {
|
|
|
8594
8624
|
}
|
|
8595
8625
|
return encodeURIComponent(id);
|
|
8596
8626
|
}
|
|
8627
|
+
function isTransientQuoteError(error) {
|
|
8628
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
8629
|
+
return /status (502|503|504)\b/i.test(message);
|
|
8630
|
+
}
|
|
8597
8631
|
var RunsClient = class extends ResourceClient {
|
|
8598
8632
|
describeEmptyQuoteFailure(input) {
|
|
8599
8633
|
const compute = input.compute && input.compute !== "auto" && input.compute !== "cpu-sim" ? input.compute : void 0;
|
|
@@ -8655,7 +8689,7 @@ var RunsClient = class extends ResourceClient {
|
|
|
8655
8689
|
projectId: input.projectId ?? this.parent.projectId,
|
|
8656
8690
|
profileSessionId: detail.session.id
|
|
8657
8691
|
});
|
|
8658
|
-
return this.
|
|
8692
|
+
return this.requestQuoteWithRetry("/v1/runs/quotes", payload);
|
|
8659
8693
|
}
|
|
8660
8694
|
async quoteLegacy(input) {
|
|
8661
8695
|
const detail = await this.ensureReadyProfile(input);
|
|
@@ -8664,7 +8698,23 @@ var RunsClient = class extends ResourceClient {
|
|
|
8664
8698
|
projectId: input.projectId ?? this.parent.projectId,
|
|
8665
8699
|
profileSessionId: detail.session.id
|
|
8666
8700
|
});
|
|
8667
|
-
return this.
|
|
8701
|
+
return this.requestQuoteWithRetry("/v1/runs/quote", payload);
|
|
8702
|
+
}
|
|
8703
|
+
async requestQuoteWithRetry(pathname, payload) {
|
|
8704
|
+
const attempts = Math.max(1, Number(process.env.TRAINFABRIC_QUOTE_RETRY_ATTEMPTS ?? 3));
|
|
8705
|
+
let lastError;
|
|
8706
|
+
for (let attempt = 1; attempt <= attempts; attempt += 1) {
|
|
8707
|
+
try {
|
|
8708
|
+
return await this.requestPost(pathname, payload);
|
|
8709
|
+
} catch (error) {
|
|
8710
|
+
lastError = error;
|
|
8711
|
+
if (!isTransientQuoteError(error) || attempt === attempts) {
|
|
8712
|
+
throw error;
|
|
8713
|
+
}
|
|
8714
|
+
await wait(500 * attempt);
|
|
8715
|
+
}
|
|
8716
|
+
}
|
|
8717
|
+
throw lastError instanceof Error ? lastError : new Error("Quote request failed.");
|
|
8668
8718
|
}
|
|
8669
8719
|
async create(input) {
|
|
8670
8720
|
const projectId = input.projectId ?? this.parent.projectId;
|
|
@@ -9250,6 +9300,16 @@ function normalizeLearningRate(lr) {
|
|
|
9250
9300
|
}
|
|
9251
9301
|
return parsed;
|
|
9252
9302
|
}
|
|
9303
|
+
function normalizeMaxCost(maxCost) {
|
|
9304
|
+
if (maxCost === void 0) {
|
|
9305
|
+
return void 0;
|
|
9306
|
+
}
|
|
9307
|
+
const parsed = Number(maxCost);
|
|
9308
|
+
if (!Number.isFinite(parsed) || parsed <= 0 || parsed > 1e5) {
|
|
9309
|
+
throw new Error("Max cost must be a positive USD amount up to 100000.");
|
|
9310
|
+
}
|
|
9311
|
+
return Number(parsed.toFixed(2));
|
|
9312
|
+
}
|
|
9253
9313
|
function buildComputeSpec(options) {
|
|
9254
9314
|
const gpuCount = normalizePositiveInteger(options.gpus, "GPU count", 1, 64);
|
|
9255
9315
|
const nodeCount = normalizePositiveInteger(options.nodes, "Node count", 1, 16);
|
|
@@ -9291,7 +9351,7 @@ function buildComputeSpec(options) {
|
|
|
9291
9351
|
|
|
9292
9352
|
// src/index.ts
|
|
9293
9353
|
var DEFAULT_TRAINFABRIC_API_URL2 = "https://api.trainfabric.com";
|
|
9294
|
-
var CLI_VERSION = "0.1.
|
|
9354
|
+
var CLI_VERSION = "0.1.46";
|
|
9295
9355
|
var CONFIG_DIR = import_node_path3.default.join(import_node_os2.default.homedir(), ".trainfabric");
|
|
9296
9356
|
var CONFIG_PATH = import_node_path3.default.join(CONFIG_DIR, "config.json");
|
|
9297
9357
|
var FALLBACK_SECRET_PATH = import_node_path3.default.join(CONFIG_DIR, "session.enc");
|
|
@@ -9667,6 +9727,16 @@ function requireProjectId(options, config) {
|
|
|
9667
9727
|
}
|
|
9668
9728
|
return projectId;
|
|
9669
9729
|
}
|
|
9730
|
+
function normalizeRunStatusFilter(status) {
|
|
9731
|
+
if (status === void 0) {
|
|
9732
|
+
return void 0;
|
|
9733
|
+
}
|
|
9734
|
+
const normalized = String(status).trim().toLowerCase();
|
|
9735
|
+
if (!runStatuses.includes(normalized)) {
|
|
9736
|
+
throw new Error(`Run status is invalid. Use one of: ${runStatuses.join(", ")}.`);
|
|
9737
|
+
}
|
|
9738
|
+
return normalized;
|
|
9739
|
+
}
|
|
9670
9740
|
function optionWasProvided(command, optionName) {
|
|
9671
9741
|
return command.getOptionValueSource(optionName) === "cli";
|
|
9672
9742
|
}
|
|
@@ -9720,6 +9790,7 @@ function buildRunInput(options, config = loadConfig()) {
|
|
|
9720
9790
|
pricingQuoteId: quoteId,
|
|
9721
9791
|
evalDatasetId: normalizeOptionalId(options.eval, "dataset", "Eval dataset ID"),
|
|
9722
9792
|
...sourceOptions,
|
|
9793
|
+
maxCostUsd: normalizeMaxCost(options.maxCost),
|
|
9723
9794
|
mode: normalizeTrainingMode(options.mode)
|
|
9724
9795
|
};
|
|
9725
9796
|
if (projectId) {
|
|
@@ -9814,7 +9885,8 @@ async function watchRun(runId, json = false, timeoutMs, pollMs) {
|
|
|
9814
9885
|
});
|
|
9815
9886
|
handle.on("log", (event) => {
|
|
9816
9887
|
const payload = event.payload;
|
|
9817
|
-
|
|
9888
|
+
const eventLabel = formatRunEventCode(payload.eventCode);
|
|
9889
|
+
console.log(`[${eventLabel ?? payload.phase ?? "run"}:${payload.level ?? "info"}] ${payload.message ?? ""}`);
|
|
9818
9890
|
});
|
|
9819
9891
|
handle.on("metric", (event) => {
|
|
9820
9892
|
const payload = event.payload;
|
|
@@ -9845,6 +9917,24 @@ async function watchRun(runId, json = false, timeoutMs, pollMs) {
|
|
|
9845
9917
|
);
|
|
9846
9918
|
}
|
|
9847
9919
|
}
|
|
9920
|
+
function formatRunEventCode(eventCode) {
|
|
9921
|
+
switch (eventCode) {
|
|
9922
|
+
case "provider_waiting_for_ssh":
|
|
9923
|
+
return "provider-waiting";
|
|
9924
|
+
case "relay_confirmation_timeout_nonfatal":
|
|
9925
|
+
return "relay-monitoring";
|
|
9926
|
+
case "dependency_installing":
|
|
9927
|
+
return "dependency-installing";
|
|
9928
|
+
case "runtime_bootstrap_fallback":
|
|
9929
|
+
return "runtime-bootstrap";
|
|
9930
|
+
case "training_started":
|
|
9931
|
+
return "training-started";
|
|
9932
|
+
case "artifact_syncing":
|
|
9933
|
+
return "artifact-syncing";
|
|
9934
|
+
default:
|
|
9935
|
+
return void 0;
|
|
9936
|
+
}
|
|
9937
|
+
}
|
|
9848
9938
|
function parseDurationMs(value) {
|
|
9849
9939
|
if (!value) {
|
|
9850
9940
|
return void 0;
|
|
@@ -10053,7 +10143,7 @@ program2.command("datasets:upload").argument("<file>").option("--project <projec
|
|
|
10053
10143
|
});
|
|
10054
10144
|
printJson(dataset);
|
|
10055
10145
|
});
|
|
10056
|
-
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; use only with --yes").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. When using --quote, do not pass project, dataset, model, compute, mode, source, or hyperparameter flags; launch with `trainfabric runs:create --quote <quoteId> --yes`.").action(async (options, command) => {
|
|
10146
|
+
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("--max-cost <usd>", "maximum accepted quoted customer charge in USD").option("--quote <pricingQuoteId>", "launch the exact accepted quote id from runs:quote; use only with --yes").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. When using --quote, do not pass project, dataset, model, compute, mode, source, or hyperparameter flags; launch with `trainfabric runs:create --quote <quoteId> --yes`.").action(async (options, command) => {
|
|
10057
10147
|
const config = loadConfig();
|
|
10058
10148
|
assertQuoteCreateHasNoLaunchOverrides(options, command);
|
|
10059
10149
|
const runInput = buildRunInput(options, config);
|
|
@@ -10100,7 +10190,7 @@ program2.command("runtime:build").option("--project <projectId>").requiredOption
|
|
|
10100
10190
|
)
|
|
10101
10191
|
);
|
|
10102
10192
|
});
|
|
10103
|
-
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("--json", "print raw JSON output; this is the default unless --summary is used").option("--summary", "print a human-readable price summary instead of raw JSON").description("Preview Efficient, Balanced, and Power launch options").action(async (options) => {
|
|
10193
|
+
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("--max-cost <usd>", "maximum accepted quoted customer charge in USD").option("--repo <path>").option("--git <url>").option("--branch <branch>").option("--json", "print raw JSON output; this is the default unless --summary is used").option("--summary", "print a human-readable price summary instead of raw JSON").description("Preview Efficient, Balanced, and Power launch options").action(async (options) => {
|
|
10104
10194
|
const config = loadConfig();
|
|
10105
10195
|
const bundle = filterQuoteBundleForRequestedMode(
|
|
10106
10196
|
await createClient(config).runs.quote(buildRunInput(options, config)),
|
|
@@ -10113,8 +10203,10 @@ program2.command("runs:quote").option("--project <projectId>").requiredOption("-
|
|
|
10113
10203
|
printJson(redactInlineSource(bundle));
|
|
10114
10204
|
}
|
|
10115
10205
|
});
|
|
10116
|
-
program2.command("runs:list").option("--project <projectId>").description("List runs").action(async (options) => {
|
|
10117
|
-
|
|
10206
|
+
program2.command("runs:list").option("--project <projectId>").option("--status <status>", "filter by run status").option("--json", "print raw JSON output; this is the default").description("List runs").action(async (options) => {
|
|
10207
|
+
const status = normalizeRunStatusFilter(options.status);
|
|
10208
|
+
const runs = await createClient(loadConfig()).runs.list(normalizeOptionalId(options.project, "project", "Project ID"));
|
|
10209
|
+
printJson(status ? runs.filter((run) => run.status === status) : runs);
|
|
10118
10210
|
});
|
|
10119
10211
|
program2.command("runs:status").argument("<runId>").description("Fetch full run detail").action(async (runId) => {
|
|
10120
10212
|
const detail = await createClient(loadConfig()).runs.get(normalizeId(runId, "run", "Run ID"));
|