trainfabric 0.1.26 → 0.1.28
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 +58 -9
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -8905,6 +8905,14 @@ function validateGitUrl(value) {
|
|
|
8905
8905
|
}
|
|
8906
8906
|
return value;
|
|
8907
8907
|
}
|
|
8908
|
+
function validateGitBranch(value) {
|
|
8909
|
+
const branch = String(value ?? "").trim();
|
|
8910
|
+
const invalidCharacterPattern = /[\x00-\x20~^:?*[\]\\]/;
|
|
8911
|
+
if (!branch || branch === "@" || branch.startsWith("-") || branch.startsWith("/") || branch.endsWith("/") || branch.endsWith(".") || branch.includes("//") || branch.includes("..") || branch.includes("@{") || invalidCharacterPattern.test(branch) || branch.split("/").some((part) => !part || part.startsWith(".") || part.endsWith(".lock"))) {
|
|
8912
|
+
throw new Error("Git branch is invalid. Use a valid git branch name, for example main or feature/train-run.");
|
|
8913
|
+
}
|
|
8914
|
+
return branch;
|
|
8915
|
+
}
|
|
8908
8916
|
function validateRepoPath(repoPath) {
|
|
8909
8917
|
const absolute = import_node_path2.default.resolve(repoPath);
|
|
8910
8918
|
const parsed = import_node_path2.default.parse(absolute);
|
|
@@ -8921,6 +8929,9 @@ function buildSourceOptions(options) {
|
|
|
8921
8929
|
if (options.repo && options.git) {
|
|
8922
8930
|
throw new Error("Use either --repo or --git, not both.");
|
|
8923
8931
|
}
|
|
8932
|
+
if (options.branch && !options.git) {
|
|
8933
|
+
throw new Error("--branch only applies when --git is used.");
|
|
8934
|
+
}
|
|
8924
8935
|
if (options.repo) {
|
|
8925
8936
|
const repoPath = validateRepoPath(options.repo);
|
|
8926
8937
|
const files = collectRuntimeFiles(repoPath);
|
|
@@ -8937,7 +8948,7 @@ function buildSourceOptions(options) {
|
|
|
8937
8948
|
source: {
|
|
8938
8949
|
kind: "git",
|
|
8939
8950
|
repoUrl: validateGitUrl(options.git),
|
|
8940
|
-
branch: options.branch
|
|
8951
|
+
branch: options.branch === void 0 ? void 0 : validateGitBranch(options.branch)
|
|
8941
8952
|
}
|
|
8942
8953
|
};
|
|
8943
8954
|
}
|
|
@@ -8983,6 +8994,9 @@ function normalizeHumanName(value, label) {
|
|
|
8983
8994
|
if (!/[A-Za-z0-9]/.test(name)) {
|
|
8984
8995
|
throw new Error(`${label} is required.`);
|
|
8985
8996
|
}
|
|
8997
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9 ._-]{0,79}$/.test(name) || name.includes("..")) {
|
|
8998
|
+
throw new Error(`${label} contains invalid characters. Use letters, numbers, spaces, dots, underscores, or hyphens.`);
|
|
8999
|
+
}
|
|
8986
9000
|
return name;
|
|
8987
9001
|
}
|
|
8988
9002
|
function normalizeId(value, kind, label) {
|
|
@@ -9024,6 +9038,8 @@ var BASE_MODEL_ALIASES = {
|
|
|
9024
9038
|
var ACCELERATOR_CLASSES = /* @__PURE__ */ new Set(["a10g", "l4", "a40", "l40s", "a100", "h100", "h200", "b200"]);
|
|
9025
9039
|
var PRECISION_MODES = /* @__PURE__ */ new Set(["fp16_bf16", "fp8", "fp32"]);
|
|
9026
9040
|
var INTERCONNECT_TYPES = /* @__PURE__ */ new Set(["pcie", "nvlink"]);
|
|
9041
|
+
var BASE_MODELS = new Set(baseModels);
|
|
9042
|
+
var TRAINING_MODES = new Set(trainingModes);
|
|
9027
9043
|
function normalizePositiveInteger(value, label, fallback) {
|
|
9028
9044
|
const parsed = Number(value ?? String(fallback));
|
|
9029
9045
|
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
@@ -9052,7 +9068,35 @@ function normalizeOptionalChoice(value, allowed, label, examples) {
|
|
|
9052
9068
|
return normalized;
|
|
9053
9069
|
}
|
|
9054
9070
|
function normalizeBaseModel(model) {
|
|
9055
|
-
|
|
9071
|
+
const normalized = BASE_MODEL_ALIASES[String(model ?? "").trim().toLowerCase()];
|
|
9072
|
+
if (normalized) {
|
|
9073
|
+
return normalized;
|
|
9074
|
+
}
|
|
9075
|
+
const rawModel = String(model ?? "").trim();
|
|
9076
|
+
if (!BASE_MODELS.has(rawModel)) {
|
|
9077
|
+
throw new Error("Model is invalid. Use llama-3-8b, mistral-7b, or qwen-2.5-7b.");
|
|
9078
|
+
}
|
|
9079
|
+
return rawModel;
|
|
9080
|
+
}
|
|
9081
|
+
function normalizeTrainingMode(mode) {
|
|
9082
|
+
if (mode === void 0) {
|
|
9083
|
+
return void 0;
|
|
9084
|
+
}
|
|
9085
|
+
const normalized = String(mode).trim().toLowerCase();
|
|
9086
|
+
if (!TRAINING_MODES.has(normalized)) {
|
|
9087
|
+
throw new Error("Mode is invalid. Use efficient, balanced, or power.");
|
|
9088
|
+
}
|
|
9089
|
+
return normalized;
|
|
9090
|
+
}
|
|
9091
|
+
function normalizeEpochs(epochs) {
|
|
9092
|
+
return normalizePositiveInteger(epochs, "Epochs", 3);
|
|
9093
|
+
}
|
|
9094
|
+
function normalizeLearningRate(lr) {
|
|
9095
|
+
const parsed = Number(lr ?? "0.0002");
|
|
9096
|
+
if (!Number.isFinite(parsed) || parsed < 1e-5 || parsed > 0.01) {
|
|
9097
|
+
throw new Error("Learning rate must be a number between 0.00001 and 0.01.");
|
|
9098
|
+
}
|
|
9099
|
+
return parsed;
|
|
9056
9100
|
}
|
|
9057
9101
|
function buildComputeSpec(options) {
|
|
9058
9102
|
const gpuCount = normalizePositiveInteger(options.gpus, "GPU count", 1);
|
|
@@ -9089,7 +9133,7 @@ function buildComputeSpec(options) {
|
|
|
9089
9133
|
|
|
9090
9134
|
// src/index.ts
|
|
9091
9135
|
var DEFAULT_TRAINFABRIC_API_URL2 = "https://api.trainfabric.com";
|
|
9092
|
-
var CLI_VERSION = "0.1.
|
|
9136
|
+
var CLI_VERSION = "0.1.28";
|
|
9093
9137
|
var CONFIG_DIR = import_node_path3.default.join(import_node_os2.default.homedir(), ".trainfabric");
|
|
9094
9138
|
var CONFIG_PATH = import_node_path3.default.join(CONFIG_DIR, "config.json");
|
|
9095
9139
|
var FALLBACK_SECRET_PATH = import_node_path3.default.join(CONFIG_DIR, "session.enc");
|
|
@@ -9441,15 +9485,15 @@ function buildRunInput(options, config = loadConfig()) {
|
|
|
9441
9485
|
task: "sft",
|
|
9442
9486
|
method: "lora",
|
|
9443
9487
|
baseModel: normalizeBaseModel(options.model),
|
|
9444
|
-
datasetId: options.dataset,
|
|
9445
|
-
evalDatasetId: options.eval,
|
|
9488
|
+
datasetId: normalizeId(options.dataset, "dataset", "Dataset ID"),
|
|
9489
|
+
evalDatasetId: normalizeOptionalId(options.eval, "dataset", "Eval dataset ID"),
|
|
9446
9490
|
pricingQuoteId: options.quote,
|
|
9447
9491
|
...sourceOptions,
|
|
9448
|
-
mode: options.mode,
|
|
9492
|
+
mode: normalizeTrainingMode(options.mode),
|
|
9449
9493
|
compute: buildComputeSpec(options),
|
|
9450
9494
|
hyperparameters: {
|
|
9451
|
-
epochs:
|
|
9452
|
-
lr:
|
|
9495
|
+
epochs: normalizeEpochs(options.epochs),
|
|
9496
|
+
lr: normalizeLearningRate(options.lr),
|
|
9453
9497
|
batchSize: "auto"
|
|
9454
9498
|
}
|
|
9455
9499
|
};
|
|
@@ -9868,7 +9912,12 @@ program2.command("deployments:create").requiredOption("--model <modelId>").optio
|
|
|
9868
9912
|
await client.projects.get(projectId);
|
|
9869
9913
|
}
|
|
9870
9914
|
const modelId = normalizeId(options.model, "model", "Model ID");
|
|
9871
|
-
|
|
9915
|
+
try {
|
|
9916
|
+
printJson(await client.deployments.create({ modelId }));
|
|
9917
|
+
} catch (error) {
|
|
9918
|
+
printJson({ error: error instanceof Error ? error.message : String(error) });
|
|
9919
|
+
process.exitCode = 1;
|
|
9920
|
+
}
|
|
9872
9921
|
});
|
|
9873
9922
|
program2.command("deployments:get").argument("<deploymentId>").description("Fetch a deployment").action(async (deploymentId) => {
|
|
9874
9923
|
printJson(await createClient(loadConfig()).deployments.get(normalizeId(deploymentId, "deployment", "Deployment ID")));
|