@tuned-tensor/cli 0.4.9 → 0.4.11

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
@@ -106,25 +106,22 @@ Use `--dataset <dataset-id-or-prefix>` with `tt runs start` to train from an upl
106
106
 
107
107
  Use `--max-eval-examples <n>` and `--max-test-eval-examples <n>` with `tt runs start` to cap primary and secondary test evaluation passes for larger datasets; the runs backend still clamps values to its configured ceiling.
108
108
 
109
- Use `--no-llm-judge` with `tt runs start` to opt out of Bedrock LLM judging for a new run.
109
+ Use `--no-llm-judge` with `tt runs start` to opt out of LLM judging for a new run.
110
110
 
111
- `tt models download` downloads models that have a Tuned Tensor-hosted artifact, such as SageMaker training outputs. Provider-hosted models can still be used for inference through their `provider_model_id`, but may not expose downloadable weights.
111
+ `tt models download` downloads models that have a Tuned Tensor-hosted artifact. Hosted models can still be used for inference through their model ID, but may not expose downloadable weights.
112
112
 
113
113
  ## Billing & Credits
114
114
 
115
115
  Tuned Tensor uses prepaid credits. New accounts start at a zero balance, so top up before starting your first fine-tuning run; you only pay for successful runs.
116
116
 
117
117
  ```bash
118
- tt balance # show available credits, holds, and recent transactions
118
+ tt balance # show credit balance and recent transactions
119
119
  tt topup --amount 25 # opens Stripe Checkout in your browser
120
120
  tt topup --amount 25 --no-open # print the URL instead
121
121
  ```
122
122
 
123
- `tt balance` separates **Available** credits from **Total balance**. Starting a
124
- run or auto-tune session places an estimate on hold, so you can have a positive
125
- total balance while `Available` is too low to start another run. If a run is
126
- rejected with `402 insufficient_credits`, top up or wait for active holds to
127
- settle/release, then retry.
123
+ `tt balance` shows your current credit balance. If a run is rejected with
124
+ `402 insufficient_credits`, top up and retry.
128
125
 
129
126
  ## Spec Validation
130
127
 
package/dist/index.js CHANGED
@@ -595,6 +595,39 @@ function formatEvalScore(run) {
595
595
  const score = getEvalScore(run);
596
596
  return score == null ? void 0 : (score * 100).toFixed(1) + "%";
597
597
  }
598
+ function formatMinutes(minutes) {
599
+ if (minutes == null) return void 0;
600
+ if (minutes < 60) return `${Math.max(1, Math.round(minutes))}m`;
601
+ return `${(minutes / 60).toFixed(1)}h`;
602
+ }
603
+ function formatEpochProgress(diagnostics) {
604
+ const curve = diagnostics.training.curve;
605
+ if (curve.latest_epoch == null) return void 0;
606
+ if (curve.target_epochs == null) return curve.latest_epoch.toFixed(4);
607
+ return `${curve.latest_epoch.toFixed(4)} / ${curve.target_epochs.toFixed(2)}`;
608
+ }
609
+ function printDiagnostics(diagnostics) {
610
+ const curve = diagnostics.training.curve;
611
+ const perFive = curve.epoch_rate_per_minute == null ? void 0 : (curve.epoch_rate_per_minute * 5).toFixed(4);
612
+ printDetail([
613
+ ["Run", shortId(diagnostics.run_id)],
614
+ ["Status", formatStatus(diagnostics.status)],
615
+ ["Stage", diagnostics.stage_label ?? diagnostics.stage ?? void 0],
616
+ ["Summary", diagnostics.summary],
617
+ ["Training", diagnostics.training.state],
618
+ ["Epoch", formatEpochProgress(diagnostics)],
619
+ ["Latest Loss", curve.latest_loss == null ? void 0 : curve.latest_loss.toFixed(4)],
620
+ ["Pace", perFive ? `${perFive} epoch / 5m` : void 0],
621
+ ["ETA", formatMinutes(curve.estimated_minutes_remaining)],
622
+ ["Latest Update", formatDate(diagnostics.training.last_updated_at)]
623
+ ]);
624
+ if (diagnostics.insights.length) {
625
+ console.log("\nInsights:");
626
+ for (const insight of diagnostics.insights) {
627
+ console.log(` - ${insight}`);
628
+ }
629
+ }
630
+ }
598
631
  function registerRunsCommands(parent) {
599
632
  const runs = parent.command("runs").description("Manage runs");
600
633
  runs.command("list").description("List runs").option("-s, --spec <id>", "Filter by spec ID (full UUID or 8+ char prefix)").option("-p, --page <n>", "Page number", "1").option("--per-page <n>", "Results per page", "20").action(async (cmdOpts) => {
@@ -673,7 +706,7 @@ Eval Results (${data._evals.length}):`);
673
706
  );
674
707
  }
675
708
  });
676
- runs.command("start").description("Start a new run for a behaviour spec").argument("<spec-id>", "Behaviour spec ID (full UUID or 8+ char prefix)").option("--no-augment", "Disable data augmentation").option("--no-llm-judge", "Disable Bedrock LLM judging").option("--epochs <n>", "Number of training epochs").option("--lr <rate>", "Learning rate").option("--batch-size <n>", "Batch size").option("--dataset <id>", "Dataset ID to use instead of inline spec examples (full UUID or 4+ char prefix)").option("--train-ratio <ratio>", "Dataset training split ratio (default: 0.8 when any split ratio is set)").option("--validation-ratio <ratio>", "Dataset validation split ratio (default: 0.1 when any split ratio is set)").option("--test-ratio <ratio>", "Dataset test split ratio (default: 0.1 when any split ratio is set)").option("--lora-rank <n>", "LoRA rank").option("--lora-alpha <n>", "LoRA alpha").option("--max-eval-examples <n>", "Max examples for the primary eval pass").option("--max-test-eval-examples <n>", "Max examples for the secondary test eval pass").action(async (specId, cmdOpts) => {
709
+ runs.command("start").description("Start a new run for a behaviour spec").argument("<spec-id>", "Behaviour spec ID (full UUID or 8+ char prefix)").option("--no-augment", "Disable data augmentation").option("--no-llm-judge", "Disable LLM judging").option("--epochs <n>", "Number of training epochs").option("--lr <rate>", "Learning rate").option("--batch-size <n>", "Batch size").option("--dataset <id>", "Dataset ID to use instead of inline spec examples (full UUID or 4+ char prefix)").option("--train-ratio <ratio>", "Dataset training split ratio (default: 0.8 when any split ratio is set)").option("--validation-ratio <ratio>", "Dataset validation split ratio (default: 0.1 when any split ratio is set)").option("--test-ratio <ratio>", "Dataset test split ratio (default: 0.1 when any split ratio is set)").option("--lora-rank <n>", "LoRA rank").option("--lora-alpha <n>", "LoRA alpha").option("--max-eval-examples <n>", "Max examples for the primary eval pass").option("--max-test-eval-examples <n>", "Max examples for the secondary test eval pass").action(async (specId, cmdOpts) => {
677
710
  const opts = parent.opts();
678
711
  const body = {};
679
712
  if (cmdOpts.augment === false) body.augment = false;
@@ -748,6 +781,17 @@ Eval Results (${data._evals.length}):`);
748
781
  ["Completed", formatDate(run.completed_at)]
749
782
  ]);
750
783
  });
784
+ runs.command("diagnose").description("Show live run diagnostics").argument("<id>", "Run ID (full UUID or 8+ char prefix)").action(async (id) => {
785
+ const opts = parent.opts();
786
+ const fullId = await resolveRunId(id, opts);
787
+ const { data } = await get(
788
+ `/runs/${fullId}/diagnostics`,
789
+ void 0,
790
+ opts
791
+ );
792
+ if (isJsonMode()) return printJson(data);
793
+ printDiagnostics(data);
794
+ });
751
795
  }
752
796
 
753
797
  // src/commands/datasets.ts
@@ -757,6 +801,54 @@ function formatBytes(bytes) {
757
801
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
758
802
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
759
803
  }
804
+ var FORBIDDEN_CONTROL_CODEPOINTS = [
805
+ // C0 control chars except whitespace we explicitly allow inside string values.
806
+ // U+0009 TAB, U+000A LF, U+000D CR are kept since they appear in normal text.
807
+ { code: 0, name: "NULL" },
808
+ { code: 1, name: "START OF HEADING" },
809
+ { code: 2, name: "START OF TEXT" },
810
+ { code: 3, name: "END OF TEXT" },
811
+ { code: 4, name: "END OF TRANSMISSION" },
812
+ { code: 5, name: "ENQUIRY" },
813
+ { code: 6, name: "ACKNOWLEDGE" },
814
+ { code: 7, name: "BELL" },
815
+ { code: 8, name: "BACKSPACE" },
816
+ { code: 11, name: "VERTICAL TAB" },
817
+ { code: 12, name: "FORM FEED" },
818
+ { code: 14, name: "SHIFT OUT" },
819
+ { code: 15, name: "SHIFT IN" },
820
+ // 0x10..0x1F all rejected; named lookup falls back to "CONTROL CHARACTER".
821
+ { code: 28, name: "FILE SEPARATOR" },
822
+ { code: 29, name: "GROUP SEPARATOR" },
823
+ { code: 30, name: "RECORD SEPARATOR" },
824
+ // C1 control range U+0080..U+009F (all invisible, often mojibake from
825
+ // Windows-1252 smart quotes mis-tagged as Unicode codepoints).
826
+ { code: 133, name: "NEXT LINE" },
827
+ // Unicode line/paragraph separators - cut lines too.
828
+ { code: 8232, name: "LINE SEPARATOR" },
829
+ { code: 8233, name: "PARAGRAPH SEPARATOR" }
830
+ ];
831
+ function findControlChar(value) {
832
+ for (let i = 0; i < value.length; i++) {
833
+ const code = value.charCodeAt(i);
834
+ if (code < 32 && code !== 9 && code !== 10 && code !== 13) {
835
+ const named = FORBIDDEN_CONTROL_CODEPOINTS.find((entry) => entry.code === code);
836
+ return { codepoint: code, offset: i, name: named?.name ?? "CONTROL CHARACTER" };
837
+ }
838
+ if (code >= 128 && code <= 159) {
839
+ const named = FORBIDDEN_CONTROL_CODEPOINTS.find((entry) => entry.code === code);
840
+ return { codepoint: code, offset: i, name: named?.name ?? "C1 CONTROL CHARACTER" };
841
+ }
842
+ if (code === 8232 || code === 8233) {
843
+ const named = FORBIDDEN_CONTROL_CODEPOINTS.find((entry) => entry.code === code);
844
+ return { codepoint: code, offset: i, name: named?.name ?? "LINE BREAK" };
845
+ }
846
+ }
847
+ return null;
848
+ }
849
+ function formatCodepoint(code) {
850
+ return `U+${code.toString(16).toUpperCase().padStart(4, "0")}`;
851
+ }
760
852
  function validateDatasetFile(file) {
761
853
  const lines = readFileSync4(file, "utf8").split(/\r?\n/);
762
854
  const errors = [];
@@ -790,6 +882,16 @@ function validateDatasetFile(file) {
790
882
  if (typeof record.output !== "string") {
791
883
  errors.push(`Row ${rowNumber}: missing string "output" field`);
792
884
  }
885
+ for (const field of ["input", "output"]) {
886
+ const value = record[field];
887
+ if (typeof value !== "string") continue;
888
+ const hit = findControlChar(value);
889
+ if (hit) {
890
+ errors.push(
891
+ `Row ${rowNumber}: field "${field}" contains invisible control character ${formatCodepoint(hit.codepoint)} (${hit.name}) at offset ${hit.offset} \u2014 strip or escape before uploading; some training paths split on it`
892
+ );
893
+ }
894
+ }
793
895
  }
794
896
  if (rowCount === 0) {
795
897
  errors.push("File contains no JSONL rows");
@@ -979,7 +1081,7 @@ function registerModelsCommands(parent) {
979
1081
  ["Name", data.name],
980
1082
  ["Base Model", data.base_model],
981
1083
  ["Provider", data.provider],
982
- ["Provider Model", data.provider_model_id],
1084
+ ["Hosted Model", data.provider_model_id],
983
1085
  ["Description", data.description ?? void 0],
984
1086
  ["Created", formatDate(data.created_at)]
985
1087
  ]);
@@ -1039,7 +1141,7 @@ function formatSigned(cents) {
1039
1141
  return formatCents(cents);
1040
1142
  }
1041
1143
  function registerBalanceCommands(parent) {
1042
- parent.command("balance").description("Show available credits, held credits, and recent transactions").option("-n, --limit <n>", "Number of transactions to show (default 10)", "10").action(async (options) => {
1144
+ parent.command("balance").description("Show credit balance and recent transactions").option("-n, --limit <n>", "Number of transactions to show (default 10)", "10").action(async (options) => {
1043
1145
  const opts = parent.opts();
1044
1146
  const limit = Number(options.limit) || 10;
1045
1147
  const [{ data: balance }, { data: transactions }] = await Promise.all([
@@ -1049,12 +1151,10 @@ function registerBalanceCommands(parent) {
1049
1151
  if (isJsonMode()) {
1050
1152
  return printJson({ balance, transactions });
1051
1153
  }
1052
- const lowBalance = balance.available_cents < 100;
1053
- const availableLine = lowBalance ? chalk3.red(formatCents(balance.available_cents)) + chalk3.dim(" (low)") : chalk3.bold.green(formatCents(balance.available_cents));
1154
+ const lowBalance = balance.balance_cents < 100;
1155
+ const balanceLine = lowBalance ? chalk3.red(formatCents(balance.balance_cents)) + chalk3.dim(" (low)") : chalk3.bold.green(formatCents(balance.balance_cents));
1054
1156
  printDetail([
1055
- ["Available", availableLine],
1056
- ["Total balance", formatCents(balance.balance_cents)],
1057
- ["On hold", formatCents(balance.reserved_cents)],
1157
+ ["Credits", balanceLine],
1058
1158
  ["Lifetime top-ups", formatCents(balance.lifetime_topup_cents)]
1059
1159
  ]);
1060
1160
  if (transactions && transactions.length > 0) {
@@ -1080,7 +1180,7 @@ ${chalk3.dim("No transactions yet \u2014 run `tt topup` to add credits.")}`
1080
1180
  console.log(
1081
1181
  `
1082
1182
  ${formatStatus("preparing")} ${chalk3.yellow(
1083
- "Run `tt topup` to add more available credits before starting a run."
1183
+ "Run `tt topup` to add more credits before starting a run."
1084
1184
  )}`
1085
1185
  );
1086
1186
  }
@@ -1361,7 +1461,7 @@ function registerPushCommand(parent) {
1361
1461
 
1362
1462
  // src/index.ts
1363
1463
  var program = new Command();
1364
- program.name("tt").description("Tuned Tensor CLI \u2014 fine-tune and evaluate LLMs").version("0.4.9").option("-k, --api-key <key>", "API key (overrides stored key)").option(
1464
+ program.name("tt").description("Tuned Tensor CLI \u2014 fine-tune and evaluate LLMs").version("0.4.11").option("-k, --api-key <key>", "API key (overrides stored key)").option(
1365
1465
  "-u, --base-url <url>",
1366
1466
  "API base URL (default: https://tunedtensor.com)"
1367
1467
  ).option("--json", "Output raw JSON").option("--no-color", "Disable colors").hook("preAction", (_thisCommand, actionCommand) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/output.ts","../src/client.ts","../src/config.ts","../src/commands/auth.ts","../src/commands/specs.ts","../src/resolve.ts","../src/base-models.ts","../src/commands/runs.ts","../src/commands/datasets.ts","../src/commands/models.ts","../src/commands/balance.ts","../src/commands/topup.ts","../src/commands/init.ts","../src/commands/eval.ts","../src/eval/rules.ts","../src/commands/push.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { setJsonMode, reportError } from \"./output.js\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerSpecsCommands } from \"./commands/specs.js\";\nimport { registerRunsCommands } from \"./commands/runs.js\";\nimport { registerDatasetsCommands } from \"./commands/datasets.js\";\nimport { registerModelsCommands } from \"./commands/models.js\";\n\nimport { registerBalanceCommands } from \"./commands/balance.js\";\nimport { registerTopupCommands } from \"./commands/topup.js\";\nimport { registerInitCommand } from \"./commands/init.js\";\nimport { registerEvalCommand } from \"./commands/eval.js\";\nimport { registerPushCommand } from \"./commands/push.js\";\n\ndeclare const __TT_VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name(\"tt\")\n .description(\"Tuned Tensor CLI — fine-tune and evaluate LLMs\")\n .version(__TT_VERSION__)\n .option(\"-k, --api-key <key>\", \"API key (overrides stored key)\")\n .option(\n \"-u, --base-url <url>\",\n \"API base URL (default: https://tunedtensor.com)\",\n )\n .option(\"--json\", \"Output raw JSON\")\n .option(\"--no-color\", \"Disable colors\")\n .hook(\"preAction\", (_thisCommand, actionCommand) => {\n const rootOpts = program.opts();\n if (rootOpts.json) setJsonMode(true);\n if (rootOpts.color === false) {\n process.env.FORCE_COLOR = \"0\";\n }\n });\n\nregisterAuthCommands(program);\nregisterSpecsCommands(program);\nregisterRunsCommands(program);\nregisterDatasetsCommands(program);\nregisterModelsCommands(program);\n\nregisterBalanceCommands(program);\nregisterTopupCommands(program);\nregisterInitCommand(program);\nregisterEvalCommand(program);\nregisterPushCommand(program);\n\n// Honor --json even when parsing fails before the preAction hook runs\n// (e.g. on unknown commands). Cheap argv sniff is fine here.\nif (process.argv.includes(\"--json\")) setJsonMode(true);\n\nprogram.parseAsync().catch((err) => {\n reportError(err);\n process.exit(1);\n});\n","import chalk from \"chalk\";\nimport Table from \"cli-table3\";\nimport { ApiError } from \"./client.js\";\n\nlet jsonMode = false;\n\nexport function setJsonMode(enabled: boolean) {\n jsonMode = enabled;\n}\n\nexport function isJsonMode(): boolean {\n return jsonMode;\n}\n\nexport function printJson(data: unknown) {\n console.log(JSON.stringify(data, null, 2));\n}\n\nexport function printTable(\n headers: string[],\n rows: string[][],\n meta?: { page: number; per_page: number; total: number },\n) {\n const table = new Table({\n head: headers.map((h) => chalk.bold.cyan(h)),\n style: { head: [], border: [] },\n });\n for (const row of rows) {\n table.push(row);\n }\n console.log(table.toString());\n\n if (meta) {\n const totalPages = Math.ceil(meta.total / meta.per_page);\n console.log(\n chalk.dim(\n `\\nPage ${meta.page}/${totalPages} (${meta.total} total)`,\n ),\n );\n }\n}\n\nexport function printDetail(fields: [string, string | undefined][]) {\n const maxLabel = Math.max(...fields.map(([l]) => l.length));\n for (const [label, value] of fields) {\n const paddedLabel = label.padEnd(maxLabel);\n console.log(`${chalk.bold.cyan(paddedLabel)} ${value ?? chalk.dim(\"—\")}`);\n }\n}\n\nexport function printSuccess(message: string) {\n console.log(chalk.green(\"✓\") + \" \" + message);\n}\n\nexport function printWarning(message: string) {\n console.log(chalk.yellow(\"!\") + \" \" + message);\n}\n\nexport function printError(message: string) {\n console.error(chalk.red(\"✗\") + \" \" + message);\n}\n\nexport function reportError(err: unknown): void {\n const isApi = err instanceof ApiError;\n const message = (err as Error)?.message || String(err);\n\n if (jsonMode) {\n printJson({\n error: {\n status: isApi ? err.status : null,\n code: isApi ? err.code : \"CLI_ERROR\",\n message,\n },\n });\n } else if (isApi) {\n printError(`[${err.status}] ${message}`);\n } else {\n printError(message);\n }\n}\n\nexport function formatDate(iso?: string | null): string {\n if (!iso) return \"—\";\n return new Date(iso).toLocaleString();\n}\n\nexport function formatStatus(status: string): string {\n const map: Record<string, (s: string) => string> = {\n completed: chalk.green,\n running: chalk.blue,\n training: chalk.blue,\n evaluating: chalk.blue,\n preparing: chalk.yellow,\n pending: chalk.yellow,\n uploading: chalk.yellow,\n failed: chalk.red,\n cancelled: chalk.dim,\n validated: chalk.green,\n invalid: chalk.red,\n };\n const colorFn = map[status] || chalk.white;\n return colorFn(status);\n}\n\nexport function truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 1) + \"…\";\n}\n\nexport function shortId(id: string): string {\n return id.slice(0, 8);\n}\n","import { readFileSync, statSync } from \"node:fs\";\nimport { basename } from \"node:path\";\nimport { getApiKey, getBaseUrl } from \"./config.js\";\n\nexport interface ApiResponse<T> {\n data: T;\n meta?: { page: number; per_page: number; total: number };\n}\n\nexport interface ApiErrorBody {\n error: { code: string; message: string };\n}\n\nexport class ApiError extends Error {\n constructor(\n public status: number,\n public code: string,\n message: string,\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n\nexport interface ClientOpts {\n apiKey?: string;\n baseUrl?: string;\n}\n\nfunction resolveKey(opts?: ClientOpts): string {\n const key = getApiKey(opts);\n if (!key) {\n throw new ApiError(\n 401,\n \"NO_API_KEY\",\n \"No API key found. Run `tt auth login` or set TUNED_TENSOR_API_KEY.\",\n );\n }\n return key;\n}\n\nfunction buildUrl(\n path: string,\n query?: Record<string, string | number | undefined>,\n opts?: ClientOpts,\n): string {\n const base = getBaseUrl(opts);\n const url = new URL(`/api/v1${path}`, base);\n if (query) {\n for (const [k, v] of Object.entries(query)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n return url.toString();\n}\n\nasync function request<T>(\n method: string,\n path: string,\n options: {\n query?: Record<string, string | number | undefined>;\n body?: unknown;\n opts?: ClientOpts;\n } = {},\n): Promise<ApiResponse<T>> {\n const key = resolveKey(options.opts);\n const url = buildUrl(path, options.query, options.opts);\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${key}`,\n };\n\n let bodyPayload: string | undefined;\n if (options.body) {\n headers[\"Content-Type\"] = \"application/json\";\n bodyPayload = JSON.stringify(options.body);\n }\n\n const res = await fetch(url, { method, headers, body: bodyPayload });\n\n if (!res.ok) {\n let errBody: ApiErrorBody;\n try {\n errBody = (await res.json()) as ApiErrorBody;\n } catch {\n throw new ApiError(res.status, \"UNKNOWN\", res.statusText);\n }\n throw new ApiError(\n res.status,\n errBody.error?.code || \"UNKNOWN\",\n errBody.error?.message || res.statusText,\n );\n }\n\n if (res.status === 204) return { data: null as T };\n return (await res.json()) as ApiResponse<T>;\n}\n\nexport function get<T>(\n path: string,\n query?: Record<string, string | number | undefined>,\n opts?: ClientOpts,\n) {\n return request<T>(\"GET\", path, { query, opts });\n}\n\nexport function post<T>(\n path: string,\n body?: unknown,\n opts?: ClientOpts,\n) {\n return request<T>(\"POST\", path, { body, opts });\n}\n\nexport function put<T>(\n path: string,\n body?: unknown,\n opts?: ClientOpts,\n) {\n return request<T>(\"PUT\", path, { body, opts });\n}\n\nexport function patch<T>(\n path: string,\n body?: unknown,\n opts?: ClientOpts,\n) {\n return request<T>(\"PATCH\", path, { body, opts });\n}\n\nexport function del<T>(path: string, opts?: ClientOpts) {\n return request<T>(\"DELETE\", path, { opts });\n}\n\nexport async function upload<T>(\n path: string,\n filePath: string,\n fields: Record<string, string>,\n opts?: ClientOpts,\n): Promise<ApiResponse<T>> {\n const key = resolveKey(opts);\n const url = buildUrl(path, undefined, opts);\n\n const form = new FormData();\n for (const [k, v] of Object.entries(fields)) {\n form.append(k, v);\n }\n\n const fileBytes = readFileSync(filePath);\n const fileSize = statSync(filePath).size;\n const blob = new Blob([fileBytes], { type: \"application/jsonl\" });\n form.append(\"file\", blob, basename(filePath));\n\n const res = await fetch(url, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${key}` },\n body: form,\n });\n\n if (!res.ok) {\n let errBody: ApiErrorBody;\n try {\n errBody = (await res.json()) as ApiErrorBody;\n } catch {\n throw new ApiError(res.status, \"UNKNOWN\", res.statusText);\n }\n throw new ApiError(\n res.status,\n errBody.error?.code || \"UNKNOWN\",\n errBody.error?.message || res.statusText,\n );\n }\n\n return (await res.json()) as ApiResponse<T>;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface Config {\n api_key?: string;\n base_url?: string;\n}\n\nconst CONFIG_DIR_NAME = \"tuned-tensor\";\nconst CONFIG_FILE_NAME = \"config.json\";\n\nfunction getConfigDir(): string {\n const xdg = process.env.XDG_CONFIG_HOME;\n const base = xdg || join(homedir(), \".config\");\n return join(base, CONFIG_DIR_NAME);\n}\n\nfunction getConfigPath(): string {\n return join(getConfigDir(), CONFIG_FILE_NAME);\n}\n\nexport function readConfig(): Config {\n const path = getConfigPath();\n if (!existsSync(path)) return {};\n try {\n return JSON.parse(readFileSync(path, \"utf-8\"));\n } catch {\n return {};\n }\n}\n\nexport function writeConfig(config: Config): void {\n const dir = getConfigDir();\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n writeFileSync(getConfigPath(), JSON.stringify(config, null, 2) + \"\\n\");\n}\n\nexport function updateConfig(partial: Partial<Config>): void {\n const current = readConfig();\n writeConfig({ ...current, ...partial });\n}\n\nexport function clearConfig(): void {\n const path = getConfigPath();\n if (existsSync(path)) writeFileSync(path, \"{}\\n\");\n}\n\nexport const DEFAULT_BASE_URL = \"https://tunedtensor.com\";\n\nexport function getBaseUrl(opts?: { baseUrl?: string }): string {\n return opts?.baseUrl || process.env.TUNED_TENSOR_URL || readConfig().base_url || DEFAULT_BASE_URL;\n}\n\nexport function getApiKey(opts?: { apiKey?: string }): string | undefined {\n return opts?.apiKey || process.env.TUNED_TENSOR_API_KEY || readConfig().api_key;\n}\n","import { Command } from \"commander\";\nimport { createInterface } from \"node:readline/promises\";\nimport { stdin, stdout } from \"node:process\";\nimport {\n readConfig,\n updateConfig,\n clearConfig,\n getApiKey,\n getBaseUrl,\n DEFAULT_BASE_URL,\n} from \"../config.js\";\nimport {\n printSuccess,\n printDetail,\n printError,\n printWarning,\n isJsonMode,\n printJson,\n} from \"../output.js\";\nimport chalk from \"chalk\";\n\nexport function registerAuthCommands(parent: Command) {\n const auth = parent.command(\"auth\").description(\"Manage authentication\");\n\n auth\n .command(\"login\")\n .description(\"Store an API key for authentication\")\n .argument(\"[key]\", \"API key (tt_...). If omitted, you will be prompted.\")\n .action(async (key?: string) => {\n let apiKey = key;\n\n if (!apiKey) {\n const settingsUrl = `${DEFAULT_BASE_URL}/dashboard/settings`;\n console.log();\n console.log(\n ` To get your API key, go to ${chalk.bold(\"Settings → API Keys\")} in the Tuned Tensor dashboard:`,\n );\n console.log(` ${chalk.cyan.underline(settingsUrl)}`);\n console.log();\n\n const rl = createInterface({ input: stdin, output: stdout });\n apiKey = await rl.question(\"Enter your API key (tt_...): \");\n rl.close();\n }\n\n apiKey = apiKey.trim();\n\n if (!apiKey.startsWith(\"tt_\") || apiKey.length !== 51) {\n printError(\n \"Invalid API key format. Keys start with tt_ and are 51 characters long.\",\n );\n process.exit(1);\n }\n\n updateConfig({ api_key: apiKey });\n printSuccess(\n `API key stored (${apiKey.slice(0, 8)}...). You're ready to go.`,\n );\n });\n\n auth\n .command(\"logout\")\n .description(\"Remove stored credentials\")\n .action(() => {\n clearConfig();\n printSuccess(\"Credentials removed.\");\n });\n\n auth\n .command(\"status\")\n .description(\"Show current authentication status\")\n .action(() => {\n const opts = parent.opts();\n const apiKey = getApiKey(opts);\n const baseUrl = getBaseUrl(opts);\n\n if (isJsonMode()) {\n printJson({\n authenticated: !!apiKey,\n key_prefix: apiKey ? apiKey.slice(0, 8) + \"...\" : null,\n base_url: baseUrl,\n });\n return;\n }\n\n if (apiKey) {\n printDetail([\n [\"Authenticated\", \"Yes\"],\n [\"API Key\", apiKey.slice(0, 8) + \"...\"],\n [\"Base URL\", baseUrl],\n ]);\n } else {\n printWarning(\n \"Not authenticated. Run `tt auth login` to store an API key.\",\n );\n printDetail([[\"Base URL\", baseUrl]]);\n }\n });\n}\n","import { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport { get, post, put, del, type ClientOpts } from \"../client.js\";\nimport { resolveSpecId } from \"../resolve.js\";\nimport { canonicalizeBaseModel, canonicalizeSpecBaseModel } from \"../base-models.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printWarning,\n printJson,\n isJsonMode,\n formatDate,\n formatStatus,\n truncate,\n shortId,\n} from \"../output.js\";\n\nconst SPEC_BODY_KEYS = new Set([\n \"name\",\n \"description\",\n \"base_model\",\n \"system_prompt\",\n \"guidelines\",\n \"constraints\",\n \"examples\",\n]);\n\nconst RUN_INPUT_KEYS = [\"run_id\", \"behavior_spec_id\", \"spec_snapshot\", \"run_number\"];\n\nclass SpecBodyError extends Error {}\n\nfunction loadSpecBody(filePath: string, mode: \"create\" | \"update\"): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(readFileSync(filePath, \"utf-8\"));\n } catch (e) {\n throw new SpecBodyError(\n `Could not parse ${filePath}: ${(e as Error).message}`,\n );\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new SpecBodyError(\n `${filePath} must contain a JSON object at the top level.`,\n );\n }\n\n const body = parsed as Record<string, unknown>;\n\n const runInputHits = RUN_INPUT_KEYS.filter((k) => k in body);\n if (runInputHits.length >= 2 || \"spec_snapshot\" in body) {\n const hint = \"spec_snapshot\" in body\n ? `This file looks like a run-input payload (top-level keys: ${runInputHits.join(\", \")}). The actual spec is nested under \"spec_snapshot\". Try:\\n jq '.spec_snapshot' ${filePath} > spec.json\\n tt specs ${mode === \"create\" ? \"create\" : \"update <id>\"} --file spec.json`\n : `This file looks like a run-input payload (top-level keys: ${runInputHits.join(\", \")}), not a behaviour spec. To start a run on an existing spec, use: tt runs start <spec-id>`;\n throw new SpecBodyError(hint);\n }\n\n if (mode === \"create\" && typeof body.name !== \"string\") {\n throw new SpecBodyError(\n `${filePath} is missing required field \"name\" (string).`,\n );\n }\n\n const unknown = Object.keys(body).filter(\n (k) => !SPEC_BODY_KEYS.has(k) && k !== \"id\" && k !== \"eval_cases\",\n );\n if (unknown.length && !isJsonMode()) {\n printWarning(\n `Unknown spec field(s) in ${filePath}: ${unknown.join(\", \")}. They will be sent but may be rejected by the API.`,\n );\n }\n\n return canonicalizeSpecBaseModel(body);\n}\n\ninterface BehaviorSpec {\n id: string;\n name: string;\n description: string;\n system_prompt: string;\n guidelines: string[];\n examples: { input: string; output: string }[];\n constraints: string[];\n base_model: string;\n created_at: string;\n updated_at: string;\n _run_count?: number;\n _latest_run_status?: string;\n _latest_run_score?: number;\n _runs?: unknown[];\n}\n\nexport function registerSpecsCommands(parent: Command) {\n const specs = parent\n .command(\"specs\")\n .description(\"Manage behaviour specs\");\n\n specs\n .command(\"list\")\n .description(\"List behaviour specs\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const { data, meta } = await get<BehaviorSpec[]>(\n \"/behavior-specs\",\n { page: cmdOpts.page, per_page: cmdOpts.perPage },\n opts,\n );\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Name\", \"Model\", \"Examples\", \"Runs\", \"Status\", \"Updated\"],\n data.map((s) => [\n shortId(s.id),\n truncate(s.name, 30),\n s.base_model.split(\"/\").pop() || s.base_model,\n String(s.examples?.length ?? 0),\n String(s._run_count ?? 0),\n s._latest_run_status ? formatStatus(s._latest_run_status) : \"—\",\n formatDate(s.updated_at),\n ]),\n meta,\n );\n });\n\n specs\n .command(\"get\")\n .description(\"Show spec details\")\n .argument(\"<id>\", \"Spec ID (full UUID or 8+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveSpecId(id, opts);\n const { data } = await get<BehaviorSpec>(`/behavior-specs/${fullId}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Name\", data.name],\n [\"Description\", data.description || undefined],\n [\"Base Model\", data.base_model],\n [\"System Prompt\", data.system_prompt ? truncate(data.system_prompt, 80) : undefined],\n [\"Guidelines\", data.guidelines?.length ? data.guidelines.join(\", \") : undefined],\n [\"Constraints\", data.constraints?.length ? data.constraints.join(\", \") : undefined],\n [\"Examples\", String(data.examples?.length ?? 0)],\n [\"Runs\", String(data._run_count ?? data._runs?.length ?? 0)],\n [\"Created\", formatDate(data.created_at)],\n [\"Updated\", formatDate(data.updated_at)],\n ]);\n\n if (data.examples?.length) {\n console.log(\"\\nExamples:\");\n for (const [i, ex] of data.examples.slice(0, 5).entries()) {\n console.log(` ${i + 1}. Input: ${truncate(ex.input, 60)}`);\n console.log(` Output: ${truncate(ex.output, 60)}`);\n }\n if (data.examples.length > 5) {\n console.log(` ... and ${data.examples.length - 5} more`);\n }\n }\n });\n\n specs\n .command(\"create\")\n .description(\"Create a behaviour spec\")\n .option(\"-f, --file <path>\", \"JSON file with spec definition\")\n .option(\"-n, --name <name>\", \"Spec name\")\n .option(\"--model <model>\", \"Base model ID\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n let body: Record<string, unknown>;\n\n if (cmdOpts.file) {\n body = loadSpecBody(cmdOpts.file, \"create\");\n } else if (cmdOpts.name) {\n body = { name: cmdOpts.name };\n if (cmdOpts.model) body.base_model = canonicalizeBaseModel(cmdOpts.model);\n } else {\n throw new SpecBodyError(\"Provide --file or --name\");\n }\n\n const { data } = await post<BehaviorSpec>(\"/behavior-specs\", body, opts);\n\n if (isJsonMode()) return printJson(data);\n printSuccess(`Spec created: ${data.name} (${shortId(data.id)})`);\n });\n\n specs\n .command(\"update\")\n .description(\"Update a behaviour spec\")\n .argument(\"<id>\", \"Spec ID (full UUID or 8+ char prefix)\")\n .option(\"-f, --file <path>\", \"JSON file with fields to update\")\n .option(\"-n, --name <name>\", \"New name\")\n .option(\"--model <model>\", \"New base model ID\")\n .action(async (id: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n let body: Record<string, unknown>;\n\n if (cmdOpts.file) {\n body = loadSpecBody(cmdOpts.file, \"update\");\n } else {\n body = {};\n if (cmdOpts.name) body.name = cmdOpts.name;\n if (cmdOpts.model) body.base_model = canonicalizeBaseModel(cmdOpts.model);\n }\n\n const fullId = await resolveSpecId(id, opts);\n const { data } = await put<BehaviorSpec>(\n `/behavior-specs/${fullId}`,\n body,\n opts,\n );\n\n if (isJsonMode()) return printJson(data);\n printSuccess(`Spec updated: ${data.name} (${shortId(data.id)})`);\n });\n\n specs\n .command(\"delete\")\n .description(\"Delete a behaviour spec\")\n .argument(\"<id>\", \"Spec ID (full UUID or 8+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveSpecId(id, opts);\n await del(`/behavior-specs/${fullId}`, opts);\n\n if (isJsonMode()) return printJson({ id: fullId, deleted: true });\n printSuccess(`Spec deleted: ${shortId(fullId)}`);\n });\n}\n","import { get, type ClientOpts } from \"./client.js\";\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nconst RESOLVE_PAGE_SIZE = 100;\nconst MIN_PREFIX_LEN = 4;\n\ninterface Identifiable {\n id: string;\n name?: string;\n run_number?: number;\n}\n\ninterface Listed<T> {\n data: T[];\n meta?: { page: number; per_page: number; total: number };\n}\n\nexport class ResolveError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ResolveError\";\n }\n}\n\nexport function isFullUuid(value: string): boolean {\n return UUID_RE.test(value);\n}\n\nasync function resolvePrefix<T extends Identifiable>(\n prefix: string,\n kind: \"spec\" | \"run\" | \"dataset\" | \"model\",\n listPath: string,\n describe: (item: T) => string,\n opts?: ClientOpts,\n): Promise<string> {\n if (isFullUuid(prefix)) return prefix;\n\n const noun = kind;\n const listCmd = `tt ${kind}s list --json`;\n\n if (prefix.length < MIN_PREFIX_LEN) {\n throw new ResolveError(\n `${capitalize(noun)} ID prefix \"${prefix}\" is too short — provide at least ${MIN_PREFIX_LEN} characters or the full UUID.`,\n );\n }\n\n const lower = prefix.toLowerCase();\n const { data, meta } = (await get<T[]>(\n listPath,\n { page: 1, per_page: RESOLVE_PAGE_SIZE },\n opts,\n )) as Listed<T>;\n\n const matches = data.filter((item) => item.id.toLowerCase().startsWith(lower));\n\n if (matches.length === 1) return matches[0].id;\n\n if (matches.length === 0) {\n if (meta && meta.total > data.length) {\n throw new ResolveError(\n `No ${noun} found with ID prefix \"${prefix}\" in the first ${data.length} ${noun}s (you have ${meta.total} total). Use the full UUID — see \\`${listCmd}\\`.`,\n );\n }\n throw new ResolveError(`No ${noun} found with ID prefix \"${prefix}\".`);\n }\n\n const list = matches.map((m) => ` ${describe(m)}`).join(\"\\n\");\n throw new ResolveError(\n `${capitalize(noun)} ID prefix \"${prefix}\" is ambiguous (${matches.length} matches):\\n${list}\\nProvide more characters or the full UUID.`,\n );\n}\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nexport function resolveSpecId(prefix: string, opts?: ClientOpts): Promise<string> {\n return resolvePrefix<Identifiable>(\n prefix,\n \"spec\",\n \"/behavior-specs\",\n (s) => `${s.id}${s.name ? ` (${s.name})` : \"\"}`,\n opts,\n );\n}\n\nexport function resolveRunId(prefix: string, opts?: ClientOpts): Promise<string> {\n return resolvePrefix<Identifiable>(\n prefix,\n \"run\",\n \"/runs\",\n (r) => `${r.id}${r.run_number != null ? ` (run #${r.run_number})` : \"\"}`,\n opts,\n );\n}\n\nexport function resolveDatasetId(prefix: string, opts?: ClientOpts): Promise<string> {\n return resolvePrefix<Identifiable>(\n prefix,\n \"dataset\",\n \"/datasets\",\n (d) => `${d.id}${d.name ? ` (${d.name})` : \"\"}`,\n opts,\n );\n}\n\nexport function resolveModelId(prefix: string, opts?: ClientOpts): Promise<string> {\n return resolvePrefix<Identifiable>(\n prefix,\n \"model\",\n \"/models\",\n (m) => `${m.id}${m.name ? ` (${m.name})` : \"\"}`,\n opts,\n );\n}\n","export const SUPPORTED_BASE_MODELS = [\n \"google/gemma-4-E2B-it\",\n \"google/gemma-4-E4B-it\",\n \"Qwen/Qwen3.5-2B\",\n \"Qwen/Qwen3.5-4B\",\n \"meta-llama/Llama-3.2-3B-Instruct\",\n \"microsoft/Phi-4-mini-instruct\",\n \"ibm-granite/granite-3.3-2b-instruct\",\n \"bigcode/starcoder2-3b\",\n] as const;\n\nexport type SupportedBaseModel = (typeof SUPPORTED_BASE_MODELS)[number];\n\nconst BASE_MODEL_ALIASES = new Map<string, SupportedBaseModel>();\n\nfor (const model of SUPPORTED_BASE_MODELS) {\n BASE_MODEL_ALIASES.set(model.toLowerCase(), model);\n}\n\nfor (const [alias, model] of [\n [\"google/gemma-4-E2B\", \"google/gemma-4-E2B-it\"],\n [\"google/gemma-4-e2b\", \"google/gemma-4-E2B-it\"],\n [\"google/gemma-4-e2b-it\", \"google/gemma-4-E2B-it\"],\n [\"google/gemma-4-E4B\", \"google/gemma-4-E4B-it\"],\n [\"google/gemma-4-e4b\", \"google/gemma-4-E4B-it\"],\n [\"google/gemma-4-e4b-it\", \"google/gemma-4-E4B-it\"],\n [\"qwen/qwen3.5-2b\", \"Qwen/Qwen3.5-2B\"],\n [\"Qwen/Qwen3.5-2B-Base\", \"Qwen/Qwen3.5-2B\"],\n [\"qwen/qwen3.5-2b-base\", \"Qwen/Qwen3.5-2B\"],\n [\"qwen/qwen3.5-4b\", \"Qwen/Qwen3.5-4B\"],\n [\"Qwen/Qwen3.5-4B-Base\", \"Qwen/Qwen3.5-4B\"],\n [\"qwen/qwen3.5-4b-base\", \"Qwen/Qwen3.5-4B\"],\n [\"meta-llama/llama-3.2-3b-instruct\", \"meta-llama/Llama-3.2-3B-Instruct\"],\n [\"meta-llama/Llama-3.2-3B\", \"meta-llama/Llama-3.2-3B-Instruct\"],\n [\"meta-llama/llama-3.2-3b\", \"meta-llama/Llama-3.2-3B-Instruct\"],\n [\"microsoft/phi-4-mini-instruct\", \"microsoft/Phi-4-mini-instruct\"],\n [\"phi-4-mini-instruct\", \"microsoft/Phi-4-mini-instruct\"],\n [\"ibm-granite/granite-3.3-2b-instruct\", \"ibm-granite/granite-3.3-2b-instruct\"],\n [\"granite-3.3-2b-instruct\", \"ibm-granite/granite-3.3-2b-instruct\"],\n [\"bigcode/starcoder2-3b\", \"bigcode/starcoder2-3b\"],\n [\"starcoder2-3b\", \"bigcode/starcoder2-3b\"],\n] as const) {\n BASE_MODEL_ALIASES.set(alias.toLowerCase(), model);\n}\n\nexport class UnsupportedBaseModelError extends Error {\n constructor(model: unknown) {\n const supported = SUPPORTED_BASE_MODELS.join(\", \");\n super(\n `Unsupported base_model \"${String(model)}\". Supported base models: ${supported}`,\n );\n this.name = \"UnsupportedBaseModelError\";\n }\n}\n\nexport function canonicalizeBaseModel(model: unknown): SupportedBaseModel {\n if (typeof model !== \"string\" || !model.trim()) {\n throw new UnsupportedBaseModelError(model);\n }\n\n const canonical = BASE_MODEL_ALIASES.get(model.trim().toLowerCase());\n if (!canonical) {\n throw new UnsupportedBaseModelError(model);\n }\n\n return canonical;\n}\n\nexport function canonicalizeSpecBaseModel<T extends Record<string, unknown>>(body: T): T {\n if (\"base_model\" in body && body.base_model !== undefined) {\n return { ...body, base_model: canonicalizeBaseModel(body.base_model) };\n }\n\n return body;\n}\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { get, post, type ClientOpts } from \"../client.js\";\nimport { resolveSpecId, resolveRunId, resolveDatasetId } from \"../resolve.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printJson,\n isJsonMode,\n formatDate,\n formatStatus,\n shortId,\n truncate,\n} from \"../output.js\";\n\ninterface Run {\n id: string;\n behavior_spec_id: string;\n run_number: number;\n status: string;\n current_stage?: string | null;\n stage_label?: string | null;\n progress_pct?: number | null;\n status_message?: string | null;\n hyperparameters: Record<string, unknown> | null;\n eval_summary: { avg_score?: number; mean_score?: number; pass_rate?: number } | null;\n error: string | null;\n started_at: string | null;\n completed_at: string | null;\n created_at: string;\n updated_at: string;\n _spec_name?: string;\n _evals?: RunEval[];\n _events?: RunEvent[];\n}\n\ninterface RunEval {\n id: string;\n prompt: string;\n expected: string;\n actual: string;\n passed: boolean;\n score: number | null;\n reasoning: string | null;\n latency_ms: number | null;\n}\n\ninterface RunEvent {\n id: string;\n stage: string;\n label: string;\n status: string;\n message: string | null;\n occurred_at: string;\n}\n\nfunction formatProgress(run: Run): string | undefined {\n if (run.progress_pct == null && !run.stage_label) return undefined;\n const label = run.stage_label ?? run.current_stage ?? \"Progress\";\n return run.progress_pct == null ? label : `${label} (${run.progress_pct}%)`;\n}\n\nfunction getEvalScore(run: Run): number | undefined {\n return run.eval_summary?.avg_score ?? run.eval_summary?.mean_score;\n}\n\nfunction formatEvalScore(run: Run): string | undefined {\n const score = getEvalScore(run);\n return score == null ? undefined : (score * 100).toFixed(1) + \"%\";\n}\n\nexport function registerRunsCommands(parent: Command) {\n const runs = parent.command(\"runs\").description(\"Manage runs\");\n\n runs\n .command(\"list\")\n .description(\"List runs\")\n .option(\"-s, --spec <id>\", \"Filter by spec ID (full UUID or 8+ char prefix)\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n\n let path = \"/runs\";\n const query: Record<string, string | number> = {\n page: cmdOpts.page,\n per_page: cmdOpts.perPage,\n };\n\n if (cmdOpts.spec) {\n const fullSpecId = await resolveSpecId(cmdOpts.spec, opts);\n path = `/behavior-specs/${fullSpecId}/runs`;\n }\n\n const { data, meta } = await get<Run[]>(path, query, opts);\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Spec\", \"#\", \"Status\", \"Score\", \"Started\", \"Completed\"],\n data.map((r) => [\n shortId(r.id),\n r._spec_name ? truncate(r._spec_name, 20) : shortId(r.behavior_spec_id),\n String(r.run_number),\n formatStatus(r.status),\n formatEvalScore(r) ?? \"—\",\n formatDate(r.started_at),\n formatDate(r.completed_at),\n ]),\n meta,\n );\n });\n\n runs\n .command(\"get\")\n .description(\"Show run details and eval results\")\n .argument(\"<id>\", \"Run ID (full UUID or 8+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveRunId(id, opts);\n const { data } = await get<Run>(`/runs/${fullId}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Spec\", data._spec_name ?? shortId(data.behavior_spec_id)],\n [\"Run #\", String(data.run_number)],\n [\"Status\", formatStatus(data.status)],\n [\"Stage\", formatProgress(data)],\n [\"Message\", data.status_message ?? undefined],\n [\"Score\", formatEvalScore(data)],\n [\"Pass Rate\", data.eval_summary?.pass_rate != null\n ? (data.eval_summary.pass_rate * 100).toFixed(1) + \"%\"\n : undefined],\n [\"Error\", data.error ?? undefined],\n [\"Started\", formatDate(data.started_at)],\n [\"Completed\", formatDate(data.completed_at)],\n [\"Created\", formatDate(data.created_at)],\n ]);\n\n if (data.hyperparameters && Object.keys(data.hyperparameters).length) {\n console.log(\"\\nHyperparameters:\");\n for (const [k, v] of Object.entries(data.hyperparameters)) {\n console.log(` ${k}: ${v}`);\n }\n }\n\n if (data._events?.length) {\n console.log(\"\\nLatest Updates:\");\n for (const event of data._events.slice(-5)) {\n const time = formatDate(event.occurred_at);\n console.log(\n ` ${time} ${formatStatus(event.status)} ${event.label}${event.message ? ` — ${event.message}` : \"\"}`,\n );\n }\n }\n\n if (data._evals?.length) {\n console.log(`\\nEval Results (${data._evals.length}):`);\n printTable(\n [\"#\", \"Passed\", \"Score\", \"Prompt\", \"Latency\"],\n data._evals.map((e, i) => [\n String(i + 1),\n e.passed ? \"✓\" : \"✗\",\n e.score != null ? e.score.toFixed(2) : \"—\",\n truncate(e.prompt, 40),\n e.latency_ms != null ? `${e.latency_ms}ms` : \"—\",\n ]),\n );\n }\n });\n\n runs\n .command(\"start\")\n .description(\"Start a new run for a behaviour spec\")\n .argument(\"<spec-id>\", \"Behaviour spec ID (full UUID or 8+ char prefix)\")\n .option(\"--no-augment\", \"Disable data augmentation\")\n .option(\"--no-llm-judge\", \"Disable Bedrock LLM judging\")\n .option(\"--epochs <n>\", \"Number of training epochs\")\n .option(\"--lr <rate>\", \"Learning rate\")\n .option(\"--batch-size <n>\", \"Batch size\")\n .option(\"--dataset <id>\", \"Dataset ID to use instead of inline spec examples (full UUID or 4+ char prefix)\")\n .option(\"--train-ratio <ratio>\", \"Dataset training split ratio (default: 0.8 when any split ratio is set)\")\n .option(\"--validation-ratio <ratio>\", \"Dataset validation split ratio (default: 0.1 when any split ratio is set)\")\n .option(\"--test-ratio <ratio>\", \"Dataset test split ratio (default: 0.1 when any split ratio is set)\")\n .option(\"--lora-rank <n>\", \"LoRA rank\")\n .option(\"--lora-alpha <n>\", \"LoRA alpha\")\n .option(\"--max-eval-examples <n>\", \"Max examples for the primary eval pass\")\n .option(\"--max-test-eval-examples <n>\", \"Max examples for the secondary test eval pass\")\n .action(async (specId: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const body: Record<string, unknown> = {};\n\n if (cmdOpts.augment === false) body.augment = false;\n if (cmdOpts.dataset) body.dataset_id = await resolveDatasetId(cmdOpts.dataset, opts);\n\n const splitRatioOptions = [\n cmdOpts.trainRatio,\n cmdOpts.validationRatio,\n cmdOpts.testRatio,\n ];\n if (splitRatioOptions.some((value) => value != null)) {\n body.split_ratios = {\n train: cmdOpts.trainRatio != null ? Number(cmdOpts.trainRatio) : 0.8,\n validation:\n cmdOpts.validationRatio != null ? Number(cmdOpts.validationRatio) : 0.1,\n test: cmdOpts.testRatio != null ? Number(cmdOpts.testRatio) : 0.1,\n };\n }\n\n const hp: Record<string, unknown> = {};\n if (cmdOpts.epochs) hp.n_epochs = Number(cmdOpts.epochs);\n if (cmdOpts.lr) hp.learning_rate = Number(cmdOpts.lr);\n if (cmdOpts.batchSize) hp.batch_size = Number(cmdOpts.batchSize);\n if (cmdOpts.loraRank) hp.lora_rank = Number(cmdOpts.loraRank);\n if (cmdOpts.loraAlpha) hp.lora_alpha = Number(cmdOpts.loraAlpha);\n if (cmdOpts.maxEvalExamples) hp.max_eval_examples = Number(cmdOpts.maxEvalExamples);\n if (cmdOpts.maxTestEvalExamples) hp.max_test_eval_examples = Number(cmdOpts.maxTestEvalExamples);\n if (cmdOpts.llmJudge === false) body.use_llm_judge = false;\n if (Object.keys(hp).length) body.hyperparameters = hp;\n\n const fullSpecId = await resolveSpecId(specId, opts);\n const { data } = await post<Run>(\n `/behavior-specs/${fullSpecId}/runs`,\n body,\n opts,\n );\n\n if (isJsonMode()) return printJson(data);\n printSuccess(\n `Run #${data.run_number} started (${shortId(data.id)}). ${formatProgress(data) ?? `Status: ${formatStatus(data.status)}`}`,\n );\n });\n\n runs\n .command(\"cancel\")\n .description(\"Cancel a running run\")\n .argument(\"<id>\", \"Run ID (full UUID or 8+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveRunId(id, opts);\n const { data } = await post<Run>(`/runs/${fullId}/cancel`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n printSuccess(`Run ${shortId(fullId)} cancelled.`);\n });\n\n runs\n .command(\"watch\")\n .description(\"Watch a run until it completes\")\n .argument(\"<id>\", \"Run ID (full UUID or 8+ char prefix)\")\n .option(\"--interval <ms>\", \"Poll interval in milliseconds\", \"5000\")\n .action(async (id: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const interval = Number(cmdOpts.interval);\n const fullId = await resolveRunId(id, opts);\n const spinner = ora(`Watching run ${shortId(fullId)}...`).start();\n\n const terminalStates = new Set([\n \"completed\",\n \"failed\",\n \"cancelled\",\n ]);\n\n let run: Run;\n while (true) {\n const { data } = await get<Run>(`/runs/${fullId}`, undefined, opts);\n run = data;\n spinner.text = `Run ${shortId(fullId)} — ${formatProgress(run) ?? formatStatus(run.status)}`;\n\n if (terminalStates.has(run.status)) break;\n await new Promise((r) => setTimeout(r, interval));\n }\n\n spinner.stop();\n\n if (isJsonMode()) return printJson(run);\n\n printDetail([\n [\"Run\", shortId(run.id)],\n [\"Status\", formatStatus(run.status)],\n [\"Stage\", formatProgress(run)],\n [\"Message\", run.status_message ?? undefined],\n [\"Score\", formatEvalScore(run)],\n [\"Error\", run.error ?? undefined],\n [\"Completed\", formatDate(run.completed_at)],\n ]);\n });\n}\n","import { Command } from \"commander\";\nimport { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { get, del, post, type ClientOpts } from \"../client.js\";\nimport { resolveDatasetId } from \"../resolve.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printJson,\n printError,\n isJsonMode,\n formatDate,\n formatStatus,\n shortId,\n truncate,\n} from \"../output.js\";\n\ninterface Dataset {\n id: string;\n name: string;\n description: string | null;\n storage_path: string;\n file_size_bytes: number;\n row_count: number;\n format: string;\n status: string;\n validation_errors: string[] | null;\n created_at: string;\n updated_at: string;\n}\n\ninterface DatasetUploadUrl {\n path: string;\n upload_url: string;\n method: \"PUT\";\n headers?: Record<string, string>;\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction validateDatasetFile(file: string): void {\n const lines = readFileSync(file, \"utf8\").split(/\\r?\\n/);\n const errors: string[] = [];\n let rowCount = 0;\n\n for (const [index, rawLine] of lines.entries()) {\n const line = rawLine.trim();\n if (!line) continue;\n\n rowCount += 1;\n const rowNumber = index + 1;\n let row: unknown;\n\n try {\n row = JSON.parse(line);\n } catch {\n errors.push(`Row ${rowNumber}: invalid JSON`);\n continue;\n }\n\n if (!row || typeof row !== \"object\" || Array.isArray(row)) {\n errors.push(`Row ${rowNumber}: expected an object with \"input\" and \"output\" fields`);\n continue;\n }\n\n const record = row as Record<string, unknown>;\n if (\"messages\" in record && !(\"input\" in record) && !(\"output\" in record)) {\n errors.push(\n `Row ${rowNumber}: found OpenAI SFT-style \"messages\"; Tuned Tensor datasets require flat \"input\" and \"output\" strings`,\n );\n continue;\n }\n\n if (typeof record.input !== \"string\") {\n errors.push(`Row ${rowNumber}: missing string \"input\" field`);\n }\n if (typeof record.output !== \"string\") {\n errors.push(`Row ${rowNumber}: missing string \"output\" field`);\n }\n }\n\n if (rowCount === 0) {\n errors.push(\"File contains no JSONL rows\");\n }\n\n if (errors.length > 0) {\n const preview = errors.slice(0, 5).join(\"\\n\");\n const suffix = errors.length > 5 ? `\\n...and ${errors.length - 5} more error(s)` : \"\";\n throw new Error(\n `Invalid dataset format. Each JSONL row must be {\"input\": \"...\", \"output\": \"...\"}.\\n${preview}${suffix}`,\n );\n }\n}\n\nexport function registerDatasetsCommands(parent: Command) {\n const datasets = parent\n .command(\"datasets\")\n .description(\"Manage datasets\");\n\n datasets\n .command(\"list\")\n .description(\"List datasets\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const { data, meta } = await get<Dataset[]>(\n \"/datasets\",\n { page: cmdOpts.page, per_page: cmdOpts.perPage },\n opts,\n );\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Name\", \"Rows\", \"Size\", \"Status\", \"Created\"],\n data.map((d) => [\n shortId(d.id),\n truncate(d.name, 30),\n String(d.row_count),\n formatBytes(d.file_size_bytes),\n formatStatus(d.status),\n formatDate(d.created_at),\n ]),\n meta,\n );\n });\n\n datasets\n .command(\"get\")\n .description(\"Show dataset details\")\n .argument(\"<id>\", \"Dataset ID (full UUID or 4+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveDatasetId(id, opts);\n const { data } = await get<Dataset>(`/datasets/${fullId}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Name\", data.name],\n [\"Description\", data.description ?? undefined],\n [\"Format\", data.format],\n [\"Rows\", String(data.row_count)],\n [\"Size\", formatBytes(data.file_size_bytes)],\n [\"Status\", formatStatus(data.status)],\n [\"Created\", formatDate(data.created_at)],\n [\"Updated\", formatDate(data.updated_at)],\n ]);\n\n if (data.validation_errors?.length) {\n console.log(\"\\nValidation Errors:\");\n for (const err of data.validation_errors) {\n console.log(` - ${err}`);\n }\n }\n });\n\n datasets\n .command(\"upload\")\n .description(\"Upload a JSONL dataset file\")\n .argument(\"<file>\", \"Path to JSONL file\")\n .option(\"-n, --name <name>\", \"Dataset name (defaults to filename)\")\n .option(\"-d, --description <desc>\", \"Dataset description\")\n .action(async (file: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n\n if (!existsSync(file)) {\n printError(`File not found: ${file}`);\n process.exit(1);\n }\n\n validateDatasetFile(file);\n\n const name = cmdOpts.name || file.split(\"/\").pop()!.replace(/\\.jsonl?$/, \"\");\n const fileBytes = readFileSync(file);\n const uploadUrl = await post<DatasetUploadUrl>(\n \"/datasets/upload-url\",\n {\n name,\n description: cmdOpts.description ?? null,\n filename: file.split(\"/\").pop()!,\n size: statSync(file).size,\n contentType: \"application/jsonl\",\n },\n opts,\n );\n\n const uploadRes = await fetch(uploadUrl.data.upload_url, {\n method: uploadUrl.data.method,\n headers: uploadUrl.data.headers ?? { \"Content-Type\": \"application/jsonl\" },\n body: new Blob([fileBytes], { type: \"application/jsonl\" }),\n });\n if (!uploadRes.ok) {\n throw new Error(`Dataset upload failed: ${uploadRes.status} ${uploadRes.statusText}`);\n }\n\n const { data } = await post<Dataset>(\n \"/datasets/finalize\",\n {\n path: uploadUrl.data.path,\n name,\n description: cmdOpts.description ?? null,\n },\n opts,\n );\n\n if (isJsonMode()) return printJson(data);\n printSuccess(\n `Dataset uploaded: ${data.name} (${shortId(data.id)}) — ${data.row_count} rows`,\n );\n });\n\n datasets\n .command(\"delete\")\n .description(\"Delete a dataset\")\n .argument(\"<id>\", \"Dataset ID (full UUID or 4+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveDatasetId(id, opts);\n await del(`/datasets/${fullId}`, opts);\n\n if (isJsonMode()) return printJson({ id: fullId, deleted: true });\n printSuccess(`Dataset deleted: ${shortId(fullId)}`);\n });\n}\n","import { Command } from \"commander\";\nimport { existsSync, mkdirSync, statSync, createWriteStream, unlinkSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { Readable } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport { get, del, type ClientOpts } from \"../client.js\";\nimport { resolveModelId } from \"../resolve.js\";\nimport { SUPPORTED_BASE_MODELS } from \"../base-models.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printJson,\n isJsonMode,\n formatDate,\n shortId,\n truncate,\n} from \"../output.js\";\n\ninterface Model {\n id: string;\n name: string;\n provider: string;\n provider_model_id: string;\n base_model: string;\n description: string | null;\n created_at: string;\n}\n\ninterface ModelDownload {\n url: string;\n filename: string;\n expires_at: string;\n}\n\nfunction resolveOutputPath(output: string | undefined, filename: string): string {\n if (!output) return filename;\n if (existsSync(output) && statSync(output).isDirectory()) {\n return join(output, filename);\n }\n return output;\n}\n\nasync function downloadUrlToFile(url: string, outputPath: string): Promise<number | null> {\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Download failed: ${res.status} ${res.statusText}`);\n }\n if (!res.body) {\n throw new Error(\"Download failed: response body was empty\");\n }\n\n mkdirSync(dirname(outputPath), { recursive: true });\n const file = createWriteStream(outputPath);\n\n try {\n await pipeline(Readable.fromWeb(res.body), file);\n } catch (err) {\n try {\n unlinkSync(outputPath);\n } catch {\n // Best effort cleanup for partially written downloads.\n }\n throw err;\n }\n\n const length = res.headers.get(\"content-length\");\n return length ? Number(length) : null;\n}\n\nexport function registerModelsCommands(parent: Command) {\n const models = parent.command(\"models\").description(\"Manage fine-tuned models\");\n\n models\n .command(\"base\")\n .description(\"List supported base models\")\n .action(async () => {\n const data = SUPPORTED_BASE_MODELS.map((model) => ({\n id: model,\n name: model.split(\"/\").pop() || model,\n type: \"base\" as const,\n }));\n\n if (isJsonMode()) return printJson({ data });\n\n printTable(\n [\"ID\", \"Name\", \"Type\"],\n data.map((m) => [m.id, m.name, m.type]),\n );\n });\n\n models\n .command(\"list\")\n .description(\"List fine-tuned models\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const { data, meta } = await get<Model[]>(\n \"/models\",\n { page: cmdOpts.page, per_page: cmdOpts.perPage },\n opts,\n );\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Name\", \"Base Model\", \"Provider\", \"Created\"],\n data.map((m) => [\n shortId(m.id),\n truncate(m.name, 30),\n m.base_model.split(\"/\").pop() || m.base_model,\n m.provider,\n formatDate(m.created_at),\n ]),\n meta,\n );\n });\n\n models\n .command(\"get\")\n .description(\"Show model details\")\n .argument(\"<id>\", \"Model ID (full UUID or 4+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveModelId(id, opts);\n const { data } = await get<Model>(`/models/${fullId}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Name\", data.name],\n [\"Base Model\", data.base_model],\n [\"Provider\", data.provider],\n [\"Provider Model\", data.provider_model_id],\n [\"Description\", data.description ?? undefined],\n [\"Created\", formatDate(data.created_at)],\n ]);\n });\n\n models\n .command(\"download\")\n .description(\"Download a fine-tuned model artifact\")\n .argument(\"<id>\", \"Model ID (full UUID or 4+ char prefix)\")\n .option(\"-o, --output <path>\", \"Output file or directory\")\n .option(\"-f, --force\", \"Overwrite the output file if it already exists\")\n .action(async (id: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveModelId(id, opts);\n const { data } = await get<ModelDownload>(\n `/models/${fullId}/download`,\n undefined,\n opts,\n );\n\n const outputPath = resolveOutputPath(cmdOpts.output, data.filename);\n if (existsSync(outputPath) && !cmdOpts.force) {\n throw new Error(`Output file already exists: ${outputPath}. Use --force to overwrite.`);\n }\n\n const bytes = await downloadUrlToFile(data.url, outputPath);\n\n if (isJsonMode()) {\n return printJson({\n id: fullId,\n output_path: outputPath,\n filename: data.filename,\n bytes,\n expires_at: data.expires_at,\n });\n }\n\n const size = bytes == null ? \"\" : ` (${bytes} bytes)`;\n printSuccess(`Model downloaded to ${outputPath}${size}`);\n });\n\n models\n .command(\"delete\")\n .description(\"Delete a model\")\n .argument(\"<id>\", \"Model ID (full UUID or 4+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveModelId(id, opts);\n await del(`/models/${fullId}`, opts);\n\n if (isJsonMode()) return printJson({ id: fullId, deleted: true });\n printSuccess(`Model deleted: ${shortId(fullId)}`);\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { get, type ClientOpts } from \"../client.js\";\nimport {\n printDetail,\n printJson,\n printTable,\n isJsonMode,\n formatDate,\n formatStatus,\n shortId,\n} from \"../output.js\";\n\ninterface BalanceResponse {\n balance_cents: number;\n reserved_cents: number;\n available_cents: number;\n lifetime_topup_cents: number;\n}\n\ntype CreditKind =\n | \"signup_bonus\"\n | \"topup\"\n | \"debit_run\"\n | \"debit_autotune\"\n | \"refund\"\n | \"adjustment\";\n\ninterface LedgerRow {\n id: string;\n kind: CreditKind;\n amount_cents: number;\n balance_after_cents: number;\n reference_id: string | null;\n created_at: string;\n}\n\nconst KIND_LABELS: Record<CreditKind, string> = {\n signup_bonus: \"Signup bonus\",\n topup: \"Top-up\",\n debit_run: \"Run\",\n debit_autotune: \"Auto-tune\",\n refund: \"Refund\",\n adjustment: \"Adjustment\",\n};\n\nfunction formatCents(cents: number): string {\n const sign = cents < 0 ? \"-\" : \"\";\n const abs = Math.abs(cents);\n return `${sign}$${(abs / 100).toFixed(2)}`;\n}\n\nfunction formatSigned(cents: number): string {\n if (cents > 0) return chalk.green(`+${formatCents(cents)}`);\n if (cents < 0) return chalk.red(formatCents(cents));\n return formatCents(cents);\n}\n\nexport function registerBalanceCommands(parent: Command) {\n parent\n .command(\"balance\")\n .description(\"Show available credits, held credits, and recent transactions\")\n .option(\"-n, --limit <n>\", \"Number of transactions to show (default 10)\", \"10\")\n .action(async (options) => {\n const opts = parent.opts() as ClientOpts;\n const limit = Number(options.limit) || 10;\n\n const [{ data: balance }, { data: transactions }] = await Promise.all([\n get<BalanceResponse>(\"/billing/balance\", undefined, opts),\n get<LedgerRow[]>(\"/billing/transactions\", { per_page: limit }, opts),\n ]);\n\n if (isJsonMode()) {\n return printJson({ balance, transactions });\n }\n\n const lowBalance = balance.available_cents < 100;\n const availableLine = lowBalance\n ? chalk.red(formatCents(balance.available_cents)) + chalk.dim(\" (low)\")\n : chalk.bold.green(formatCents(balance.available_cents));\n\n printDetail([\n [\"Available\", availableLine],\n [\"Total balance\", formatCents(balance.balance_cents)],\n [\"On hold\", formatCents(balance.reserved_cents)],\n [\"Lifetime top-ups\", formatCents(balance.lifetime_topup_cents)],\n ]);\n\n if (transactions && transactions.length > 0) {\n console.log(`\\n${chalk.bold(\"Recent transactions\")}`);\n printTable(\n [\"Date\", \"Type\", \"Amount\", \"Balance\", \"Reference\"],\n transactions.map((row) => [\n formatDate(row.created_at),\n KIND_LABELS[row.kind] ?? row.kind,\n formatSigned(row.amount_cents),\n formatCents(row.balance_after_cents),\n row.reference_id ? shortId(row.reference_id) : chalk.dim(\"—\"),\n ])\n );\n } else {\n console.log(\n `\\n${chalk.dim(\"No transactions yet — run `tt topup` to add credits.\")}`\n );\n }\n\n if (lowBalance) {\n console.log(\n `\\n${formatStatus(\"preparing\")} ${chalk.yellow(\n \"Run `tt topup` to add more available credits before starting a run.\"\n )}`\n );\n }\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport open from \"open\";\nimport { post, type ClientOpts } from \"../client.js\";\nimport { printJson, isJsonMode, printSuccess } from \"../output.js\";\n\ninterface TopupResponse {\n checkout_url: string;\n session_id: string;\n}\n\nconst PRESETS_USD = [10, 25, 50, 100];\nconst MIN_USD = 5;\nconst MAX_USD = 10000;\n\nfunction parseAmount(input: string | undefined): number | null {\n if (!input) return null;\n const cleaned = input.replace(/^\\$/, \"\").trim();\n const num = Number(cleaned);\n if (!Number.isFinite(num) || num <= 0) return null;\n return num;\n}\n\nasync function readLine(prompt: string): Promise<string> {\n const readline = await import(\"node:readline/promises\");\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n try {\n return (await rl.question(prompt)).trim();\n } finally {\n rl.close();\n }\n}\n\nexport function registerTopupCommands(parent: Command) {\n parent\n .command(\"topup\")\n .description(\"Add prepaid credits via Stripe Checkout\")\n .option(\"-a, --amount <usd>\", \"Amount in USD (e.g. 25)\")\n .option(\"--no-open\", \"Print checkout URL instead of opening the browser\")\n .action(async (options) => {\n const opts = parent.opts() as ClientOpts;\n\n let amountUsd: number | null;\n\n if (options.amount !== undefined) {\n amountUsd = parseAmount(options.amount);\n if (amountUsd === null) {\n throw new Error(\"Invalid amount\");\n }\n } else {\n if (isJsonMode()) {\n throw new Error(\n \"amount is required in --json mode (use --amount <usd>)\"\n );\n }\n console.log(chalk.bold(\"Add credits via Stripe Checkout\"));\n console.log(\n chalk.dim(\n `Quick picks: ${PRESETS_USD.map((n) => `$${n}`).join(\", \")}`\n )\n );\n const input = await readLine(`Amount in USD (min $${MIN_USD}): `);\n amountUsd = parseAmount(input);\n if (amountUsd === null) {\n throw new Error(\"Invalid amount\");\n }\n }\n\n if (amountUsd < MIN_USD) {\n throw new Error(`Minimum top-up is $${MIN_USD}`);\n }\n if (amountUsd > MAX_USD) {\n throw new Error(`Maximum top-up is $${MAX_USD}`);\n }\n\n const amountCents = Math.round(amountUsd * 100);\n\n const { data } = await post<TopupResponse>(\n \"/billing/topup\",\n { amount_cents: amountCents },\n opts\n );\n\n if (isJsonMode()) {\n return printJson(data);\n }\n\n const url = data.checkout_url;\n console.log(\n `${chalk.bold(\"Checkout URL:\")} ${chalk.cyan(url)}\\n` +\n chalk.dim(\"Complete the payment to credit your account.\")\n );\n\n if (options.open !== false) {\n try {\n await open(url);\n printSuccess(\"Opened Stripe Checkout in your browser.\");\n } catch {\n console.log(\n chalk.yellow(\n \"Could not open browser automatically — copy the URL above.\"\n )\n );\n }\n }\n });\n}\n","import { Command } from \"commander\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { printSuccess, printError, printWarning } from \"../output.js\";\nimport type { LocalSpec } from \"../eval/types.js\";\nimport { canonicalizeBaseModel } from \"../base-models.js\";\n\nconst DEFAULT_SPEC_FILE = \"tunedtensor.json\";\n\nconst SCAFFOLD: LocalSpec = {\n name: \"My Agent\",\n description: \"\",\n base_model: \"Qwen/Qwen3.5-2B\",\n system_prompt: \"You are a helpful assistant.\",\n guidelines: [],\n constraints: [],\n examples: [\n { input: \"Hello\", output: \"Hi! How can I help you today?\" },\n ],\n eval_cases: [],\n};\n\nexport function registerInitCommand(parent: Command) {\n parent\n .command(\"init\")\n .description(\"Create a local behaviour spec file\")\n .option(\"-n, --name <name>\", \"Spec name\")\n .option(\"--model <model>\", \"Base model ID\")\n .option(\"-f, --file <path>\", \"Output file path\", DEFAULT_SPEC_FILE)\n .action(async (cmdOpts) => {\n const filePath = resolve(cmdOpts.file);\n\n if (existsSync(filePath)) {\n printWarning(`${cmdOpts.file} already exists. Use tt eval to validate it or edit it directly.`);\n return;\n }\n\n const spec: LocalSpec = { ...SCAFFOLD };\n if (cmdOpts.name) spec.name = cmdOpts.name;\n if (cmdOpts.model) spec.base_model = canonicalizeBaseModel(cmdOpts.model);\n\n writeFileSync(filePath, JSON.stringify(spec, null, 2) + \"\\n\");\n printSuccess(`Created ${cmdOpts.file}`);\n console.log(\"\\nNext steps:\");\n console.log(\" 1. Edit the spec: system_prompt, guidelines, examples\");\n console.log(\" 2. Validate spec: tt eval\");\n console.log(\" 3. Push to remote: tt push\");\n });\n}\n\nexport function loadSpec(filePath?: string): LocalSpec {\n const resolved = resolve(filePath || DEFAULT_SPEC_FILE);\n if (!existsSync(resolved)) {\n printError(\n `Spec file not found: ${filePath || DEFAULT_SPEC_FILE}\\nRun \\`tt init\\` to create one.`,\n );\n process.exit(1);\n }\n\n const raw = JSON.parse(readFileSync(resolved, \"utf-8\"));\n return raw as LocalSpec;\n}\n\nexport { DEFAULT_SPEC_FILE };\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport {\n printJson,\n isJsonMode,\n} from \"../output.js\";\nimport { loadSpec, DEFAULT_SPEC_FILE } from \"./init.js\";\nimport { validateSpec } from \"../eval/rules.js\";\nimport type { ValidationCheck } from \"../eval/types.js\";\n\nexport function registerEvalCommand(parent: Command) {\n parent\n .command(\"eval\")\n .description(\"Validate a local behaviour spec\")\n .option(\"-m, --model <model>\", \"Deprecated; ignored because tt eval only validates the local spec\")\n .option(\"-f, --file <path>\", \"Spec file path\", DEFAULT_SPEC_FILE)\n .action(async (cmdOpts) => {\n const spec = loadSpec(cmdOpts.file);\n const validation = validateSpec(spec);\n\n if (!isJsonMode()) {\n console.log(chalk.dim(`\\nSpec: ${cmdOpts.file}\\n`));\n }\n\n if (isJsonMode()) {\n printJson(validation);\n } else {\n printValidation(validation.checks);\n }\n\n if (!validation.valid) {\n process.exitCode = 1;\n }\n });\n}\n\nfunction printValidation(checks: ValidationCheck[]) {\n console.log(chalk.bold(\"Spec Validation\"));\n for (const check of checks) {\n const icon = check.passed ? chalk.green(\"✓\") : chalk.red(\"✗\");\n const msg = check.message\n ? chalk.dim(` — ${check.message}`)\n : \"\";\n console.log(` ${icon} ${check.name}${msg}`);\n }\n}\n","import type {\n AssertionResult,\n LocalSpec,\n ValidationCheck,\n ValidationResult,\n} from \"./types.js\";\n\nexport function validateSpec(spec: LocalSpec): ValidationResult {\n const checks: ValidationCheck[] = [];\n\n checks.push({\n name: \"Has name\",\n passed: Boolean(spec.name?.trim()),\n message: spec.name?.trim() ? undefined : \"Spec is missing a name\",\n });\n\n checks.push({\n name: \"Has system prompt\",\n passed: Boolean(spec.system_prompt?.trim()),\n message: spec.system_prompt?.trim()\n ? undefined\n : \"Spec is missing a system_prompt\",\n });\n\n checks.push({\n name: \"Has base model\",\n passed: Boolean(spec.base_model?.trim()),\n message: spec.base_model?.trim()\n ? undefined\n : \"Spec is missing a base_model\",\n });\n\n const exCount = spec.examples?.length ?? 0;\n checks.push({\n name: \"Has examples\",\n passed: exCount > 0,\n message: exCount > 0 ? `${exCount} example(s)` : \"Add at least one example\",\n });\n\n checks.push({\n name: \"Has guidelines\",\n passed: (spec.guidelines?.length ?? 0) > 0,\n message:\n (spec.guidelines?.length ?? 0) > 0\n ? undefined\n : \"Consider adding guidelines for better eval coverage\",\n });\n\n if (spec.constraints?.length && spec.examples?.length) {\n const violations = checkExamplesAgainstConstraints(spec);\n checks.push({\n name: \"Examples satisfy constraints\",\n passed: violations.length === 0,\n message:\n violations.length === 0\n ? undefined\n : violations.join(\"; \"),\n });\n }\n\n return {\n valid: checks.every((c) => c.passed),\n checks,\n };\n}\n\nfunction checkExamplesAgainstConstraints(spec: LocalSpec): string[] {\n const violations: string[] = [];\n for (const [i, ex] of spec.examples.entries()) {\n for (const constraint of spec.constraints) {\n const result = evaluateConstraint(ex.output, constraint);\n if (!result.passed) {\n violations.push(`Example ${i + 1} violates \"${constraint}\": ${result.message}`);\n }\n }\n }\n return violations;\n}\n\nfunction evaluateConstraint(\n text: string,\n constraint: string,\n): { passed: boolean; message?: string } {\n const lower = constraint.toLowerCase();\n\n const neverMatch = lower.match(/^never (?:share|mention|include|reveal|use|say|output|return|give|provide|show|disclose|expose)\\s+(.+)/);\n if (neverMatch) {\n const forbidden = neverMatch[1].replace(/['\"]/g, \"\").trim();\n if (text.toLowerCase().includes(forbidden.toLowerCase())) {\n return { passed: false, message: `Output contains \"${forbidden}\"` };\n }\n return { passed: true };\n }\n\n const alwaysMatch = lower.match(/^always (?:include|use|start with|end with|contain|respond in|reply in)\\s+(.+)/);\n if (alwaysMatch) {\n const required = alwaysMatch[1].replace(/['\"]/g, \"\").trim();\n if (!text.toLowerCase().includes(required.toLowerCase())) {\n return { passed: false, message: `Output missing \"${required}\"` };\n }\n return { passed: true };\n }\n\n return {\n passed: true,\n message: `Constraint not enforceable by rules: \"${constraint}\" (will be checked by LLM judge if a provider is configured)`,\n };\n}\n\nexport function runAssertions(\n text: string,\n assertions: string[],\n): AssertionResult[] {\n return assertions.map((assertion) => runSingleAssertion(text, assertion));\n}\n\nfunction runSingleAssertion(text: string, assertion: string): AssertionResult {\n const [type, ...rest] = assertion.split(\":\");\n const value = rest.join(\":\");\n\n switch (type) {\n case \"contains\":\n return {\n assertion,\n passed: text.includes(value),\n message: text.includes(value)\n ? undefined\n : `Expected output to contain \"${value}\"`,\n };\n\n case \"not-contains\":\n return {\n assertion,\n passed: !text.includes(value),\n message: !text.includes(value)\n ? undefined\n : `Expected output to not contain \"${value}\"`,\n };\n\n case \"matches\": {\n const re = new RegExp(value);\n const match = re.test(text);\n return {\n assertion,\n passed: match,\n message: match ? undefined : `Output did not match pattern /${value}/`,\n };\n }\n\n case \"max-length\": {\n const max = Number(value);\n return {\n assertion,\n passed: text.length <= max,\n message:\n text.length <= max\n ? undefined\n : `Output length ${text.length} exceeds max ${max}`,\n };\n }\n\n case \"min-length\": {\n const min = Number(value);\n return {\n assertion,\n passed: text.length >= min,\n message:\n text.length >= min\n ? undefined\n : `Output length ${text.length} below min ${min}`,\n };\n }\n\n case \"is-json\": {\n let valid = false;\n try {\n JSON.parse(text);\n valid = true;\n } catch {}\n return {\n assertion,\n passed: valid,\n message: valid ? undefined : \"Output is not valid JSON\",\n };\n }\n\n default:\n return {\n assertion,\n passed: true,\n message: `Unknown assertion type: ${type} (skipped)`,\n };\n }\n}\n\nexport function checkConstraints(\n text: string,\n constraints: string[],\n): AssertionResult[] {\n return constraints.map((constraint) => {\n const result = evaluateConstraint(text, constraint);\n return {\n assertion: `constraint: ${constraint}`,\n passed: result.passed,\n message: result.message,\n };\n });\n}\n","import { Command } from \"commander\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { post, put, type ClientOpts } from \"../client.js\";\nimport { printSuccess, printJson, isJsonMode, shortId } from \"../output.js\";\nimport { loadSpec, DEFAULT_SPEC_FILE } from \"./init.js\";\nimport { canonicalizeSpecBaseModel } from \"../base-models.js\";\n\ninterface RemoteSpec {\n id: string;\n name: string;\n [key: string]: unknown;\n}\n\nexport function registerPushCommand(parent: Command) {\n parent\n .command(\"push\")\n .description(\"Push local spec to the Tuned Tensor API\")\n .option(\"-f, --file <path>\", \"Spec file path\", DEFAULT_SPEC_FILE)\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const filePath = resolve(cmdOpts.file);\n const spec = loadSpec(cmdOpts.file);\n\n const { id, eval_cases, ...rawBody } = spec as unknown as Record<string, unknown>;\n const body = canonicalizeSpecBaseModel(rawBody);\n\n let data: RemoteSpec;\n\n if (id) {\n const res = await put<RemoteSpec>(`/behavior-specs/${id}`, body, opts);\n data = res.data;\n } else {\n const res = await post<RemoteSpec>(\"/behavior-specs\", body, opts);\n data = res.data;\n\n const raw = JSON.parse(readFileSync(filePath, \"utf-8\"));\n raw.id = data.id;\n writeFileSync(filePath, JSON.stringify(raw, null, 2) + \"\\n\");\n }\n\n if (isJsonMode()) return printJson(data);\n printSuccess(\n `Spec ${id ? \"updated\" : \"created\"}: ${data.name} (${shortId(data.id)})`,\n );\n });\n}\n"],"mappings":"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","names":["readFileSync","chalk","readFileSync","readFileSync","existsSync","readFileSync","statSync","readFileSync","existsSync","statSync","existsSync","mkdirSync","statSync","join","existsSync","statSync","join","mkdirSync","chalk","chalk","chalk","chalk","existsSync","readFileSync","writeFileSync","existsSync","writeFileSync","readFileSync","chalk","chalk","readFileSync","writeFileSync","resolve","resolve","readFileSync","writeFileSync"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/output.ts","../src/client.ts","../src/config.ts","../src/commands/auth.ts","../src/commands/specs.ts","../src/resolve.ts","../src/base-models.ts","../src/commands/runs.ts","../src/commands/datasets.ts","../src/commands/models.ts","../src/commands/balance.ts","../src/commands/topup.ts","../src/commands/init.ts","../src/commands/eval.ts","../src/eval/rules.ts","../src/commands/push.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { setJsonMode, reportError } from \"./output.js\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerSpecsCommands } from \"./commands/specs.js\";\nimport { registerRunsCommands } from \"./commands/runs.js\";\nimport { registerDatasetsCommands } from \"./commands/datasets.js\";\nimport { registerModelsCommands } from \"./commands/models.js\";\n\nimport { registerBalanceCommands } from \"./commands/balance.js\";\nimport { registerTopupCommands } from \"./commands/topup.js\";\nimport { registerInitCommand } from \"./commands/init.js\";\nimport { registerEvalCommand } from \"./commands/eval.js\";\nimport { registerPushCommand } from \"./commands/push.js\";\n\ndeclare const __TT_VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name(\"tt\")\n .description(\"Tuned Tensor CLI — fine-tune and evaluate LLMs\")\n .version(__TT_VERSION__)\n .option(\"-k, --api-key <key>\", \"API key (overrides stored key)\")\n .option(\n \"-u, --base-url <url>\",\n \"API base URL (default: https://tunedtensor.com)\",\n )\n .option(\"--json\", \"Output raw JSON\")\n .option(\"--no-color\", \"Disable colors\")\n .hook(\"preAction\", (_thisCommand, actionCommand) => {\n const rootOpts = program.opts();\n if (rootOpts.json) setJsonMode(true);\n if (rootOpts.color === false) {\n process.env.FORCE_COLOR = \"0\";\n }\n });\n\nregisterAuthCommands(program);\nregisterSpecsCommands(program);\nregisterRunsCommands(program);\nregisterDatasetsCommands(program);\nregisterModelsCommands(program);\n\nregisterBalanceCommands(program);\nregisterTopupCommands(program);\nregisterInitCommand(program);\nregisterEvalCommand(program);\nregisterPushCommand(program);\n\n// Honor --json even when parsing fails before the preAction hook runs\n// (e.g. on unknown commands). Cheap argv sniff is fine here.\nif (process.argv.includes(\"--json\")) setJsonMode(true);\n\nprogram.parseAsync().catch((err) => {\n reportError(err);\n process.exit(1);\n});\n","import chalk from \"chalk\";\nimport Table from \"cli-table3\";\nimport { ApiError } from \"./client.js\";\n\nlet jsonMode = false;\n\nexport function setJsonMode(enabled: boolean) {\n jsonMode = enabled;\n}\n\nexport function isJsonMode(): boolean {\n return jsonMode;\n}\n\nexport function printJson(data: unknown) {\n console.log(JSON.stringify(data, null, 2));\n}\n\nexport function printTable(\n headers: string[],\n rows: string[][],\n meta?: { page: number; per_page: number; total: number },\n) {\n const table = new Table({\n head: headers.map((h) => chalk.bold.cyan(h)),\n style: { head: [], border: [] },\n });\n for (const row of rows) {\n table.push(row);\n }\n console.log(table.toString());\n\n if (meta) {\n const totalPages = Math.ceil(meta.total / meta.per_page);\n console.log(\n chalk.dim(\n `\\nPage ${meta.page}/${totalPages} (${meta.total} total)`,\n ),\n );\n }\n}\n\nexport function printDetail(fields: [string, string | undefined][]) {\n const maxLabel = Math.max(...fields.map(([l]) => l.length));\n for (const [label, value] of fields) {\n const paddedLabel = label.padEnd(maxLabel);\n console.log(`${chalk.bold.cyan(paddedLabel)} ${value ?? chalk.dim(\"—\")}`);\n }\n}\n\nexport function printSuccess(message: string) {\n console.log(chalk.green(\"✓\") + \" \" + message);\n}\n\nexport function printWarning(message: string) {\n console.log(chalk.yellow(\"!\") + \" \" + message);\n}\n\nexport function printError(message: string) {\n console.error(chalk.red(\"✗\") + \" \" + message);\n}\n\nexport function reportError(err: unknown): void {\n const isApi = err instanceof ApiError;\n const message = (err as Error)?.message || String(err);\n\n if (jsonMode) {\n printJson({\n error: {\n status: isApi ? err.status : null,\n code: isApi ? err.code : \"CLI_ERROR\",\n message,\n },\n });\n } else if (isApi) {\n printError(`[${err.status}] ${message}`);\n } else {\n printError(message);\n }\n}\n\nexport function formatDate(iso?: string | null): string {\n if (!iso) return \"—\";\n return new Date(iso).toLocaleString();\n}\n\nexport function formatStatus(status: string): string {\n const map: Record<string, (s: string) => string> = {\n completed: chalk.green,\n running: chalk.blue,\n training: chalk.blue,\n evaluating: chalk.blue,\n preparing: chalk.yellow,\n pending: chalk.yellow,\n uploading: chalk.yellow,\n failed: chalk.red,\n cancelled: chalk.dim,\n validated: chalk.green,\n invalid: chalk.red,\n };\n const colorFn = map[status] || chalk.white;\n return colorFn(status);\n}\n\nexport function truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 1) + \"…\";\n}\n\nexport function shortId(id: string): string {\n return id.slice(0, 8);\n}\n","import { readFileSync, statSync } from \"node:fs\";\nimport { basename } from \"node:path\";\nimport { getApiKey, getBaseUrl } from \"./config.js\";\n\nexport interface ApiResponse<T> {\n data: T;\n meta?: { page: number; per_page: number; total: number };\n}\n\nexport interface ApiErrorBody {\n error: { code: string; message: string };\n}\n\nexport class ApiError extends Error {\n constructor(\n public status: number,\n public code: string,\n message: string,\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n\nexport interface ClientOpts {\n apiKey?: string;\n baseUrl?: string;\n}\n\nfunction resolveKey(opts?: ClientOpts): string {\n const key = getApiKey(opts);\n if (!key) {\n throw new ApiError(\n 401,\n \"NO_API_KEY\",\n \"No API key found. Run `tt auth login` or set TUNED_TENSOR_API_KEY.\",\n );\n }\n return key;\n}\n\nfunction buildUrl(\n path: string,\n query?: Record<string, string | number | undefined>,\n opts?: ClientOpts,\n): string {\n const base = getBaseUrl(opts);\n const url = new URL(`/api/v1${path}`, base);\n if (query) {\n for (const [k, v] of Object.entries(query)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n return url.toString();\n}\n\nasync function request<T>(\n method: string,\n path: string,\n options: {\n query?: Record<string, string | number | undefined>;\n body?: unknown;\n opts?: ClientOpts;\n } = {},\n): Promise<ApiResponse<T>> {\n const key = resolveKey(options.opts);\n const url = buildUrl(path, options.query, options.opts);\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${key}`,\n };\n\n let bodyPayload: string | undefined;\n if (options.body) {\n headers[\"Content-Type\"] = \"application/json\";\n bodyPayload = JSON.stringify(options.body);\n }\n\n const res = await fetch(url, { method, headers, body: bodyPayload });\n\n if (!res.ok) {\n let errBody: ApiErrorBody;\n try {\n errBody = (await res.json()) as ApiErrorBody;\n } catch {\n throw new ApiError(res.status, \"UNKNOWN\", res.statusText);\n }\n throw new ApiError(\n res.status,\n errBody.error?.code || \"UNKNOWN\",\n errBody.error?.message || res.statusText,\n );\n }\n\n if (res.status === 204) return { data: null as T };\n return (await res.json()) as ApiResponse<T>;\n}\n\nexport function get<T>(\n path: string,\n query?: Record<string, string | number | undefined>,\n opts?: ClientOpts,\n) {\n return request<T>(\"GET\", path, { query, opts });\n}\n\nexport function post<T>(\n path: string,\n body?: unknown,\n opts?: ClientOpts,\n) {\n return request<T>(\"POST\", path, { body, opts });\n}\n\nexport function put<T>(\n path: string,\n body?: unknown,\n opts?: ClientOpts,\n) {\n return request<T>(\"PUT\", path, { body, opts });\n}\n\nexport function patch<T>(\n path: string,\n body?: unknown,\n opts?: ClientOpts,\n) {\n return request<T>(\"PATCH\", path, { body, opts });\n}\n\nexport function del<T>(path: string, opts?: ClientOpts) {\n return request<T>(\"DELETE\", path, { opts });\n}\n\nexport async function upload<T>(\n path: string,\n filePath: string,\n fields: Record<string, string>,\n opts?: ClientOpts,\n): Promise<ApiResponse<T>> {\n const key = resolveKey(opts);\n const url = buildUrl(path, undefined, opts);\n\n const form = new FormData();\n for (const [k, v] of Object.entries(fields)) {\n form.append(k, v);\n }\n\n const fileBytes = readFileSync(filePath);\n const fileSize = statSync(filePath).size;\n const blob = new Blob([fileBytes], { type: \"application/jsonl\" });\n form.append(\"file\", blob, basename(filePath));\n\n const res = await fetch(url, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${key}` },\n body: form,\n });\n\n if (!res.ok) {\n let errBody: ApiErrorBody;\n try {\n errBody = (await res.json()) as ApiErrorBody;\n } catch {\n throw new ApiError(res.status, \"UNKNOWN\", res.statusText);\n }\n throw new ApiError(\n res.status,\n errBody.error?.code || \"UNKNOWN\",\n errBody.error?.message || res.statusText,\n );\n }\n\n return (await res.json()) as ApiResponse<T>;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface Config {\n api_key?: string;\n base_url?: string;\n}\n\nconst CONFIG_DIR_NAME = \"tuned-tensor\";\nconst CONFIG_FILE_NAME = \"config.json\";\n\nfunction getConfigDir(): string {\n const xdg = process.env.XDG_CONFIG_HOME;\n const base = xdg || join(homedir(), \".config\");\n return join(base, CONFIG_DIR_NAME);\n}\n\nfunction getConfigPath(): string {\n return join(getConfigDir(), CONFIG_FILE_NAME);\n}\n\nexport function readConfig(): Config {\n const path = getConfigPath();\n if (!existsSync(path)) return {};\n try {\n return JSON.parse(readFileSync(path, \"utf-8\"));\n } catch {\n return {};\n }\n}\n\nexport function writeConfig(config: Config): void {\n const dir = getConfigDir();\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n writeFileSync(getConfigPath(), JSON.stringify(config, null, 2) + \"\\n\");\n}\n\nexport function updateConfig(partial: Partial<Config>): void {\n const current = readConfig();\n writeConfig({ ...current, ...partial });\n}\n\nexport function clearConfig(): void {\n const path = getConfigPath();\n if (existsSync(path)) writeFileSync(path, \"{}\\n\");\n}\n\nexport const DEFAULT_BASE_URL = \"https://tunedtensor.com\";\n\nexport function getBaseUrl(opts?: { baseUrl?: string }): string {\n return opts?.baseUrl || process.env.TUNED_TENSOR_URL || readConfig().base_url || DEFAULT_BASE_URL;\n}\n\nexport function getApiKey(opts?: { apiKey?: string }): string | undefined {\n return opts?.apiKey || process.env.TUNED_TENSOR_API_KEY || readConfig().api_key;\n}\n","import { Command } from \"commander\";\nimport { createInterface } from \"node:readline/promises\";\nimport { stdin, stdout } from \"node:process\";\nimport {\n readConfig,\n updateConfig,\n clearConfig,\n getApiKey,\n getBaseUrl,\n DEFAULT_BASE_URL,\n} from \"../config.js\";\nimport {\n printSuccess,\n printDetail,\n printError,\n printWarning,\n isJsonMode,\n printJson,\n} from \"../output.js\";\nimport chalk from \"chalk\";\n\nexport function registerAuthCommands(parent: Command) {\n const auth = parent.command(\"auth\").description(\"Manage authentication\");\n\n auth\n .command(\"login\")\n .description(\"Store an API key for authentication\")\n .argument(\"[key]\", \"API key (tt_...). If omitted, you will be prompted.\")\n .action(async (key?: string) => {\n let apiKey = key;\n\n if (!apiKey) {\n const settingsUrl = `${DEFAULT_BASE_URL}/dashboard/settings`;\n console.log();\n console.log(\n ` To get your API key, go to ${chalk.bold(\"Settings → API Keys\")} in the Tuned Tensor dashboard:`,\n );\n console.log(` ${chalk.cyan.underline(settingsUrl)}`);\n console.log();\n\n const rl = createInterface({ input: stdin, output: stdout });\n apiKey = await rl.question(\"Enter your API key (tt_...): \");\n rl.close();\n }\n\n apiKey = apiKey.trim();\n\n if (!apiKey.startsWith(\"tt_\") || apiKey.length !== 51) {\n printError(\n \"Invalid API key format. Keys start with tt_ and are 51 characters long.\",\n );\n process.exit(1);\n }\n\n updateConfig({ api_key: apiKey });\n printSuccess(\n `API key stored (${apiKey.slice(0, 8)}...). You're ready to go.`,\n );\n });\n\n auth\n .command(\"logout\")\n .description(\"Remove stored credentials\")\n .action(() => {\n clearConfig();\n printSuccess(\"Credentials removed.\");\n });\n\n auth\n .command(\"status\")\n .description(\"Show current authentication status\")\n .action(() => {\n const opts = parent.opts();\n const apiKey = getApiKey(opts);\n const baseUrl = getBaseUrl(opts);\n\n if (isJsonMode()) {\n printJson({\n authenticated: !!apiKey,\n key_prefix: apiKey ? apiKey.slice(0, 8) + \"...\" : null,\n base_url: baseUrl,\n });\n return;\n }\n\n if (apiKey) {\n printDetail([\n [\"Authenticated\", \"Yes\"],\n [\"API Key\", apiKey.slice(0, 8) + \"...\"],\n [\"Base URL\", baseUrl],\n ]);\n } else {\n printWarning(\n \"Not authenticated. Run `tt auth login` to store an API key.\",\n );\n printDetail([[\"Base URL\", baseUrl]]);\n }\n });\n}\n","import { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport { get, post, put, del, type ClientOpts } from \"../client.js\";\nimport { resolveSpecId } from \"../resolve.js\";\nimport { canonicalizeBaseModel, canonicalizeSpecBaseModel } from \"../base-models.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printWarning,\n printJson,\n isJsonMode,\n formatDate,\n formatStatus,\n truncate,\n shortId,\n} from \"../output.js\";\n\nconst SPEC_BODY_KEYS = new Set([\n \"name\",\n \"description\",\n \"base_model\",\n \"system_prompt\",\n \"guidelines\",\n \"constraints\",\n \"examples\",\n]);\n\nconst RUN_INPUT_KEYS = [\"run_id\", \"behavior_spec_id\", \"spec_snapshot\", \"run_number\"];\n\nclass SpecBodyError extends Error {}\n\nfunction loadSpecBody(filePath: string, mode: \"create\" | \"update\"): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(readFileSync(filePath, \"utf-8\"));\n } catch (e) {\n throw new SpecBodyError(\n `Could not parse ${filePath}: ${(e as Error).message}`,\n );\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new SpecBodyError(\n `${filePath} must contain a JSON object at the top level.`,\n );\n }\n\n const body = parsed as Record<string, unknown>;\n\n const runInputHits = RUN_INPUT_KEYS.filter((k) => k in body);\n if (runInputHits.length >= 2 || \"spec_snapshot\" in body) {\n const hint = \"spec_snapshot\" in body\n ? `This file looks like a run-input payload (top-level keys: ${runInputHits.join(\", \")}). The actual spec is nested under \"spec_snapshot\". Try:\\n jq '.spec_snapshot' ${filePath} > spec.json\\n tt specs ${mode === \"create\" ? \"create\" : \"update <id>\"} --file spec.json`\n : `This file looks like a run-input payload (top-level keys: ${runInputHits.join(\", \")}), not a behaviour spec. To start a run on an existing spec, use: tt runs start <spec-id>`;\n throw new SpecBodyError(hint);\n }\n\n if (mode === \"create\" && typeof body.name !== \"string\") {\n throw new SpecBodyError(\n `${filePath} is missing required field \"name\" (string).`,\n );\n }\n\n const unknown = Object.keys(body).filter(\n (k) => !SPEC_BODY_KEYS.has(k) && k !== \"id\" && k !== \"eval_cases\",\n );\n if (unknown.length && !isJsonMode()) {\n printWarning(\n `Unknown spec field(s) in ${filePath}: ${unknown.join(\", \")}. They will be sent but may be rejected by the API.`,\n );\n }\n\n return canonicalizeSpecBaseModel(body);\n}\n\ninterface BehaviorSpec {\n id: string;\n name: string;\n description: string;\n system_prompt: string;\n guidelines: string[];\n examples: { input: string; output: string }[];\n constraints: string[];\n base_model: string;\n created_at: string;\n updated_at: string;\n _run_count?: number;\n _latest_run_status?: string;\n _latest_run_score?: number;\n _runs?: unknown[];\n}\n\nexport function registerSpecsCommands(parent: Command) {\n const specs = parent\n .command(\"specs\")\n .description(\"Manage behaviour specs\");\n\n specs\n .command(\"list\")\n .description(\"List behaviour specs\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const { data, meta } = await get<BehaviorSpec[]>(\n \"/behavior-specs\",\n { page: cmdOpts.page, per_page: cmdOpts.perPage },\n opts,\n );\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Name\", \"Model\", \"Examples\", \"Runs\", \"Status\", \"Updated\"],\n data.map((s) => [\n shortId(s.id),\n truncate(s.name, 30),\n s.base_model.split(\"/\").pop() || s.base_model,\n String(s.examples?.length ?? 0),\n String(s._run_count ?? 0),\n s._latest_run_status ? formatStatus(s._latest_run_status) : \"—\",\n formatDate(s.updated_at),\n ]),\n meta,\n );\n });\n\n specs\n .command(\"get\")\n .description(\"Show spec details\")\n .argument(\"<id>\", \"Spec ID (full UUID or 8+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveSpecId(id, opts);\n const { data } = await get<BehaviorSpec>(`/behavior-specs/${fullId}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Name\", data.name],\n [\"Description\", data.description || undefined],\n [\"Base Model\", data.base_model],\n [\"System Prompt\", data.system_prompt ? truncate(data.system_prompt, 80) : undefined],\n [\"Guidelines\", data.guidelines?.length ? data.guidelines.join(\", \") : undefined],\n [\"Constraints\", data.constraints?.length ? data.constraints.join(\", \") : undefined],\n [\"Examples\", String(data.examples?.length ?? 0)],\n [\"Runs\", String(data._run_count ?? data._runs?.length ?? 0)],\n [\"Created\", formatDate(data.created_at)],\n [\"Updated\", formatDate(data.updated_at)],\n ]);\n\n if (data.examples?.length) {\n console.log(\"\\nExamples:\");\n for (const [i, ex] of data.examples.slice(0, 5).entries()) {\n console.log(` ${i + 1}. Input: ${truncate(ex.input, 60)}`);\n console.log(` Output: ${truncate(ex.output, 60)}`);\n }\n if (data.examples.length > 5) {\n console.log(` ... and ${data.examples.length - 5} more`);\n }\n }\n });\n\n specs\n .command(\"create\")\n .description(\"Create a behaviour spec\")\n .option(\"-f, --file <path>\", \"JSON file with spec definition\")\n .option(\"-n, --name <name>\", \"Spec name\")\n .option(\"--model <model>\", \"Base model ID\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n let body: Record<string, unknown>;\n\n if (cmdOpts.file) {\n body = loadSpecBody(cmdOpts.file, \"create\");\n } else if (cmdOpts.name) {\n body = { name: cmdOpts.name };\n if (cmdOpts.model) body.base_model = canonicalizeBaseModel(cmdOpts.model);\n } else {\n throw new SpecBodyError(\"Provide --file or --name\");\n }\n\n const { data } = await post<BehaviorSpec>(\"/behavior-specs\", body, opts);\n\n if (isJsonMode()) return printJson(data);\n printSuccess(`Spec created: ${data.name} (${shortId(data.id)})`);\n });\n\n specs\n .command(\"update\")\n .description(\"Update a behaviour spec\")\n .argument(\"<id>\", \"Spec ID (full UUID or 8+ char prefix)\")\n .option(\"-f, --file <path>\", \"JSON file with fields to update\")\n .option(\"-n, --name <name>\", \"New name\")\n .option(\"--model <model>\", \"New base model ID\")\n .action(async (id: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n let body: Record<string, unknown>;\n\n if (cmdOpts.file) {\n body = loadSpecBody(cmdOpts.file, \"update\");\n } else {\n body = {};\n if (cmdOpts.name) body.name = cmdOpts.name;\n if (cmdOpts.model) body.base_model = canonicalizeBaseModel(cmdOpts.model);\n }\n\n const fullId = await resolveSpecId(id, opts);\n const { data } = await put<BehaviorSpec>(\n `/behavior-specs/${fullId}`,\n body,\n opts,\n );\n\n if (isJsonMode()) return printJson(data);\n printSuccess(`Spec updated: ${data.name} (${shortId(data.id)})`);\n });\n\n specs\n .command(\"delete\")\n .description(\"Delete a behaviour spec\")\n .argument(\"<id>\", \"Spec ID (full UUID or 8+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveSpecId(id, opts);\n await del(`/behavior-specs/${fullId}`, opts);\n\n if (isJsonMode()) return printJson({ id: fullId, deleted: true });\n printSuccess(`Spec deleted: ${shortId(fullId)}`);\n });\n}\n","import { get, type ClientOpts } from \"./client.js\";\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nconst RESOLVE_PAGE_SIZE = 100;\nconst MIN_PREFIX_LEN = 4;\n\ninterface Identifiable {\n id: string;\n name?: string;\n run_number?: number;\n}\n\ninterface Listed<T> {\n data: T[];\n meta?: { page: number; per_page: number; total: number };\n}\n\nexport class ResolveError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ResolveError\";\n }\n}\n\nexport function isFullUuid(value: string): boolean {\n return UUID_RE.test(value);\n}\n\nasync function resolvePrefix<T extends Identifiable>(\n prefix: string,\n kind: \"spec\" | \"run\" | \"dataset\" | \"model\",\n listPath: string,\n describe: (item: T) => string,\n opts?: ClientOpts,\n): Promise<string> {\n if (isFullUuid(prefix)) return prefix;\n\n const noun = kind;\n const listCmd = `tt ${kind}s list --json`;\n\n if (prefix.length < MIN_PREFIX_LEN) {\n throw new ResolveError(\n `${capitalize(noun)} ID prefix \"${prefix}\" is too short — provide at least ${MIN_PREFIX_LEN} characters or the full UUID.`,\n );\n }\n\n const lower = prefix.toLowerCase();\n const { data, meta } = (await get<T[]>(\n listPath,\n { page: 1, per_page: RESOLVE_PAGE_SIZE },\n opts,\n )) as Listed<T>;\n\n const matches = data.filter((item) => item.id.toLowerCase().startsWith(lower));\n\n if (matches.length === 1) return matches[0].id;\n\n if (matches.length === 0) {\n if (meta && meta.total > data.length) {\n throw new ResolveError(\n `No ${noun} found with ID prefix \"${prefix}\" in the first ${data.length} ${noun}s (you have ${meta.total} total). Use the full UUID — see \\`${listCmd}\\`.`,\n );\n }\n throw new ResolveError(`No ${noun} found with ID prefix \"${prefix}\".`);\n }\n\n const list = matches.map((m) => ` ${describe(m)}`).join(\"\\n\");\n throw new ResolveError(\n `${capitalize(noun)} ID prefix \"${prefix}\" is ambiguous (${matches.length} matches):\\n${list}\\nProvide more characters or the full UUID.`,\n );\n}\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nexport function resolveSpecId(prefix: string, opts?: ClientOpts): Promise<string> {\n return resolvePrefix<Identifiable>(\n prefix,\n \"spec\",\n \"/behavior-specs\",\n (s) => `${s.id}${s.name ? ` (${s.name})` : \"\"}`,\n opts,\n );\n}\n\nexport function resolveRunId(prefix: string, opts?: ClientOpts): Promise<string> {\n return resolvePrefix<Identifiable>(\n prefix,\n \"run\",\n \"/runs\",\n (r) => `${r.id}${r.run_number != null ? ` (run #${r.run_number})` : \"\"}`,\n opts,\n );\n}\n\nexport function resolveDatasetId(prefix: string, opts?: ClientOpts): Promise<string> {\n return resolvePrefix<Identifiable>(\n prefix,\n \"dataset\",\n \"/datasets\",\n (d) => `${d.id}${d.name ? ` (${d.name})` : \"\"}`,\n opts,\n );\n}\n\nexport function resolveModelId(prefix: string, opts?: ClientOpts): Promise<string> {\n return resolvePrefix<Identifiable>(\n prefix,\n \"model\",\n \"/models\",\n (m) => `${m.id}${m.name ? ` (${m.name})` : \"\"}`,\n opts,\n );\n}\n","export const SUPPORTED_BASE_MODELS = [\n \"google/gemma-4-E2B-it\",\n \"google/gemma-4-E4B-it\",\n \"Qwen/Qwen3.5-2B\",\n \"Qwen/Qwen3.5-4B\",\n \"meta-llama/Llama-3.2-3B-Instruct\",\n \"microsoft/Phi-4-mini-instruct\",\n \"ibm-granite/granite-3.3-2b-instruct\",\n \"bigcode/starcoder2-3b\",\n] as const;\n\nexport type SupportedBaseModel = (typeof SUPPORTED_BASE_MODELS)[number];\n\nconst BASE_MODEL_ALIASES = new Map<string, SupportedBaseModel>();\n\nfor (const model of SUPPORTED_BASE_MODELS) {\n BASE_MODEL_ALIASES.set(model.toLowerCase(), model);\n}\n\nfor (const [alias, model] of [\n [\"google/gemma-4-E2B\", \"google/gemma-4-E2B-it\"],\n [\"google/gemma-4-e2b\", \"google/gemma-4-E2B-it\"],\n [\"google/gemma-4-e2b-it\", \"google/gemma-4-E2B-it\"],\n [\"google/gemma-4-E4B\", \"google/gemma-4-E4B-it\"],\n [\"google/gemma-4-e4b\", \"google/gemma-4-E4B-it\"],\n [\"google/gemma-4-e4b-it\", \"google/gemma-4-E4B-it\"],\n [\"qwen/qwen3.5-2b\", \"Qwen/Qwen3.5-2B\"],\n [\"Qwen/Qwen3.5-2B-Base\", \"Qwen/Qwen3.5-2B\"],\n [\"qwen/qwen3.5-2b-base\", \"Qwen/Qwen3.5-2B\"],\n [\"qwen/qwen3.5-4b\", \"Qwen/Qwen3.5-4B\"],\n [\"Qwen/Qwen3.5-4B-Base\", \"Qwen/Qwen3.5-4B\"],\n [\"qwen/qwen3.5-4b-base\", \"Qwen/Qwen3.5-4B\"],\n [\"meta-llama/llama-3.2-3b-instruct\", \"meta-llama/Llama-3.2-3B-Instruct\"],\n [\"meta-llama/Llama-3.2-3B\", \"meta-llama/Llama-3.2-3B-Instruct\"],\n [\"meta-llama/llama-3.2-3b\", \"meta-llama/Llama-3.2-3B-Instruct\"],\n [\"microsoft/phi-4-mini-instruct\", \"microsoft/Phi-4-mini-instruct\"],\n [\"phi-4-mini-instruct\", \"microsoft/Phi-4-mini-instruct\"],\n [\"ibm-granite/granite-3.3-2b-instruct\", \"ibm-granite/granite-3.3-2b-instruct\"],\n [\"granite-3.3-2b-instruct\", \"ibm-granite/granite-3.3-2b-instruct\"],\n [\"bigcode/starcoder2-3b\", \"bigcode/starcoder2-3b\"],\n [\"starcoder2-3b\", \"bigcode/starcoder2-3b\"],\n] as const) {\n BASE_MODEL_ALIASES.set(alias.toLowerCase(), model);\n}\n\nexport class UnsupportedBaseModelError extends Error {\n constructor(model: unknown) {\n const supported = SUPPORTED_BASE_MODELS.join(\", \");\n super(\n `Unsupported base_model \"${String(model)}\". Supported base models: ${supported}`,\n );\n this.name = \"UnsupportedBaseModelError\";\n }\n}\n\nexport function canonicalizeBaseModel(model: unknown): SupportedBaseModel {\n if (typeof model !== \"string\" || !model.trim()) {\n throw new UnsupportedBaseModelError(model);\n }\n\n const canonical = BASE_MODEL_ALIASES.get(model.trim().toLowerCase());\n if (!canonical) {\n throw new UnsupportedBaseModelError(model);\n }\n\n return canonical;\n}\n\nexport function canonicalizeSpecBaseModel<T extends Record<string, unknown>>(body: T): T {\n if (\"base_model\" in body && body.base_model !== undefined) {\n return { ...body, base_model: canonicalizeBaseModel(body.base_model) };\n }\n\n return body;\n}\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { get, post, type ClientOpts } from \"../client.js\";\nimport { resolveSpecId, resolveRunId, resolveDatasetId } from \"../resolve.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printJson,\n isJsonMode,\n formatDate,\n formatStatus,\n shortId,\n truncate,\n} from \"../output.js\";\n\ninterface Run {\n id: string;\n behavior_spec_id: string;\n run_number: number;\n status: string;\n current_stage?: string | null;\n stage_label?: string | null;\n progress_pct?: number | null;\n status_message?: string | null;\n hyperparameters: Record<string, unknown> | null;\n eval_summary: { avg_score?: number; mean_score?: number; pass_rate?: number } | null;\n error: string | null;\n started_at: string | null;\n completed_at: string | null;\n created_at: string;\n updated_at: string;\n _spec_name?: string;\n _evals?: RunEval[];\n _events?: RunEvent[];\n}\n\ninterface RunEval {\n id: string;\n prompt: string;\n expected: string;\n actual: string;\n passed: boolean;\n score: number | null;\n reasoning: string | null;\n latency_ms: number | null;\n}\n\ninterface RunEvent {\n id: string;\n stage: string;\n label: string;\n status: string;\n message: string | null;\n occurred_at: string;\n}\n\ninterface RunDiagnostics {\n run_id: string;\n status: string;\n stage: string | null;\n stage_label: string | null;\n progress_pct: number | null;\n status_message: string | null;\n summary: string;\n insights: string[];\n training: {\n state: string;\n started_at: string | null;\n completed_at: string | null;\n last_updated_at: string | null;\n curve: {\n target_epochs: number | null;\n latest_epoch: number | null;\n latest_loss: number | null;\n previous_loss: number | null;\n epoch_rate_per_minute: number | null;\n estimated_minutes_remaining: number | null;\n latest_log_at: string | null;\n samples: {\n timestamp: string;\n epoch: number;\n loss?: number;\n learning_rate?: number;\n }[];\n };\n };\n generated_at: string;\n}\n\nfunction formatProgress(run: Run): string | undefined {\n if (run.progress_pct == null && !run.stage_label) return undefined;\n const label = run.stage_label ?? run.current_stage ?? \"Progress\";\n return run.progress_pct == null ? label : `${label} (${run.progress_pct}%)`;\n}\n\nfunction getEvalScore(run: Run): number | undefined {\n return run.eval_summary?.avg_score ?? run.eval_summary?.mean_score;\n}\n\nfunction formatEvalScore(run: Run): string | undefined {\n const score = getEvalScore(run);\n return score == null ? undefined : (score * 100).toFixed(1) + \"%\";\n}\n\nfunction formatMinutes(minutes?: number | null): string | undefined {\n if (minutes == null) return undefined;\n if (minutes < 60) return `${Math.max(1, Math.round(minutes))}m`;\n return `${(minutes / 60).toFixed(1)}h`;\n}\n\nfunction formatEpochProgress(diagnostics: RunDiagnostics): string | undefined {\n const curve = diagnostics.training.curve;\n if (curve.latest_epoch == null) return undefined;\n if (curve.target_epochs == null) return curve.latest_epoch.toFixed(4);\n return `${curve.latest_epoch.toFixed(4)} / ${curve.target_epochs.toFixed(2)}`;\n}\n\nfunction printDiagnostics(diagnostics: RunDiagnostics) {\n const curve = diagnostics.training.curve;\n const perFive = curve.epoch_rate_per_minute == null\n ? undefined\n : (curve.epoch_rate_per_minute * 5).toFixed(4);\n\n printDetail([\n [\"Run\", shortId(diagnostics.run_id)],\n [\"Status\", formatStatus(diagnostics.status)],\n [\"Stage\", diagnostics.stage_label ?? diagnostics.stage ?? undefined],\n [\"Summary\", diagnostics.summary],\n [\"Training\", diagnostics.training.state],\n [\"Epoch\", formatEpochProgress(diagnostics)],\n [\"Latest Loss\", curve.latest_loss == null ? undefined : curve.latest_loss.toFixed(4)],\n [\"Pace\", perFive ? `${perFive} epoch / 5m` : undefined],\n [\"ETA\", formatMinutes(curve.estimated_minutes_remaining)],\n [\"Latest Update\", formatDate(diagnostics.training.last_updated_at)],\n ]);\n\n if (diagnostics.insights.length) {\n console.log(\"\\nInsights:\");\n for (const insight of diagnostics.insights) {\n console.log(` - ${insight}`);\n }\n }\n}\n\nexport function registerRunsCommands(parent: Command) {\n const runs = parent.command(\"runs\").description(\"Manage runs\");\n\n runs\n .command(\"list\")\n .description(\"List runs\")\n .option(\"-s, --spec <id>\", \"Filter by spec ID (full UUID or 8+ char prefix)\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n\n let path = \"/runs\";\n const query: Record<string, string | number> = {\n page: cmdOpts.page,\n per_page: cmdOpts.perPage,\n };\n\n if (cmdOpts.spec) {\n const fullSpecId = await resolveSpecId(cmdOpts.spec, opts);\n path = `/behavior-specs/${fullSpecId}/runs`;\n }\n\n const { data, meta } = await get<Run[]>(path, query, opts);\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Spec\", \"#\", \"Status\", \"Score\", \"Started\", \"Completed\"],\n data.map((r) => [\n shortId(r.id),\n r._spec_name ? truncate(r._spec_name, 20) : shortId(r.behavior_spec_id),\n String(r.run_number),\n formatStatus(r.status),\n formatEvalScore(r) ?? \"—\",\n formatDate(r.started_at),\n formatDate(r.completed_at),\n ]),\n meta,\n );\n });\n\n runs\n .command(\"get\")\n .description(\"Show run details and eval results\")\n .argument(\"<id>\", \"Run ID (full UUID or 8+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveRunId(id, opts);\n const { data } = await get<Run>(`/runs/${fullId}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Spec\", data._spec_name ?? shortId(data.behavior_spec_id)],\n [\"Run #\", String(data.run_number)],\n [\"Status\", formatStatus(data.status)],\n [\"Stage\", formatProgress(data)],\n [\"Message\", data.status_message ?? undefined],\n [\"Score\", formatEvalScore(data)],\n [\"Pass Rate\", data.eval_summary?.pass_rate != null\n ? (data.eval_summary.pass_rate * 100).toFixed(1) + \"%\"\n : undefined],\n [\"Error\", data.error ?? undefined],\n [\"Started\", formatDate(data.started_at)],\n [\"Completed\", formatDate(data.completed_at)],\n [\"Created\", formatDate(data.created_at)],\n ]);\n\n if (data.hyperparameters && Object.keys(data.hyperparameters).length) {\n console.log(\"\\nHyperparameters:\");\n for (const [k, v] of Object.entries(data.hyperparameters)) {\n console.log(` ${k}: ${v}`);\n }\n }\n\n if (data._events?.length) {\n console.log(\"\\nLatest Updates:\");\n for (const event of data._events.slice(-5)) {\n const time = formatDate(event.occurred_at);\n console.log(\n ` ${time} ${formatStatus(event.status)} ${event.label}${event.message ? ` — ${event.message}` : \"\"}`,\n );\n }\n }\n\n if (data._evals?.length) {\n console.log(`\\nEval Results (${data._evals.length}):`);\n printTable(\n [\"#\", \"Passed\", \"Score\", \"Prompt\", \"Latency\"],\n data._evals.map((e, i) => [\n String(i + 1),\n e.passed ? \"✓\" : \"✗\",\n e.score != null ? e.score.toFixed(2) : \"—\",\n truncate(e.prompt, 40),\n e.latency_ms != null ? `${e.latency_ms}ms` : \"—\",\n ]),\n );\n }\n });\n\n runs\n .command(\"start\")\n .description(\"Start a new run for a behaviour spec\")\n .argument(\"<spec-id>\", \"Behaviour spec ID (full UUID or 8+ char prefix)\")\n .option(\"--no-augment\", \"Disable data augmentation\")\n .option(\"--no-llm-judge\", \"Disable LLM judging\")\n .option(\"--epochs <n>\", \"Number of training epochs\")\n .option(\"--lr <rate>\", \"Learning rate\")\n .option(\"--batch-size <n>\", \"Batch size\")\n .option(\"--dataset <id>\", \"Dataset ID to use instead of inline spec examples (full UUID or 4+ char prefix)\")\n .option(\"--train-ratio <ratio>\", \"Dataset training split ratio (default: 0.8 when any split ratio is set)\")\n .option(\"--validation-ratio <ratio>\", \"Dataset validation split ratio (default: 0.1 when any split ratio is set)\")\n .option(\"--test-ratio <ratio>\", \"Dataset test split ratio (default: 0.1 when any split ratio is set)\")\n .option(\"--lora-rank <n>\", \"LoRA rank\")\n .option(\"--lora-alpha <n>\", \"LoRA alpha\")\n .option(\"--max-eval-examples <n>\", \"Max examples for the primary eval pass\")\n .option(\"--max-test-eval-examples <n>\", \"Max examples for the secondary test eval pass\")\n .action(async (specId: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const body: Record<string, unknown> = {};\n\n if (cmdOpts.augment === false) body.augment = false;\n if (cmdOpts.dataset) body.dataset_id = await resolveDatasetId(cmdOpts.dataset, opts);\n\n const splitRatioOptions = [\n cmdOpts.trainRatio,\n cmdOpts.validationRatio,\n cmdOpts.testRatio,\n ];\n if (splitRatioOptions.some((value) => value != null)) {\n body.split_ratios = {\n train: cmdOpts.trainRatio != null ? Number(cmdOpts.trainRatio) : 0.8,\n validation:\n cmdOpts.validationRatio != null ? Number(cmdOpts.validationRatio) : 0.1,\n test: cmdOpts.testRatio != null ? Number(cmdOpts.testRatio) : 0.1,\n };\n }\n\n const hp: Record<string, unknown> = {};\n if (cmdOpts.epochs) hp.n_epochs = Number(cmdOpts.epochs);\n if (cmdOpts.lr) hp.learning_rate = Number(cmdOpts.lr);\n if (cmdOpts.batchSize) hp.batch_size = Number(cmdOpts.batchSize);\n if (cmdOpts.loraRank) hp.lora_rank = Number(cmdOpts.loraRank);\n if (cmdOpts.loraAlpha) hp.lora_alpha = Number(cmdOpts.loraAlpha);\n if (cmdOpts.maxEvalExamples) hp.max_eval_examples = Number(cmdOpts.maxEvalExamples);\n if (cmdOpts.maxTestEvalExamples) hp.max_test_eval_examples = Number(cmdOpts.maxTestEvalExamples);\n if (cmdOpts.llmJudge === false) body.use_llm_judge = false;\n if (Object.keys(hp).length) body.hyperparameters = hp;\n\n const fullSpecId = await resolveSpecId(specId, opts);\n const { data } = await post<Run>(\n `/behavior-specs/${fullSpecId}/runs`,\n body,\n opts,\n );\n\n if (isJsonMode()) return printJson(data);\n printSuccess(\n `Run #${data.run_number} started (${shortId(data.id)}). ${formatProgress(data) ?? `Status: ${formatStatus(data.status)}`}`,\n );\n });\n\n runs\n .command(\"cancel\")\n .description(\"Cancel a running run\")\n .argument(\"<id>\", \"Run ID (full UUID or 8+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveRunId(id, opts);\n const { data } = await post<Run>(`/runs/${fullId}/cancel`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n printSuccess(`Run ${shortId(fullId)} cancelled.`);\n });\n\n runs\n .command(\"watch\")\n .description(\"Watch a run until it completes\")\n .argument(\"<id>\", \"Run ID (full UUID or 8+ char prefix)\")\n .option(\"--interval <ms>\", \"Poll interval in milliseconds\", \"5000\")\n .action(async (id: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const interval = Number(cmdOpts.interval);\n const fullId = await resolveRunId(id, opts);\n const spinner = ora(`Watching run ${shortId(fullId)}...`).start();\n\n const terminalStates = new Set([\n \"completed\",\n \"failed\",\n \"cancelled\",\n ]);\n\n let run: Run;\n while (true) {\n const { data } = await get<Run>(`/runs/${fullId}`, undefined, opts);\n run = data;\n spinner.text = `Run ${shortId(fullId)} — ${formatProgress(run) ?? formatStatus(run.status)}`;\n\n if (terminalStates.has(run.status)) break;\n await new Promise((r) => setTimeout(r, interval));\n }\n\n spinner.stop();\n\n if (isJsonMode()) return printJson(run);\n\n printDetail([\n [\"Run\", shortId(run.id)],\n [\"Status\", formatStatus(run.status)],\n [\"Stage\", formatProgress(run)],\n [\"Message\", run.status_message ?? undefined],\n [\"Score\", formatEvalScore(run)],\n [\"Error\", run.error ?? undefined],\n [\"Completed\", formatDate(run.completed_at)],\n ]);\n });\n\n runs\n .command(\"diagnose\")\n .description(\"Show live run diagnostics\")\n .argument(\"<id>\", \"Run ID (full UUID or 8+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveRunId(id, opts);\n const { data } = await get<RunDiagnostics>(\n `/runs/${fullId}/diagnostics`,\n undefined,\n opts,\n );\n\n if (isJsonMode()) return printJson(data);\n printDiagnostics(data);\n });\n}\n","import { Command } from \"commander\";\nimport { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { get, del, post, type ClientOpts } from \"../client.js\";\nimport { resolveDatasetId } from \"../resolve.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printJson,\n printError,\n isJsonMode,\n formatDate,\n formatStatus,\n shortId,\n truncate,\n} from \"../output.js\";\n\ninterface Dataset {\n id: string;\n name: string;\n description: string | null;\n storage_path: string;\n file_size_bytes: number;\n row_count: number;\n format: string;\n status: string;\n validation_errors: string[] | null;\n created_at: string;\n updated_at: string;\n}\n\ninterface DatasetUploadUrl {\n path: string;\n upload_url: string;\n method: \"PUT\";\n headers?: Record<string, string>;\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\n// Invisible characters that JSON parsers accept but downstream JSONL consumers\n// often mishandle. Concretely: Python's str.splitlines() treats every char in\n// this set as a line break, so a row containing one of them gets cut in half\n// before json.loads sees it. We strip these at validate-time so the failure\n// mode is \"row 1099 has U+0085 at offset 4078\" (seconds, locally) instead of\n// \"AlgorithmError: exit code 1\" after a training launch (minutes, remote).\nconst FORBIDDEN_CONTROL_CODEPOINTS: ReadonlyArray<{ code: number; name: string }> = [\n // C0 control chars except whitespace we explicitly allow inside string values.\n // U+0009 TAB, U+000A LF, U+000D CR are kept since they appear in normal text.\n { code: 0x00, name: \"NULL\" },\n { code: 0x01, name: \"START OF HEADING\" },\n { code: 0x02, name: \"START OF TEXT\" },\n { code: 0x03, name: \"END OF TEXT\" },\n { code: 0x04, name: \"END OF TRANSMISSION\" },\n { code: 0x05, name: \"ENQUIRY\" },\n { code: 0x06, name: \"ACKNOWLEDGE\" },\n { code: 0x07, name: \"BELL\" },\n { code: 0x08, name: \"BACKSPACE\" },\n { code: 0x0b, name: \"VERTICAL TAB\" },\n { code: 0x0c, name: \"FORM FEED\" },\n { code: 0x0e, name: \"SHIFT OUT\" },\n { code: 0x0f, name: \"SHIFT IN\" },\n // 0x10..0x1F all rejected; named lookup falls back to \"CONTROL CHARACTER\".\n { code: 0x1c, name: \"FILE SEPARATOR\" },\n { code: 0x1d, name: \"GROUP SEPARATOR\" },\n { code: 0x1e, name: \"RECORD SEPARATOR\" },\n // C1 control range U+0080..U+009F (all invisible, often mojibake from\n // Windows-1252 smart quotes mis-tagged as Unicode codepoints).\n { code: 0x0085, name: \"NEXT LINE\" },\n // Unicode line/paragraph separators - cut lines too.\n { code: 0x2028, name: \"LINE SEPARATOR\" },\n { code: 0x2029, name: \"PARAGRAPH SEPARATOR\" },\n];\n\nfunction findControlChar(value: string): { codepoint: number; offset: number; name: string } | null {\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i);\n // Whitelist real whitespace; everything in C0 below 0x20 (besides tab/LF/CR) is hazardous.\n if (code < 0x20 && code !== 0x09 && code !== 0x0a && code !== 0x0d) {\n const named = FORBIDDEN_CONTROL_CODEPOINTS.find((entry) => entry.code === code);\n return { codepoint: code, offset: i, name: named?.name ?? \"CONTROL CHARACTER\" };\n }\n // C1 control range - all hazardous (NEL, etc.); JSON parsers accept these\n // but Python's splitlines() splits on several of them.\n if (code >= 0x80 && code <= 0x9f) {\n const named = FORBIDDEN_CONTROL_CODEPOINTS.find((entry) => entry.code === code);\n return { codepoint: code, offset: i, name: named?.name ?? \"C1 CONTROL CHARACTER\" };\n }\n if (code === 0x2028 || code === 0x2029) {\n const named = FORBIDDEN_CONTROL_CODEPOINTS.find((entry) => entry.code === code);\n return { codepoint: code, offset: i, name: named?.name ?? \"LINE BREAK\" };\n }\n }\n return null;\n}\n\nfunction formatCodepoint(code: number): string {\n return `U+${code.toString(16).toUpperCase().padStart(4, \"0\")}`;\n}\n\nfunction validateDatasetFile(file: string): void {\n const lines = readFileSync(file, \"utf8\").split(/\\r?\\n/);\n const errors: string[] = [];\n let rowCount = 0;\n\n for (const [index, rawLine] of lines.entries()) {\n const line = rawLine.trim();\n if (!line) continue;\n\n rowCount += 1;\n const rowNumber = index + 1;\n let row: unknown;\n\n try {\n row = JSON.parse(line);\n } catch {\n errors.push(`Row ${rowNumber}: invalid JSON`);\n continue;\n }\n\n if (!row || typeof row !== \"object\" || Array.isArray(row)) {\n errors.push(`Row ${rowNumber}: expected an object with \"input\" and \"output\" fields`);\n continue;\n }\n\n const record = row as Record<string, unknown>;\n if (\"messages\" in record && !(\"input\" in record) && !(\"output\" in record)) {\n errors.push(\n `Row ${rowNumber}: found OpenAI SFT-style \"messages\"; Tuned Tensor datasets require flat \"input\" and \"output\" strings`,\n );\n continue;\n }\n\n if (typeof record.input !== \"string\") {\n errors.push(`Row ${rowNumber}: missing string \"input\" field`);\n }\n if (typeof record.output !== \"string\") {\n errors.push(`Row ${rowNumber}: missing string \"output\" field`);\n }\n\n for (const field of [\"input\", \"output\"] as const) {\n const value = record[field];\n if (typeof value !== \"string\") continue;\n const hit = findControlChar(value);\n if (hit) {\n errors.push(\n `Row ${rowNumber}: field \"${field}\" contains invisible control character ${formatCodepoint(hit.codepoint)} (${hit.name}) at offset ${hit.offset} — strip or escape before uploading; some training paths split on it`,\n );\n }\n }\n }\n\n if (rowCount === 0) {\n errors.push(\"File contains no JSONL rows\");\n }\n\n if (errors.length > 0) {\n const preview = errors.slice(0, 5).join(\"\\n\");\n const suffix = errors.length > 5 ? `\\n...and ${errors.length - 5} more error(s)` : \"\";\n throw new Error(\n `Invalid dataset format. Each JSONL row must be {\"input\": \"...\", \"output\": \"...\"}.\\n${preview}${suffix}`,\n );\n }\n}\n\nexport function registerDatasetsCommands(parent: Command) {\n const datasets = parent\n .command(\"datasets\")\n .description(\"Manage datasets\");\n\n datasets\n .command(\"list\")\n .description(\"List datasets\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const { data, meta } = await get<Dataset[]>(\n \"/datasets\",\n { page: cmdOpts.page, per_page: cmdOpts.perPage },\n opts,\n );\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Name\", \"Rows\", \"Size\", \"Status\", \"Created\"],\n data.map((d) => [\n shortId(d.id),\n truncate(d.name, 30),\n String(d.row_count),\n formatBytes(d.file_size_bytes),\n formatStatus(d.status),\n formatDate(d.created_at),\n ]),\n meta,\n );\n });\n\n datasets\n .command(\"get\")\n .description(\"Show dataset details\")\n .argument(\"<id>\", \"Dataset ID (full UUID or 4+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveDatasetId(id, opts);\n const { data } = await get<Dataset>(`/datasets/${fullId}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Name\", data.name],\n [\"Description\", data.description ?? undefined],\n [\"Format\", data.format],\n [\"Rows\", String(data.row_count)],\n [\"Size\", formatBytes(data.file_size_bytes)],\n [\"Status\", formatStatus(data.status)],\n [\"Created\", formatDate(data.created_at)],\n [\"Updated\", formatDate(data.updated_at)],\n ]);\n\n if (data.validation_errors?.length) {\n console.log(\"\\nValidation Errors:\");\n for (const err of data.validation_errors) {\n console.log(` - ${err}`);\n }\n }\n });\n\n datasets\n .command(\"upload\")\n .description(\"Upload a JSONL dataset file\")\n .argument(\"<file>\", \"Path to JSONL file\")\n .option(\"-n, --name <name>\", \"Dataset name (defaults to filename)\")\n .option(\"-d, --description <desc>\", \"Dataset description\")\n .action(async (file: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n\n if (!existsSync(file)) {\n printError(`File not found: ${file}`);\n process.exit(1);\n }\n\n validateDatasetFile(file);\n\n const name = cmdOpts.name || file.split(\"/\").pop()!.replace(/\\.jsonl?$/, \"\");\n const fileBytes = readFileSync(file);\n const uploadUrl = await post<DatasetUploadUrl>(\n \"/datasets/upload-url\",\n {\n name,\n description: cmdOpts.description ?? null,\n filename: file.split(\"/\").pop()!,\n size: statSync(file).size,\n contentType: \"application/jsonl\",\n },\n opts,\n );\n\n const uploadRes = await fetch(uploadUrl.data.upload_url, {\n method: uploadUrl.data.method,\n headers: uploadUrl.data.headers ?? { \"Content-Type\": \"application/jsonl\" },\n body: new Blob([fileBytes], { type: \"application/jsonl\" }),\n });\n if (!uploadRes.ok) {\n throw new Error(`Dataset upload failed: ${uploadRes.status} ${uploadRes.statusText}`);\n }\n\n const { data } = await post<Dataset>(\n \"/datasets/finalize\",\n {\n path: uploadUrl.data.path,\n name,\n description: cmdOpts.description ?? null,\n },\n opts,\n );\n\n if (isJsonMode()) return printJson(data);\n printSuccess(\n `Dataset uploaded: ${data.name} (${shortId(data.id)}) — ${data.row_count} rows`,\n );\n });\n\n datasets\n .command(\"delete\")\n .description(\"Delete a dataset\")\n .argument(\"<id>\", \"Dataset ID (full UUID or 4+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveDatasetId(id, opts);\n await del(`/datasets/${fullId}`, opts);\n\n if (isJsonMode()) return printJson({ id: fullId, deleted: true });\n printSuccess(`Dataset deleted: ${shortId(fullId)}`);\n });\n}\n","import { Command } from \"commander\";\nimport { existsSync, mkdirSync, statSync, createWriteStream, unlinkSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { Readable } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport { get, del, type ClientOpts } from \"../client.js\";\nimport { resolveModelId } from \"../resolve.js\";\nimport { SUPPORTED_BASE_MODELS } from \"../base-models.js\";\nimport {\n printTable,\n printDetail,\n printSuccess,\n printJson,\n isJsonMode,\n formatDate,\n shortId,\n truncate,\n} from \"../output.js\";\n\ninterface Model {\n id: string;\n name: string;\n provider: string;\n provider_model_id: string;\n base_model: string;\n description: string | null;\n created_at: string;\n}\n\ninterface ModelDownload {\n url: string;\n filename: string;\n expires_at: string;\n}\n\nfunction resolveOutputPath(output: string | undefined, filename: string): string {\n if (!output) return filename;\n if (existsSync(output) && statSync(output).isDirectory()) {\n return join(output, filename);\n }\n return output;\n}\n\nasync function downloadUrlToFile(url: string, outputPath: string): Promise<number | null> {\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Download failed: ${res.status} ${res.statusText}`);\n }\n if (!res.body) {\n throw new Error(\"Download failed: response body was empty\");\n }\n\n mkdirSync(dirname(outputPath), { recursive: true });\n const file = createWriteStream(outputPath);\n\n try {\n await pipeline(Readable.fromWeb(res.body), file);\n } catch (err) {\n try {\n unlinkSync(outputPath);\n } catch {\n // Best effort cleanup for partially written downloads.\n }\n throw err;\n }\n\n const length = res.headers.get(\"content-length\");\n return length ? Number(length) : null;\n}\n\nexport function registerModelsCommands(parent: Command) {\n const models = parent.command(\"models\").description(\"Manage fine-tuned models\");\n\n models\n .command(\"base\")\n .description(\"List supported base models\")\n .action(async () => {\n const data = SUPPORTED_BASE_MODELS.map((model) => ({\n id: model,\n name: model.split(\"/\").pop() || model,\n type: \"base\" as const,\n }));\n\n if (isJsonMode()) return printJson({ data });\n\n printTable(\n [\"ID\", \"Name\", \"Type\"],\n data.map((m) => [m.id, m.name, m.type]),\n );\n });\n\n models\n .command(\"list\")\n .description(\"List fine-tuned models\")\n .option(\"-p, --page <n>\", \"Page number\", \"1\")\n .option(\"--per-page <n>\", \"Results per page\", \"20\")\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const { data, meta } = await get<Model[]>(\n \"/models\",\n { page: cmdOpts.page, per_page: cmdOpts.perPage },\n opts,\n );\n\n if (isJsonMode()) return printJson({ data, meta });\n\n printTable(\n [\"ID\", \"Name\", \"Base Model\", \"Provider\", \"Created\"],\n data.map((m) => [\n shortId(m.id),\n truncate(m.name, 30),\n m.base_model.split(\"/\").pop() || m.base_model,\n m.provider,\n formatDate(m.created_at),\n ]),\n meta,\n );\n });\n\n models\n .command(\"get\")\n .description(\"Show model details\")\n .argument(\"<id>\", \"Model ID (full UUID or 4+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveModelId(id, opts);\n const { data } = await get<Model>(`/models/${fullId}`, undefined, opts);\n\n if (isJsonMode()) return printJson(data);\n\n printDetail([\n [\"ID\", data.id],\n [\"Name\", data.name],\n [\"Base Model\", data.base_model],\n [\"Provider\", data.provider],\n [\"Hosted Model\", data.provider_model_id],\n [\"Description\", data.description ?? undefined],\n [\"Created\", formatDate(data.created_at)],\n ]);\n });\n\n models\n .command(\"download\")\n .description(\"Download a fine-tuned model artifact\")\n .argument(\"<id>\", \"Model ID (full UUID or 4+ char prefix)\")\n .option(\"-o, --output <path>\", \"Output file or directory\")\n .option(\"-f, --force\", \"Overwrite the output file if it already exists\")\n .action(async (id: string, cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveModelId(id, opts);\n const { data } = await get<ModelDownload>(\n `/models/${fullId}/download`,\n undefined,\n opts,\n );\n\n const outputPath = resolveOutputPath(cmdOpts.output, data.filename);\n if (existsSync(outputPath) && !cmdOpts.force) {\n throw new Error(`Output file already exists: ${outputPath}. Use --force to overwrite.`);\n }\n\n const bytes = await downloadUrlToFile(data.url, outputPath);\n\n if (isJsonMode()) {\n return printJson({\n id: fullId,\n output_path: outputPath,\n filename: data.filename,\n bytes,\n expires_at: data.expires_at,\n });\n }\n\n const size = bytes == null ? \"\" : ` (${bytes} bytes)`;\n printSuccess(`Model downloaded to ${outputPath}${size}`);\n });\n\n models\n .command(\"delete\")\n .description(\"Delete a model\")\n .argument(\"<id>\", \"Model ID (full UUID or 4+ char prefix)\")\n .action(async (id: string) => {\n const opts = parent.opts() as ClientOpts;\n const fullId = await resolveModelId(id, opts);\n await del(`/models/${fullId}`, opts);\n\n if (isJsonMode()) return printJson({ id: fullId, deleted: true });\n printSuccess(`Model deleted: ${shortId(fullId)}`);\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { get, type ClientOpts } from \"../client.js\";\nimport {\n printDetail,\n printJson,\n printTable,\n isJsonMode,\n formatDate,\n formatStatus,\n shortId,\n} from \"../output.js\";\n\ninterface BalanceResponse {\n balance_cents: number;\n reserved_cents: number;\n available_cents: number;\n lifetime_topup_cents: number;\n}\n\ntype CreditKind =\n | \"signup_bonus\"\n | \"topup\"\n | \"debit_run\"\n | \"debit_autotune\"\n | \"refund\"\n | \"adjustment\";\n\ninterface LedgerRow {\n id: string;\n kind: CreditKind;\n amount_cents: number;\n balance_after_cents: number;\n reference_id: string | null;\n created_at: string;\n}\n\nconst KIND_LABELS: Record<CreditKind, string> = {\n signup_bonus: \"Signup bonus\",\n topup: \"Top-up\",\n debit_run: \"Run\",\n debit_autotune: \"Auto-tune\",\n refund: \"Refund\",\n adjustment: \"Adjustment\",\n};\n\nfunction formatCents(cents: number): string {\n const sign = cents < 0 ? \"-\" : \"\";\n const abs = Math.abs(cents);\n return `${sign}$${(abs / 100).toFixed(2)}`;\n}\n\nfunction formatSigned(cents: number): string {\n if (cents > 0) return chalk.green(`+${formatCents(cents)}`);\n if (cents < 0) return chalk.red(formatCents(cents));\n return formatCents(cents);\n}\n\nexport function registerBalanceCommands(parent: Command) {\n parent\n .command(\"balance\")\n .description(\"Show credit balance and recent transactions\")\n .option(\"-n, --limit <n>\", \"Number of transactions to show (default 10)\", \"10\")\n .action(async (options) => {\n const opts = parent.opts() as ClientOpts;\n const limit = Number(options.limit) || 10;\n\n const [{ data: balance }, { data: transactions }] = await Promise.all([\n get<BalanceResponse>(\"/billing/balance\", undefined, opts),\n get<LedgerRow[]>(\"/billing/transactions\", { per_page: limit }, opts),\n ]);\n\n if (isJsonMode()) {\n return printJson({ balance, transactions });\n }\n\n const lowBalance = balance.balance_cents < 100;\n const balanceLine = lowBalance\n ? chalk.red(formatCents(balance.balance_cents)) + chalk.dim(\" (low)\")\n : chalk.bold.green(formatCents(balance.balance_cents));\n\n printDetail([\n [\"Credits\", balanceLine],\n [\"Lifetime top-ups\", formatCents(balance.lifetime_topup_cents)],\n ]);\n\n if (transactions && transactions.length > 0) {\n console.log(`\\n${chalk.bold(\"Recent transactions\")}`);\n printTable(\n [\"Date\", \"Type\", \"Amount\", \"Balance\", \"Reference\"],\n transactions.map((row) => [\n formatDate(row.created_at),\n KIND_LABELS[row.kind] ?? row.kind,\n formatSigned(row.amount_cents),\n formatCents(row.balance_after_cents),\n row.reference_id ? shortId(row.reference_id) : chalk.dim(\"—\"),\n ])\n );\n } else {\n console.log(\n `\\n${chalk.dim(\"No transactions yet — run `tt topup` to add credits.\")}`\n );\n }\n\n if (lowBalance) {\n console.log(\n `\\n${formatStatus(\"preparing\")} ${chalk.yellow(\n \"Run `tt topup` to add more credits before starting a run.\"\n )}`\n );\n }\n });\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport open from \"open\";\nimport { post, type ClientOpts } from \"../client.js\";\nimport { printJson, isJsonMode, printSuccess } from \"../output.js\";\n\ninterface TopupResponse {\n checkout_url: string;\n session_id: string;\n}\n\nconst PRESETS_USD = [10, 25, 50, 100];\nconst MIN_USD = 5;\nconst MAX_USD = 10000;\n\nfunction parseAmount(input: string | undefined): number | null {\n if (!input) return null;\n const cleaned = input.replace(/^\\$/, \"\").trim();\n const num = Number(cleaned);\n if (!Number.isFinite(num) || num <= 0) return null;\n return num;\n}\n\nasync function readLine(prompt: string): Promise<string> {\n const readline = await import(\"node:readline/promises\");\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n try {\n return (await rl.question(prompt)).trim();\n } finally {\n rl.close();\n }\n}\n\nexport function registerTopupCommands(parent: Command) {\n parent\n .command(\"topup\")\n .description(\"Add prepaid credits via Stripe Checkout\")\n .option(\"-a, --amount <usd>\", \"Amount in USD (e.g. 25)\")\n .option(\"--no-open\", \"Print checkout URL instead of opening the browser\")\n .action(async (options) => {\n const opts = parent.opts() as ClientOpts;\n\n let amountUsd: number | null;\n\n if (options.amount !== undefined) {\n amountUsd = parseAmount(options.amount);\n if (amountUsd === null) {\n throw new Error(\"Invalid amount\");\n }\n } else {\n if (isJsonMode()) {\n throw new Error(\n \"amount is required in --json mode (use --amount <usd>)\"\n );\n }\n console.log(chalk.bold(\"Add credits via Stripe Checkout\"));\n console.log(\n chalk.dim(\n `Quick picks: ${PRESETS_USD.map((n) => `$${n}`).join(\", \")}`\n )\n );\n const input = await readLine(`Amount in USD (min $${MIN_USD}): `);\n amountUsd = parseAmount(input);\n if (amountUsd === null) {\n throw new Error(\"Invalid amount\");\n }\n }\n\n if (amountUsd < MIN_USD) {\n throw new Error(`Minimum top-up is $${MIN_USD}`);\n }\n if (amountUsd > MAX_USD) {\n throw new Error(`Maximum top-up is $${MAX_USD}`);\n }\n\n const amountCents = Math.round(amountUsd * 100);\n\n const { data } = await post<TopupResponse>(\n \"/billing/topup\",\n { amount_cents: amountCents },\n opts\n );\n\n if (isJsonMode()) {\n return printJson(data);\n }\n\n const url = data.checkout_url;\n console.log(\n `${chalk.bold(\"Checkout URL:\")} ${chalk.cyan(url)}\\n` +\n chalk.dim(\"Complete the payment to credit your account.\")\n );\n\n if (options.open !== false) {\n try {\n await open(url);\n printSuccess(\"Opened Stripe Checkout in your browser.\");\n } catch {\n console.log(\n chalk.yellow(\n \"Could not open browser automatically — copy the URL above.\"\n )\n );\n }\n }\n });\n}\n","import { Command } from \"commander\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { printSuccess, printError, printWarning } from \"../output.js\";\nimport type { LocalSpec } from \"../eval/types.js\";\nimport { canonicalizeBaseModel } from \"../base-models.js\";\n\nconst DEFAULT_SPEC_FILE = \"tunedtensor.json\";\n\nconst SCAFFOLD: LocalSpec = {\n name: \"My Agent\",\n description: \"\",\n base_model: \"Qwen/Qwen3.5-2B\",\n system_prompt: \"You are a helpful assistant.\",\n guidelines: [],\n constraints: [],\n examples: [\n { input: \"Hello\", output: \"Hi! How can I help you today?\" },\n ],\n eval_cases: [],\n};\n\nexport function registerInitCommand(parent: Command) {\n parent\n .command(\"init\")\n .description(\"Create a local behaviour spec file\")\n .option(\"-n, --name <name>\", \"Spec name\")\n .option(\"--model <model>\", \"Base model ID\")\n .option(\"-f, --file <path>\", \"Output file path\", DEFAULT_SPEC_FILE)\n .action(async (cmdOpts) => {\n const filePath = resolve(cmdOpts.file);\n\n if (existsSync(filePath)) {\n printWarning(`${cmdOpts.file} already exists. Use tt eval to validate it or edit it directly.`);\n return;\n }\n\n const spec: LocalSpec = { ...SCAFFOLD };\n if (cmdOpts.name) spec.name = cmdOpts.name;\n if (cmdOpts.model) spec.base_model = canonicalizeBaseModel(cmdOpts.model);\n\n writeFileSync(filePath, JSON.stringify(spec, null, 2) + \"\\n\");\n printSuccess(`Created ${cmdOpts.file}`);\n console.log(\"\\nNext steps:\");\n console.log(\" 1. Edit the spec: system_prompt, guidelines, examples\");\n console.log(\" 2. Validate spec: tt eval\");\n console.log(\" 3. Push to remote: tt push\");\n });\n}\n\nexport function loadSpec(filePath?: string): LocalSpec {\n const resolved = resolve(filePath || DEFAULT_SPEC_FILE);\n if (!existsSync(resolved)) {\n printError(\n `Spec file not found: ${filePath || DEFAULT_SPEC_FILE}\\nRun \\`tt init\\` to create one.`,\n );\n process.exit(1);\n }\n\n const raw = JSON.parse(readFileSync(resolved, \"utf-8\"));\n return raw as LocalSpec;\n}\n\nexport { DEFAULT_SPEC_FILE };\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport {\n printJson,\n isJsonMode,\n} from \"../output.js\";\nimport { loadSpec, DEFAULT_SPEC_FILE } from \"./init.js\";\nimport { validateSpec } from \"../eval/rules.js\";\nimport type { ValidationCheck } from \"../eval/types.js\";\n\nexport function registerEvalCommand(parent: Command) {\n parent\n .command(\"eval\")\n .description(\"Validate a local behaviour spec\")\n .option(\"-m, --model <model>\", \"Deprecated; ignored because tt eval only validates the local spec\")\n .option(\"-f, --file <path>\", \"Spec file path\", DEFAULT_SPEC_FILE)\n .action(async (cmdOpts) => {\n const spec = loadSpec(cmdOpts.file);\n const validation = validateSpec(spec);\n\n if (!isJsonMode()) {\n console.log(chalk.dim(`\\nSpec: ${cmdOpts.file}\\n`));\n }\n\n if (isJsonMode()) {\n printJson(validation);\n } else {\n printValidation(validation.checks);\n }\n\n if (!validation.valid) {\n process.exitCode = 1;\n }\n });\n}\n\nfunction printValidation(checks: ValidationCheck[]) {\n console.log(chalk.bold(\"Spec Validation\"));\n for (const check of checks) {\n const icon = check.passed ? chalk.green(\"✓\") : chalk.red(\"✗\");\n const msg = check.message\n ? chalk.dim(` — ${check.message}`)\n : \"\";\n console.log(` ${icon} ${check.name}${msg}`);\n }\n}\n","import type {\n AssertionResult,\n LocalSpec,\n ValidationCheck,\n ValidationResult,\n} from \"./types.js\";\n\nexport function validateSpec(spec: LocalSpec): ValidationResult {\n const checks: ValidationCheck[] = [];\n\n checks.push({\n name: \"Has name\",\n passed: Boolean(spec.name?.trim()),\n message: spec.name?.trim() ? undefined : \"Spec is missing a name\",\n });\n\n checks.push({\n name: \"Has system prompt\",\n passed: Boolean(spec.system_prompt?.trim()),\n message: spec.system_prompt?.trim()\n ? undefined\n : \"Spec is missing a system_prompt\",\n });\n\n checks.push({\n name: \"Has base model\",\n passed: Boolean(spec.base_model?.trim()),\n message: spec.base_model?.trim()\n ? undefined\n : \"Spec is missing a base_model\",\n });\n\n const exCount = spec.examples?.length ?? 0;\n checks.push({\n name: \"Has examples\",\n passed: exCount > 0,\n message: exCount > 0 ? `${exCount} example(s)` : \"Add at least one example\",\n });\n\n checks.push({\n name: \"Has guidelines\",\n passed: (spec.guidelines?.length ?? 0) > 0,\n message:\n (spec.guidelines?.length ?? 0) > 0\n ? undefined\n : \"Consider adding guidelines for better eval coverage\",\n });\n\n if (spec.constraints?.length && spec.examples?.length) {\n const violations = checkExamplesAgainstConstraints(spec);\n checks.push({\n name: \"Examples satisfy constraints\",\n passed: violations.length === 0,\n message:\n violations.length === 0\n ? undefined\n : violations.join(\"; \"),\n });\n }\n\n return {\n valid: checks.every((c) => c.passed),\n checks,\n };\n}\n\nfunction checkExamplesAgainstConstraints(spec: LocalSpec): string[] {\n const violations: string[] = [];\n for (const [i, ex] of spec.examples.entries()) {\n for (const constraint of spec.constraints) {\n const result = evaluateConstraint(ex.output, constraint);\n if (!result.passed) {\n violations.push(`Example ${i + 1} violates \"${constraint}\": ${result.message}`);\n }\n }\n }\n return violations;\n}\n\nfunction evaluateConstraint(\n text: string,\n constraint: string,\n): { passed: boolean; message?: string } {\n const lower = constraint.toLowerCase();\n\n const neverMatch = lower.match(/^never (?:share|mention|include|reveal|use|say|output|return|give|provide|show|disclose|expose)\\s+(.+)/);\n if (neverMatch) {\n const forbidden = neverMatch[1].replace(/['\"]/g, \"\").trim();\n if (text.toLowerCase().includes(forbidden.toLowerCase())) {\n return { passed: false, message: `Output contains \"${forbidden}\"` };\n }\n return { passed: true };\n }\n\n const alwaysMatch = lower.match(/^always (?:include|use|start with|end with|contain|respond in|reply in)\\s+(.+)/);\n if (alwaysMatch) {\n const required = alwaysMatch[1].replace(/['\"]/g, \"\").trim();\n if (!text.toLowerCase().includes(required.toLowerCase())) {\n return { passed: false, message: `Output missing \"${required}\"` };\n }\n return { passed: true };\n }\n\n return {\n passed: true,\n message: `Constraint not enforceable by rules: \"${constraint}\" (will be checked by LLM judge if a provider is configured)`,\n };\n}\n\nexport function runAssertions(\n text: string,\n assertions: string[],\n): AssertionResult[] {\n return assertions.map((assertion) => runSingleAssertion(text, assertion));\n}\n\nfunction runSingleAssertion(text: string, assertion: string): AssertionResult {\n const [type, ...rest] = assertion.split(\":\");\n const value = rest.join(\":\");\n\n switch (type) {\n case \"contains\":\n return {\n assertion,\n passed: text.includes(value),\n message: text.includes(value)\n ? undefined\n : `Expected output to contain \"${value}\"`,\n };\n\n case \"not-contains\":\n return {\n assertion,\n passed: !text.includes(value),\n message: !text.includes(value)\n ? undefined\n : `Expected output to not contain \"${value}\"`,\n };\n\n case \"matches\": {\n const re = new RegExp(value);\n const match = re.test(text);\n return {\n assertion,\n passed: match,\n message: match ? undefined : `Output did not match pattern /${value}/`,\n };\n }\n\n case \"max-length\": {\n const max = Number(value);\n return {\n assertion,\n passed: text.length <= max,\n message:\n text.length <= max\n ? undefined\n : `Output length ${text.length} exceeds max ${max}`,\n };\n }\n\n case \"min-length\": {\n const min = Number(value);\n return {\n assertion,\n passed: text.length >= min,\n message:\n text.length >= min\n ? undefined\n : `Output length ${text.length} below min ${min}`,\n };\n }\n\n case \"is-json\": {\n let valid = false;\n try {\n JSON.parse(text);\n valid = true;\n } catch {}\n return {\n assertion,\n passed: valid,\n message: valid ? undefined : \"Output is not valid JSON\",\n };\n }\n\n default:\n return {\n assertion,\n passed: true,\n message: `Unknown assertion type: ${type} (skipped)`,\n };\n }\n}\n\nexport function checkConstraints(\n text: string,\n constraints: string[],\n): AssertionResult[] {\n return constraints.map((constraint) => {\n const result = evaluateConstraint(text, constraint);\n return {\n assertion: `constraint: ${constraint}`,\n passed: result.passed,\n message: result.message,\n };\n });\n}\n","import { Command } from \"commander\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { post, put, type ClientOpts } from \"../client.js\";\nimport { printSuccess, printJson, isJsonMode, shortId } from \"../output.js\";\nimport { loadSpec, DEFAULT_SPEC_FILE } from \"./init.js\";\nimport { canonicalizeSpecBaseModel } from \"../base-models.js\";\n\ninterface RemoteSpec {\n id: string;\n name: string;\n [key: string]: unknown;\n}\n\nexport function registerPushCommand(parent: Command) {\n parent\n .command(\"push\")\n .description(\"Push local spec to the Tuned Tensor API\")\n .option(\"-f, --file <path>\", \"Spec file path\", DEFAULT_SPEC_FILE)\n .action(async (cmdOpts) => {\n const opts = parent.opts() as ClientOpts;\n const filePath = resolve(cmdOpts.file);\n const spec = loadSpec(cmdOpts.file);\n\n const { id, eval_cases, ...rawBody } = spec as unknown as Record<string, unknown>;\n const body = canonicalizeSpecBaseModel(rawBody);\n\n let data: RemoteSpec;\n\n if (id) {\n const res = await put<RemoteSpec>(`/behavior-specs/${id}`, body, opts);\n data = res.data;\n } else {\n const res = await post<RemoteSpec>(\"/behavior-specs\", body, opts);\n data = res.data;\n\n const raw = JSON.parse(readFileSync(filePath, \"utf-8\"));\n raw.id = data.id;\n writeFileSync(filePath, JSON.stringify(raw, null, 2) + \"\\n\");\n }\n\n if (isJsonMode()) return printJson(data);\n printSuccess(\n `Spec ${id ? \"updated\" : \"created\"}: ${data.name} (${shortId(data.id)})`,\n );\n });\n}\n"],"mappings":"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","names":["readFileSync","chalk","readFileSync","readFileSync","existsSync","readFileSync","statSync","readFileSync","existsSync","statSync","existsSync","mkdirSync","statSync","join","existsSync","statSync","join","mkdirSync","chalk","chalk","chalk","chalk","existsSync","readFileSync","writeFileSync","existsSync","writeFileSync","readFileSync","chalk","chalk","readFileSync","writeFileSync","resolve","resolve","readFileSync","writeFileSync"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuned-tensor/cli",
3
- "version": "0.4.9",
3
+ "version": "0.4.11",
4
4
  "description": "CLI for Tuned Tensor — fine-tune and evaluate LLMs from the command line",
5
5
  "type": "module",
6
6
  "bin": {