@tuned-tensor/cli 0.15.1 → 0.16.0

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.
@@ -14,6 +14,7 @@ import {
14
14
  buildModelPrefetchPayload,
15
15
  buildSystemMessage,
16
16
  canonicalLocalPipeline,
17
+ checkAwsGpu,
17
18
  comparisonReportSchema,
18
19
  compileSpecToJsonl,
19
20
  createLocalStore,
@@ -64,6 +65,7 @@ import {
64
65
  resolveModelLoader,
65
66
  resolveRequestedBaseModelRevision,
66
67
  resolveTrainingModel,
68
+ runGpuProcess,
67
69
  runLocalFineTune,
68
70
  runLocalPipeline,
69
71
  runReportSchema,
@@ -81,13 +83,13 @@ import {
81
83
  withHuggingFaceCacheEnvironment,
82
84
  withOfflineHuggingFaceCacheEnvironment,
83
85
  writePrivateJsonAtomic
84
- } from "./chunk-VVKC563R.js";
86
+ } from "./chunk-6RLNBTM6.js";
85
87
 
86
88
  // src/local-runtime/index.ts
87
- import { readFileSync as readFileSync2, realpathSync } from "fs";
89
+ import { readFileSync as readFileSync3, realpathSync } from "fs";
88
90
  import { createHash as createHash2 } from "crypto";
89
91
  import { readFile as readFile2, stat } from "fs/promises";
90
- import { basename, dirname, join as join4, resolve as resolve3 } from "path";
92
+ import { basename, dirname, join as join5, resolve as resolve3 } from "path";
91
93
  import { cwd } from "process";
92
94
  import { fileURLToPath as fileURLToPath2 } from "url";
93
95
 
@@ -290,6 +292,22 @@ function foundationPythonProbePlan(requireBf16) {
290
292
  env: withFoundationPythonEnvironment(process.env)
291
293
  };
292
294
  }
295
+ function localPreparationProbePlan(foundation) {
296
+ const source = [
297
+ "import json",
298
+ foundation ? "import numpy, safetensors, tokenizers, torch" : "import torch, transformers, peft, huggingface_hub",
299
+ "assert torch.ones(1, device='cpu').item() == 1",
300
+ "print(json.dumps({'python_ok': True, 'device': 'cpu', 'purpose': 'local preparation and CPU work'}))"
301
+ ].join("; ");
302
+ const entrypoint = foundation ? buildFoundationPythonCommand("-c", [source]) : buildBundledPythonCommand("-c", [source]);
303
+ const env = minimalMachineLearningEnvironment(process.env);
304
+ return {
305
+ name: "python-runtime",
306
+ command: entrypoint.command,
307
+ args: entrypoint.commandArgs,
308
+ env: foundation ? withFoundationPythonEnvironment(env) : withBundledPythonEnvironment(env)
309
+ };
310
+ }
293
311
  function pythonProbeSource(device) {
294
312
  return [
295
313
  "import json",
@@ -430,7 +448,7 @@ async function runDoctor(config, request, foundationSpec) {
430
448
  checks.push(placeholderSpecCheck(request));
431
449
  resolveTrainingModel(request.spec_snapshot.base_model);
432
450
  }
433
- const pythonPlans = foundationSpec && !config.dryRun ? [foundationPythonProbePlan(foundationSpec.foundation.bf16 !== false)] : buildDoctorPythonPlans(config);
451
+ const pythonPlans = config.dryRun ? [] : config.gpu ? [localPreparationProbePlan(Boolean(foundationSpec))] : foundationSpec ? [foundationPythonProbePlan(foundationSpec.foundation.bf16 !== false)] : buildDoctorPythonPlans(config);
434
452
  if (pythonPlans.length > 0) {
435
453
  const uvVersion = await runCommand("uv", ["--version"]);
436
454
  checks.push({
@@ -465,7 +483,28 @@ async function runDoctor(config, request, foundationSpec) {
465
483
  });
466
484
  }
467
485
  const device = config.evaluation.inference.device;
468
- if (!config.dryRun) {
486
+ if (config.gpu && !config.dryRun) {
487
+ try {
488
+ await checkAwsGpu(config.gpu);
489
+ const plans = foundationSpec ? [foundationPythonProbePlan(foundationSpec.foundation.bf16 !== false)] : buildDoctorPythonPlans(config);
490
+ for (const plan of plans) {
491
+ const result = await runGpuProcess({
492
+ gpu: config.gpu,
493
+ runtime: foundationSpec ? "foundation" : "adapter",
494
+ files: [],
495
+ command: plan.command,
496
+ commandArgs: plan.args,
497
+ env: plan.env,
498
+ stage: "gpu_check",
499
+ timeoutMs: 18e5
500
+ });
501
+ if (result.exitCode !== 0) throw new Error(`Remote Python/CUDA check failed: ${result.stderr}`);
502
+ }
503
+ checks.push({ name: "aws-gpu", ok: true, message: `GPU execution on ${config.gpu.instanceId}; orchestration stays local.` });
504
+ } catch (error) {
505
+ checks.push({ name: "aws-gpu", ok: false, message: error instanceof Error ? error.message : String(error) });
506
+ }
507
+ } else if (!config.dryRun) {
469
508
  const queried = await runCommand("nvidia-smi", [
470
509
  "--query-gpu=name,driver_version",
471
510
  "--format=csv,noheader"
@@ -503,8 +542,9 @@ async function runDoctor(config, request, foundationSpec) {
503
542
  }
504
543
 
505
544
  // src/local-runtime/model-server.ts
545
+ import { readFileSync as readFileSync2, statSync } from "fs";
506
546
  import { spawn as spawn2 } from "child_process";
507
- import { resolve as resolve2 } from "path";
547
+ import { resolve as resolve2, join as join3 } from "path";
508
548
  import { fileURLToPath } from "url";
509
549
 
510
550
  // src/local-runtime/serving-runtime.ts
@@ -562,7 +602,16 @@ function buildModelServerLaunch(args) {
562
602
  const options = args.options ?? {};
563
603
  const device = options.device ?? args.config.evaluation.inference.device;
564
604
  if (device !== "cuda") throw new Error("The pinned vLLM serving runtime requires CUDA; CPU serving is not supported.");
565
- const contextLength = boundedNumber("contextLength", options.contextLength ?? 16384, 512, 131072, true);
605
+ const contextLength = boundedNumber(
606
+ "contextLength",
607
+ options.contextLength ?? args.foundation?.contextLength ?? 16384,
608
+ args.foundation ? 1 : 512,
609
+ 131072,
610
+ true
611
+ );
612
+ if (args.foundation && contextLength > args.foundation.contextLength) {
613
+ throw new Error("Context length exceeds the foundation checkpoint sequence_length.");
614
+ }
566
615
  const gpuMemoryUtilization = boundedNumber("gpuMemoryUtilization", options.gpuMemoryUtilization ?? 0.8, 0.05, 0.95);
567
616
  const host = options.host ?? "127.0.0.1";
568
617
  const remote = !isLoopbackHost(host);
@@ -575,7 +624,7 @@ function buildModelServerLaunch(args) {
575
624
  throw new Error("Non-loopback serving requires --api-key-env with a populated environment variable.");
576
625
  }
577
626
  const port = boundedNumber("port", options.port ?? 8e3, 1, 65535, true);
578
- const maxTokens = boundedNumber("maxTokens", options.maxTokens ?? 512, 1, 8192, true);
627
+ const maxTokens = boundedNumber("maxTokens", options.maxTokens ?? Math.min(512, contextLength), 1, 8192, true);
579
628
  const temperature = boundedNumber("temperature", options.temperature ?? 0, 0, 5);
580
629
  const topP = boundedNumber("topP", options.topP ?? 1, 0, 1);
581
630
  const maxConcurrentRequests = boundedNumber(
@@ -587,14 +636,14 @@ function buildModelServerLaunch(args) {
587
636
  );
588
637
  const artifactPath = args.artifactUri ? localArtifactPath(args.artifactUri) : void 0;
589
638
  const recordedBaseModelPath = options.baseModelArtifactUri ? localArtifactPath(options.baseModelArtifactUri) : void 0;
590
- const configuredBaseModelPath = args.config.paths.baseModel ? resolve2(args.config.paths.baseModel) : void 0;
639
+ const configuredBaseModelPath = !args.foundation && args.config.paths.baseModel ? resolve2(args.config.paths.baseModel) : void 0;
591
640
  if (recordedBaseModelPath && configuredBaseModelPath && resolve2(recordedBaseModelPath) !== configuredBaseModelPath) {
592
641
  throw new Error(
593
642
  `Configured paths.baseModel ${configuredBaseModelPath} does not match the base model recorded for this artifact: ` + recordedBaseModelPath
594
643
  );
595
644
  }
596
645
  const localBaseModelPath = recordedBaseModelPath ?? configuredBaseModelPath;
597
- const requestedBaseModelRevision = resolveRequestedBaseModelRevision(
646
+ const requestedBaseModelRevision = args.foundation ? void 0 : resolveRequestedBaseModelRevision(
598
647
  args.baseModel,
599
648
  options.baseModelRevision
600
649
  );
@@ -610,7 +659,11 @@ function buildModelServerLaunch(args) {
610
659
  TT_MODEL_NAME: args.modelName,
611
660
  TT_CONTEXT_LENGTH: String(contextLength),
612
661
  TT_GPU_MEMORY_UTILIZATION: String(gpuMemoryUtilization),
613
- TT_MODEL_LOADER: resolveModelLoader(args.baseModel),
662
+ TT_MODEL_LOADER: args.foundation ? "foundation" : resolveModelLoader(args.baseModel),
663
+ ...args.foundation ? {
664
+ TT_FOUNDATION_CHECKPOINT: args.foundation.checkpoint,
665
+ TT_FOUNDATION_TOKENIZER: args.foundation.tokenizer
666
+ } : {},
614
667
  TT_HOST: host,
615
668
  TT_PORT: String(port),
616
669
  TT_DEVICE: device,
@@ -710,16 +763,32 @@ async function serveLocalModel(launch) {
710
763
  });
711
764
  });
712
765
  }
766
+ function buildFoundationModelServerLaunch(args) {
767
+ const checkpoint = resolve2(args.checkpoint);
768
+ const tokenizer = resolve2(args.tokenizer);
769
+ for (const path of [join3(checkpoint, "model.safetensors"), tokenizer]) {
770
+ if (!statSync(path).isFile()) throw new Error(`Expected foundation artifact file: ${path}`);
771
+ }
772
+ const metadata = JSON.parse(readFileSync2(join3(checkpoint, "config.json"), "utf8"));
773
+ const contextLength = boundedNumber("sequence_length", metadata.sequence_length, 1, 131072, true);
774
+ return buildModelServerLaunch({
775
+ modelName: "foundation",
776
+ baseModel: "foundation",
777
+ config: args.config,
778
+ options: args.options,
779
+ foundation: { checkpoint, tokenizer, contextLength }
780
+ });
781
+ }
713
782
 
714
783
  // src/local-runtime/active-model.ts
715
784
  import { randomUUID } from "crypto";
716
785
  import { appendFile, chmod, readFile, rename, writeFile as writeFile2 } from "fs/promises";
717
- import { join as join3 } from "path";
786
+ import { join as join4 } from "path";
718
787
  function pointerPath(store) {
719
- return join3(store.root, "active-model.json");
788
+ return join4(store.root, "active-model.json");
720
789
  }
721
790
  function historyPath(store) {
722
- return join3(store.root, "activation-history.jsonl");
791
+ return join4(store.root, "activation-history.jsonl");
723
792
  }
724
793
  async function readPointer(store) {
725
794
  if (!await hardenExistingLocalStore(store.root)) return null;
@@ -759,7 +828,7 @@ async function assertModelCanActivate(store, modelId) {
759
828
  throw new Error(`Model ${model.id} belongs to run ${run.id}, which is not completed.`);
760
829
  }
761
830
  const report = runReportSchema.parse(
762
- JSON.parse(await readFile(join3(model.artifact_dir, "run-report.json"), "utf8"))
831
+ JSON.parse(await readFile(join4(model.artifact_dir, "run-report.json"), "utf8"))
763
832
  );
764
833
  if (!report.general_regression) {
765
834
  throw new Error(`Model ${model.id} has no general regression evaluation.`);
@@ -816,7 +885,7 @@ async function rollbackActiveModel(store) {
816
885
  function packageVersion() {
817
886
  try {
818
887
  const packageJson = JSON.parse(
819
- readFileSync2(resolve3(localRuntimePackageRoot(import.meta.url), "package.json"), "utf8")
888
+ readFileSync3(resolve3(localRuntimePackageRoot(import.meta.url), "package.json"), "utf8")
820
889
  );
821
890
  return typeof packageJson.version === "string" ? packageJson.version : "unknown";
822
891
  } catch {
@@ -851,7 +920,7 @@ Commands:
851
920
  hardware [--config local-runner.json] [--quick]
852
921
  validate [tunedtensor.json] [--config local-runner.json]
853
922
  run [tunedtensor.json] [--config local-runner.json] [--dry-run] [--verbose] [--quiet]
854
- serve <model-id|active|base> [--config local-runner.json] [--host 127.0.0.1] [--port 8000]
923
+ serve <model-id|active|base|foundation> [--config local-runner.json] [--host 127.0.0.1] [--port 8000]
855
924
  runs list|get|events|report|compare [args] [--config local-runner.json]
856
925
  models list|get|verify|prefetch|verify-base|active|activate|rollback|serve [args] [--config local-runner.json]
857
926
 
@@ -869,6 +938,8 @@ var VERBOSE_OPTION = { name: "--verbose", description: "Stream subprocess output
869
938
  var QUIET_OPTION = { name: "--quiet", description: "Suppress progress output on stderr" };
870
939
  var MODEL_SERVE_OPTIONS = [
871
940
  CONFIG_OPTION,
941
+ { name: "--checkpoint", value: "path", description: "Foundation model directory (target: foundation)" },
942
+ { name: "--tokenizer", value: "path", description: "Foundation tokenizer.json (target: foundation)" },
872
943
  { name: "--host", value: "host", description: "Bind host (localhost by default)" },
873
944
  { name: "--port", value: "port", description: "Bind port" },
874
945
  { name: "--device", value: "device", description: "cuda (pinned vLLM runtime)" },
@@ -876,7 +947,7 @@ var MODEL_SERVE_OPTIONS = [
876
947
  { name: "--temperature", value: "number", description: "Default sampling temperature" },
877
948
  { name: "--top-p", value: "number", description: "Default nucleus sampling threshold" },
878
949
  { name: "--max-concurrent-requests", value: "count", description: "Maximum sequences in an upstream generation batch" },
879
- { name: "--context-length", value: "count", description: "Total context token budget (default 16384)" },
950
+ { name: "--context-length", value: "count", description: "Total context token budget (foundation: checkpoint limit; otherwise 16384)" },
880
951
  { name: "--gpu-memory-utilization", value: "fraction", description: "vLLM GPU memory budget fraction (default 0.8)" },
881
952
  { name: "--spec", value: "path", description: "Behavior spec whose instructions are enforced" },
882
953
  { name: "--no-spec-prompt", description: "Do not enforce the stored behavior-spec prompt" },
@@ -939,8 +1010,8 @@ var COMMAND_DEFINITIONS = {
939
1010
  maxPositionals: 1
940
1011
  },
941
1012
  serve: {
942
- usage: "tt serve <model-id|active|base> [options]",
943
- description: "Serve a verified adapter, the active model, or the protected base.",
1013
+ usage: "tt serve <model-id|active|base|foundation> [options]",
1014
+ description: "Serve an adapter, pretrained base, or foundation checkpoint with vLLM.",
944
1015
  options: MODEL_SERVE_OPTIONS,
945
1016
  minPositionals: 1,
946
1017
  maxPositionals: 1,
@@ -1006,7 +1077,7 @@ var COMMAND_GROUPS = {
1006
1077
  maxPositionals: 0
1007
1078
  },
1008
1079
  serve: {
1009
- usage: "tt models serve <model-id|active|base> [options]",
1080
+ usage: "tt models serve <model-id|active|base|foundation> [options]",
1010
1081
  description: "Alias for `tt serve`.",
1011
1082
  options: MODEL_SERVE_OPTIONS,
1012
1083
  minPositionals: 1,
@@ -1146,7 +1217,7 @@ function readNumberOption(argv, name) {
1146
1217
  async function selectedConfigPath(argv, adjacentTo) {
1147
1218
  const explicitPath = readOption(argv, "--config");
1148
1219
  if (explicitPath) return resolve3(explicitPath);
1149
- const candidate = join4(adjacentTo ? dirname(resolve3(adjacentTo)) : cwd(), "local-runner.json");
1220
+ const candidate = join5(adjacentTo ? dirname(resolve3(adjacentTo)) : cwd(), "local-runner.json");
1150
1221
  const metadata = await stat(candidate).catch(() => null);
1151
1222
  return metadata?.isFile() ? candidate : void 0;
1152
1223
  }
@@ -1211,7 +1282,7 @@ function createConsoleReporter(options) {
1211
1282
  };
1212
1283
  }
1213
1284
  async function verifyStoredModel(model, config) {
1214
- const manifestPath = join4(model.artifact_dir, "artifact-manifest.json");
1285
+ const manifestPath = join5(model.artifact_dir, "artifact-manifest.json");
1215
1286
  const integrity = await assertArtifactManifest(manifestPath, {
1216
1287
  requiredPaths: ["stage-metadata.json", "training-report.json"],
1217
1288
  scopeToRequired: true,
@@ -1246,8 +1317,8 @@ async function verifyStoredModel(model, config) {
1246
1317
  };
1247
1318
  }
1248
1319
  async function verifyActivationEvidence(model) {
1249
- const generalBaseline = join4(model.artifact_dir, "general-baseline-eval.json");
1250
- const generalCandidate = join4(model.artifact_dir, "general-candidate-eval.json");
1320
+ const generalBaseline = join5(model.artifact_dir, "general-baseline-eval.json");
1321
+ const generalCandidate = join5(model.artifact_dir, "general-candidate-eval.json");
1251
1322
  const [hasBaseline, hasCandidate] = await Promise.all([
1252
1323
  stat(generalBaseline).then((metadata) => metadata.isFile(), () => false),
1253
1324
  stat(generalCandidate).then((metadata) => metadata.isFile(), () => false)
@@ -1257,7 +1328,7 @@ async function verifyActivationEvidence(model) {
1257
1328
  "This model cannot be activated because the run did not include a general-regression suite. Add evaluation.generalRegression to local-runner.json with a held-out dataset, re-run training, then activate. Until then, serve the adapter with `tt serve local-<run-id>`."
1258
1329
  );
1259
1330
  }
1260
- await assertArtifactManifest(join4(model.artifact_dir, "artifact-manifest.json"), {
1331
+ await assertArtifactManifest(join5(model.artifact_dir, "artifact-manifest.json"), {
1261
1332
  requiredPaths: [
1262
1333
  "run-report.json",
1263
1334
  "general-baseline-eval.json",
@@ -1283,7 +1354,7 @@ async function verifyModelArtifactPath(input, config) {
1283
1354
  if (!metadata) throw new Error(`Model not found and artifact path does not exist: ${input}`);
1284
1355
  let current = metadata.isDirectory() ? inputPath : dirname(inputPath);
1285
1356
  for (let depth = 0; depth < 8; depth += 1) {
1286
- const candidate = join4(current, "artifact-manifest.json");
1357
+ const candidate = join5(current, "artifact-manifest.json");
1287
1358
  const raw = await readFile2(candidate, "utf8").catch(() => null);
1288
1359
  if (raw) {
1289
1360
  const parsed = JSON.parse(raw);
@@ -1337,11 +1408,11 @@ async function modelSystemPrompt(args) {
1337
1408
  throw new Error(`--spec must contain a tunedtensor.json behavior spec: ${resolve3(specPath)}`);
1338
1409
  }
1339
1410
  if (isFoundationSpecFile(local.data)) {
1340
- throw new Error("Foundation specs have no Hugging Face base model. `tt serve` cannot host them yet.");
1411
+ throw new Error("Foundation specs have no Hugging Face base model. Use `tt serve foundation --checkpoint <model-dir> --tokenizer <tokenizer.json>`.");
1341
1412
  }
1342
1413
  spec = local.data;
1343
1414
  } else {
1344
- const runRequestPath = join4(args.store.paths.runsDir, args.model.run_id, "request.json");
1415
+ const runRequestPath = join5(args.store.paths.runsDir, args.model.run_id, "request.json");
1345
1416
  let persistedRequest = null;
1346
1417
  try {
1347
1418
  persistedRequest = fineTuneRunRequestSchema.parse(JSON.parse(await readFile2(runRequestPath, "utf8")));
@@ -1357,7 +1428,7 @@ async function modelSystemPrompt(args) {
1357
1428
  }
1358
1429
  const prompt = buildSystemMessage(spec);
1359
1430
  const metadata = JSON.parse(
1360
- await readFile2(join4(args.model.artifact_dir, "stage-metadata.json"), "utf8")
1431
+ await readFile2(join5(args.model.artifact_dir, "stage-metadata.json"), "utf8")
1361
1432
  );
1362
1433
  const promptHash = createHash2("sha256").update(prompt).digest("hex");
1363
1434
  if (metadata.system_prompt_sha256 !== promptHash) {
@@ -1400,7 +1471,7 @@ function printServeClientConfig(argv, launch) {
1400
1471
  supportsUsageInStreaming: true,
1401
1472
  maxTokensField: "max_tokens"
1402
1473
  },
1403
- models: [.../* @__PURE__ */ new Set([launch.modelName, `base:${launch.env.TT_BASE_MODEL}`])].map((id) => ({
1474
+ models: [...new Set(launch.env.TT_FOUNDATION_CHECKPOINT ? [launch.modelName] : [launch.modelName, `base:${launch.env.TT_BASE_MODEL}`])].map((id) => ({
1404
1475
  id,
1405
1476
  name: id,
1406
1477
  // This endpoint exports ordinary text/tool calls, not reasoning-effort controls.
@@ -1488,7 +1559,7 @@ async function serveBaseModelFromCli(args) {
1488
1559
  JSON.parse(await readFile2(specPath, "utf8"))
1489
1560
  ) : void 0;
1490
1561
  if (spec && isFoundationSpecFile(spec)) {
1491
- throw new Error("Foundation specs have no Hugging Face base model. `tt serve` cannot host them yet.");
1562
+ throw new Error("Foundation specs have no Hugging Face base model. Use `tt serve foundation --checkpoint <model-dir> --tokenizer <tokenizer.json>`.");
1492
1563
  }
1493
1564
  let baseModel = spec?.base_model;
1494
1565
  if (!baseModel) {
@@ -1525,6 +1596,45 @@ async function serveBaseModelFromCli(args) {
1525
1596
  await serveLocalModel(launch);
1526
1597
  }
1527
1598
  async function serveModelTargetFromCli(args) {
1599
+ if (args.target === "foundation") {
1600
+ const checkpoint = readOption(args.argv, "--checkpoint");
1601
+ const tokenizer = readOption(args.argv, "--tokenizer");
1602
+ if (!checkpoint || !tokenizer) {
1603
+ throw new Error("Foundation serving requires --checkpoint <model-dir> and --tokenizer <tokenizer.json>.");
1604
+ }
1605
+ const specPath = readOption(args.argv, "--spec");
1606
+ if (specPath && hasFlag(args.argv, "--no-spec-prompt")) {
1607
+ throw new Error("Use only one of --spec or --no-spec-prompt.");
1608
+ }
1609
+ const spec = specPath ? localBehaviorSpecFileSchema.parse(JSON.parse(await readFile2(resolve3(specPath), "utf8"))) : void 0;
1610
+ if (spec && !isFoundationSpecFile(spec)) throw new Error("Foundation serving requires a foundation spec.");
1611
+ const launch = buildFoundationModelServerLaunch({
1612
+ checkpoint,
1613
+ tokenizer,
1614
+ config: args.config,
1615
+ options: {
1616
+ ...serveOptionsFromArgv(args.argv),
1617
+ systemPrompt: spec ? buildSystemMessage(spec) : void 0
1618
+ }
1619
+ });
1620
+ if (printServeClientConfig(args.argv, launch)) return;
1621
+ if (hasFlag(args.argv, "--print-command")) {
1622
+ printJson({
1623
+ ok: true,
1624
+ model_id: launch.modelName,
1625
+ url: launch.url,
1626
+ command: launch.displayCommand,
1627
+ checkpoint: launch.env.TT_FOUNDATION_CHECKPOINT,
1628
+ tokenizer: launch.env.TT_FOUNDATION_TOKENIZER
1629
+ });
1630
+ return;
1631
+ }
1632
+ await serveLocalModel(launch);
1633
+ return;
1634
+ }
1635
+ if (readOption(args.argv, "--checkpoint") || readOption(args.argv, "--tokenizer")) {
1636
+ throw new Error("--checkpoint and --tokenizer require the foundation target.");
1637
+ }
1528
1638
  if (args.target === "base") {
1529
1639
  return serveBaseModelFromCli(args);
1530
1640
  }
@@ -1903,6 +2013,7 @@ export {
1903
2013
  baseModelRevisionSchema,
1904
2014
  behaviorSpecExampleSchema,
1905
2015
  behaviorSpecSchema,
2016
+ buildFoundationModelServerLaunch,
1906
2017
  buildLocalBaseModelServerLaunch,
1907
2018
  buildLocalModelServerLaunch,
1908
2019
  buildModelPrefetchPayload,