@runtypelabs/cli 2.17.0 → 2.18.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.
Files changed (2) hide show
  1. package/dist/index.js +1737 -600
  2. package/package.json +6 -5
package/dist/index.js CHANGED
@@ -68,9 +68,9 @@ var init_credential_store = __esm({
68
68
  }
69
69
  }
70
70
  getMachineKey() {
71
- const hostname3 = os.hostname();
71
+ const hostname4 = os.hostname();
72
72
  const username = os.userInfo().username;
73
- return crypto3.createHash("sha256").update(`runtype-cli-${hostname3}-${username}`).digest("hex").substring(0, 32);
73
+ return crypto3.createHash("sha256").update(`runtype-cli-${hostname4}-${username}`).digest("hex").substring(0, 32);
74
74
  }
75
75
  async saveCredentials(credentials) {
76
76
  const configData = {
@@ -131,15 +131,15 @@ var init_credential_store = __esm({
131
131
  });
132
132
 
133
133
  // src/index.ts
134
- import { Command as Command32 } from "commander";
135
- import chalk41 from "chalk";
134
+ import { Command as Command33 } from "commander";
135
+ import chalk42 from "chalk";
136
136
 
137
137
  // src/lib/load-env.ts
138
138
  import { readFileSync } from "fs";
139
139
  import { resolve } from "path";
140
- function loadEnv(path17 = resolve(process.cwd(), ".env")) {
140
+ function loadEnv(path18 = resolve(process.cwd(), ".env")) {
141
141
  try {
142
- const content = readFileSync(path17, "utf8").replace(/\r\n?/g, "\n");
142
+ const content = readFileSync(path18, "utf8").replace(/\r\n?/g, "\n");
143
143
  for (const line of content.split("\n")) {
144
144
  if (!line.trim() || line.trimStart().startsWith("#")) continue;
145
145
  const match = line.match(/^\s*([\w.-]+)\s*=\s*(.*)?\s*$/);
@@ -174,8 +174,8 @@ var CallbackServer = class {
174
174
  expectedState;
175
175
  constructor() {
176
176
  this.app = express();
177
- this.codePromise = new Promise((resolve10, reject) => {
178
- this.codeResolve = resolve10;
177
+ this.codePromise = new Promise((resolve11, reject) => {
178
+ this.codeResolve = resolve11;
179
179
  this.codeReject = reject;
180
180
  });
181
181
  this.app.get("/callback", (req, res) => {
@@ -1381,10 +1381,10 @@ function mergeDefs(...defs) {
1381
1381
  function cloneDef(schema) {
1382
1382
  return mergeDefs(schema._zod.def);
1383
1383
  }
1384
- function getElementAtPath(obj, path17) {
1385
- if (!path17)
1384
+ function getElementAtPath(obj, path18) {
1385
+ if (!path18)
1386
1386
  return obj;
1387
- return path17.reduce((acc, key) => acc?.[key], obj);
1387
+ return path18.reduce((acc, key) => acc?.[key], obj);
1388
1388
  }
1389
1389
  function promiseAllObject(promisesObj) {
1390
1390
  const keys = Object.keys(promisesObj);
@@ -1793,11 +1793,11 @@ function explicitlyAborted(x2, startIndex = 0) {
1793
1793
  }
1794
1794
  return false;
1795
1795
  }
1796
- function prefixIssues(path17, issues) {
1796
+ function prefixIssues(path18, issues) {
1797
1797
  return issues.map((iss) => {
1798
1798
  var _a3;
1799
1799
  (_a3 = iss).path ?? (_a3.path = []);
1800
- iss.path.unshift(path17);
1800
+ iss.path.unshift(path18);
1801
1801
  return iss;
1802
1802
  });
1803
1803
  }
@@ -1944,16 +1944,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
1944
1944
  }
1945
1945
  function formatError(error51, mapper = (issue2) => issue2.message) {
1946
1946
  const fieldErrors = { _errors: [] };
1947
- const processError = (error52, path17 = []) => {
1947
+ const processError = (error52, path18 = []) => {
1948
1948
  for (const issue2 of error52.issues) {
1949
1949
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1950
- issue2.errors.map((issues) => processError({ issues }, [...path17, ...issue2.path]));
1950
+ issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
1951
1951
  } else if (issue2.code === "invalid_key") {
1952
- processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1952
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1953
1953
  } else if (issue2.code === "invalid_element") {
1954
- processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1954
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1955
1955
  } else {
1956
- const fullpath = [...path17, ...issue2.path];
1956
+ const fullpath = [...path18, ...issue2.path];
1957
1957
  if (fullpath.length === 0) {
1958
1958
  fieldErrors._errors.push(mapper(issue2));
1959
1959
  } else {
@@ -1980,17 +1980,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
1980
1980
  }
1981
1981
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
1982
1982
  const result = { errors: [] };
1983
- const processError = (error52, path17 = []) => {
1983
+ const processError = (error52, path18 = []) => {
1984
1984
  var _a3, _b;
1985
1985
  for (const issue2 of error52.issues) {
1986
1986
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1987
- issue2.errors.map((issues) => processError({ issues }, [...path17, ...issue2.path]));
1987
+ issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
1988
1988
  } else if (issue2.code === "invalid_key") {
1989
- processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1989
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1990
1990
  } else if (issue2.code === "invalid_element") {
1991
- processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1991
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1992
1992
  } else {
1993
- const fullpath = [...path17, ...issue2.path];
1993
+ const fullpath = [...path18, ...issue2.path];
1994
1994
  if (fullpath.length === 0) {
1995
1995
  result.errors.push(mapper(issue2));
1996
1996
  continue;
@@ -2022,8 +2022,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
2022
2022
  }
2023
2023
  function toDotPath(_path) {
2024
2024
  const segs = [];
2025
- const path17 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
2026
- for (const seg of path17) {
2025
+ const path18 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
2026
+ for (const seg of path18) {
2027
2027
  if (typeof seg === "number")
2028
2028
  segs.push(`[${seg}]`);
2029
2029
  else if (typeof seg === "symbol")
@@ -14709,13 +14709,13 @@ function resolveRef(ref, ctx) {
14709
14709
  if (!ref.startsWith("#")) {
14710
14710
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14711
14711
  }
14712
- const path17 = ref.slice(1).split("/").filter(Boolean);
14713
- if (path17.length === 0) {
14712
+ const path18 = ref.slice(1).split("/").filter(Boolean);
14713
+ if (path18.length === 0) {
14714
14714
  return ctx.rootSchema;
14715
14715
  }
14716
14716
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14717
- if (path17[0] === defsKey) {
14718
- const key = path17[1];
14717
+ if (path18[0] === defsKey) {
14718
+ const key = path18[1];
14719
14719
  if (!key || !ctx.defs[key]) {
14720
14720
  throw new Error(`Reference not found: ${ref}`);
14721
14721
  }
@@ -15160,8 +15160,8 @@ var apiRoutingDocSchema = external_exports.object({
15160
15160
  });
15161
15161
 
15162
15162
  // ../shared/dist/chunk-3V2W6XMX.mjs
15163
- function getNestedValue(obj, path17) {
15164
- let normalizedPath = path17;
15163
+ function getNestedValue(obj, path18) {
15164
+ let normalizedPath = path18;
15165
15165
  normalizedPath = normalizedPath.replace(/^\$\.?/, "");
15166
15166
  normalizedPath = normalizedPath.replace(/\[(\d+)\]/g, ".$1");
15167
15167
  normalizedPath = normalizedPath.replace(/\[['"]([^'"\]]+)['"]\]/g, ".$1");
@@ -16095,6 +16095,27 @@ var artifactSSEEventSchema = external_exports.discriminatedUnion("type", [
16095
16095
  artifactCompleteEventSchema,
16096
16096
  artifactSingleEventSchema
16097
16097
  ]);
16098
+ var AGENT_CONTENT_CONFIG_KEYS = {
16099
+ model: true,
16100
+ systemPrompt: true,
16101
+ temperature: true,
16102
+ topP: true,
16103
+ topK: true,
16104
+ frequencyPenalty: true,
16105
+ presencePenalty: true,
16106
+ seed: true,
16107
+ tools: true,
16108
+ reasoning: true,
16109
+ advisor: true,
16110
+ loopConfig: true,
16111
+ voice: true,
16112
+ errorHandling: true,
16113
+ artifacts: true,
16114
+ loggingPolicy: true,
16115
+ temporal: true,
16116
+ memory: true
16117
+ };
16118
+ var AGENT_CONTENT_CONFIG_KEY_LIST = Object.keys(AGENT_CONTENT_CONFIG_KEYS).sort();
16098
16119
  var configurationStatusSchema = external_exports.enum([
16099
16120
  "configured",
16100
16121
  "needs_configuration",
@@ -17594,6 +17615,10 @@ var runtimeArtifactSandboxSchema = external_exports.enum([
17594
17615
  var runtimeArtifactServiceBackingSchema = external_exports.enum(["none", "service-binding"]);
17595
17616
  var runtimeArtifactPersistenceSchema = external_exports.enum(["none", "kv", "service-binding"]);
17596
17617
  var runtimeArtifactKeyModeSchema = external_exports.enum(["own", "platform", "hybrid"]);
17618
+ var runtimeArtifactServiceBindingTargetSchema = external_exports.string().regex(
17619
+ /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/,
17620
+ "Service binding target must be a Cloudflare service name (lowercase letters, numbers, and hyphens; no leading/trailing hyphen)."
17621
+ );
17597
17622
  var runtimeArtifactBindingTypeSchema = external_exports.enum([
17598
17623
  "service",
17599
17624
  "kv_namespace",
@@ -17613,6 +17638,13 @@ var runtimeArtifactBindingSchema = external_exports.object({
17613
17638
  type: runtimeArtifactBindingTypeSchema,
17614
17639
  target: external_exports.string().min(1).optional(),
17615
17640
  optional: external_exports.boolean().optional()
17641
+ }).superRefine((binding, ctx) => {
17642
+ if (binding.type !== "service" || binding.target === void 0) return;
17643
+ const parsed = runtimeArtifactServiceBindingTargetSchema.safeParse(binding.target);
17644
+ if (parsed.success) return;
17645
+ for (const issue2 of parsed.error.issues) {
17646
+ ctx.addIssue({ ...issue2, path: ["target", ...issue2.path] });
17647
+ }
17616
17648
  });
17617
17649
  var runtimeArtifactEligibilityReasonSchema = external_exports.object({
17618
17650
  code: external_exports.string().min(1),
@@ -33460,9 +33492,9 @@ var DEFAULT_MODELS_FOR_NEW_ACCOUNTS = [
33460
33492
  { provider: "runtype", modelId: "gemini-3-1-flash-lite", isDefault: false },
33461
33493
  { provider: "runtype", modelId: "gemini-3-1-flash-image", isDefault: false },
33462
33494
  { provider: "runtype", modelId: "gemini-3.1-pro", isDefault: false },
33463
- // xAI models (routed via xAI direct, with Vercel fallback)
33464
- { provider: "runtype", modelId: "grok-4", isDefault: false },
33465
- { provider: "runtype", modelId: "grok-4-fast", isDefault: false },
33495
+ // xAI models (routed via Vercel, with xAI fallback when available)
33496
+ { provider: "runtype", modelId: "grok-4.3", isDefault: false },
33497
+ { provider: "runtype", modelId: "grok-4.1-fast-non-reasoning", isDefault: false },
33466
33498
  // Inception models (routed via Vercel)
33467
33499
  { provider: "runtype", modelId: "mercury-2", isDefault: false },
33468
33500
  // Moonshot models (routed via Cloudflare Workers AI)
@@ -33486,13 +33518,8 @@ var userProfileFeaturesSchema = external_exports.object({
33486
33518
  dashboardAssistantModel: external_exports.string()
33487
33519
  });
33488
33520
  var MODEL_FAMILY_PROVIDER_IDS = {
33489
- "claude-4-opus": {
33490
- "vercel": "anthropic/claude-4-opus"
33491
- },
33492
- "claude-4-sonnet": {
33493
- "vercel": "anthropic/claude-4-sonnet"
33494
- },
33495
33521
  "claude-fable-5": {
33522
+ "anthropic": "claude-fable-5",
33496
33523
  "vercel": "anthropic/claude-fable-5"
33497
33524
  },
33498
33525
  "claude-haiku-4-5": {
@@ -33507,12 +33534,13 @@ var MODEL_FAMILY_PROVIDER_IDS = {
33507
33534
  },
33508
33535
  "claude-opus-4": {
33509
33536
  "anthropic": "claude-opus-4-20250514",
33510
- "bedrock": "bedrock/claude-opus-4",
33511
33537
  "vercel": "anthropic/claude-opus-4"
33512
33538
  },
33539
+ "claude-opus-4-0": {
33540
+ "anthropic": "claude-opus-4-0"
33541
+ },
33513
33542
  "claude-opus-4-1": {
33514
33543
  "anthropic": "claude-opus-4-1-20250805",
33515
- "bedrock": "bedrock/claude-opus-4-1",
33516
33544
  "vercel": "anthropic/claude-opus-4.1"
33517
33545
  },
33518
33546
  "claude-opus-4-1-20250805": {
@@ -33522,17 +33550,22 @@ var MODEL_FAMILY_PROVIDER_IDS = {
33522
33550
  "anthropic": "claude-opus-4-20250514"
33523
33551
  },
33524
33552
  "claude-opus-4-5": {
33525
- "anthropic": "anthropic/claude-opus-4-5",
33553
+ "anthropic": "claude-opus-4-5-20251101",
33526
33554
  "vercel": "anthropic/claude-opus-4.5"
33527
33555
  },
33556
+ "claude-opus-4-5-20251101": {
33557
+ "anthropic": "claude-opus-4-5-20251101"
33558
+ },
33528
33559
  "claude-opus-4-6": {
33529
- "anthropic": "anthropic/claude-opus-4-6",
33560
+ "anthropic": "claude-opus-4-6",
33530
33561
  "vercel": "anthropic/claude-opus-4.6"
33531
33562
  },
33532
33563
  "claude-opus-4-7": {
33564
+ "anthropic": "claude-opus-4-7",
33533
33565
  "vercel": "anthropic/claude-opus-4.7"
33534
33566
  },
33535
33567
  "claude-opus-4-8": {
33568
+ "anthropic": "claude-opus-4-8",
33536
33569
  "vercel": "anthropic/claude-opus-4.8"
33537
33570
  },
33538
33571
  "claude-opus-4.1": {
@@ -33552,9 +33585,11 @@ var MODEL_FAMILY_PROVIDER_IDS = {
33552
33585
  },
33553
33586
  "claude-sonnet-4": {
33554
33587
  "anthropic": "claude-sonnet-4-20250514",
33555
- "bedrock": "bedrock/claude-sonnet-4",
33556
33588
  "vercel": "anthropic/claude-sonnet-4"
33557
33589
  },
33590
+ "claude-sonnet-4-0": {
33591
+ "anthropic": "claude-sonnet-4-0"
33592
+ },
33558
33593
  "claude-sonnet-4-20250514": {
33559
33594
  "anthropic": "claude-sonnet-4-20250514"
33560
33595
  },
@@ -33566,12 +33601,9 @@ var MODEL_FAMILY_PROVIDER_IDS = {
33566
33601
  "anthropic": "claude-sonnet-4-5-20250929"
33567
33602
  },
33568
33603
  "claude-sonnet-4-6": {
33569
- "anthropic": "claude-sonnet-4-6-20260217",
33604
+ "anthropic": "claude-sonnet-4-6",
33570
33605
  "vercel": "anthropic/claude-sonnet-4.6"
33571
33606
  },
33572
- "claude-sonnet-4-6-20260217": {
33573
- "anthropic": "claude-sonnet-4-6-20260217"
33574
- },
33575
33607
  "claude-sonnet-4.5": {
33576
33608
  "vercel": "anthropic/claude-sonnet-4.5"
33577
33609
  },
@@ -33584,36 +33616,40 @@ var MODEL_FAMILY_PROVIDER_IDS = {
33584
33616
  "codestral-embed": {
33585
33617
  "vercel": "mistral/codestral-embed"
33586
33618
  },
33619
+ "cogito-v2-1-671b": {
33620
+ "togetherai": "togetherai/deepcogito/cogito-v2-1-671b"
33621
+ },
33587
33622
  "command-a": {
33588
33623
  "vercel": "cohere/command-a"
33589
33624
  },
33590
- "command-r": {
33591
- "vercel": "cohere/command-r"
33592
- },
33593
- "command-r-plus": {
33594
- "vercel": "cohere/command-r-plus"
33625
+ "deepcogito/cogito-v2-1-671b": {
33626
+ "togetherai": "togetherai/deepcogito/cogito-v2-1-671b"
33595
33627
  },
33596
33628
  "deepseek": {
33597
- "togetherai": "deepseek-ai/DeepSeek-V3",
33629
+ "togetherai": "togetherai/deepseek-ai/DeepSeek-V3",
33598
33630
  "vercel": "deepseek/deepseek-v3"
33599
33631
  },
33600
- "deepseek-r1": {
33601
- "togetherai": "deepseek-ai/DeepSeek-R1",
33602
- "vercel": "deepseek/deepseek-r1"
33632
+ "deepseek-ai/DeepSeek-R1": {
33633
+ "togetherai": "togetherai/deepseek-ai/DeepSeek-R1"
33603
33634
  },
33604
- "DeepSeek-R1": {
33605
- "togetherai": "deepseek-ai/DeepSeek-R1"
33635
+ "deepseek-ai/DeepSeek-V3": {
33636
+ "togetherai": "togetherai/deepseek-ai/DeepSeek-V3"
33637
+ },
33638
+ "deepseek-ai/DeepSeek-V3-1": {
33639
+ "togetherai": "togetherai/deepseek-ai/DeepSeek-V3-1"
33640
+ },
33641
+ "deepseek-ai/DeepSeek-V4-Pro": {
33642
+ "togetherai": "togetherai/deepseek-ai/DeepSeek-V4-Pro"
33606
33643
  },
33607
- "deepseek-r1-distill-llama-70b": {
33608
- "vercel": "deepseek/deepseek-r1-distill-llama-70b"
33644
+ "deepseek-r1": {
33645
+ "togetherai": "togetherai/deepseek-ai/DeepSeek-R1",
33646
+ "vercel": "deepseek/deepseek-r1"
33609
33647
  },
33610
33648
  "deepseek-v3": {
33611
33649
  "vercel": "deepseek/deepseek-v3"
33612
33650
  },
33613
- "DeepSeek-V3": {
33614
- "togetherai": "deepseek-ai/DeepSeek-V3"
33615
- },
33616
33651
  "deepseek-v3-1": {
33652
+ "togetherai": "togetherai/deepseek-ai/DeepSeek-V3-1",
33617
33653
  "vercel": "deepseek/deepseek-v3.1"
33618
33654
  },
33619
33655
  "deepseek-v3-1-terminus": {
@@ -33638,6 +33674,7 @@ var MODEL_FAMILY_PROVIDER_IDS = {
33638
33674
  "vercel": "deepseek/deepseek-v4-flash"
33639
33675
  },
33640
33676
  "deepseek-v4-pro": {
33677
+ "togetherai": "togetherai/deepseek-ai/DeepSeek-V4-Pro",
33641
33678
  "vercel": "deepseek/deepseek-v4-pro"
33642
33679
  },
33643
33680
  "devstral-2": {
@@ -33655,91 +33692,162 @@ var MODEL_FAMILY_PROVIDER_IDS = {
33655
33692
  "embed-v4.0": {
33656
33693
  "vercel": "cohere/embed-v4.0"
33657
33694
  },
33695
+ "essentialai/Rnj-1-Instruct": {
33696
+ "togetherai": "togetherai/essentialai/Rnj-1-Instruct"
33697
+ },
33698
+ "flux-2-flex": {
33699
+ "vercel": "bfl/flux-2-flex"
33700
+ },
33701
+ "flux-2-klein-4b": {
33702
+ "vercel": "bfl/flux-2-klein-4b"
33703
+ },
33704
+ "flux-2-klein-9b": {
33705
+ "vercel": "bfl/flux-2-klein-9b"
33706
+ },
33707
+ "flux-2-max": {
33708
+ "vercel": "bfl/flux-2-max"
33709
+ },
33710
+ "flux-2-pro": {
33711
+ "vercel": "bfl/flux-2-pro"
33712
+ },
33713
+ "flux-fast-schnell": {
33714
+ "vercel": "prodia/flux-fast-schnell"
33715
+ },
33716
+ "flux-kontext-max": {
33717
+ "vercel": "bfl/flux-kontext-max"
33718
+ },
33719
+ "flux-kontext-pro": {
33720
+ "vercel": "bfl/flux-kontext-pro"
33721
+ },
33722
+ "flux-pro-1-0-fill": {
33723
+ "vercel": "bfl/flux-pro-1.0-fill"
33724
+ },
33725
+ "flux-pro-1-1": {
33726
+ "vercel": "bfl/flux-pro-1.1"
33727
+ },
33728
+ "flux-pro-1-1-ultra": {
33729
+ "vercel": "bfl/flux-pro-1.1-ultra"
33730
+ },
33731
+ "flux-pro-1.0-fill": {
33732
+ "vercel": "bfl/flux-pro-1.0-fill"
33733
+ },
33734
+ "flux-pro-1.1": {
33735
+ "vercel": "bfl/flux-pro-1.1"
33736
+ },
33737
+ "flux-pro-1.1-ultra": {
33738
+ "vercel": "bfl/flux-pro-1.1-ultra"
33739
+ },
33658
33740
  "gemini-2-5-flash": {
33659
- "google": "google/gemini-2.5-flash-preview",
33660
- "vercel": "google/gemini-2-5-flash"
33741
+ "google": "gemini-2.5-flash",
33742
+ "vercel": "google/gemini-2.5-flash"
33661
33743
  },
33662
33744
  "gemini-2-5-flash-image": {
33663
33745
  "google": "google/gemini-2.5-flash-image-preview",
33664
33746
  "vercel": "google/gemini-2.5-flash-image"
33665
33747
  },
33666
33748
  "gemini-2-5-flash-lite": {
33749
+ "google": "gemini-2.5-flash-lite",
33667
33750
  "vercel": "google/gemini-2.5-flash-lite"
33668
33751
  },
33669
- "gemini-2-5-flash-preview-image": {
33670
- "google": "google/gemini-2.5-flash-preview-image"
33752
+ "gemini-2-5-flash-preview-tts": {
33753
+ "google": "gemini-2.5-flash-preview-tts"
33671
33754
  },
33672
33755
  "gemini-2-5-pro": {
33673
33756
  "google": "gemini-2.5-pro",
33674
- "vercel": "google/gemini-2-5-pro"
33757
+ "vercel": "google/gemini-2.5-pro"
33758
+ },
33759
+ "gemini-2-5-pro-preview-tts": {
33760
+ "google": "gemini-2.5-pro-preview-tts"
33675
33761
  },
33676
33762
  "gemini-2.5-flash": {
33677
33763
  "google": "gemini-2.5-flash",
33678
33764
  "vercel": "google/gemini-2.5-flash"
33679
33765
  },
33680
33766
  "gemini-2.5-flash-image": {
33767
+ "google": "gemini-2.5-flash-image",
33681
33768
  "vercel": "google/gemini-2.5-flash-image"
33682
33769
  },
33683
33770
  "gemini-2.5-flash-image-preview": {
33684
33771
  "google": "google/gemini-2.5-flash-image-preview"
33685
33772
  },
33686
33773
  "gemini-2.5-flash-lite": {
33774
+ "google": "gemini-2.5-flash-lite",
33687
33775
  "vercel": "google/gemini-2.5-flash-lite"
33688
33776
  },
33689
- "gemini-2.5-flash-preview": {
33690
- "google": "google/gemini-2.5-flash-preview"
33691
- },
33692
- "gemini-2.5-flash-preview-image": {
33693
- "google": "google/gemini-2.5-flash-preview-image"
33777
+ "gemini-2.5-flash-preview-tts": {
33778
+ "google": "gemini-2.5-flash-preview-tts"
33694
33779
  },
33695
33780
  "gemini-2.5-pro": {
33696
33781
  "google": "gemini-2.5-pro",
33697
33782
  "vercel": "google/gemini-2.5-pro"
33698
33783
  },
33784
+ "gemini-2.5-pro-preview-tts": {
33785
+ "google": "gemini-2.5-pro-preview-tts"
33786
+ },
33699
33787
  "gemini-3-1-flash-image": {
33700
33788
  "vercel": "google/gemini-3.1-flash-image"
33701
33789
  },
33702
33790
  "gemini-3-1-flash-lite": {
33791
+ "google": "gemini-3.1-flash-lite",
33703
33792
  "vercel": "google/gemini-3.1-flash-lite"
33704
33793
  },
33705
33794
  "gemini-3-1-pro": {
33795
+ "google": "gemini-3.1-pro-preview",
33706
33796
  "vercel": "google/gemini-3.1-pro-preview"
33707
33797
  },
33798
+ "gemini-3-1-pro-preview-customtools": {
33799
+ "google": "gemini-3.1-pro-preview-customtools"
33800
+ },
33708
33801
  "gemini-3-5-flash": {
33802
+ "google": "gemini-3.5-flash",
33709
33803
  "vercel": "google/gemini-3.5-flash"
33710
33804
  },
33711
33805
  "gemini-3-flash": {
33712
- "google": "google/gemini-3-flash-preview",
33806
+ "google": "gemini-3-flash-preview",
33713
33807
  "vercel": "google/gemini-3-flash"
33714
33808
  },
33715
33809
  "gemini-3-flash-preview": {
33716
- "google": "google/gemini-3-flash-preview"
33810
+ "google": "gemini-3-flash-preview"
33717
33811
  },
33718
33812
  "gemini-3-pro-image": {
33813
+ "google": "gemini-3-pro-image-preview",
33719
33814
  "vercel": "google/gemini-3-pro-image"
33720
33815
  },
33816
+ "gemini-3-pro-image-preview": {
33817
+ "google": "gemini-3-pro-image-preview"
33818
+ },
33721
33819
  "gemini-3.1-flash-image": {
33722
33820
  "vercel": "google/gemini-3.1-flash-image"
33723
33821
  },
33724
33822
  "gemini-3.1-flash-lite": {
33823
+ "google": "gemini-3.1-flash-lite",
33725
33824
  "vercel": "google/gemini-3.1-flash-lite"
33726
33825
  },
33727
33826
  "gemini-3.1-pro-preview": {
33827
+ "google": "gemini-3.1-pro-preview",
33728
33828
  "vercel": "google/gemini-3.1-pro-preview"
33729
33829
  },
33830
+ "gemini-3.1-pro-preview-customtools": {
33831
+ "google": "gemini-3.1-pro-preview-customtools"
33832
+ },
33730
33833
  "gemini-3.5-flash": {
33834
+ "google": "gemini-3.5-flash",
33731
33835
  "vercel": "google/gemini-3.5-flash"
33732
33836
  },
33733
33837
  "gemini-embedding-001": {
33838
+ "google": "gemini-embedding-001",
33734
33839
  "vercel": "google/gemini-embedding-001"
33735
33840
  },
33736
33841
  "gemini-embedding-2": {
33737
33842
  "vercel": "google/gemini-embedding-2"
33738
33843
  },
33739
33844
  "gemma-4-26b-a4b-it": {
33845
+ "google": "gemma-4-26b-a4b-it",
33740
33846
  "vercel": "google/gemma-4-26b-a4b-it"
33741
33847
  },
33742
33848
  "gemma-4-31b-it": {
33849
+ "google": "gemma-4-31b-it",
33850
+ "togetherai": "togetherai/pearl-ai/gemma-4-31b-it",
33743
33851
  "vercel": "google/gemma-4-31b-it"
33744
33852
  },
33745
33853
  "glm-4-5": {
@@ -33797,9 +33905,11 @@ var MODEL_FAMILY_PROVIDER_IDS = {
33797
33905
  "vercel": "zai/glm-4.7-flashx"
33798
33906
  },
33799
33907
  "glm-5": {
33908
+ "togetherai": "togetherai/zai-org/GLM-5",
33800
33909
  "vercel": "zai/glm-5"
33801
33910
  },
33802
33911
  "glm-5-1": {
33912
+ "togetherai": "togetherai/zai-org/GLM-5.1",
33803
33913
  "vercel": "zai/glm-5.1"
33804
33914
  },
33805
33915
  "glm-5-turbo": {
@@ -33811,87 +33921,47 @@ var MODEL_FAMILY_PROVIDER_IDS = {
33811
33921
  "glm-5v-turbo": {
33812
33922
  "vercel": "zai/glm-5v-turbo"
33813
33923
  },
33924
+ "google/gemma-4-31B-it": {
33925
+ "togetherai": "togetherai/google/gemma-4-31B-it"
33926
+ },
33814
33927
  "gpt-4-1": {
33815
33928
  "openai": "gpt-4.1",
33816
- "vercel": "openai/gpt-4-1"
33817
- },
33818
- "gpt-4-1-batch": {
33819
- "openai": "gpt-4.1-batch"
33929
+ "vercel": "openai/gpt-4.1"
33820
33930
  },
33821
33931
  "gpt-4-1-mini": {
33822
33932
  "openai": "gpt-4.1-mini",
33823
- "vercel": "openai/gpt-4-1-mini"
33824
- },
33825
- "gpt-4-1-mini-batch": {
33826
- "openai": "gpt-4.1-mini-batch"
33933
+ "vercel": "openai/gpt-4.1-mini"
33827
33934
  },
33828
33935
  "gpt-4-1-nano": {
33829
33936
  "openai": "gpt-4.1-nano",
33830
- "vercel": "openai/gpt-4-1-nano"
33831
- },
33832
- "gpt-4-1-nano-batch": {
33833
- "openai": "gpt-4.1-nano-batch"
33937
+ "vercel": "openai/gpt-4.1-nano"
33834
33938
  },
33835
33939
  "gpt-4.1": {
33836
33940
  "openai": "gpt-4.1",
33837
33941
  "vercel": "openai/gpt-4.1"
33838
33942
  },
33839
- "gpt-4.1-batch": {
33840
- "openai": "gpt-4.1-batch"
33841
- },
33842
33943
  "gpt-4.1-mini": {
33843
33944
  "openai": "gpt-4.1-mini",
33844
33945
  "vercel": "openai/gpt-4.1-mini"
33845
33946
  },
33846
- "gpt-4.1-mini-batch": {
33847
- "openai": "gpt-4.1-mini-batch"
33848
- },
33849
33947
  "gpt-4.1-nano": {
33850
33948
  "openai": "gpt-4.1-nano",
33851
33949
  "vercel": "openai/gpt-4.1-nano"
33852
33950
  },
33853
- "gpt-4.1-nano-batch": {
33854
- "openai": "gpt-4.1-nano-batch"
33855
- },
33856
33951
  "gpt-4o": {
33857
33952
  "openai": "gpt-4o",
33858
33953
  "vercel": "openai/gpt-4o"
33859
33954
  },
33860
- "gpt-4o-batch": {
33861
- "openai": "gpt-4o-batch"
33862
- },
33863
33955
  "gpt-4o-mini": {
33864
33956
  "openai": "gpt-4o-mini",
33865
33957
  "vercel": "openai/gpt-4o-mini"
33866
33958
  },
33867
- "gpt-4o-mini-batch": {
33868
- "openai": "gpt-4o-mini-batch"
33869
- },
33870
- "gpt-4o-mini-realtime": {
33871
- "openai": "openai/gpt-4o-mini-realtime"
33872
- },
33873
- "gpt-4o-mini-realtime-batch": {
33874
- "openai": "gpt-4o-mini-realtime-batch"
33875
- },
33876
33959
  "gpt-4o-mini-search": {
33877
- "openai": "openai/openai/gpt-4o-mini-search-preview",
33878
33960
  "vercel": "openai/gpt-4o-mini-search-preview"
33879
33961
  },
33880
33962
  "gpt-4o-mini-search-preview": {
33881
33963
  "vercel": "openai/gpt-4o-mini-search-preview"
33882
33964
  },
33883
- "gpt-4o-mini-search-preview-batch": {
33884
- "openai": "openai/gpt-4o-mini-search-preview-batch"
33885
- },
33886
- "gpt-4o-realtime": {
33887
- "openai": "openai/gpt-4o-realtime"
33888
- },
33889
- "gpt-4o-realtime-batch": {
33890
- "openai": "gpt-4o-realtime-batch"
33891
- },
33892
- "gpt-4o-search-preview-batch": {
33893
- "openai": "gpt-4o-search-preview-batch"
33894
- },
33895
33965
  "gpt-5": {
33896
33966
  "openai": "gpt-5",
33897
33967
  "vercel": "openai/gpt-5"
@@ -33900,26 +33970,18 @@ var MODEL_FAMILY_PROVIDER_IDS = {
33900
33970
  "openai": "gpt-5.1",
33901
33971
  "vercel": "openai/gpt-5.1-thinking"
33902
33972
  },
33903
- "gpt-5-1-batch": {
33904
- "openai": "gpt-5.1-batch"
33905
- },
33906
33973
  "gpt-5-1-codex": {
33907
33974
  "openai": "gpt-5.1-codex",
33908
33975
  "vercel": "openai/gpt-5.1-codex"
33909
33976
  },
33910
- "gpt-5-1-codex-batch": {
33911
- "openai": "gpt-5.1-codex-batch"
33912
- },
33913
33977
  "gpt-5-1-codex-max": {
33978
+ "openai": "gpt-5.1-codex-max",
33914
33979
  "vercel": "openai/gpt-5.1-codex-max"
33915
33980
  },
33916
33981
  "gpt-5-1-codex-mini": {
33917
33982
  "openai": "gpt-5.1-codex-mini",
33918
33983
  "vercel": "openai/gpt-5.1-codex-mini"
33919
33984
  },
33920
- "gpt-5-1-codex-mini-batch": {
33921
- "openai": "gpt-5.1-codex-mini-batch"
33922
- },
33923
33985
  "gpt-5-1-instant": {
33924
33986
  "vercel": "openai/gpt-5.1-instant"
33925
33987
  },
@@ -33927,95 +33989,85 @@ var MODEL_FAMILY_PROVIDER_IDS = {
33927
33989
  "openai": "gpt-5.2",
33928
33990
  "vercel": "openai/gpt-5.2"
33929
33991
  },
33930
- "gpt-5-2-batch": {
33931
- "openai": "gpt-5.2-batch"
33932
- },
33933
33992
  "gpt-5-2-chat": {
33934
33993
  "vercel": "openai/gpt-5.2-chat"
33935
33994
  },
33936
33995
  "gpt-5-2-codex": {
33996
+ "openai": "gpt-5.2-codex",
33937
33997
  "vercel": "openai/gpt-5.2-codex"
33938
33998
  },
33939
33999
  "gpt-5-2-pro": {
33940
34000
  "openai": "gpt-5.2-pro",
33941
34001
  "vercel": "openai/gpt-5.2-pro"
33942
34002
  },
33943
- "gpt-5-2-pro-batch": {
33944
- "openai": "gpt-5.2-pro-batch"
33945
- },
33946
34003
  "gpt-5-3-chat": {
33947
34004
  "vercel": "openai/gpt-5.3-chat"
33948
34005
  },
33949
34006
  "gpt-5-3-codex": {
34007
+ "openai": "gpt-5.3-codex",
33950
34008
  "vercel": "openai/gpt-5.3-codex"
33951
34009
  },
34010
+ "gpt-5-3-codex-spark": {
34011
+ "openai": "gpt-5.3-codex-spark"
34012
+ },
33952
34013
  "gpt-5-4": {
34014
+ "openai": "gpt-5.4",
33953
34015
  "vercel": "openai/gpt-5.4"
33954
34016
  },
33955
34017
  "gpt-5-4-mini": {
34018
+ "openai": "gpt-5.4-mini",
33956
34019
  "vercel": "openai/gpt-5.4-mini"
33957
34020
  },
33958
34021
  "gpt-5-4-nano": {
34022
+ "openai": "gpt-5.4-nano",
33959
34023
  "vercel": "openai/gpt-5.4-nano"
33960
34024
  },
33961
34025
  "gpt-5-4-pro": {
34026
+ "openai": "gpt-5.4-pro",
33962
34027
  "vercel": "openai/gpt-5.4-pro"
33963
34028
  },
33964
34029
  "gpt-5-5": {
34030
+ "openai": "gpt-5.5",
33965
34031
  "vercel": "openai/gpt-5.5"
33966
34032
  },
33967
34033
  "gpt-5-5-pro": {
34034
+ "openai": "gpt-5.5-pro",
33968
34035
  "vercel": "openai/gpt-5.5-pro"
33969
34036
  },
33970
- "gpt-5-batch": {
33971
- "openai": "gpt-5-batch"
33972
- },
33973
34037
  "gpt-5-chat": {
33974
34038
  "vercel": "openai/gpt-5-chat"
33975
34039
  },
33976
34040
  "gpt-5-codex": {
34041
+ "openai": "gpt-5-codex",
33977
34042
  "vercel": "openai/gpt-5-codex"
33978
34043
  },
33979
34044
  "gpt-5-mini": {
33980
34045
  "openai": "gpt-5-mini",
33981
34046
  "vercel": "openai/gpt-5-mini"
33982
34047
  },
33983
- "gpt-5-mini-batch": {
33984
- "openai": "gpt-5-mini-batch"
33985
- },
33986
34048
  "gpt-5-nano": {
33987
34049
  "openai": "gpt-5-nano",
33988
34050
  "vercel": "openai/gpt-5-nano"
33989
34051
  },
33990
- "gpt-5-nano-batch": {
33991
- "openai": "gpt-5-nano-batch"
33992
- },
33993
34052
  "gpt-5-pro": {
34053
+ "openai": "gpt-5-pro",
33994
34054
  "vercel": "openai/gpt-5-pro"
33995
34055
  },
33996
34056
  "gpt-5.1": {
33997
34057
  "openai": "gpt-5.1"
33998
34058
  },
33999
- "gpt-5.1-batch": {
34000
- "openai": "gpt-5.1-batch"
34001
- },
34002
34059
  "gpt-5.1-codex": {
34003
34060
  "openai": "gpt-5.1-codex",
34004
34061
  "vercel": "openai/gpt-5.1-codex"
34005
34062
  },
34006
- "gpt-5.1-codex-batch": {
34007
- "openai": "gpt-5.1-codex-batch"
34008
- },
34009
34063
  "gpt-5.1-codex-max": {
34064
+ "openai": "gpt-5.1-codex-max",
34010
34065
  "vercel": "openai/gpt-5.1-codex-max"
34011
34066
  },
34012
34067
  "gpt-5.1-codex-mini": {
34013
34068
  "openai": "gpt-5.1-codex-mini",
34014
34069
  "vercel": "openai/gpt-5.1-codex-mini"
34015
34070
  },
34016
- "gpt-5.1-codex-mini-batch": {
34017
- "openai": "gpt-5.1-codex-mini-batch"
34018
- },
34019
34071
  "gpt-5.1-instant": {
34020
34072
  "vercel": "openai/gpt-5.1-instant"
34021
34073
  },
@@ -34026,68 +34078,99 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34026
34078
  "openai": "gpt-5.2",
34027
34079
  "vercel": "openai/gpt-5.2"
34028
34080
  },
34029
- "gpt-5.2-batch": {
34030
- "openai": "gpt-5.2-batch"
34031
- },
34032
34081
  "gpt-5.2-chat": {
34033
34082
  "vercel": "openai/gpt-5.2-chat"
34034
34083
  },
34035
34084
  "gpt-5.2-codex": {
34085
+ "openai": "gpt-5.2-codex",
34036
34086
  "vercel": "openai/gpt-5.2-codex"
34037
34087
  },
34038
34088
  "gpt-5.2-pro": {
34039
34089
  "openai": "gpt-5.2-pro",
34040
34090
  "vercel": "openai/gpt-5.2-pro"
34041
34091
  },
34042
- "gpt-5.2-pro-batch": {
34043
- "openai": "gpt-5.2-pro-batch"
34044
- },
34045
34092
  "gpt-5.3-chat": {
34046
34093
  "vercel": "openai/gpt-5.3-chat"
34047
34094
  },
34048
34095
  "gpt-5.3-codex": {
34096
+ "openai": "gpt-5.3-codex",
34049
34097
  "vercel": "openai/gpt-5.3-codex"
34050
34098
  },
34099
+ "gpt-5.3-codex-spark": {
34100
+ "openai": "gpt-5.3-codex-spark"
34101
+ },
34051
34102
  "gpt-5.4": {
34103
+ "openai": "gpt-5.4",
34052
34104
  "vercel": "openai/gpt-5.4"
34053
34105
  },
34054
34106
  "gpt-5.4-mini": {
34107
+ "openai": "gpt-5.4-mini",
34055
34108
  "vercel": "openai/gpt-5.4-mini"
34056
34109
  },
34057
34110
  "gpt-5.4-nano": {
34111
+ "openai": "gpt-5.4-nano",
34058
34112
  "vercel": "openai/gpt-5.4-nano"
34059
34113
  },
34060
34114
  "gpt-5.4-pro": {
34115
+ "openai": "gpt-5.4-pro",
34061
34116
  "vercel": "openai/gpt-5.4-pro"
34062
34117
  },
34063
34118
  "gpt-5.5": {
34119
+ "openai": "gpt-5.5",
34064
34120
  "vercel": "openai/gpt-5.5"
34065
34121
  },
34066
34122
  "gpt-5.5-pro": {
34123
+ "openai": "gpt-5.5-pro",
34067
34124
  "vercel": "openai/gpt-5.5-pro"
34068
34125
  },
34126
+ "gpt-image-1": {
34127
+ "openai": "gpt-image-1",
34128
+ "vercel": "openai/gpt-image-1"
34129
+ },
34130
+ "gpt-image-1-5": {
34131
+ "openai": "gpt-image-1.5",
34132
+ "vercel": "openai/gpt-image-1.5"
34133
+ },
34134
+ "gpt-image-1-mini": {
34135
+ "openai": "gpt-image-1-mini",
34136
+ "vercel": "openai/gpt-image-1-mini"
34137
+ },
34138
+ "gpt-image-1.5": {
34139
+ "openai": "gpt-image-1.5",
34140
+ "vercel": "openai/gpt-image-1.5"
34141
+ },
34142
+ "gpt-image-2": {
34143
+ "vercel": "openai/gpt-image-2"
34144
+ },
34069
34145
  "gpt-oss-120b": {
34146
+ "togetherai": "togetherai/openai/gpt-oss-120b",
34070
34147
  "vercel": "openai/gpt-oss-120b"
34071
34148
  },
34072
34149
  "gpt-oss-20b": {
34150
+ "togetherai": "togetherai/openai/gpt-oss-20b",
34073
34151
  "vercel": "openai/gpt-oss-20b"
34074
34152
  },
34075
34153
  "gpt-oss-safeguard-20b": {
34076
34154
  "vercel": "openai/gpt-oss-safeguard-20b"
34077
34155
  },
34078
- "grok-4": {
34079
- "vercel": "xai/grok-4",
34080
- "xai": "x/grok-4"
34081
- },
34082
34156
  "grok-4-1-fast-non-reasoning": {
34083
34157
  "vercel": "xai/grok-4.1-fast-non-reasoning"
34084
34158
  },
34085
34159
  "grok-4-1-fast-reasoning": {
34086
34160
  "vercel": "xai/grok-4.1-fast-reasoning"
34087
34161
  },
34162
+ "grok-4-20-0309-non-reasoning": {
34163
+ "xai": "grok-4.20-0309-non-reasoning"
34164
+ },
34165
+ "grok-4-20-0309-reasoning": {
34166
+ "xai": "grok-4.20-0309-reasoning"
34167
+ },
34088
34168
  "grok-4-20-multi-agent": {
34089
34169
  "vercel": "xai/grok-4.20-multi-agent"
34090
34170
  },
34171
+ "grok-4-20-multi-agent-0309": {
34172
+ "xai": "grok-4.20-multi-agent-0309"
34173
+ },
34091
34174
  "grok-4-20-multi-agent-beta": {
34092
34175
  "vercel": "xai/grok-4.20-multi-agent-beta"
34093
34176
  },
@@ -34104,10 +34187,8 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34104
34187
  "vercel": "xai/grok-4.20-reasoning-beta"
34105
34188
  },
34106
34189
  "grok-4-3": {
34107
- "vercel": "xai/grok-4.3"
34108
- },
34109
- "grok-4-fast": {
34110
- "xai": "x/grok-4-fast"
34190
+ "vercel": "xai/grok-4.3",
34191
+ "xai": "grok-4.3"
34111
34192
  },
34112
34193
  "grok-4.1-fast-non-reasoning": {
34113
34194
  "vercel": "xai/grok-4.1-fast-non-reasoning"
@@ -34115,9 +34196,18 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34115
34196
  "grok-4.1-fast-reasoning": {
34116
34197
  "vercel": "xai/grok-4.1-fast-reasoning"
34117
34198
  },
34199
+ "grok-4.20-0309-non-reasoning": {
34200
+ "xai": "grok-4.20-0309-non-reasoning"
34201
+ },
34202
+ "grok-4.20-0309-reasoning": {
34203
+ "xai": "grok-4.20-0309-reasoning"
34204
+ },
34118
34205
  "grok-4.20-multi-agent": {
34119
34206
  "vercel": "xai/grok-4.20-multi-agent"
34120
34207
  },
34208
+ "grok-4.20-multi-agent-0309": {
34209
+ "xai": "grok-4.20-multi-agent-0309"
34210
+ },
34121
34211
  "grok-4.20-multi-agent-beta": {
34122
34212
  "vercel": "xai/grok-4.20-multi-agent-beta"
34123
34213
  },
@@ -34134,16 +34224,51 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34134
34224
  "vercel": "xai/grok-4.20-reasoning-beta"
34135
34225
  },
34136
34226
  "grok-4.3": {
34137
- "vercel": "xai/grok-4.3"
34227
+ "vercel": "xai/grok-4.3",
34228
+ "xai": "grok-4.3"
34138
34229
  },
34139
34230
  "grok-build-0-1": {
34140
- "vercel": "xai/grok-build-0.1"
34231
+ "vercel": "xai/grok-build-0.1",
34232
+ "xai": "grok-build-0.1"
34141
34233
  },
34142
34234
  "grok-build-0.1": {
34143
- "vercel": "xai/grok-build-0.1"
34235
+ "vercel": "xai/grok-build-0.1",
34236
+ "xai": "grok-build-0.1"
34237
+ },
34238
+ "grok-imagine-image": {
34239
+ "vercel": "xai/grok-imagine-image",
34240
+ "xai": "grok-imagine-image"
34241
+ },
34242
+ "grok-imagine-image-quality": {
34243
+ "xai": "grok-imagine-image-quality"
34244
+ },
34245
+ "grok-imagine-video": {
34246
+ "vercel": "xai/grok-imagine-video",
34247
+ "xai": "grok-imagine-video"
34248
+ },
34249
+ "grok-imagine-video-1-5": {
34250
+ "vercel": "xai/grok-imagine-video-1.5-preview"
34251
+ },
34252
+ "grok-imagine-video-1.5-preview": {
34253
+ "vercel": "xai/grok-imagine-video-1.5-preview"
34144
34254
  },
34145
- "grok-code-fast-1": {
34146
- "xai": "x/grok-code-fast-1"
34255
+ "imagen-4-0-fast-generate-001": {
34256
+ "vercel": "google/imagen-4.0-fast-generate-001"
34257
+ },
34258
+ "imagen-4-0-generate-001": {
34259
+ "vercel": "google/imagen-4.0-generate-001"
34260
+ },
34261
+ "imagen-4-0-ultra-generate-001": {
34262
+ "vercel": "google/imagen-4.0-ultra-generate-001"
34263
+ },
34264
+ "imagen-4.0-fast-generate-001": {
34265
+ "vercel": "google/imagen-4.0-fast-generate-001"
34266
+ },
34267
+ "imagen-4.0-generate-001": {
34268
+ "vercel": "google/imagen-4.0-generate-001"
34269
+ },
34270
+ "imagen-4.0-ultra-generate-001": {
34271
+ "vercel": "google/imagen-4.0-ultra-generate-001"
34147
34272
  },
34148
34273
  "interfaze-beta": {
34149
34274
  "vercel": "interfaze/interfaze-beta"
@@ -34161,49 +34286,96 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34161
34286
  "vercel": "moonshotai/kimi-k2-thinking"
34162
34287
  },
34163
34288
  "kimi-k2-5": {
34289
+ "togetherai": "togetherai/moonshotai/Kimi-K2.5",
34164
34290
  "vercel": "moonshotai/kimi-k2.5"
34165
34291
  },
34166
34292
  "kimi-k2-6": {
34293
+ "togetherai": "togetherai/moonshotai/Kimi-K2.6",
34167
34294
  "vercel": "moonshotai/kimi-k2.6"
34168
34295
  },
34296
+ "kimi-k2-7-code": {
34297
+ "vercel": "moonshotai/kimi-k2.7-code"
34298
+ },
34169
34299
  "kimi-k2-thinking": {
34170
34300
  "vercel": "moonshotai/kimi-k2-thinking"
34171
34301
  },
34172
- "kimi-k2-thinking-turbo": {
34173
- "vercel": "moonshotai/kimi-k2-thinking-turbo"
34174
- },
34175
- "kimi-k2-turbo": {
34176
- "vercel": "moonshotai/kimi-k2-turbo"
34177
- },
34178
34302
  "kimi-k2.5": {
34179
34303
  "vercel": "moonshotai/kimi-k2.5"
34180
34304
  },
34181
34305
  "kimi-k2.6": {
34182
34306
  "vercel": "moonshotai/kimi-k2.6"
34183
34307
  },
34184
- "llama-3-1-70b": {
34185
- "vercel": "meta/llama-3-1-70b"
34308
+ "kimi-k2.7-code": {
34309
+ "vercel": "moonshotai/kimi-k2.7-code"
34310
+ },
34311
+ "kling-v2-5-turbo-i2v": {
34312
+ "vercel": "klingai/kling-v2.5-turbo-i2v"
34313
+ },
34314
+ "kling-v2-5-turbo-t2v": {
34315
+ "vercel": "klingai/kling-v2.5-turbo-t2v"
34316
+ },
34317
+ "kling-v2-6-i2v": {
34318
+ "vercel": "klingai/kling-v2.6-i2v"
34319
+ },
34320
+ "kling-v2-6-motion-control": {
34321
+ "vercel": "klingai/kling-v2.6-motion-control"
34322
+ },
34323
+ "kling-v2-6-t2v": {
34324
+ "vercel": "klingai/kling-v2.6-t2v"
34325
+ },
34326
+ "kling-v2.5-turbo-i2v": {
34327
+ "vercel": "klingai/kling-v2.5-turbo-i2v"
34328
+ },
34329
+ "kling-v2.5-turbo-t2v": {
34330
+ "vercel": "klingai/kling-v2.5-turbo-t2v"
34331
+ },
34332
+ "kling-v2.6-i2v": {
34333
+ "vercel": "klingai/kling-v2.6-i2v"
34334
+ },
34335
+ "kling-v2.6-motion-control": {
34336
+ "vercel": "klingai/kling-v2.6-motion-control"
34337
+ },
34338
+ "kling-v2.6-t2v": {
34339
+ "vercel": "klingai/kling-v2.6-t2v"
34340
+ },
34341
+ "kling-v3-0-i2v": {
34342
+ "vercel": "klingai/kling-v3.0-i2v"
34343
+ },
34344
+ "kling-v3-0-motion-control": {
34345
+ "vercel": "klingai/kling-v3.0-motion-control"
34346
+ },
34347
+ "kling-v3-0-t2v": {
34348
+ "vercel": "klingai/kling-v3.0-t2v"
34186
34349
  },
34187
- "llama-3-1-8b": {
34188
- "vercel": "meta/llama-3-1-8b"
34350
+ "kling-v3.0-i2v": {
34351
+ "vercel": "klingai/kling-v3.0-i2v"
34352
+ },
34353
+ "kling-v3.0-motion-control": {
34354
+ "vercel": "klingai/kling-v3.0-motion-control"
34355
+ },
34356
+ "kling-v3.0-t2v": {
34357
+ "vercel": "klingai/kling-v3.0-t2v"
34358
+ },
34359
+ "lfm2-24b-a2b": {
34360
+ "togetherai": "togetherai/LiquidAI/LFM2-24B-A2B"
34361
+ },
34362
+ "LiquidAI/LFM2-24B-A2B": {
34363
+ "togetherai": "togetherai/LiquidAI/LFM2-24B-A2B"
34189
34364
  },
34190
34365
  "llama-3-2-11b": {
34191
- "vercel": "meta/llama-3-2-11b"
34366
+ "vercel": "meta/llama-3.2-11b"
34192
34367
  },
34193
34368
  "llama-3-2-1b": {
34194
- "vercel": "meta/llama-3-2-1b"
34369
+ "vercel": "meta/llama-3.2-1b"
34195
34370
  },
34196
34371
  "llama-3-2-3b": {
34197
- "vercel": "meta/llama-3-2-3b"
34372
+ "vercel": "meta/llama-3.2-3b"
34198
34373
  },
34199
34374
  "llama-3-2-90b": {
34200
- "vercel": "meta/llama-3-2-90b"
34201
- },
34202
- "llama-3-3-70b": {
34203
- "vercel": "meta/llama-3-3-70b"
34375
+ "vercel": "meta/llama-3.2-90b"
34204
34376
  },
34205
34377
  "llama-3-3-70b-instruct-turbo": {
34206
- "togetherai": "meta-llama/Llama-3.3-70B-Instruct-Turbo"
34378
+ "togetherai": "togetherai/meta-llama/Llama-3.3-70B-Instruct-Turbo"
34207
34379
  },
34208
34380
  "llama-3.1-70b": {
34209
34381
  "vercel": "meta/llama-3.1-70b"
@@ -34226,17 +34398,14 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34226
34398
  "llama-3.3-70b": {
34227
34399
  "vercel": "meta/llama-3.3-70b"
34228
34400
  },
34229
- "Llama-3.3-70B-Instruct-Turbo": {
34230
- "togetherai": "meta-llama/Llama-3.3-70B-Instruct-Turbo"
34231
- },
34232
34401
  "llama3-1-70b": {
34233
- "vercel": "meta/llama-3-1-70b"
34402
+ "vercel": "meta/llama-3.1-70b"
34234
34403
  },
34235
34404
  "llama3-1-8b": {
34236
- "vercel": "meta/llama-3-1-8b"
34405
+ "vercel": "meta/llama-3.1-8b"
34237
34406
  },
34238
34407
  "llama3-3-70b": {
34239
- "vercel": "meta/llama-3-3-70b"
34408
+ "vercel": "meta/llama-3.3-70b"
34240
34409
  },
34241
34410
  "longcat-flash-chat": {
34242
34411
  "vercel": "meituan/longcat-flash-chat"
@@ -34256,29 +34425,8 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34256
34425
  "mercury-coder-small": {
34257
34426
  "vercel": "inception/mercury-coder-small"
34258
34427
  },
34259
- "meta-llama-3-1-405b-instruct-turbo": {
34260
- "togetherai": "meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo"
34261
- },
34262
- "meta-llama-3-1-70b-instruct-turbo": {
34263
- "togetherai": "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo"
34264
- },
34265
- "meta-llama-3-1-8b-instruct-turbo": {
34266
- "togetherai": "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo"
34267
- },
34268
- "meta-llama-3-3-70b-instruct-turbo": {
34269
- "togetherai": "meta-llama/Meta-Llama-3.3-70B-Instruct-Turbo"
34270
- },
34271
- "Meta-Llama-3.1-405B-Instruct-Turbo": {
34272
- "togetherai": "meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo"
34273
- },
34274
- "Meta-Llama-3.1-70B-Instruct-Turbo": {
34275
- "togetherai": "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo"
34276
- },
34277
- "Meta-Llama-3.1-8B-Instruct-Turbo": {
34278
- "togetherai": "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo"
34279
- },
34280
- "Meta-Llama-3.3-70B-Instruct-Turbo": {
34281
- "togetherai": "meta-llama/Meta-Llama-3.3-70B-Instruct-Turbo"
34428
+ "meta-llama/Llama-3.3-70B-Instruct-Turbo": {
34429
+ "togetherai": "togetherai/meta-llama/Llama-3.3-70B-Instruct-Turbo"
34282
34430
  },
34283
34431
  "mimo-v2-5": {
34284
34432
  "vercel": "xiaomi/mimo-v2.5"
@@ -34308,6 +34456,7 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34308
34456
  "vercel": "minimax/minimax-m2.1-lightning"
34309
34457
  },
34310
34458
  "minimax-m2-5": {
34459
+ "togetherai": "togetherai/MiniMaxAI/MiniMax-M2.5",
34311
34460
  "vercel": "minimax/minimax-m2.5"
34312
34461
  },
34313
34462
  "minimax-m2-5-highspeed": {
@@ -34315,6 +34464,7 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34315
34464
  },
34316
34465
  "minimax-m2-7": {
34317
34466
  "general-compute": "general-compute/minimax-m2.7",
34467
+ "togetherai": "togetherai/MiniMaxAI/MiniMax-M2.7",
34318
34468
  "vercel": "minimax/minimax-m2.7"
34319
34469
  },
34320
34470
  "minimax-m2-7-highspeed": {
@@ -34342,6 +34492,12 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34342
34492
  "minimax-m3": {
34343
34493
  "vercel": "minimax/minimax-m3"
34344
34494
  },
34495
+ "MiniMaxAI/MiniMax-M2.5": {
34496
+ "togetherai": "togetherai/MiniMaxAI/MiniMax-M2.5"
34497
+ },
34498
+ "MiniMaxAI/MiniMax-M2.7": {
34499
+ "togetherai": "togetherai/MiniMaxAI/MiniMax-M2.7"
34500
+ },
34345
34501
  "ministral-14b": {
34346
34502
  "vercel": "mistral/ministral-14b"
34347
34503
  },
@@ -34351,9 +34507,6 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34351
34507
  "ministral-8b": {
34352
34508
  "vercel": "mistral/ministral-8b"
34353
34509
  },
34354
- "mistral-large": {
34355
- "vercel": "mistral/mistral-large"
34356
- },
34357
34510
  "mistral-large-3": {
34358
34511
  "vercel": "mistral/mistral-large-3"
34359
34512
  },
@@ -34363,12 +34516,15 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34363
34516
  "mistral-medium-3.5": {
34364
34517
  "vercel": "mistral/mistral-medium-3.5"
34365
34518
  },
34366
- "mistral-saba-24b": {
34367
- "vercel": "mistral/mistral-saba-24b"
34368
- },
34369
34519
  "mistral-small": {
34370
34520
  "vercel": "mistral/mistral-small"
34371
34521
  },
34522
+ "moonshotai/Kimi-K2.5": {
34523
+ "togetherai": "togetherai/moonshotai/Kimi-K2.5"
34524
+ },
34525
+ "moonshotai/Kimi-K2.6": {
34526
+ "togetherai": "togetherai/moonshotai/Kimi-K2.6"
34527
+ },
34372
34528
  "morph-v3-fast": {
34373
34529
  "vercel": "morph/morph-v3-fast"
34374
34530
  },
@@ -34382,6 +34538,7 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34382
34538
  "vercel": "nvidia/nemotron-3-super-120b-a12b"
34383
34539
  },
34384
34540
  "nemotron-3-ultra-550b-a55b": {
34541
+ "togetherai": "togetherai/nvidia/nemotron-3-ultra-550b-a55b",
34385
34542
  "vercel": "nvidia/nemotron-3-ultra-550b-a55b"
34386
34543
  },
34387
34544
  "nemotron-nano-12b-v2-vl": {
@@ -34405,26 +34562,36 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34405
34562
  "nova-pro": {
34406
34563
  "vercel": "amazon/nova-pro"
34407
34564
  },
34565
+ "nvidia/nemotron-3-ultra-550b-a55b": {
34566
+ "togetherai": "togetherai/nvidia/nemotron-3-ultra-550b-a55b"
34567
+ },
34408
34568
  "o3": {
34569
+ "openai": "o3",
34409
34570
  "vercel": "openai/o3"
34410
34571
  },
34411
34572
  "o3-deep-research": {
34573
+ "openai": "o3-deep-research",
34412
34574
  "vercel": "openai/o3-deep-research"
34413
34575
  },
34414
34576
  "o3-pro": {
34577
+ "openai": "o3-pro",
34415
34578
  "vercel": "openai/o3-pro"
34416
34579
  },
34417
- "o3-pro-batch": {
34418
- "openai": "o3-pro-batch"
34419
- },
34420
34580
  "o4-mini": {
34581
+ "openai": "o4-mini",
34421
34582
  "vercel": "openai/o4-mini"
34422
34583
  },
34423
- "o4-mini-batch": {
34424
- "openai": "o4-mini-batch"
34584
+ "o4-mini-deep-research": {
34585
+ "openai": "o4-mini-deep-research"
34586
+ },
34587
+ "openai/gpt-oss-120b": {
34588
+ "togetherai": "togetherai/openai/gpt-oss-120b"
34425
34589
  },
34426
- "openai/gpt-4o-mini-search-preview": {
34427
- "openai": "openai/openai/gpt-4o-mini-search-preview"
34590
+ "openai/gpt-oss-20b": {
34591
+ "togetherai": "togetherai/openai/gpt-oss-20b"
34592
+ },
34593
+ "pearl-ai/gemma-4-31b-it": {
34594
+ "togetherai": "togetherai/pearl-ai/gemma-4-31b-it"
34428
34595
  },
34429
34596
  "pixtral-12b": {
34430
34597
  "vercel": "mistral/pixtral-12b"
@@ -34450,26 +34617,55 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34450
34617
  "qwen-3.6-max-preview": {
34451
34618
  "vercel": "alibaba/qwen-3.6-max-preview"
34452
34619
  },
34620
+ "Qwen/Qwen3-235B-A22B-Instruct-2507-tput": {
34621
+ "togetherai": "togetherai/Qwen/Qwen3-235B-A22B-Instruct-2507-tput"
34622
+ },
34623
+ "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8": {
34624
+ "togetherai": "togetherai/Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8"
34625
+ },
34626
+ "Qwen/Qwen3-Coder-Next-FP8": {
34627
+ "togetherai": "togetherai/Qwen/Qwen3-Coder-Next-FP8"
34628
+ },
34629
+ "Qwen/Qwen3.5-397B-A17B": {
34630
+ "togetherai": "togetherai/Qwen/Qwen3.5-397B-A17B"
34631
+ },
34632
+ "Qwen/Qwen3.5-9B": {
34633
+ "togetherai": "togetherai/Qwen/Qwen3.5-9B"
34634
+ },
34635
+ "Qwen/Qwen3.6-Plus": {
34636
+ "togetherai": "togetherai/Qwen/Qwen3.6-Plus"
34637
+ },
34638
+ "Qwen/Qwen3.7-Max": {
34639
+ "togetherai": "togetherai/Qwen/Qwen3.7-Max"
34640
+ },
34453
34641
  "qwen3-235b-a22b": {
34454
34642
  "vercel": "alibaba/qwen3-235b-a22b-thinking"
34455
34643
  },
34644
+ "qwen3-235b-a22b-instruct-2507-tput": {
34645
+ "togetherai": "togetherai/Qwen/Qwen3-235B-A22B-Instruct-2507-tput"
34646
+ },
34456
34647
  "qwen3-235b-a22b-thinking": {
34457
34648
  "vercel": "alibaba/qwen3-235b-a22b-thinking"
34458
34649
  },
34459
34650
  "qwen3-32b": {
34460
34651
  "vercel": "alibaba/qwen-3-32b"
34461
34652
  },
34653
+ "qwen3-5-122b-a10b": {
34654
+ "mixlayer": "qwen/qwen3.5-122b-a10b"
34655
+ },
34462
34656
  "qwen3-5-35b-a3b": {
34463
34657
  "mixlayer": "qwen/qwen3.5-35b-a3b"
34464
34658
  },
34465
34659
  "qwen3-5-397b-a17b": {
34466
- "mixlayer": "qwen/qwen3.5-397b-a17b"
34660
+ "mixlayer": "qwen/qwen3.5-397b-a17b",
34661
+ "togetherai": "togetherai/Qwen/Qwen3.5-397B-A17B"
34467
34662
  },
34468
34663
  "qwen3-5-4b-free": {
34469
34664
  "mixlayer": "qwen/qwen3.5-4b-free"
34470
34665
  },
34471
34666
  "qwen3-5-9b": {
34472
- "mixlayer": "qwen/qwen3.5-9b"
34667
+ "mixlayer": "qwen/qwen3.5-9b",
34668
+ "togetherai": "togetherai/Qwen/Qwen3.5-9B"
34473
34669
  },
34474
34670
  "qwen3-5-flash": {
34475
34671
  "vercel": "alibaba/qwen3.5-flash"
@@ -34485,9 +34681,11 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34485
34681
  "mixlayer": "qwen/qwen3.6-35b-a3b"
34486
34682
  },
34487
34683
  "qwen3-6-plus": {
34684
+ "togetherai": "togetherai/Qwen/Qwen3.6-Plus",
34488
34685
  "vercel": "alibaba/qwen3.6-plus"
34489
34686
  },
34490
34687
  "qwen3-7-max": {
34688
+ "togetherai": "togetherai/Qwen/Qwen3.7-Max",
34491
34689
  "vercel": "alibaba/qwen3.7-max"
34492
34690
  },
34493
34691
  "qwen3-7-plus": {
@@ -34499,9 +34697,15 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34499
34697
  "qwen3-coder-30b-a3b": {
34500
34698
  "vercel": "alibaba/qwen3-coder-30b-a3b"
34501
34699
  },
34700
+ "qwen3-coder-480b-a35b-instruct-fp8": {
34701
+ "togetherai": "togetherai/Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8"
34702
+ },
34502
34703
  "qwen3-coder-next": {
34503
34704
  "vercel": "alibaba/qwen3-coder-next"
34504
34705
  },
34706
+ "qwen3-coder-next-fp8": {
34707
+ "togetherai": "togetherai/Qwen/Qwen3-Coder-Next-FP8"
34708
+ },
34505
34709
  "qwen3-coder-plus": {
34506
34710
  "vercel": "alibaba/qwen3-coder-plus"
34507
34711
  },
@@ -34547,6 +34751,9 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34547
34751
  "qwen3-vl-thinking": {
34548
34752
  "vercel": "alibaba/qwen3-vl-thinking"
34549
34753
  },
34754
+ "qwen3.5-122b-a10b": {
34755
+ "mixlayer": "qwen/qwen3.5-122b-a10b"
34756
+ },
34550
34757
  "qwen3.5-35b-a3b": {
34551
34758
  "mixlayer": "qwen/qwen3.5-35b-a3b"
34552
34759
  },
@@ -34581,6 +34788,72 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34581
34788
  "qwen3.7-plus": {
34582
34789
  "vercel": "alibaba/qwen3.7-plus"
34583
34790
  },
34791
+ "recraft": {
34792
+ "vercel": "recraft/recraft-v4"
34793
+ },
34794
+ "recraft-v2": {
34795
+ "vercel": "recraft/recraft-v2"
34796
+ },
34797
+ "recraft-v3": {
34798
+ "vercel": "recraft/recraft-v3"
34799
+ },
34800
+ "recraft-v4": {
34801
+ "vercel": "recraft/recraft-v4"
34802
+ },
34803
+ "recraft-v4-1": {
34804
+ "vercel": "recraft/recraft-v4.1"
34805
+ },
34806
+ "recraft-v4-1-pro": {
34807
+ "vercel": "recraft/recraft-v4.1-pro"
34808
+ },
34809
+ "recraft-v4-1-utility": {
34810
+ "vercel": "recraft/recraft-v4.1-utility"
34811
+ },
34812
+ "recraft-v4-1-utility-pro": {
34813
+ "vercel": "recraft/recraft-v4.1-utility-pro"
34814
+ },
34815
+ "recraft-v4-pro": {
34816
+ "vercel": "recraft/recraft-v4-pro"
34817
+ },
34818
+ "recraft-v4.1": {
34819
+ "vercel": "recraft/recraft-v4.1"
34820
+ },
34821
+ "recraft-v4.1-pro": {
34822
+ "vercel": "recraft/recraft-v4.1-pro"
34823
+ },
34824
+ "recraft-v4.1-utility": {
34825
+ "vercel": "recraft/recraft-v4.1-utility"
34826
+ },
34827
+ "recraft-v4.1-utility-pro": {
34828
+ "vercel": "recraft/recraft-v4.1-utility-pro"
34829
+ },
34830
+ "rerank-2-5": {
34831
+ "vercel": "voyage/rerank-2.5"
34832
+ },
34833
+ "rerank-2-5-lite": {
34834
+ "vercel": "voyage/rerank-2.5-lite"
34835
+ },
34836
+ "rerank-2.5": {
34837
+ "vercel": "voyage/rerank-2.5"
34838
+ },
34839
+ "rerank-2.5-lite": {
34840
+ "vercel": "voyage/rerank-2.5-lite"
34841
+ },
34842
+ "rerank-v3-5": {
34843
+ "vercel": "cohere/rerank-v3.5"
34844
+ },
34845
+ "rerank-v3.5": {
34846
+ "vercel": "cohere/rerank-v3.5"
34847
+ },
34848
+ "rerank-v4-fast": {
34849
+ "vercel": "cohere/rerank-v4-fast"
34850
+ },
34851
+ "rerank-v4-pro": {
34852
+ "vercel": "cohere/rerank-v4-pro"
34853
+ },
34854
+ "rnj-1-instruct": {
34855
+ "togetherai": "togetherai/essentialai/Rnj-1-Instruct"
34856
+ },
34584
34857
  "seed-1-6": {
34585
34858
  "vercel": "bytedance/seed-1.6"
34586
34859
  },
@@ -34593,15 +34866,72 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34593
34866
  "seed-1.8": {
34594
34867
  "vercel": "bytedance/seed-1.8"
34595
34868
  },
34869
+ "seedance-2-0": {
34870
+ "vercel": "bytedance/seedance-2.0"
34871
+ },
34872
+ "seedance-2-0-fast": {
34873
+ "vercel": "bytedance/seedance-2.0-fast"
34874
+ },
34875
+ "seedance-2.0": {
34876
+ "vercel": "bytedance/seedance-2.0"
34877
+ },
34878
+ "seedance-2.0-fast": {
34879
+ "vercel": "bytedance/seedance-2.0-fast"
34880
+ },
34881
+ "seedance-v1-0-lite-i2v": {
34882
+ "vercel": "bytedance/seedance-v1.0-lite-i2v"
34883
+ },
34884
+ "seedance-v1-0-lite-t2v": {
34885
+ "vercel": "bytedance/seedance-v1.0-lite-t2v"
34886
+ },
34887
+ "seedance-v1-0-pro": {
34888
+ "vercel": "bytedance/seedance-v1.0-pro"
34889
+ },
34890
+ "seedance-v1-0-pro-fast": {
34891
+ "vercel": "bytedance/seedance-v1.0-pro-fast"
34892
+ },
34893
+ "seedance-v1-5-pro": {
34894
+ "vercel": "bytedance/seedance-v1.5-pro"
34895
+ },
34896
+ "seedance-v1.0-lite-i2v": {
34897
+ "vercel": "bytedance/seedance-v1.0-lite-i2v"
34898
+ },
34899
+ "seedance-v1.0-lite-t2v": {
34900
+ "vercel": "bytedance/seedance-v1.0-lite-t2v"
34901
+ },
34902
+ "seedance-v1.0-pro": {
34903
+ "vercel": "bytedance/seedance-v1.0-pro"
34904
+ },
34905
+ "seedance-v1.0-pro-fast": {
34906
+ "vercel": "bytedance/seedance-v1.0-pro-fast"
34907
+ },
34908
+ "seedance-v1.5-pro": {
34909
+ "vercel": "bytedance/seedance-v1.5-pro"
34910
+ },
34911
+ "seedream-4-0": {
34912
+ "vercel": "bytedance/seedream-4.0"
34913
+ },
34914
+ "seedream-4-5": {
34915
+ "vercel": "bytedance/seedream-4.5"
34916
+ },
34917
+ "seedream-4.0": {
34918
+ "vercel": "bytedance/seedream-4.0"
34919
+ },
34920
+ "seedream-4.5": {
34921
+ "vercel": "bytedance/seedream-4.5"
34922
+ },
34923
+ "seedream-5-0-lite": {
34924
+ "vercel": "bytedance/seedream-5.0-lite"
34925
+ },
34926
+ "seedream-5.0-lite": {
34927
+ "vercel": "bytedance/seedream-5.0-lite"
34928
+ },
34596
34929
  "sonar": {
34597
34930
  "vercel": "perplexity/sonar"
34598
34931
  },
34599
34932
  "sonar-pro": {
34600
34933
  "vercel": "perplexity/sonar-pro"
34601
34934
  },
34602
- "sonar-reasoning": {
34603
- "vercel": "perplexity/sonar-reasoning"
34604
- },
34605
34935
  "sonar-reasoning-pro": {
34606
34936
  "vercel": "perplexity/sonar-reasoning-pro"
34607
34937
  },
@@ -34624,35 +34954,14 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34624
34954
  "openai": "text-embedding-3-large",
34625
34955
  "vercel": "openai/text-embedding-3-large"
34626
34956
  },
34627
- "text-embedding-3-large-batch": {
34628
- "openai": "text-embedding-3-large-batch"
34629
- },
34630
34957
  "text-embedding-3-small": {
34631
34958
  "openai": "text-embedding-3-small",
34632
34959
  "vercel": "openai/text-embedding-3-small"
34633
34960
  },
34634
- "text-embedding-3-small-batch": {
34635
- "openai": "text-embedding-3-small-batch"
34636
- },
34637
- "text-embedding-ada": {
34638
- "openai": "text-embedding-ada"
34639
- },
34640
34961
  "text-embedding-ada-002": {
34641
- "openai": "text-embedding-ada-002-v2",
34962
+ "openai": "text-embedding-ada-002",
34642
34963
  "vercel": "openai/text-embedding-ada-002"
34643
34964
  },
34644
- "text-embedding-ada-002-batch": {
34645
- "openai": "text-embedding-ada-002-batch"
34646
- },
34647
- "text-embedding-ada-002-v2": {
34648
- "openai": "text-embedding-ada-002-v2"
34649
- },
34650
- "text-embedding-ada-002-v2-batch": {
34651
- "openai": "text-embedding-ada-002-v2-batch"
34652
- },
34653
- "text-embedding-ada-batch": {
34654
- "openai": "text-embedding-ada-batch"
34655
- },
34656
34965
  "text-multilingual-embedding-002": {
34657
34966
  "vercel": "google/text-multilingual-embedding-002"
34658
34967
  },
@@ -34674,17 +34983,29 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34674
34983
  "trinity-mini": {
34675
34984
  "vercel": "arcee-ai/trinity-mini"
34676
34985
  },
34677
- "v0-1-0-md": {
34678
- "vercel": "v0-1.0-md"
34986
+ "veo-3-0-fast-generate-001": {
34987
+ "vercel": "google/veo-3.0-fast-generate-001"
34988
+ },
34989
+ "veo-3-0-generate-001": {
34990
+ "vercel": "google/veo-3.0-generate-001"
34679
34991
  },
34680
- "v0-1-5-md": {
34681
- "vercel": "v0-1.5-md"
34992
+ "veo-3-1-fast-generate-001": {
34993
+ "vercel": "google/veo-3.1-fast-generate-001"
34682
34994
  },
34683
- "v0-1.0-md": {
34684
- "vercel": "v0-1.0-md"
34995
+ "veo-3-1-generate-001": {
34996
+ "vercel": "google/veo-3.1-generate-001"
34685
34997
  },
34686
- "v0-1.5-md": {
34687
- "vercel": "v0-1.5-md"
34998
+ "veo-3.0-fast-generate-001": {
34999
+ "vercel": "google/veo-3.0-fast-generate-001"
35000
+ },
35001
+ "veo-3.0-generate-001": {
35002
+ "vercel": "google/veo-3.0-generate-001"
35003
+ },
35004
+ "veo-3.1-fast-generate-001": {
35005
+ "vercel": "google/veo-3.1-fast-generate-001"
35006
+ },
35007
+ "veo-3.1-generate-001": {
35008
+ "vercel": "google/veo-3.1-generate-001"
34688
35009
  },
34689
35010
  "voyage-3-5": {
34690
35011
  "vercel": "voyage/voyage-3.5"
@@ -34721,6 +35042,48 @@ var MODEL_FAMILY_PROVIDER_IDS = {
34721
35042
  },
34722
35043
  "voyage-law-2": {
34723
35044
  "vercel": "voyage/voyage-law-2"
35045
+ },
35046
+ "wan-v2-5-t2v": {
35047
+ "vercel": "alibaba/wan-v2.5-t2v-preview"
35048
+ },
35049
+ "wan-v2-6-i2v": {
35050
+ "vercel": "alibaba/wan-v2.6-i2v"
35051
+ },
35052
+ "wan-v2-6-i2v-flash": {
35053
+ "vercel": "alibaba/wan-v2.6-i2v-flash"
35054
+ },
35055
+ "wan-v2-6-r2v": {
35056
+ "vercel": "alibaba/wan-v2.6-r2v"
35057
+ },
35058
+ "wan-v2-6-r2v-flash": {
35059
+ "vercel": "alibaba/wan-v2.6-r2v-flash"
35060
+ },
35061
+ "wan-v2-6-t2v": {
35062
+ "vercel": "alibaba/wan-v2.6-t2v"
35063
+ },
35064
+ "wan-v2.5-t2v-preview": {
35065
+ "vercel": "alibaba/wan-v2.5-t2v-preview"
35066
+ },
35067
+ "wan-v2.6-i2v": {
35068
+ "vercel": "alibaba/wan-v2.6-i2v"
35069
+ },
35070
+ "wan-v2.6-i2v-flash": {
35071
+ "vercel": "alibaba/wan-v2.6-i2v-flash"
35072
+ },
35073
+ "wan-v2.6-r2v": {
35074
+ "vercel": "alibaba/wan-v2.6-r2v"
35075
+ },
35076
+ "wan-v2.6-r2v-flash": {
35077
+ "vercel": "alibaba/wan-v2.6-r2v-flash"
35078
+ },
35079
+ "wan-v2.6-t2v": {
35080
+ "vercel": "alibaba/wan-v2.6-t2v"
35081
+ },
35082
+ "zai-org/GLM-5": {
35083
+ "togetherai": "togetherai/zai-org/GLM-5"
35084
+ },
35085
+ "zai-org/GLM-5.1": {
35086
+ "togetherai": "togetherai/zai-org/GLM-5.1"
34724
35087
  }
34725
35088
  };
34726
35089
  var PLATFORM_KEY_PROVIDER_MAP = {
@@ -34751,12 +35114,13 @@ var MANUAL_PROVIDER_MAP_OVERRIDES = {
34751
35114
  "claude-sonnet-4-5": {
34752
35115
  "bedrock": "anthropic.claude-3-5-sonnet-20241022-v2:0"
34753
35116
  },
34754
- // xAI uses x/ prefix internally
35117
+ // Legacy xAI aliases route to the current successor model IDs.
34755
35118
  "grok-4": {
34756
- "xai": "x/grok-4"
35119
+ "vercel": "xai/grok-4.3",
35120
+ "xai": "grok-4.3"
34757
35121
  },
34758
35122
  "grok-4-fast": {
34759
- "xai": "x/grok-4-fast"
35123
+ "vercel": "xai/grok-4.1-fast-non-reasoning"
34760
35124
  },
34761
35125
  // TogetherAI uses their own model ID format
34762
35126
  "llama-3-3-70b": {
@@ -34775,6 +35139,9 @@ var MANUAL_PROVIDER_MAP_OVERRIDES = {
34775
35139
  "kimi-k2.6": {
34776
35140
  "workers-ai": "@cf/moonshotai/kimi-k2.6"
34777
35141
  },
35142
+ "kimi-k2.7-code": {
35143
+ "workers-ai": "@cf/moonshotai/kimi-k2.7-code"
35144
+ },
34778
35145
  "nemotron-3-120b-a12b": {
34779
35146
  "workers-ai": "@cf/nvidia/nemotron-3-120b-a12b"
34780
35147
  },
@@ -36258,8 +36625,8 @@ var FLAT_ADVANCED_CONFIG_KEYS = {
36258
36625
  var FLAT_ADVANCED_CONFIG_KEY_LIST = Object.keys(
36259
36626
  FLAT_ADVANCED_CONFIG_KEYS
36260
36627
  );
36261
- function createIssue(severity, code, message, path17, suggestedFix) {
36262
- return { code, message, path: path17, severity, ...suggestedFix ? { suggestedFix } : {} };
36628
+ function createIssue(severity, code, message, path18, suggestedFix) {
36629
+ return { code, message, path: path18, severity, ...suggestedFix ? { suggestedFix } : {} };
36263
36630
  }
36264
36631
  function emptyResult() {
36265
36632
  return { valid: true, errors: [], warnings: [], recommendations: [] };
@@ -36965,16 +37332,16 @@ var fullProductObjectTemplateSchema = external_exports.object({
36965
37332
  });
36966
37333
  var FLOW_PREFIX = "flow:";
36967
37334
  var SECRET_PREFIX = "secret:";
36968
- function collectStringLeafPaths(value, path17 = []) {
37335
+ function collectStringLeafPaths(value, path18 = []) {
36969
37336
  if (typeof value === "string") {
36970
- return [{ path: path17, value }];
37337
+ return [{ path: path18, value }];
36971
37338
  }
36972
37339
  if (Array.isArray(value)) {
36973
- return value.flatMap((item, index) => collectStringLeafPaths(item, [...path17, String(index)]));
37340
+ return value.flatMap((item, index) => collectStringLeafPaths(item, [...path18, String(index)]));
36974
37341
  }
36975
37342
  if (value && typeof value === "object") {
36976
37343
  return Object.entries(value).flatMap(
36977
- ([key, nestedValue]) => collectStringLeafPaths(nestedValue, [...path17, key])
37344
+ ([key, nestedValue]) => collectStringLeafPaths(nestedValue, [...path18, key])
36978
37345
  );
36979
37346
  }
36980
37347
  return [];
@@ -38773,7 +39140,7 @@ function buildDashboardUrl(opts) {
38773
39140
  while (base.endsWith("/")) {
38774
39141
  base = base.slice(0, -1);
38775
39142
  }
38776
- const path17 = opts.path.startsWith("/") ? opts.path : `/${opts.path}`;
39143
+ const path18 = opts.path.startsWith("/") ? opts.path : `/${opts.path}`;
38777
39144
  const params = new URLSearchParams();
38778
39145
  if (isValidAccountId(opts.account)) {
38779
39146
  params.set(ACCOUNT_QUERY_PARAM, opts.account);
@@ -38786,7 +39153,7 @@ function buildDashboardUrl(opts) {
38786
39153
  }
38787
39154
  }
38788
39155
  const qs = params.toString();
38789
- return qs ? `${base}${path17}?${qs}` : `${base}${path17}`;
39156
+ return qs ? `${base}${path18}?${qs}` : `${base}${path18}`;
38790
39157
  }
38791
39158
  function parseAccountId(value) {
38792
39159
  if (!value) return null;
@@ -40018,13 +40385,13 @@ function parseJsonObject(raw, label) {
40018
40385
  }
40019
40386
  return parsed;
40020
40387
  }
40021
- function readJsonFile(path17, opts = {}) {
40388
+ function readJsonFile(path18, opts = {}) {
40022
40389
  const label = opts.label ?? "file";
40023
40390
  let raw;
40024
40391
  try {
40025
- raw = readFileSync3(path17, "utf-8");
40392
+ raw = readFileSync3(path18, "utf-8");
40026
40393
  } catch {
40027
- console.error(chalk2.red(`Failed to read ${label}: ${path17}`));
40394
+ console.error(chalk2.red(`Failed to read ${label}: ${path18}`));
40028
40395
  process.exit(1);
40029
40396
  }
40030
40397
  const obj = parseJsonObject(raw, label);
@@ -40068,14 +40435,14 @@ async function promptConfirm(message, options) {
40068
40435
  output: process.stdout,
40069
40436
  terminal: true
40070
40437
  });
40071
- return new Promise((resolve10) => {
40438
+ return new Promise((resolve11) => {
40072
40439
  rl.question(chalk3.cyan(`${message} (${hint}): `), (answer) => {
40073
40440
  rl.close();
40074
40441
  const trimmed = answer.trim().toLowerCase();
40075
40442
  if (trimmed === "") {
40076
- resolve10(defaultYes);
40443
+ resolve11(defaultYes);
40077
40444
  } else {
40078
- resolve10(trimmed === "y" || trimmed === "yes");
40445
+ resolve11(trimmed === "y" || trimmed === "yes");
40079
40446
  }
40080
40447
  });
40081
40448
  });
@@ -41523,13 +41890,13 @@ promptsCommand.command("delete <id>").description("Delete a prompt").option("--t
41523
41890
  await waitUntilExit2();
41524
41891
  return;
41525
41892
  }
41526
- const confirmed = await new Promise((resolve10) => {
41893
+ const confirmed = await new Promise((resolve11) => {
41527
41894
  const { unmount } = render4(
41528
41895
  React4.createElement(ConfirmPrompt, {
41529
41896
  message: `Delete prompt ${id}?`,
41530
41897
  defaultValue: false,
41531
41898
  onConfirm: (result) => {
41532
- resolve10(result);
41899
+ resolve11(result);
41533
41900
  unmount();
41534
41901
  }
41535
41902
  })
@@ -42414,13 +42781,13 @@ secretsCommand.command("delete <id>").description("Delete a secret").option("--t
42414
42781
  await waitUntilExit2();
42415
42782
  return;
42416
42783
  }
42417
- const confirmed = await new Promise((resolve10) => {
42784
+ const confirmed = await new Promise((resolve11) => {
42418
42785
  const { unmount } = render6(
42419
42786
  React6.createElement(ConfirmPrompt, {
42420
42787
  message: `Delete secret ${id}?`,
42421
42788
  defaultValue: false,
42422
42789
  onConfirm: (result) => {
42423
- resolve10(result);
42790
+ resolve11(result);
42424
42791
  unmount();
42425
42792
  }
42426
42793
  })
@@ -42832,13 +43199,13 @@ toolsCommand.command("delete <id>").description("Delete a tool").option("--tty",
42832
43199
  await waitUntilExit2();
42833
43200
  return;
42834
43201
  }
42835
- const confirmed = await new Promise((resolve10) => {
43202
+ const confirmed = await new Promise((resolve11) => {
42836
43203
  const { unmount } = render7(
42837
43204
  React7.createElement(ConfirmPrompt, {
42838
43205
  message: `Delete tool ${id}?`,
42839
43206
  defaultValue: false,
42840
43207
  onConfirm: (result) => {
42841
- resolve10(result);
43208
+ resolve11(result);
42842
43209
  unmount();
42843
43210
  }
42844
43211
  })
@@ -45229,13 +45596,13 @@ conversationsCommand.command("delete <id>").description("Delete a conversation")
45229
45596
  await waitUntilExit2();
45230
45597
  return;
45231
45598
  }
45232
- const confirmed = await new Promise((resolve10) => {
45599
+ const confirmed = await new Promise((resolve11) => {
45233
45600
  const { unmount } = render14(
45234
45601
  React14.createElement(ConfirmPrompt, {
45235
45602
  message: `Delete conversation ${id}?`,
45236
45603
  defaultValue: false,
45237
45604
  onConfirm: (result) => {
45238
- resolve10(result);
45605
+ resolve11(result);
45239
45606
  unmount();
45240
45607
  }
45241
45608
  })
@@ -47492,7 +47859,8 @@ var CHECKPOINT_COMMANDS = [
47492
47859
  var STEERING_SHORTCUTS = [
47493
47860
  { key: "Enter", desc: "Queue a steering message while the agent works" },
47494
47861
  { key: "Tab", desc: "Toggle delivery: next turn / after all work" },
47495
- { key: "Esc", desc: "Close the composer (keeps your draft)" }
47862
+ { key: "Esc", desc: "Close the composer (keeps your draft)" },
47863
+ { key: "Esc Esc", desc: "Interrupt the agent (queued text restores at the prompt)" }
47496
47864
  ];
47497
47865
  function buildLines(isCheckpoint) {
47498
47866
  const lines = [];
@@ -48185,14 +48553,24 @@ function readSessionEventLog(stateFilePath2, sessionIndex) {
48185
48553
  import * as fs4 from "fs";
48186
48554
  import * as path4 from "path";
48187
48555
  import { randomUUID } from "crypto";
48556
+ import * as os3 from "os";
48188
48557
  var TREE_LOG_FORMAT_VERSION = 1;
48189
48558
  function treeLogPathForStateFile(stateFilePath2) {
48190
48559
  return `${stateFilePath2.replace(/\.json$/, "")}.tree.jsonl`;
48191
48560
  }
48561
+ function artifactStoreDirForStateFile(stateFilePath2) {
48562
+ return path4.join(path4.dirname(stateFilePath2), path4.basename(stateFilePath2, ".json"), "outputs");
48563
+ }
48564
+ function artifactRelativePathForStateFile(stateFilePath2, fileName) {
48565
+ return path4.relative(
48566
+ path4.dirname(treeLogPathForStateFile(stateFilePath2)),
48567
+ path4.join(artifactStoreDirForStateFile(stateFilePath2), fileName)
48568
+ ).replace(/\\/g, "/");
48569
+ }
48192
48570
  function isTreeLogEntry(value) {
48193
48571
  if (typeof value !== "object" || value === null) return false;
48194
48572
  const record2 = value;
48195
- return record2.v === TREE_LOG_FORMAT_VERSION && typeof record2.id === "string" && (record2.parentId === null || typeof record2.parentId === "string") && typeof record2.ts === "string" && (record2.type === "meta" || record2.type === "delta" || record2.type === "fork" || record2.type === "head") && typeof record2.payload === "object" && record2.payload !== null;
48573
+ return record2.v === TREE_LOG_FORMAT_VERSION && typeof record2.id === "string" && (record2.parentId === null || typeof record2.parentId === "string") && typeof record2.ts === "string" && (record2.type === "meta" || record2.type === "delta" || record2.type === "fork" || record2.type === "artifact" || record2.type === "summary" || record2.type === "head") && typeof record2.payload === "object" && record2.payload !== null;
48196
48574
  }
48197
48575
  function loadTreeLog(filePath) {
48198
48576
  let raw;
@@ -48281,6 +48659,33 @@ function appendFork(log, fromEntryId, payload) {
48281
48659
  appendLine(log, entry);
48282
48660
  return entry;
48283
48661
  }
48662
+ function appendArtifact(log, payload) {
48663
+ const entry = {
48664
+ v: TREE_LOG_FORMAT_VERSION,
48665
+ id: newEntryId(),
48666
+ parentId: log.headId,
48667
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
48668
+ type: "artifact",
48669
+ payload: {
48670
+ ...payload,
48671
+ host: payload.host || os3.hostname()
48672
+ }
48673
+ };
48674
+ appendLine(log, entry);
48675
+ return entry;
48676
+ }
48677
+ function appendSummary(log, payload) {
48678
+ const entry = {
48679
+ v: TREE_LOG_FORMAT_VERSION,
48680
+ id: newEntryId(),
48681
+ parentId: log.headId,
48682
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
48683
+ type: "summary",
48684
+ payload
48685
+ };
48686
+ appendLine(log, entry);
48687
+ return entry;
48688
+ }
48284
48689
  function setHead(log, entryId) {
48285
48690
  if (!log.byId.has(entryId)) {
48286
48691
  throw new Error(`Cannot set head to unknown entry ${entryId}`);
@@ -48345,6 +48750,7 @@ function materializeAtEntry(log, entryId) {
48345
48750
  let meta3 = null;
48346
48751
  let state = null;
48347
48752
  let messages = [];
48753
+ const summaries = [];
48348
48754
  for (const entry of chain) {
48349
48755
  if (entry.type === "meta") {
48350
48756
  meta3 = entry.payload;
@@ -48357,9 +48763,31 @@ function materializeAtEntry(log, entryId) {
48357
48763
  if (entry.payload.truncateAtMessageIndex !== void 0) {
48358
48764
  messages = messages.slice(0, entry.payload.truncateAtMessageIndex);
48359
48765
  }
48766
+ } else if (entry.type === "artifact") {
48767
+ } else if (entry.type === "summary") {
48768
+ summaries.push(entry.payload);
48360
48769
  }
48361
48770
  }
48362
- return { meta: meta3, state, messages };
48771
+ return { meta: meta3, state, messages, summaries };
48772
+ }
48773
+ function summariesToContextEntries(summaries) {
48774
+ return summaries.slice(-20).map((summary) => ({
48775
+ id: summary.summaryId,
48776
+ sessionIndex: summary.sessionIndex,
48777
+ mode: summary.mode,
48778
+ strategy: summary.strategy,
48779
+ content: summary.content,
48780
+ createdAt: summary.createdAt
48781
+ }));
48782
+ }
48783
+ function findArtifactPayload(log, id) {
48784
+ for (const entry of log.entries) {
48785
+ if (entry.type !== "artifact") continue;
48786
+ if (entry.payload.artifactId === id || entry.payload.outputId === id) {
48787
+ return entry.payload;
48788
+ }
48789
+ }
48790
+ return void 0;
48363
48791
  }
48364
48792
  function materializeAtHead(log) {
48365
48793
  if (!log.headId) return null;
@@ -48398,10 +48826,33 @@ function toCheckpoint(state) {
48398
48826
  const {
48399
48827
  messages: _messages,
48400
48828
  sessionSnapshots: _snapshots,
48829
+ contextCompactionSummaries: _summaries,
48401
48830
  ...checkpoint
48402
48831
  } = state;
48403
48832
  return checkpoint;
48404
48833
  }
48834
+ function collectNewSummaries(log, state) {
48835
+ const summaries = state.contextCompactionSummaries ?? [];
48836
+ if (summaries.length === 0) return [];
48837
+ const existingIds = new Set(
48838
+ log.entries.filter(
48839
+ (entry) => entry.type === "summary"
48840
+ ).map((entry) => entry.payload.summaryId)
48841
+ );
48842
+ return summaries.filter((summary) => !existingIds.has(summary.id));
48843
+ }
48844
+ function appendNewSummaries(log, newSummaries) {
48845
+ for (const summary of newSummaries) {
48846
+ appendSummary(log, {
48847
+ summaryId: summary.id,
48848
+ sessionIndex: summary.sessionIndex,
48849
+ mode: summary.mode,
48850
+ strategy: summary.strategy,
48851
+ content: summary.content,
48852
+ createdAt: summary.createdAt
48853
+ });
48854
+ }
48855
+ }
48405
48856
  var syncStates = /* @__PURE__ */ new Map();
48406
48857
  function primeTreeLogSyncFromState(stateFilePath2, log, state) {
48407
48858
  syncStates.set(stateFilePath2, {
@@ -48437,15 +48888,19 @@ function syncTreeLogWithState(stateFilePath2, state) {
48437
48888
  const messagesDelta = computeMessagesDelta(sync.lastMessages, nextMessages);
48438
48889
  const checkpoint = toCheckpoint(state);
48439
48890
  const checkpointJson = JSON.stringify(checkpoint);
48440
- if (!messagesDelta && checkpointJson === sync.lastCheckpointJson) {
48891
+ const newSummaries = collectNewSummaries(sync.log, state);
48892
+ if (!messagesDelta && checkpointJson === sync.lastCheckpointJson && newSummaries.length === 0) {
48441
48893
  return;
48442
48894
  }
48443
- appendDelta(sync.log, {
48444
- ...messagesDelta ? { messages: messagesDelta } : {},
48445
- state: checkpoint
48446
- });
48447
- sync.lastMessages = nextMessages.map((message) => structuredClone(message));
48448
- sync.lastCheckpointJson = checkpointJson;
48895
+ appendNewSummaries(sync.log, newSummaries);
48896
+ if (messagesDelta || checkpointJson !== sync.lastCheckpointJson) {
48897
+ appendDelta(sync.log, {
48898
+ ...messagesDelta ? { messages: messagesDelta } : {},
48899
+ state: checkpoint
48900
+ });
48901
+ sync.lastMessages = nextMessages.map((message) => structuredClone(message));
48902
+ sync.lastCheckpointJson = checkpointJson;
48903
+ }
48449
48904
  } catch {
48450
48905
  }
48451
48906
  }
@@ -48465,6 +48920,13 @@ function entryLabel(entry) {
48465
48920
  const where = entry.payload.truncateAtMessageIndex !== void 0 ? ` @ message ${entry.payload.truncateAtMessageIndex}` : "";
48466
48921
  return entry.payload.label ? `fork${where} \xB7 ${previewText(entry.payload.label)}` : `fork${where}`;
48467
48922
  }
48923
+ if (entry.type === "artifact") {
48924
+ const tool = entry.payload.toolName ? `${entry.payload.toolName} ` : "";
48925
+ return `artifact \xB7 ${tool}${entry.payload.artifactId} (${entry.payload.charLength.toLocaleString()} chars)`;
48926
+ }
48927
+ if (entry.type === "summary") {
48928
+ return `summary \xB7 session ${entry.payload.sessionIndex} ${entry.payload.mode}`;
48929
+ }
48468
48930
  if (entry.type !== "delta") return entry.type;
48469
48931
  const state = entry.payload.state;
48470
48932
  const cost = typeof state.totalCost === "number" ? ` \xB7 $${state.totalCost.toFixed(4)}` : "";
@@ -48503,7 +48965,8 @@ function buildTreeView(log) {
48503
48965
  kind: entry.type,
48504
48966
  label: entryLabel(entry),
48505
48967
  isHead: entry.id === log.headId,
48506
- isOnHeadPath: onHeadPath.has(entry.id)
48968
+ isOnHeadPath: onHeadPath.has(entry.id),
48969
+ isSelectable: entry.type === "delta" || entry.type === "fork"
48507
48970
  });
48508
48971
  const children = childrenByParent.get(entry.id) ?? [];
48509
48972
  for (const child of children) {
@@ -49372,9 +49835,10 @@ function CheckpointRecap({
49372
49835
  reasoningTokens,
49373
49836
  cost,
49374
49837
  historyWarning,
49375
- isTerminal
49838
+ isTerminal,
49839
+ isStopped
49376
49840
  }) {
49377
- const label = isTerminal ? `\u2713 Run ${sessionNumber} complete` : `Run ${sessionNumber} complete`;
49841
+ const label = isStopped ? `Run ${sessionNumber} stopped` : isTerminal ? `\u2713 Run ${sessionNumber} complete` : `Run ${sessionNumber} complete`;
49378
49842
  const separator = theme22.separator ?? " \xB7 ";
49379
49843
  const usageSummary = [
49380
49844
  `Tools: ${toolCallsMade}`,
@@ -49392,7 +49856,7 @@ function CheckpointRecap({
49392
49856
  paddingX: theme22.panelPaddingX,
49393
49857
  paddingY: theme22.panelPaddingY,
49394
49858
  children: [
49395
- /* @__PURE__ */ jsx23(Text23, { color: isTerminal ? theme22.accentActive : theme22.accent, children: label }),
49859
+ /* @__PURE__ */ jsx23(Text23, { color: isStopped ? theme22.warning : isTerminal ? theme22.accentActive : theme22.accent, children: label }),
49396
49860
  /* @__PURE__ */ jsx23(Text23, { color: theme22.textMuted, children: usageSummary }),
49397
49861
  historyWarning && /* @__PURE__ */ jsx23(Text23, { color: theme22.warning, children: historyWarning })
49398
49862
  ]
@@ -49418,7 +49882,8 @@ function TreePanel({ rows, onSelect, onCancel }) {
49418
49882
  return;
49419
49883
  }
49420
49884
  if (key.return) {
49421
- if (rows.length > 0) onSelect(rows[selectedIndex]);
49885
+ const selected = rows[selectedIndex];
49886
+ if (selected && selected.isSelectable !== false) onSelect(selected);
49422
49887
  return;
49423
49888
  }
49424
49889
  if (key.upArrow) {
@@ -49455,10 +49920,11 @@ function TreePanel({ rows, onSelect, onCancel }) {
49455
49920
  const indicator = isHighlighted ? "\u203A " : " ";
49456
49921
  const indent = " ".repeat(row.depth);
49457
49922
  const headMark = row.isHead ? " \u2190 head" : "";
49923
+ const disabledMark = row.isSelectable === false ? " \xB7 metadata" : "";
49458
49924
  const color = isHighlighted ? theme23.accentActive : row.isOnHeadPath ? theme23.textMuted : theme23.textSubtle;
49459
- return /* @__PURE__ */ jsx24(Box21, { children: /* @__PURE__ */ jsx24(Text24, { color, bold: isHighlighted, children: `${indicator}${indent}${row.label}${headMark}` }) }, row.entryId);
49925
+ return /* @__PURE__ */ jsx24(Box21, { children: /* @__PURE__ */ jsx24(Text24, { color, bold: isHighlighted, children: `${indicator}${indent}${row.label}${headMark}${disabledMark}` }) }, row.entryId);
49460
49926
  }) }),
49461
- /* @__PURE__ */ jsx24(Box21, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text24, { color: theme23.textSubtle, children: ["\u2191\u2193 navigate", "Enter switch to entry", "Esc cancel"].join(
49927
+ /* @__PURE__ */ jsx24(Box21, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text24, { color: theme23.textSubtle, children: ["\u2191\u2193 navigate", "Enter switch to checkpoint", "Esc cancel"].join(
49462
49928
  theme23.separator ?? " \xB7 "
49463
49929
  ) }) })
49464
49930
  ]
@@ -49540,10 +50006,11 @@ function ForkPicker({ candidates, onSelect, onCancel }) {
49540
50006
  // src/ink/marathon/checkpoint-prompt-state.ts
49541
50007
  function shouldPauseCheckpointTimer(state) {
49542
50008
  return Boolean(
49543
- state.isTerminal || state.timeout === 0 || state.isTyping || state.hasPendingChanges || state.showModelPicker || state.showReflectEditor || state.showCommandPicker || state.showTreePanel || state.showForkPicker || state.isReviewing
50009
+ state.isTerminal || state.isStopped || state.timeout === 0 || state.isTyping || state.hasPendingChanges || state.showModelPicker || state.showReflectEditor || state.showCommandPicker || state.showTreePanel || state.showForkPicker || state.isReviewing
49544
50010
  );
49545
50011
  }
49546
50012
  function getCheckpointCountdownText(state) {
50013
+ if (state.isStopped) return "(stopped)";
49547
50014
  if (state.isTerminal) return "(complete)";
49548
50015
  if (state.timeout === 0) return "";
49549
50016
  if (state.isTyping) return "(typing)";
@@ -49564,13 +50031,15 @@ function CheckpointPrompt({
49564
50031
  onLoadForkCandidates,
49565
50032
  timeout,
49566
50033
  isTerminal,
50034
+ isStopped = false,
50035
+ initialMessage,
49567
50036
  currentModel,
49568
50037
  recap,
49569
50038
  isReviewing = false
49570
50039
  }) {
49571
- const [value, setValue] = useState26("");
50040
+ const [value, setValue] = useState26(initialMessage ?? "");
49572
50041
  const [remaining, setRemaining] = useState26(timeout);
49573
- const [isTyping, setIsTyping] = useState26(false);
50042
+ const [isTyping, setIsTyping] = useState26(Boolean(initialMessage));
49574
50043
  const [showModelPicker, setShowModelPicker] = useState26(false);
49575
50044
  const [showReflectEditor, setShowReflectEditor] = useState26(false);
49576
50045
  const [showCommandPicker, setShowCommandPicker] = useState26(false);
@@ -49618,7 +50087,7 @@ function CheckpointPrompt({
49618
50087
  };
49619
50088
  useEffect21(() => {
49620
50089
  const title = "Marathon";
49621
- const body = isTerminal ? "Marathon complete" : `Run ${recap?.sessionNumber ?? "?"} complete`;
50090
+ const body = isStopped ? `Run ${recap?.sessionNumber ?? "?"} stopped` : isTerminal ? "Marathon complete" : `Run ${recap?.sessionNumber ?? "?"} complete`;
49622
50091
  process.stderr.write(`\x1B]777;notify;${title};${body}\x07`);
49623
50092
  process.stderr.write(`\x1B]9;${body}\x07`);
49624
50093
  process.stderr.write("\x07");
@@ -49639,6 +50108,7 @@ function CheckpointPrompt({
49639
50108
  useEffect21(() => {
49640
50109
  if (shouldPauseCheckpointTimer({
49641
50110
  isTerminal,
50111
+ isStopped,
49642
50112
  timeout,
49643
50113
  isTyping,
49644
50114
  hasPendingChanges,
@@ -49671,7 +50141,20 @@ function CheckpointPrompt({
49671
50141
  timerRef.current = null;
49672
50142
  }
49673
50143
  };
49674
- }, [isTerminal, timeout, isTyping, hasPendingChanges, showModelPicker, showReflectEditor, showCommandPicker, treePanelRows, forkCandidates, isReviewing, onSubmit]);
50144
+ }, [
50145
+ isTerminal,
50146
+ isStopped,
50147
+ timeout,
50148
+ isTyping,
50149
+ hasPendingChanges,
50150
+ showModelPicker,
50151
+ showReflectEditor,
50152
+ showCommandPicker,
50153
+ treePanelRows,
50154
+ forkCandidates,
50155
+ isReviewing,
50156
+ onSubmit
50157
+ ]);
49675
50158
  const handleSubmit = (text) => {
49676
50159
  const trimmed = text.trim();
49677
50160
  const modelArg = trimmed.startsWith("/model") ? trimmed.slice("/model".length).trim() : "";
@@ -49779,6 +50262,7 @@ ${trimmed}` : trimmed);
49779
50262
  };
49780
50263
  const handleTreeSelect = (row) => {
49781
50264
  setTreePanelRows(null);
50265
+ if (row.isSelectable === false) return;
49782
50266
  if (row.isHead) return;
49783
50267
  setPendingFork(void 0);
49784
50268
  setPendingTreeHead({ entryId: row.entryId, label: row.label });
@@ -49790,6 +50274,7 @@ ${trimmed}` : trimmed);
49790
50274
  };
49791
50275
  const countdownText = getCheckpointCountdownText({
49792
50276
  isTerminal,
50277
+ isStopped,
49793
50278
  timeout,
49794
50279
  isTyping,
49795
50280
  hasPendingChanges,
@@ -49808,17 +50293,11 @@ ${trimmed}` : trimmed);
49808
50293
  const enterHint = (() => {
49809
50294
  if (isCommandDraft) return "Enter: stage command";
49810
50295
  if (pendingStop || hasPendingChanges || isTyping) return "Enter: submit";
49811
- if (isTerminal) return "Enter: exit";
50296
+ if (isTerminal || isStopped) return "Enter: exit";
49812
50297
  return "Enter: continue";
49813
50298
  })();
49814
50299
  return /* @__PURE__ */ jsxs22(Box23, { flexDirection: "column", flexShrink: 0, children: [
49815
- showCommandPicker ? /* @__PURE__ */ jsx26(
49816
- CommandPicker,
49817
- {
49818
- onSelect: handleCommandSelect,
49819
- onCancel: handleCommandCancel
49820
- }
49821
- ) : treePanelRows !== null ? /* @__PURE__ */ jsx26(
50300
+ showCommandPicker ? /* @__PURE__ */ jsx26(CommandPicker, { onSelect: handleCommandSelect, onCancel: handleCommandCancel }) : treePanelRows !== null ? /* @__PURE__ */ jsx26(
49822
50301
  TreePanel,
49823
50302
  {
49824
50303
  rows: treePanelRows,
@@ -49839,13 +50318,7 @@ ${trimmed}` : trimmed);
49839
50318
  onSelect: handleModelSelect,
49840
50319
  onCancel: handleModelCancel
49841
50320
  }
49842
- ) : showReflectEditor ? /* @__PURE__ */ jsx26(
49843
- ReflectEditor,
49844
- {
49845
- onSubmit: handleReflectSubmit,
49846
- onCancel: handleReflectCancel
49847
- }
49848
- ) : /* @__PURE__ */ jsxs22(
50321
+ ) : showReflectEditor ? /* @__PURE__ */ jsx26(ReflectEditor, { onSubmit: handleReflectSubmit, onCancel: handleReflectCancel }) : /* @__PURE__ */ jsxs22(
49849
50322
  Box23,
49850
50323
  {
49851
50324
  borderStyle: "bold",
@@ -49867,7 +50340,7 @@ ${trimmed}` : trimmed);
49867
50340
  value,
49868
50341
  onChange: handleChange,
49869
50342
  onSubmit: handleSubmit,
49870
- placeholder: isTerminal ? "Send new instructions to continue marathon, or press enter to exit..." : "Guide next iteration..."
50343
+ placeholder: isStopped ? "Send new instructions to continue, or press enter to exit..." : isTerminal ? "Send new instructions to continue marathon, or press enter to exit..." : "Guide next iteration..."
49871
50344
  }
49872
50345
  ) }),
49873
50346
  countdownText && /* @__PURE__ */ jsxs22(Text26, { color: theme25.textSubtle, children: [
@@ -49875,16 +50348,12 @@ ${trimmed}` : trimmed);
49875
50348
  countdownText
49876
50349
  ] })
49877
50350
  ] }),
49878
- /* @__PURE__ */ jsx26(Text26, { color: theme25.textSubtle, children: [
49879
- enterHint,
49880
- "/: commands",
49881
- "/help"
49882
- ].join(separator) }),
50351
+ /* @__PURE__ */ jsx26(Text26, { color: theme25.textSubtle, children: [enterHint, "/: commands", "/help"].join(separator) }),
49883
50352
  pendingSummary.length > 0 && /* @__PURE__ */ jsx26(Text26, { color: theme25.textMuted, children: `Pending: ${pendingSummary.join(separator)}` })
49884
50353
  ]
49885
50354
  }
49886
50355
  ),
49887
- /* @__PURE__ */ jsx26(CheckpointRecap, { ...recap, isTerminal })
50356
+ /* @__PURE__ */ jsx26(CheckpointRecap, { ...recap, isTerminal, isStopped })
49888
50357
  ] });
49889
50358
  }
49890
50359
 
@@ -50830,7 +51299,7 @@ function MarathonApp({
50830
51299
  stateFilePath: stateFilePath2,
50831
51300
  debug: _debug,
50832
51301
  plainText,
50833
- noCheckpoint: _noCheckpoint,
51302
+ noCheckpoint = false,
50834
51303
  checkpointTimeout,
50835
51304
  workflowMilestones,
50836
51305
  currentMilestone: initialCurrentMilestone,
@@ -50838,6 +51307,7 @@ function MarathonApp({
50838
51307
  billingUrl,
50839
51308
  onSaveState,
50840
51309
  onComplete: _onComplete,
51310
+ onAbortTurn,
50841
51311
  streamRef
50842
51312
  }) {
50843
51313
  const {
@@ -50876,6 +51346,7 @@ function MarathonApp({
50876
51346
  const [previewUrl, setPreviewUrl] = useState31(initialPreviewUrl);
50877
51347
  const [isCheckpointExploring, setIsCheckpointExploring] = useState31(false);
50878
51348
  const isRunnerAnimating = state.phase === "thinking" || state.phase === "streaming" || state.phase === "tool" || Boolean(state.contextCompaction?.active);
51349
+ const isAgentWorkingPhase = state.phase === "thinking" || state.phase === "streaming" || state.phase === "tool";
50879
51350
  const isTerminalCheckpointRef = useRef9(false);
50880
51351
  const markCheckpointExploring = useCallback8(() => {
50881
51352
  if (state.phase === "checkpoint" && checkpointRecap) {
@@ -50895,6 +51366,8 @@ function MarathonApp({
50895
51366
  const handleCheckpointSubmit = useCallback8(
50896
51367
  (result) => {
50897
51368
  setIsCheckpointExploring(false);
51369
+ setIsStoppedCheckpoint(false);
51370
+ setCheckpointInitialMessage(void 0);
50898
51371
  if (result.model) {
50899
51372
  setCurrentModel(result.model);
50900
51373
  }
@@ -50957,12 +51430,10 @@ function MarathonApp({
50957
51430
  setCheckpoint();
50958
51431
  setCheckpointRecap(recap);
50959
51432
  setIsCheckpointExploring(false);
50960
- if (isTerminal) {
50961
- setIsTerminalCheckpoint(true);
50962
- isTerminalCheckpointRef.current = true;
50963
- }
50964
- return new Promise((resolve10) => {
50965
- checkpointResolveRef.current = resolve10;
51433
+ setIsTerminalCheckpoint(Boolean(isTerminal));
51434
+ isTerminalCheckpointRef.current = Boolean(isTerminal);
51435
+ return new Promise((resolve11) => {
51436
+ checkpointResolveRef.current = resolve11;
50966
51437
  });
50967
51438
  },
50968
51439
  updateMilestone: (milestone) => {
@@ -51002,6 +51473,18 @@ function MarathonApp({
51002
51473
  const toolPanelWidth = terminalWidth < NARROW_THRESHOLD ? TOOL_PANEL_NARROW : TOOL_PANEL_WIDE;
51003
51474
  const [ctrlCPressed, setCtrlCPressed] = useState31(false);
51004
51475
  const ctrlCTimeout = useRef9(null);
51476
+ const [escAbortArmed, setEscAbortArmed] = useState31(false);
51477
+ const escAbortTimeout = useRef9(null);
51478
+ const [isStoppedCheckpoint, setIsStoppedCheckpoint] = useState31(false);
51479
+ const [checkpointInitialMessage, setCheckpointInitialMessage] = useState31(
51480
+ void 0
51481
+ );
51482
+ useEffect25(() => {
51483
+ if (!isAgentWorkingPhase && escAbortArmed) {
51484
+ if (escAbortTimeout.current) clearTimeout(escAbortTimeout.current);
51485
+ setEscAbortArmed(false);
51486
+ }
51487
+ }, [isAgentWorkingPhase, escAbortArmed]);
51005
51488
  const steeringQueueRef = useRef9([]);
51006
51489
  const followUpQueueRef = useRef9([]);
51007
51490
  const [queuedSteerCount, setQueuedSteerCount] = useState31(0);
@@ -51340,6 +51823,10 @@ function MarathonApp({
51340
51823
  [filteredEvents]
51341
51824
  );
51342
51825
  useInput14((_input, key) => {
51826
+ if (escAbortArmed && !key.escape) {
51827
+ if (escAbortTimeout.current) clearTimeout(escAbortTimeout.current);
51828
+ setEscAbortArmed(false);
51829
+ }
51343
51830
  if (_input === "u" && upgradePrompt) {
51344
51831
  void open4(billingPageUrl);
51345
51832
  setUpgradeModalDismissed(true);
@@ -51495,6 +51982,24 @@ function MarathonApp({
51495
51982
  setActiveScreen("overview");
51496
51983
  } else if (goalExpanded) {
51497
51984
  setGoalExpanded(false);
51985
+ } else if (state.phase === "thinking" || state.phase === "streaming" || state.phase === "tool") {
51986
+ if (escAbortArmed) {
51987
+ if (escAbortTimeout.current) clearTimeout(escAbortTimeout.current);
51988
+ setEscAbortArmed(false);
51989
+ if (onAbortTurn?.() && !noCheckpoint) {
51990
+ const queued = steeringQueueRef.current.splice(0);
51991
+ setQueuedSteerCount(0);
51992
+ const restored = [...queued, steerDraft].map((text) => text.trim()).filter(Boolean).join("\n\n");
51993
+ setSteerDraft("");
51994
+ setCheckpointInitialMessage(restored || void 0);
51995
+ setIsStoppedCheckpoint(true);
51996
+ }
51997
+ } else {
51998
+ setEscAbortArmed(true);
51999
+ escAbortTimeout.current = setTimeout(() => {
52000
+ setEscAbortArmed(false);
52001
+ }, 3e3);
52002
+ }
51498
52003
  }
51499
52004
  return;
51500
52005
  }
@@ -51780,6 +52285,7 @@ function MarathonApp({
51780
52285
  const statusRight = (() => {
51781
52286
  const joinHints = (...parts) => parts.filter(Boolean).join(separator);
51782
52287
  if (ctrlCPressed) return "Press Ctrl+C again to exit";
52288
+ if (escAbortArmed) return "Press Esc again to interrupt the agent";
51783
52289
  if (clipboardFlash) return clipboardFlash;
51784
52290
  if (showUpgradeModal) return joinHints("u: upgrade", "Enter: upgrade", "Esc: close", "Ctrl+C");
51785
52291
  if (state.phase === "error" && !canBrowseAfterUpgradeError) return joinHints("Enter: exit", "Ctrl+C");
@@ -52048,6 +52554,8 @@ function MarathonApp({
52048
52554
  onLoadForkCandidates: handleLoadForkCandidates,
52049
52555
  timeout: checkpointTimeout ?? 10,
52050
52556
  isTerminal: isTerminalCheckpoint,
52557
+ isStopped: isStoppedCheckpoint,
52558
+ initialMessage: checkpointInitialMessage,
52051
52559
  currentModel,
52052
52560
  currentSandbox,
52053
52561
  recap: checkpointRecap,
@@ -52330,16 +52838,16 @@ function MarathonStartupShell({
52330
52838
  latestAppPropsRef.current = marathonAppProps;
52331
52839
  useEffect26(() => {
52332
52840
  if (scene !== "app" || !appReadyResolverRef.current) return;
52333
- const resolve10 = appReadyResolverRef.current;
52841
+ const resolve11 = appReadyResolverRef.current;
52334
52842
  appReadyResolverRef.current = null;
52335
- resolve10();
52843
+ resolve11();
52336
52844
  }, [scene]);
52337
52845
  const beginTransition = (target) => {
52338
52846
  if (transitionPromiseRef.current) return transitionPromiseRef.current;
52339
52847
  if (target === "app" && !latestAppPropsRef.current) {
52340
52848
  throw new Error("Cannot complete startup before marathon app props are ready.");
52341
52849
  }
52342
- const promise2 = new Promise((resolve10) => {
52850
+ const promise2 = new Promise((resolve11) => {
52343
52851
  globalThis.setTimeout(() => {
52344
52852
  setPrompt(null);
52345
52853
  setModelChoices(null);
@@ -52360,12 +52868,12 @@ function MarathonStartupShell({
52360
52868
  if (target === "app") {
52361
52869
  appReadyResolverRef.current = () => {
52362
52870
  transitionPromiseRef.current = null;
52363
- resolve10();
52871
+ resolve11();
52364
52872
  };
52365
52873
  } else {
52366
52874
  dismissResolverRef.current = () => {
52367
52875
  transitionPromiseRef.current = null;
52368
- resolve10();
52876
+ resolve11();
52369
52877
  };
52370
52878
  }
52371
52879
  }, Math.max(0, MIN_HOLD_MS - (Date.now() - mountedAtRef.current)));
@@ -52382,8 +52890,8 @@ function MarathonStartupShell({
52382
52890
  setModelChoices(null);
52383
52891
  setPrompt(nextPrompt);
52384
52892
  setSelectedPromptIndex(0);
52385
- return new Promise((resolve10) => {
52386
- promptResolverRef.current = resolve10;
52893
+ return new Promise((resolve11) => {
52894
+ promptResolverRef.current = resolve11;
52387
52895
  });
52388
52896
  },
52389
52897
  requestModelChoice: async (nextCurrentModel, models) => {
@@ -52391,8 +52899,8 @@ function MarathonStartupShell({
52391
52899
  setPlaybookConfirm(null);
52392
52900
  setCurrentModel(nextCurrentModel);
52393
52901
  setModelChoices(models);
52394
- return new Promise((resolve10) => {
52395
- modelResolverRef.current = resolve10;
52902
+ return new Promise((resolve11) => {
52903
+ modelResolverRef.current = resolve11;
52396
52904
  });
52397
52905
  },
52398
52906
  requestPlaybookModelConfirm: async (playbookName, milestoneModels) => {
@@ -52407,8 +52915,8 @@ function MarathonStartupShell({
52407
52915
  // Default selection is the "Confirm" action (first item after milestones)
52408
52916
  selectedIndex: names.length
52409
52917
  });
52410
- return new Promise((resolve10) => {
52411
- playbookConfirmResolverRef.current = resolve10;
52918
+ return new Promise((resolve11) => {
52919
+ playbookConfirmResolverRef.current = resolve11;
52412
52920
  });
52413
52921
  },
52414
52922
  completeStartup: () => beginTransition("app"),
@@ -52675,7 +53183,7 @@ function MarathonStartupShell({
52675
53183
  }
52676
53184
 
52677
53185
  // src/commands/agents-task.ts
52678
- import * as fs14 from "fs";
53186
+ import * as fs15 from "fs";
52679
53187
  import {
52680
53188
  RuntypeClient as RuntypeClient2,
52681
53189
  defaultWorkflow,
@@ -52706,12 +53214,12 @@ import * as fs7 from "fs";
52706
53214
  import * as path8 from "path";
52707
53215
 
52708
53216
  // src/config/paths.ts
52709
- import * as os3 from "os";
53217
+ import * as os4 from "os";
52710
53218
  import * as path7 from "path";
52711
53219
  import * as crypto4 from "crypto";
52712
53220
  import * as fs6 from "fs";
52713
53221
  function getRuntypeHomeDir() {
52714
- return process.env.RUNTYPE_STATE_DIR || path7.join(os3.homedir(), ".runtype");
53222
+ return process.env.RUNTYPE_STATE_DIR || path7.join(os4.homedir(), ".runtype");
52715
53223
  }
52716
53224
  function getProjectStateDir(projectDir) {
52717
53225
  const dir = projectDir || process.cwd();
@@ -52735,20 +53243,23 @@ function defaultStateDir() {
52735
53243
  function stateSafeName(name) {
52736
53244
  return name.replace(/[^a-zA-Z0-9_-]/g, "_");
52737
53245
  }
52738
- function marathonArtifactsDir(taskName, stateDir) {
53246
+ function marathonArtifactsDir(taskName, stateDir, stateFilePath2) {
53247
+ if (stateFilePath2) {
53248
+ return path8.join(path8.dirname(stateFilePath2), path8.basename(stateFilePath2, ".json"));
53249
+ }
52739
53250
  return path8.join(stateDir || defaultStateDir(), stateSafeName(taskName));
52740
53251
  }
52741
- function resolveMarathonCheckpointPath(taskName, targetPath, stateDir) {
53252
+ function resolveMarathonCheckpointPath(taskName, targetPath, stateDir, stateFilePath2) {
52742
53253
  const normalizedTargetPath = path8.normalize(targetPath);
52743
53254
  const relativeTargetPath = path8.isAbsolute(normalizedTargetPath) ? path8.relative(process.cwd(), normalizedTargetPath) : normalizedTargetPath;
52744
53255
  return path8.join(
52745
- marathonArtifactsDir(taskName, stateDir),
53256
+ marathonArtifactsDir(taskName, stateDir, stateFilePath2),
52746
53257
  "checkpoints",
52747
53258
  "original",
52748
53259
  relativeTargetPath
52749
53260
  );
52750
53261
  }
52751
- function ensureMarathonFileCheckpoint(taskName, targetPath, stateDir) {
53262
+ function ensureMarathonFileCheckpoint(taskName, targetPath, stateDir, stateFilePath2) {
52752
53263
  const normalizedTargetPath = path8.resolve(targetPath);
52753
53264
  const relativeTargetPath = path8.relative(process.cwd(), normalizedTargetPath);
52754
53265
  if (!relativeTargetPath || relativeTargetPath.startsWith("..")) return void 0;
@@ -52757,13 +53268,18 @@ function ensureMarathonFileCheckpoint(taskName, targetPath, stateDir) {
52757
53268
  const normalizedRelativeTargetPath = relativeTargetPath.replace(/\\/g, "/");
52758
53269
  if (normalizedRelativeTargetPath.startsWith(".runtype/")) return void 0;
52759
53270
  if (normalizedTargetPath.startsWith(getRuntypeHomeDir() + path8.sep)) return void 0;
52760
- const checkpointPath = resolveMarathonCheckpointPath(taskName, normalizedTargetPath, stateDir);
53271
+ const checkpointPath = resolveMarathonCheckpointPath(
53272
+ taskName,
53273
+ normalizedTargetPath,
53274
+ stateDir,
53275
+ stateFilePath2
53276
+ );
52761
53277
  if (fs7.existsSync(checkpointPath)) return checkpointPath;
52762
53278
  fs7.mkdirSync(path8.dirname(checkpointPath), { recursive: true });
52763
53279
  fs7.copyFileSync(normalizedTargetPath, checkpointPath);
52764
53280
  return checkpointPath;
52765
53281
  }
52766
- function restoreMarathonFileCheckpoint(taskName, targetPath, stateDir) {
53282
+ function restoreMarathonFileCheckpoint(taskName, targetPath, stateDir, stateFilePath2) {
52767
53283
  const normalizedTargetPath = path8.resolve(targetPath);
52768
53284
  const relativeTargetPath = path8.relative(process.cwd(), normalizedTargetPath);
52769
53285
  if (!relativeTargetPath || relativeTargetPath.startsWith("..")) {
@@ -52772,7 +53288,12 @@ function restoreMarathonFileCheckpoint(taskName, targetPath, stateDir) {
52772
53288
  error: `Cannot restore checkpoint outside the current repository: ${normalizedTargetPath}`
52773
53289
  };
52774
53290
  }
52775
- const checkpointPath = resolveMarathonCheckpointPath(taskName, normalizedTargetPath, stateDir);
53291
+ const checkpointPath = resolveMarathonCheckpointPath(
53292
+ taskName,
53293
+ normalizedTargetPath,
53294
+ stateDir,
53295
+ stateFilePath2
53296
+ );
52776
53297
  if (!fs7.existsSync(checkpointPath)) {
52777
53298
  return {
52778
53299
  restored: false,
@@ -52897,16 +53418,33 @@ async function retryOnNetworkError(fn, opts = {}) {
52897
53418
  const maxDelay = opts.maxDelayMs ?? 6e4;
52898
53419
  let lastError;
52899
53420
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
53421
+ if (attempt > 0 && opts.signal?.aborted) {
53422
+ throw lastError;
53423
+ }
52900
53424
  try {
52901
53425
  return await fn();
52902
53426
  } catch (error51) {
52903
53427
  lastError = error51;
52904
- if (!isTransientNetworkError(error51) || attempt === maxRetries) {
53428
+ if (opts.signal?.aborted || !isTransientNetworkError(error51) || attempt === maxRetries) {
52905
53429
  throw error51;
52906
53430
  }
52907
53431
  const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
52908
53432
  opts.onRetry?.(attempt + 1, delay, error51);
52909
- await new Promise((resolve10) => setTimeout(resolve10, delay));
53433
+ await new Promise((resolve11) => {
53434
+ const signal = opts.signal;
53435
+ const onAbort = () => {
53436
+ clearTimeout(timer);
53437
+ resolve11();
53438
+ };
53439
+ const timer = setTimeout(() => {
53440
+ signal?.removeEventListener("abort", onAbort);
53441
+ resolve11();
53442
+ }, delay);
53443
+ if (signal) {
53444
+ if (signal.aborted) onAbort();
53445
+ else signal.addEventListener("abort", onAbort, { once: true });
53446
+ }
53447
+ });
52910
53448
  }
52911
53449
  }
52912
53450
  throw lastError;
@@ -53166,14 +53704,14 @@ async function promptNumericSelect(choices, promptLabel) {
53166
53704
  output: process.stdout,
53167
53705
  terminal: true
53168
53706
  });
53169
- return new Promise((resolve10) => {
53707
+ return new Promise((resolve11) => {
53170
53708
  const ask = () => {
53171
53709
  rl.question(chalk21.cyan(`
53172
53710
  ${promptLabel} (1-${choices.length}): `), (answer) => {
53173
53711
  const value = parseInt(answer.trim(), 10);
53174
53712
  if (value >= 1 && value <= choices.length) {
53175
53713
  rl.close();
53176
- resolve10(choices[value - 1].value);
53714
+ resolve11(choices[value - 1].value);
53177
53715
  return;
53178
53716
  }
53179
53717
  console.log(chalk21.red(`Please enter a number between 1 and ${choices.length}.`));
@@ -53201,7 +53739,7 @@ ${message}`));
53201
53739
  const previousRawMode = input.isRaw === true;
53202
53740
  let selectedIndex = 0;
53203
53741
  let renderedLineCount = 0;
53204
- return new Promise((resolve10) => {
53742
+ return new Promise((resolve11) => {
53205
53743
  const renderMenu = () => {
53206
53744
  if (renderedLineCount > 0) {
53207
53745
  clearRenderedLines(output, renderedLineCount);
@@ -53223,7 +53761,7 @@ ${message}`));
53223
53761
  };
53224
53762
  const finish = (value) => {
53225
53763
  cleanup();
53226
- resolve10(value);
53764
+ resolve11(value);
53227
53765
  };
53228
53766
  const onKeypress = (_, key) => {
53229
53767
  if (key.ctrl && key.name === "c") {
@@ -53373,7 +53911,9 @@ function sanitizeMarathonSessionSnapshots(snapshots) {
53373
53911
  };
53374
53912
  bySessionIndex.set(sanitizedSnapshot.sessionIndex, sanitizedSnapshot);
53375
53913
  }
53376
- return Array.from(bySessionIndex.values()).sort((left, right) => left.sessionIndex - right.sessionIndex);
53914
+ return Array.from(bySessionIndex.values()).sort(
53915
+ (left, right) => left.sessionIndex - right.sessionIndex
53916
+ );
53377
53917
  }
53378
53918
  function upsertMarathonSessionSnapshot(snapshots, nextSnapshot) {
53379
53919
  const bySessionIndex = /* @__PURE__ */ new Map();
@@ -53381,7 +53921,9 @@ function upsertMarathonSessionSnapshot(snapshots, nextSnapshot) {
53381
53921
  bySessionIndex.set(snapshot.sessionIndex, cloneSessionSnapshot2(snapshot));
53382
53922
  }
53383
53923
  bySessionIndex.set(nextSnapshot.sessionIndex, cloneSessionSnapshot2(nextSnapshot));
53384
- return Array.from(bySessionIndex.values()).sort((left, right) => left.sessionIndex - right.sessionIndex);
53924
+ return Array.from(bySessionIndex.values()).sort(
53925
+ (left, right) => left.sessionIndex - right.sessionIndex
53926
+ );
53385
53927
  }
53386
53928
  function mergeMarathonSessionSummaries(existingSessions, nextSessions, offset) {
53387
53929
  const byIndex = /* @__PURE__ */ new Map();
@@ -53434,7 +53976,9 @@ function sanitizeLoadedMarathonState(state) {
53434
53976
  (candidatePath) => marathonStatePathExists(candidatePath)
53435
53977
  );
53436
53978
  const normalizedBestCandidate = normalizeMarathonStatePath(state.bestCandidatePath);
53437
- const bestCandidatePath = normalizedBestCandidate && !isMarathonArtifactStatePath(normalizedBestCandidate) && marathonStatePathExists(normalizedBestCandidate) ? normalizedBestCandidate : [...candidatePaths, ...recentReadPaths].sort((left, right) => scoreMarathonCandidatePath(right) - scoreMarathonCandidatePath(left))[0];
53979
+ const bestCandidatePath = normalizedBestCandidate && !isMarathonArtifactStatePath(normalizedBestCandidate) && marathonStatePathExists(normalizedBestCandidate) ? normalizedBestCandidate : [...candidatePaths, ...recentReadPaths].sort(
53980
+ (left, right) => scoreMarathonCandidatePath(right) - scoreMarathonCandidatePath(left)
53981
+ )[0];
53438
53982
  const persisted = state;
53439
53983
  const {
53440
53984
  runnerPosition: _runnerPosition,
@@ -53493,8 +54037,25 @@ function extractRunTaskResumeState(state) {
53493
54037
  ...sanitized.verificationRequired !== void 0 ? { verificationRequired: sanitized.verificationRequired } : {},
53494
54038
  ...sanitized.lastVerificationPassed ? { lastVerificationPassed: sanitized.lastVerificationPassed } : {},
53495
54039
  ...sanitized.isCreationTask !== void 0 ? { isCreationTask: sanitized.isCreationTask } : {},
53496
- ...sanitized.outputRoot ? { outputRoot: sanitized.outputRoot } : {}
53497
- };
54040
+ ...sanitized.outputRoot ? { outputRoot: sanitized.outputRoot } : {},
54041
+ ...sanitized.contextCompactionSummaries?.length ? { contextCompactionSummaries: sanitized.contextCompactionSummaries } : {},
54042
+ ...typeof sanitized.contextWindowBaseIndex === "number" && sanitized.contextWindowBaseIndex > 0 ? { contextWindowBaseIndex: sanitized.contextWindowBaseIndex } : {}
54043
+ };
54044
+ }
54045
+ function offsetNewContextCompactionSummaries(summaries, existingSummaryIds, sessionOffset) {
54046
+ if (!summaries?.length) return void 0;
54047
+ if (sessionOffset === 0) return summaries;
54048
+ const existingIds = new Set(existingSummaryIds);
54049
+ return summaries.map((summary) => {
54050
+ if (existingIds.has(summary.id)) return summary;
54051
+ const absoluteSessionIndex = summary.sessionIndex + sessionOffset;
54052
+ const idPrefix = `ctx_${summary.sessionIndex}_`;
54053
+ return {
54054
+ ...summary,
54055
+ id: summary.id.startsWith(idPrefix) ? `ctx_${absoluteSessionIndex}_${summary.id.slice(idPrefix.length)}` : summary.id,
54056
+ sessionIndex: absoluteSessionIndex
54057
+ };
54058
+ });
53498
54059
  }
53499
54060
  function findStateFile(name, stateDir) {
53500
54061
  if (stateDir) {
@@ -53649,6 +54210,8 @@ function applyCheckpointTreeNavigation(stateFilePath2, navigation) {
53649
54210
  if (!log || !log.headId) return null;
53650
54211
  const destinationId = navigation.fork ? log.headId : navigation.treeHead;
53651
54212
  if (!destinationId || !log.byId.has(destinationId)) return null;
54213
+ const destination = log.byId.get(destinationId);
54214
+ if (!destination || destination.type !== "delta" && destination.type !== "fork") return null;
53652
54215
  try {
53653
54216
  if (!materializeAtEntry(log, destinationId).state) return null;
53654
54217
  } catch {
@@ -53675,21 +54238,39 @@ function applyCheckpointTreeNavigation(stateFilePath2, navigation) {
53675
54238
  lastOutput: anchor.lastOutput,
53676
54239
  lastStopReason: anchor.lastStopReason
53677
54240
  } : {};
54241
+ const forkAnchoredBase = anchor?.contextWindowBaseIndex ?? 0;
54242
+ const windowBaseOverride = navigation.fork ? {
54243
+ contextWindowBaseIndex: forkAnchoredBase <= navigation.fork.atMessageIndex ? forkAnchoredBase : 0
54244
+ } : {};
53678
54245
  const effectiveSessionCount = sessionShapedOverrides.sessionCount ?? materialized.state.sessionCount;
53679
54246
  const currentJson = loadState(stateFilePath2);
53680
54247
  const now = (/* @__PURE__ */ new Date()).toISOString();
53681
- const { sessionSnapshots: priorSnapshots, ...restJson } = currentJson ?? {};
54248
+ const {
54249
+ sessionSnapshots: priorSnapshots,
54250
+ contextCompactionSummaries: _priorSummaries,
54251
+ ...restJson
54252
+ } = currentJson ?? {};
53682
54253
  const keptSnapshots = (priorSnapshots ?? []).filter(
53683
54254
  (snapshot) => snapshot.sessionIndex <= effectiveSessionCount
53684
54255
  );
54256
+ const branchSummaries = summariesToContextEntries(materialized.summaries);
54257
+ const contextCompactionSummaries = branchSummaries.length ? branchSummaries : materialized.state.contextCompactionSummaries;
53685
54258
  const mergedState = {
53686
54259
  ...restJson,
53687
54260
  ...materialized.state,
53688
54261
  ...sessionShapedOverrides,
54262
+ ...windowBaseOverride,
53689
54263
  messages: materialized.messages,
54264
+ ...contextCompactionSummaries?.length ? { contextCompactionSummaries } : {},
53690
54265
  ...keptSnapshots.length > 0 ? { sessionSnapshots: keptSnapshots } : {},
53691
54266
  updatedAt: now
53692
54267
  };
54268
+ if (typeof mergedState.contextWindowBaseIndex === "number") {
54269
+ mergedState.contextWindowBaseIndex = Math.max(
54270
+ 0,
54271
+ Math.min(mergedState.contextWindowBaseIndex, materialized.messages.length)
54272
+ );
54273
+ }
53693
54274
  primeTreeLogSyncFromState(stateFilePath2, log, mergedState);
53694
54275
  saveState(stateFilePath2, mergedState);
53695
54276
  return { messages: materialized.messages, mergedState };
@@ -53698,7 +54279,11 @@ function applyCheckpointTreeNavigation(stateFilePath2, navigation) {
53698
54279
  // src/marathon/local-tools.ts
53699
54280
  import * as fs10 from "fs";
53700
54281
  import * as path11 from "path";
54282
+ import { createHash as createHash2 } from "crypto";
53701
54283
  import { spawnSync } from "child_process";
54284
+ import {
54285
+ LEDGER_ARTIFACT_LINE_PREFIX
54286
+ } from "@runtypelabs/sdk";
53702
54287
 
53703
54288
  // src/marathon/repo-discovery.ts
53704
54289
  import * as fs9 from "fs";
@@ -53914,8 +54499,11 @@ var DIRECT_TOOL_BLOCKED_SEGMENTS = /* @__PURE__ */ new Set([".git", ".runtype"])
53914
54499
  function stateSafeName3(name) {
53915
54500
  return name.replace(/[^a-zA-Z0-9_-]/g, "_");
53916
54501
  }
53917
- function getOffloadedOutputDir(taskName, stateDir) {
53918
- return path11.join(stateDir || getMarathonStateDir(), stateSafeName3(taskName), "outputs");
54502
+ function getStateFilePathForTask(taskName, stateDir, stateFilePath2) {
54503
+ return stateFilePath2 || path11.join(stateDir || getMarathonStateDir(), `${stateSafeName3(taskName)}.json`);
54504
+ }
54505
+ function getOffloadedOutputDir(taskName, stateDir, stateFilePath2) {
54506
+ return artifactStoreDirForStateFile(getStateFilePathForTask(taskName, stateDir, stateFilePath2));
53919
54507
  }
53920
54508
  function isPathWithinRoot(targetPath, rootPath) {
53921
54509
  const relativePath = path11.relative(rootPath, targetPath);
@@ -53962,11 +54550,10 @@ function resolveToolPath(toolPath, options = {}) {
53962
54550
  return { ok: false, error: `Path does not exist: ${requestedPath}` };
53963
54551
  }
53964
54552
  const workspaceRoot = fs10.realpathSync.native(process.cwd());
53965
- const extraRoots = (options.allowedRoots || []).map((rootPath) => canonicalizeAllowedRoot(rootPath));
53966
- const allowedRoots = [
53967
- ...extraRoots,
53968
- workspaceRoot
53969
- ];
54553
+ const extraRoots = (options.allowedRoots || []).map(
54554
+ (rootPath) => canonicalizeAllowedRoot(rootPath)
54555
+ );
54556
+ const allowedRoots = [...extraRoots, workspaceRoot];
53970
54557
  const matchedRoot = allowedRoots.find(
53971
54558
  (rootPath) => isPathWithinRoot(resolved.canonicalPath, rootPath)
53972
54559
  );
@@ -54016,15 +54603,15 @@ function resolveToolPath(toolPath, options = {}) {
54016
54603
  }
54017
54604
  return { ok: true, resolvedPath: resolved.canonicalPath };
54018
54605
  }
54019
- function getTaskStateRoot(taskName, stateDir) {
54020
- return path11.join(stateDir || getMarathonStateDir(), stateSafeName3(taskName));
54606
+ function getTaskStateRoot(taskName, stateDir, stateFilePath2) {
54607
+ return path11.dirname(getOffloadedOutputDir(taskName, stateDir, stateFilePath2));
54021
54608
  }
54022
54609
  function createDefaultLocalTools(context) {
54023
- const taskStateRoot = context?.taskName ? getTaskStateRoot(context.taskName, context.stateDir) : void 0;
54610
+ const taskStateRoot = context?.taskName ? getTaskStateRoot(context.taskName, context.stateDir, context.stateFilePath) : void 0;
54024
54611
  const planDir = context?.taskName ? path11.resolve(`.runtype/marathons/${stateSafeName3(context.taskName)}`) : void 0;
54025
54612
  const planPathDir = context?.planPath ? path11.resolve(path11.dirname(context.planPath)) : void 0;
54026
54613
  const allowedReadRoots = context?.taskName ? [
54027
- getOffloadedOutputDir(context.taskName, context.stateDir),
54614
+ getOffloadedOutputDir(context.taskName, context.stateDir, context.stateFilePath),
54028
54615
  ...taskStateRoot ? [taskStateRoot] : [],
54029
54616
  ...planDir ? [planDir] : [],
54030
54617
  ...planPathDir ? [planPathDir] : []
@@ -54082,7 +54669,9 @@ function createDefaultLocalTools(context) {
54082
54669
  requireDirectory: true
54083
54670
  });
54084
54671
  if (!resolvedPath.ok) return `Error: ${resolvedPath.error}`;
54085
- return fs10.readdirSync(resolvedPath.resolvedPath, { withFileTypes: true }).filter((entry) => !shouldIgnoreRepoEntry(path11.join(resolvedPath.resolvedPath, entry.name))).map((entry) => entry.name).join("\n");
54672
+ return fs10.readdirSync(resolvedPath.resolvedPath, { withFileTypes: true }).filter(
54673
+ (entry) => !shouldIgnoreRepoEntry(path11.join(resolvedPath.resolvedPath, entry.name))
54674
+ ).map((entry) => entry.name).join("\n");
54086
54675
  }
54087
54676
  },
54088
54677
  search_repo: {
@@ -54114,7 +54703,10 @@ function createDefaultLocalTools(context) {
54114
54703
  if (!startPath.ok) return `Error: ${startPath.error}`;
54115
54704
  const maxResults = Math.max(
54116
54705
  1,
54117
- Math.min(100, Number.isFinite(Number(args.maxResults)) ? Math.floor(Number(args.maxResults)) : 20)
54706
+ Math.min(
54707
+ 100,
54708
+ Number.isFinite(Number(args.maxResults)) ? Math.floor(Number(args.maxResults)) : 20
54709
+ )
54118
54710
  );
54119
54711
  const needle = query.toLowerCase();
54120
54712
  const tokens = tokenizeSearchQuery(query);
@@ -54221,20 +54813,31 @@ function createDefaultLocalTools(context) {
54221
54813
  if (!dirPath.ok) return `Error: ${dirPath.error}`;
54222
54814
  const maxDepth = Math.max(
54223
54815
  0,
54224
- Math.min(6, Number.isFinite(Number(args.maxDepth)) ? Math.floor(Number(args.maxDepth)) : 2)
54816
+ Math.min(
54817
+ 6,
54818
+ Number.isFinite(Number(args.maxDepth)) ? Math.floor(Number(args.maxDepth)) : 2
54819
+ )
54225
54820
  );
54226
- const lines = [`${normalizeToolPath(dirPath.resolvedPath)}/`, ...buildTree(dirPath.resolvedPath, maxDepth)];
54821
+ const lines = [
54822
+ `${normalizeToolPath(dirPath.resolvedPath)}/`,
54823
+ ...buildTree(dirPath.resolvedPath, maxDepth)
54824
+ ];
54227
54825
  return lines.join("\n");
54228
54826
  }
54229
54827
  }
54230
54828
  };
54231
54829
  }
54232
- function createCheckpointedWriteFileTool(taskName, stateDir, planPath) {
54233
- const taskStateRoot = getTaskStateRoot(taskName, stateDir);
54830
+ function createCheckpointedWriteFileTool(taskName, stateDir, planPath, stateFilePath2) {
54831
+ const taskStateRoot = getTaskStateRoot(taskName, stateDir, stateFilePath2);
54234
54832
  const planDir = path11.resolve(`.runtype/marathons/${stateSafeName3(taskName)}`);
54235
54833
  const marathonPlanRoot = path11.resolve(".runtype/marathons");
54236
54834
  const planPathDir = planPath ? path11.resolve(path11.dirname(planPath)) : void 0;
54237
- const writeAllowedRoots = [taskStateRoot, planDir, marathonPlanRoot, ...planPathDir ? [planPathDir] : []];
54835
+ const writeAllowedRoots = [
54836
+ taskStateRoot,
54837
+ planDir,
54838
+ marathonPlanRoot,
54839
+ ...planPathDir ? [planPathDir] : []
54840
+ ];
54238
54841
  return {
54239
54842
  description: "Write content to a file, creating directories as needed and checkpointing original repo files",
54240
54843
  parametersSchema: {
@@ -54252,7 +54855,7 @@ function createCheckpointedWriteFileTool(taskName, stateDir, planPath) {
54252
54855
  });
54253
54856
  if (!resolvedPath.ok) return `Error: ${resolvedPath.error}`;
54254
54857
  const content = String(args.content || "");
54255
- ensureMarathonFileCheckpoint(taskName, resolvedPath.resolvedPath, stateDir);
54858
+ ensureMarathonFileCheckpoint(taskName, resolvedPath.resolvedPath, stateDir, stateFilePath2);
54256
54859
  const dir = path11.dirname(resolvedPath.resolvedPath);
54257
54860
  fs10.mkdirSync(dir, { recursive: true });
54258
54861
  fs10.writeFileSync(resolvedPath.resolvedPath, content);
@@ -54280,12 +54883,17 @@ function quickJsSyntaxCheck(content) {
54280
54883
  return void 0;
54281
54884
  }
54282
54885
  }
54283
- function createEditFileTool(taskName, stateDir, planPath) {
54284
- const taskStateRoot = getTaskStateRoot(taskName, stateDir);
54886
+ function createEditFileTool(taskName, stateDir, planPath, stateFilePath2) {
54887
+ const taskStateRoot = getTaskStateRoot(taskName, stateDir, stateFilePath2);
54285
54888
  const planDir = path11.resolve(`.runtype/marathons/${stateSafeName3(taskName)}`);
54286
54889
  const marathonPlanRoot = path11.resolve(".runtype/marathons");
54287
54890
  const planPathDir = planPath ? path11.resolve(path11.dirname(planPath)) : void 0;
54288
- const writeAllowedRoots = [taskStateRoot, planDir, marathonPlanRoot, ...planPathDir ? [planPathDir] : []];
54891
+ const writeAllowedRoots = [
54892
+ taskStateRoot,
54893
+ planDir,
54894
+ marathonPlanRoot,
54895
+ ...planPathDir ? [planPathDir] : []
54896
+ ];
54289
54897
  return {
54290
54898
  description: "Make a targeted edit to a file by replacing a specific string. Much more efficient than rewriting the entire file with write_file. The old_string must appear exactly once in the file (or use replace_all for global replacement). Always read the file first to get the exact text to replace.",
54291
54899
  parametersSchema: {
@@ -54293,7 +54901,10 @@ function createEditFileTool(taskName, stateDir, planPath) {
54293
54901
  properties: {
54294
54902
  path: { type: "string", description: "File path to edit" },
54295
54903
  // @snake-case-ok: Parameter names use snake_case to match agent tool conventions
54296
- old_string: { type: "string", description: "Exact string to find and replace (must be unique in the file)" },
54904
+ old_string: {
54905
+ type: "string",
54906
+ description: "Exact string to find and replace (must be unique in the file)"
54907
+ },
54297
54908
  // @snake-case-ok: Parameter names use snake_case to match agent tool conventions
54298
54909
  new_string: { type: "string", description: "Replacement string" },
54299
54910
  // @snake-case-ok: Parameter names use snake_case to match agent tool conventions
@@ -54332,7 +54943,7 @@ function createEditFileTool(taskName, stateDir, planPath) {
54332
54943
  return `Error: old_string appears ${count} times in the file. Provide more surrounding context to make it unique, or set replace_all to true.`;
54333
54944
  }
54334
54945
  }
54335
- ensureMarathonFileCheckpoint(taskName, resolvedPath.resolvedPath, stateDir);
54946
+ ensureMarathonFileCheckpoint(taskName, resolvedPath.resolvedPath, stateDir, stateFilePath2);
54336
54947
  const updated = replaceAll ? content.split(oldString).join(newString) : content.replace(oldString, newString);
54337
54948
  fs10.writeFileSync(resolvedPath.resolvedPath, updated);
54338
54949
  const ext = path11.extname(resolvedPath.resolvedPath).toLowerCase();
@@ -54348,7 +54959,7 @@ function createEditFileTool(taskName, stateDir, planPath) {
54348
54959
  }
54349
54960
  };
54350
54961
  }
54351
- function createRestoreFileCheckpointTool(taskName, stateDir) {
54962
+ function createRestoreFileCheckpointTool(taskName, stateDir, stateFilePath2) {
54352
54963
  return {
54353
54964
  description: "Restore the original checkpointed contents for a previously edited repo file if a change regresses behavior",
54354
54965
  parametersSchema: {
@@ -54363,7 +54974,12 @@ function createRestoreFileCheckpointTool(taskName, stateDir) {
54363
54974
  requireFile: true
54364
54975
  });
54365
54976
  if (!resolvedPath.ok) return `Error: ${resolvedPath.error}`;
54366
- const result = restoreMarathonFileCheckpoint(taskName, resolvedPath.resolvedPath, stateDir);
54977
+ const result = restoreMarathonFileCheckpoint(
54978
+ taskName,
54979
+ resolvedPath.resolvedPath,
54980
+ stateDir,
54981
+ stateFilePath2
54982
+ );
54367
54983
  if (!result.restored) {
54368
54984
  return result.error || `No checkpoint found for ${String(args.path || "")}`;
54369
54985
  }
@@ -54371,15 +54987,15 @@ function createRestoreFileCheckpointTool(taskName, stateDir) {
54371
54987
  }
54372
54988
  };
54373
54989
  }
54374
- function createReadOffloadedOutputTool(taskName, stateDir) {
54990
+ function createReadOffloadedOutputTool(taskName, stateDir, stateFilePath2) {
54375
54991
  return {
54376
- description: "Read the full contents of a previously offloaded tool result by id",
54992
+ description: "Read the full contents of a previously offloaded ledger artifact by id",
54377
54993
  parametersSchema: {
54378
54994
  type: "object",
54379
54995
  properties: {
54380
54996
  id: {
54381
54997
  type: "string",
54382
- description: "Offloaded output id returned by a previous tool result"
54998
+ description: "Offloaded output or ledger artifact id returned by a previous tool result"
54383
54999
  }
54384
55000
  },
54385
55001
  required: ["id"]
@@ -54390,11 +55006,41 @@ function createReadOffloadedOutputTool(taskName, stateDir) {
54390
55006
  if (!/^[a-zA-Z0-9_-]+$/.test(outputId)) {
54391
55007
  return `Error: invalid offloaded output id: ${outputId}`;
54392
55008
  }
54393
- const outputPath = path11.join(getOffloadedOutputDir(taskName, stateDir), `${outputId}.txt`);
55009
+ const verifyContent = (content, expectedSha256) => {
55010
+ if (!expectedSha256) return content;
55011
+ const actual = createHash2("sha256").update(content).digest("hex");
55012
+ if (actual === expectedSha256) return content;
55013
+ return [
55014
+ `[Warning: artifact content no longer matches its recorded sha256 (${outputId}) \u2014 the file was modified after it was offloaded]`,
55015
+ content
55016
+ ].join("\n");
55017
+ };
55018
+ const idEmbeddedSha256 = /^art_([0-9a-f]{64})$/.exec(outputId)?.[1];
55019
+ const outputPath = path11.join(
55020
+ getOffloadedOutputDir(taskName, stateDir, stateFilePath2),
55021
+ `${outputId}.txt`
55022
+ );
54394
55023
  if (!fs10.existsSync(outputPath) || !fs10.statSync(outputPath).isFile()) {
55024
+ const resolvedStateFilePath = getStateFilePathForTask(taskName, stateDir, stateFilePath2);
55025
+ const log = loadTreeLog(treeLogPathForStateFile(resolvedStateFilePath));
55026
+ const artifact = log ? findArtifactPayload(log, outputId) : void 0;
55027
+ if (artifact) {
55028
+ const ledgerPath = path11.resolve(
55029
+ path11.dirname(treeLogPathForStateFile(resolvedStateFilePath)),
55030
+ artifact.relativePath
55031
+ );
55032
+ if (fs10.existsSync(ledgerPath) && fs10.statSync(ledgerPath).isFile()) {
55033
+ return verifyContent(fs10.readFileSync(ledgerPath, "utf-8"), artifact.sha256);
55034
+ }
55035
+ return [
55036
+ `Error: offloaded output recorded in the context ledger but missing locally: ${outputId}`,
55037
+ artifact.host ? `Stored on host: ${artifact.host}` : void 0,
55038
+ `${LEDGER_ARTIFACT_LINE_PREFIX}${artifact.relativePath}`
55039
+ ].filter(Boolean).join("\n");
55040
+ }
54395
55041
  return `Error: offloaded output not found: ${outputId}`;
54396
55042
  }
54397
- return fs10.readFileSync(outputPath, "utf-8");
55043
+ return verifyContent(fs10.readFileSync(outputPath, "utf-8"), idEmbeddedSha256);
54398
55044
  }
54399
55045
  };
54400
55046
  }
@@ -54533,19 +55179,34 @@ function buildLocalTools(client, sandboxProvider, options, context) {
54533
55179
  if (!options.noLocalTools) {
54534
55180
  Object.assign(enabledTools, createDefaultLocalTools(context));
54535
55181
  if (context) {
54536
- enabledTools.write_file = createCheckpointedWriteFileTool(context.taskName, context.stateDir, context.planPath);
54537
- enabledTools.edit_file = createEditFileTool(context.taskName, context.stateDir, context.planPath);
55182
+ enabledTools.write_file = createCheckpointedWriteFileTool(
55183
+ context.taskName,
55184
+ context.stateDir,
55185
+ context.planPath,
55186
+ context.stateFilePath
55187
+ );
55188
+ enabledTools.edit_file = createEditFileTool(
55189
+ context.taskName,
55190
+ context.stateDir,
55191
+ context.planPath,
55192
+ context.stateFilePath
55193
+ );
54538
55194
  enabledTools.restore_file_checkpoint = createRestoreFileCheckpointTool(
54539
55195
  context.taskName,
54540
- context.stateDir
55196
+ context.stateDir,
55197
+ context.stateFilePath
54541
55198
  );
54542
55199
  enabledTools.read_offloaded_output = createReadOffloadedOutputTool(
54543
55200
  context.taskName,
54544
- context.stateDir
55201
+ context.stateDir,
55202
+ context.stateFilePath
54545
55203
  );
54546
55204
  enabledTools.run_check = createRunCheckTool();
54547
- if (options.sessionSearch === true) {
54548
- enabledTools.search_session_history = createSearchSessionHistoryTool(client, context.taskName);
55205
+ if (options.sessionSearch !== false) {
55206
+ enabledTools.search_session_history = createSearchSessionHistoryTool(
55207
+ client,
55208
+ context.taskName
55209
+ );
54549
55210
  }
54550
55211
  }
54551
55212
  }
@@ -54561,9 +55222,33 @@ function buildLocalTools(client, sandboxProvider, options, context) {
54561
55222
  }
54562
55223
 
54563
55224
  // src/marathon/session-chunker.ts
55225
+ import * as fs11 from "fs";
55226
+ import * as path12 from "path";
55227
+ import {
55228
+ parseLedgerArtifactRelativePath,
55229
+ parseOffloadedOutputId
55230
+ } from "@runtypelabs/sdk";
54564
55231
  var DEFAULT_MAX_CHUNK_CHARS = 2e3;
54565
55232
  var MIN_CONTENT_LENGTH = 50;
54566
- function extractSessionChunks(snapshot, maxChunkChars = DEFAULT_MAX_CHUNK_CHARS) {
55233
+ function extractSessionChunksWithLedger(snapshot, options) {
55234
+ const maxChunkChars = options.maxChunkChars ?? DEFAULT_MAX_CHUNK_CHARS;
55235
+ const log = loadTreeLog(treeLogPathForStateFile(options.stateFilePath));
55236
+ const chunks = extractCoreSessionChunks(
55237
+ snapshot,
55238
+ maxChunkChars,
55239
+ (tool) => resolveLedgerToolResult(tool, options.stateFilePath, log)
55240
+ );
55241
+ for (const summary of options.summaries ?? []) {
55242
+ if (summary.sessionIndex !== snapshot.sessionIndex) continue;
55243
+ const content = `[Compaction summary]
55244
+ ${summary.content}`;
55245
+ if (content.length >= MIN_CONTENT_LENGTH) {
55246
+ chunks.push(...chunkText(content, "reasoning", maxChunkChars));
55247
+ }
55248
+ }
55249
+ return chunks;
55250
+ }
55251
+ function extractCoreSessionChunks(snapshot, maxChunkChars, resolveToolResult) {
54567
55252
  const chunks = [];
54568
55253
  if (snapshot.content && snapshot.content.length >= MIN_CONTENT_LENGTH) {
54569
55254
  chunks.push(...chunkText(snapshot.content, "response", maxChunkChars));
@@ -54572,15 +55257,43 @@ function extractSessionChunks(snapshot, maxChunkChars = DEFAULT_MAX_CHUNK_CHARS)
54572
55257
  chunks.push(...chunkText(snapshot.reasoning, "reasoning", maxChunkChars));
54573
55258
  }
54574
55259
  for (const tool of snapshot.tools) {
54575
- const result = typeof tool.result === "string" ? tool.result : JSON.stringify(tool.result ?? "");
55260
+ const result = resolveToolResult(tool);
54576
55261
  if (result.length >= MIN_CONTENT_LENGTH) {
54577
- chunks.push(
54578
- ...chunkText(result, "tool_output", maxChunkChars, tool.name)
54579
- );
55262
+ chunks.push(...chunkText(result, "tool_output", maxChunkChars, tool.name));
54580
55263
  }
54581
55264
  }
54582
55265
  return chunks;
54583
55266
  }
55267
+ function stringifyToolResult(result) {
55268
+ return typeof result === "string" ? result : JSON.stringify(result ?? "");
55269
+ }
55270
+ function resolveLedgerToolResult(tool, stateFilePath2, log) {
55271
+ const result = stringifyToolResult(tool.result);
55272
+ const artifact = findReferencedArtifact(result, log);
55273
+ if (!artifact) return result;
55274
+ const artifactPath = path12.resolve(
55275
+ path12.dirname(treeLogPathForStateFile(stateFilePath2)),
55276
+ artifact.relativePath
55277
+ );
55278
+ try {
55279
+ if (fs11.existsSync(artifactPath) && fs11.statSync(artifactPath).isFile()) {
55280
+ return fs11.readFileSync(artifactPath, "utf-8");
55281
+ }
55282
+ } catch {
55283
+ }
55284
+ return result;
55285
+ }
55286
+ function findReferencedArtifact(result, log) {
55287
+ if (!log) return void 0;
55288
+ const id = parseOffloadedOutputId(result);
55289
+ if (id) {
55290
+ const artifact = findArtifactPayload(log, id);
55291
+ if (artifact) return artifact;
55292
+ }
55293
+ const relativePath = parseLedgerArtifactRelativePath(result);
55294
+ if (!relativePath) return void 0;
55295
+ return log.entries.filter((entry) => entry.type === "artifact").map((entry) => entry.payload).find((payload) => payload.relativePath === relativePath);
55296
+ }
54584
55297
  function chunkText(text, type, maxChars, toolName) {
54585
55298
  if (text.length <= maxChars) {
54586
55299
  return [{ content: text, type, ...toolName ? { toolName } : {} }];
@@ -54696,14 +55409,15 @@ function createLoopDetector(options = {}) {
54696
55409
  }
54697
55410
 
54698
55411
  // src/marathon/context-offload.ts
54699
- import * as fs11 from "fs";
54700
- import * as path12 from "path";
55412
+ import * as fs12 from "fs";
55413
+ import * as path13 from "path";
55414
+ import { createHash as createHash3 } from "crypto";
55415
+ import { buildLedgerOffloadReference } from "@runtypelabs/sdk";
54701
55416
  var DEFAULT_OUTPUT_THRESHOLD = 2e3;
54702
55417
  var DEFAULT_PREVIEW_LENGTH = 200;
54703
- function buildOffloadedOutputId(toolName) {
54704
- offloadCounter += 1;
54705
- const safeToolName = toolName.replace(/[^a-zA-Z0-9_-]/g, "_");
54706
- return `${safeToolName}-${offloadCounter}`;
55418
+ function buildOffloadedOutputId(output) {
55419
+ const sha256 = createHash3("sha256").update(output).digest("hex");
55420
+ return `art_${sha256}`;
54707
55421
  }
54708
55422
  function defaultStateDir3() {
54709
55423
  return getMarathonStateDir();
@@ -54711,7 +55425,33 @@ function defaultStateDir3() {
54711
55425
  function stateSafeName4(name) {
54712
55426
  return name.replace(/[^a-zA-Z0-9_-]/g, "_");
54713
55427
  }
54714
- var offloadCounter = 0;
55428
+ function stateFilePathForTask(taskName, stateDir) {
55429
+ return path13.join(stateDir || defaultStateDir3(), `${stateSafeName4(taskName)}.json`);
55430
+ }
55431
+ function recordOffloadedArtifact(details) {
55432
+ const stateFilePath2 = details.options.ledger?.stateFilePath || stateFilePathForTask(details.taskName, details.stateDir);
55433
+ const logPath = treeLogPathForStateFile(stateFilePath2);
55434
+ try {
55435
+ const log = loadTreeLog(logPath) || createTreeLog(logPath, {
55436
+ taskName: details.taskName,
55437
+ agentId: details.options.ledger?.agentId || "unknown",
55438
+ ...details.options.ledger?.originalMessage ? { originalMessage: details.options.ledger.originalMessage } : {}
55439
+ });
55440
+ if (findArtifactPayload(log, details.outputId)) return;
55441
+ appendArtifact(log, {
55442
+ artifactId: details.outputId,
55443
+ outputId: details.outputId,
55444
+ kind: "tool_output",
55445
+ toolName: details.toolName,
55446
+ relativePath: artifactRelativePathForStateFile(stateFilePath2, details.fileName),
55447
+ contentType: "text/plain",
55448
+ sha256: details.sha256,
55449
+ byteLength: Buffer.byteLength(details.output, "utf-8"),
55450
+ charLength: details.output.length
55451
+ });
55452
+ } catch {
55453
+ }
55454
+ }
54715
55455
  function offloadToolOutput(taskName, toolName, output, options = {}, stateDir) {
54716
55456
  const threshold = options.threshold ?? DEFAULT_OUTPUT_THRESHOLD;
54717
55457
  const warnThreshold = options.warnThreshold;
@@ -54728,23 +55468,35 @@ function offloadToolOutput(taskName, toolName, output, options = {}, stateDir) {
54728
55468
  if (output.length <= threshold) {
54729
55469
  return { offloaded: false, content: output };
54730
55470
  }
54731
- const outputId = buildOffloadedOutputId(toolName);
54732
- const dir = path12.join(
54733
- stateDir || defaultStateDir3(),
54734
- stateSafeName4(taskName),
54735
- "outputs"
54736
- );
55471
+ const outputId = buildOffloadedOutputId(output);
55472
+ const sha256 = outputId.replace(/^art_/, "");
55473
+ const stateFilePath2 = options.ledger?.stateFilePath || stateFilePathForTask(taskName, stateDir);
55474
+ const dir = artifactStoreDirForStateFile(stateFilePath2);
54737
55475
  const fileName = `${outputId}.txt`;
54738
- const filePath = path12.join(dir, fileName);
54739
- fs11.mkdirSync(dir, { recursive: true });
54740
- fs11.writeFileSync(filePath, output, "utf-8");
55476
+ const filePath = path13.join(dir, fileName);
55477
+ fs12.mkdirSync(dir, { recursive: true });
55478
+ if (!fs12.existsSync(filePath)) {
55479
+ fs12.writeFileSync(filePath, output, "utf-8");
55480
+ }
55481
+ recordOffloadedArtifact({
55482
+ taskName,
55483
+ toolName,
55484
+ outputId,
55485
+ sha256,
55486
+ output,
55487
+ fileName,
55488
+ options,
55489
+ stateDir
55490
+ });
54741
55491
  const preview = output.slice(0, previewLength).replace(/\n/g, " ");
54742
- const reference = [
54743
- `[Output offloaded as ${outputId} \u2014 ${output.length.toLocaleString()} chars stored internally]`,
54744
- `Preview: ${preview}${output.length > previewLength ? "..." : ""}`,
54745
- "",
54746
- `Use read_offloaded_output with id "${outputId}" to retrieve the full output if needed.`
54747
- ].join("\n");
55492
+ const relativePath = artifactRelativePathForStateFile(stateFilePath2, fileName);
55493
+ const reference = buildLedgerOffloadReference({
55494
+ outputId,
55495
+ charLength: output.length,
55496
+ relativePath,
55497
+ preview,
55498
+ truncated: output.length > previewLength
55499
+ });
54748
55500
  options.onEvent?.({
54749
55501
  kind: "offloaded",
54750
55502
  toolName,
@@ -54909,20 +55661,20 @@ function resolveAutoCompactTokenThreshold(modelContextLength, rawThreshold, stra
54909
55661
  }
54910
55662
 
54911
55663
  // src/marathon/recipes.ts
54912
- import * as fs12 from "fs";
54913
- import * as path13 from "path";
55664
+ import * as fs13 from "fs";
55665
+ import * as path14 from "path";
54914
55666
  var RULES_DIR = ".marathon/rules";
54915
55667
  function loadRules(cwd) {
54916
55668
  const baseCwd = cwd || process.cwd();
54917
- const rulesDir = path13.resolve(baseCwd, RULES_DIR);
54918
- if (!fs12.existsSync(rulesDir)) return [];
55669
+ const rulesDir = path14.resolve(baseCwd, RULES_DIR);
55670
+ if (!fs13.existsSync(rulesDir)) return [];
54919
55671
  const rules = [];
54920
55672
  try {
54921
- const entries = fs12.readdirSync(rulesDir).filter((f2) => f2.endsWith(".md"));
55673
+ const entries = fs13.readdirSync(rulesDir).filter((f2) => f2.endsWith(".md"));
54922
55674
  for (const entry of entries) {
54923
- const filePath = path13.join(rulesDir, entry);
55675
+ const filePath = path14.join(rulesDir, entry);
54924
55676
  try {
54925
- const raw = fs12.readFileSync(filePath, "utf-8");
55677
+ const raw = fs13.readFileSync(filePath, "utf-8");
54926
55678
  const parsed = parseRuleFile(raw);
54927
55679
  rules.push({ ...parsed, filePath });
54928
55680
  } catch {
@@ -54996,9 +55748,9 @@ function resolveErrorHandlingForPhase(phase, cliFallbackModel, milestoneFallback
54996
55748
  }
54997
55749
 
54998
55750
  // src/marathon/playbook-loader.ts
54999
- import * as fs13 from "fs";
55000
- import * as path14 from "path";
55001
- import * as os4 from "os";
55751
+ import * as fs14 from "fs";
55752
+ import * as path15 from "path";
55753
+ import * as os5 from "os";
55002
55754
  import micromatch from "micromatch";
55003
55755
  import { parse as parseYaml } from "yaml";
55004
55756
  var DISCOVERY_TOOLS = /* @__PURE__ */ new Set([
@@ -55009,23 +55761,23 @@ var DISCOVERY_TOOLS = /* @__PURE__ */ new Set([
55009
55761
  ]);
55010
55762
  var PLAYBOOKS_DIR = ".runtype/marathons/playbooks";
55011
55763
  function getCandidatePaths(nameOrPath, cwd) {
55012
- const home = os4.homedir();
55764
+ const home = os5.homedir();
55013
55765
  return [
55014
55766
  // Exact path
55015
- path14.resolve(cwd, nameOrPath),
55767
+ path15.resolve(cwd, nameOrPath),
55016
55768
  // Repo-level
55017
- path14.resolve(cwd, PLAYBOOKS_DIR, `${nameOrPath}.yaml`),
55018
- path14.resolve(cwd, PLAYBOOKS_DIR, `${nameOrPath}.yml`),
55019
- path14.resolve(cwd, PLAYBOOKS_DIR, `${nameOrPath}.json`),
55769
+ path15.resolve(cwd, PLAYBOOKS_DIR, `${nameOrPath}.yaml`),
55770
+ path15.resolve(cwd, PLAYBOOKS_DIR, `${nameOrPath}.yml`),
55771
+ path15.resolve(cwd, PLAYBOOKS_DIR, `${nameOrPath}.json`),
55020
55772
  // User-level
55021
- path14.resolve(home, PLAYBOOKS_DIR, `${nameOrPath}.yaml`),
55022
- path14.resolve(home, PLAYBOOKS_DIR, `${nameOrPath}.yml`),
55023
- path14.resolve(home, PLAYBOOKS_DIR, `${nameOrPath}.json`)
55773
+ path15.resolve(home, PLAYBOOKS_DIR, `${nameOrPath}.yaml`),
55774
+ path15.resolve(home, PLAYBOOKS_DIR, `${nameOrPath}.yml`),
55775
+ path15.resolve(home, PLAYBOOKS_DIR, `${nameOrPath}.json`)
55024
55776
  ];
55025
55777
  }
55026
55778
  function parsePlaybookFile(filePath) {
55027
- const raw = fs13.readFileSync(filePath, "utf-8");
55028
- const ext = path14.extname(filePath).toLowerCase();
55779
+ const raw = fs14.readFileSync(filePath, "utf-8");
55780
+ const ext = path15.extname(filePath).toLowerCase();
55029
55781
  if (ext === ".json") {
55030
55782
  return JSON.parse(raw);
55031
55783
  }
@@ -55167,7 +55919,7 @@ function loadPlaybook(nameOrPath, cwd) {
55167
55919
  const baseCwd = cwd || process.cwd();
55168
55920
  const candidates = getCandidatePaths(nameOrPath, baseCwd);
55169
55921
  for (const candidate of candidates) {
55170
- if (!fs13.existsSync(candidate) || fs13.statSync(candidate).isDirectory()) continue;
55922
+ if (!fs14.existsSync(candidate) || fs14.statSync(candidate).isDirectory()) continue;
55171
55923
  const config3 = parsePlaybookFile(candidate);
55172
55924
  validatePlaybook(config3, candidate);
55173
55925
  const milestoneModels = {};
@@ -55352,7 +56104,9 @@ function normalizeMarathonAgentArgument(agent) {
55352
56104
  }
55353
56105
  function buildMarathonAutoCreatedAgentBootstrap(agentName, options = {}) {
55354
56106
  const normalizedModel = options.model?.trim();
55355
- const normalizedToolIds = [...new Set((options.toolIds || []).map((toolId) => toolId.trim()).filter(Boolean))];
56107
+ const normalizedToolIds = [
56108
+ ...new Set((options.toolIds || []).map((toolId) => toolId.trim()).filter(Boolean))
56109
+ ];
55356
56110
  const normalizedFallbackModel = options.fallbackModel?.trim();
55357
56111
  const errorHandling = normalizedFallbackModel ? {
55358
56112
  onError: "fallback",
@@ -55428,7 +56182,11 @@ async function taskAction(agent, options) {
55428
56182
  });
55429
56183
  let parsedSandbox = parseSandboxProvider(options.sandbox);
55430
56184
  if (options.sandbox && !parsedSandbox) {
55431
- console.error(chalk23.red(`Invalid --sandbox value "${options.sandbox}". Use: cloudflare-worker, runtype-sandbox, quickjs, or daytona`));
56185
+ console.error(
56186
+ chalk23.red(
56187
+ `Invalid --sandbox value "${options.sandbox}". Use: cloudflare-worker, runtype-sandbox, quickjs, or daytona`
56188
+ )
56189
+ );
55432
56190
  process.exit(1);
55433
56191
  }
55434
56192
  let requestedCompactStrategy;
@@ -55442,11 +56200,9 @@ async function taskAction(agent, options) {
55442
56200
  const rulesContext = rules.length > 0 ? rules.map((r) => r.content).join("\n\n---\n\n") : "";
55443
56201
  const allModels = [
55444
56202
  ...new Set(
55445
- [
55446
- options.model,
55447
- options.planningModel,
55448
- options.executionModel
55449
- ].filter((m2) => Boolean(m2))
56203
+ [options.model, options.planningModel, options.executionModel].filter(
56204
+ (m2) => Boolean(m2)
56205
+ )
55450
56206
  )
55451
56207
  ];
55452
56208
  let resolvedToolIds = [];
@@ -55488,7 +56244,7 @@ async function taskAction(agent, options) {
55488
56244
  waitForUiExit = renderedShell.waitUntilExit;
55489
56245
  rerenderUi = renderedShell.rerender;
55490
56246
  unmountUi = renderedShell.unmount;
55491
- await new Promise((resolve10) => setTimeout(resolve10, 0));
56247
+ await new Promise((resolve11) => setTimeout(resolve11, 0));
55492
56248
  if (!startupShellRef.current) {
55493
56249
  exitAltScreen();
55494
56250
  unmountUi?.();
@@ -55565,10 +56321,7 @@ async function taskAction(agent, options) {
55565
56321
  await failBeforeMain(formatMarathonApiError(error51));
55566
56322
  }
55567
56323
  const errMsg = error51 instanceof Error ? error51.message : String(error51);
55568
- await failBeforeMain([
55569
- chalk23.red("Failed to list agents"),
55570
- chalk23.red(errMsg)
55571
- ]);
56324
+ await failBeforeMain([chalk23.red("Failed to list agents"), chalk23.red(errMsg)]);
55572
56325
  }
55573
56326
  }
55574
56327
  let agentConfigModel;
@@ -55617,7 +56370,7 @@ async function taskAction(agent, options) {
55617
56370
  forcedResumeFilePath = stateResolution.filePath;
55618
56371
  } else {
55619
56372
  resumeRequested = false;
55620
- if (options.fresh && fs14.existsSync(filePath)) {
56373
+ if (options.fresh && fs15.existsSync(filePath)) {
55621
56374
  if (useStartupShell) {
55622
56375
  setStartupStatus("starting fresh");
55623
56376
  } else {
@@ -55757,7 +56510,10 @@ async function taskAction(agent, options) {
55757
56510
  if (firstMilestoneModel) options.model = firstMilestoneModel;
55758
56511
  confirmed = true;
55759
56512
  } else if (confirmResult.action === "edit" && confirmResult.editMilestone) {
55760
- let startupModelOptions = buildMarathonStartupModelOptions(configuredModels, availableModels);
56513
+ let startupModelOptions = buildMarathonStartupModelOptions(
56514
+ configuredModels,
56515
+ availableModels
56516
+ );
55761
56517
  if (startupModelOptions.length === 0) {
55762
56518
  startupModelOptions = DEFAULT_MODELS;
55763
56519
  }
@@ -55831,11 +56587,15 @@ ${sandboxPrompt}`;
55831
56587
 
55832
56588
  ${rulesContext}`;
55833
56589
  const currentPhase = resumeState?.workflowPhase;
55834
- const resolvedModel = resolveModelForPhase(currentPhase, {
55835
- planningModel: options.planningModel,
55836
- executionModel: options.executionModel,
55837
- defaultModel: options.model
55838
- }, playbookMilestoneModels);
56590
+ const resolvedModel = resolveModelForPhase(
56591
+ currentPhase,
56592
+ {
56593
+ planningModel: options.planningModel,
56594
+ executionModel: options.executionModel,
56595
+ defaultModel: options.model
56596
+ },
56597
+ playbookMilestoneModels
56598
+ );
55839
56599
  if (resolvedModel) options.model = resolvedModel;
55840
56600
  if (autoCreatedAgent) {
55841
56601
  const bootstrapPayload = buildMarathonAutoCreatedAgentBootstrap(normalizedAgent, {
@@ -55872,6 +56632,7 @@ ${rulesContext}`;
55872
56632
  let localTools = buildLocalTools(client, parsedSandbox, options, {
55873
56633
  taskName,
55874
56634
  stateDir: options.stateDir,
56635
+ stateFilePath: filePath,
55875
56636
  planPath: resolvedPlanPath
55876
56637
  });
55877
56638
  const resolveContextLimitForModel = (modelId) => resolveModelContextLength(modelId, configuredModels, availableModels);
@@ -55894,16 +56655,21 @@ ${rulesContext}`;
55894
56655
  const reportContextNotice = (event) => {
55895
56656
  streamRef.current?.reportContextNotice(event);
55896
56657
  };
55897
- if (localTools && offloadOptions) {
55898
- const toolNames = Object.keys(localTools);
55899
- for (const toolName of toolNames) {
56658
+ const applyOffloadWrapping = (tools) => {
56659
+ if (!tools || !offloadOptions) return tools;
56660
+ for (const toolName of Object.keys(tools)) {
55900
56661
  if (toolName === "search_repo" || toolName === "read_file" || toolName === "glob_files" || toolName === "tree_directory" || toolName === "list_directory") {
55901
- localTools[toolName] = withOffloading(
55902
- localTools[toolName],
56662
+ tools[toolName] = withOffloading(
56663
+ tools[toolName],
55903
56664
  taskName,
55904
56665
  toolName,
55905
56666
  {
55906
56667
  ...offloadOptions,
56668
+ ledger: {
56669
+ stateFilePath: filePath,
56670
+ agentId,
56671
+ originalMessage: baseMessage
56672
+ },
55907
56673
  onEvent: (event) => {
55908
56674
  if (event.kind === "warning") {
55909
56675
  reportContextNotice({
@@ -55927,14 +56693,19 @@ ${rulesContext}`;
55927
56693
  );
55928
56694
  }
55929
56695
  }
55930
- }
56696
+ return tools;
56697
+ };
56698
+ localTools = applyOffloadWrapping(localTools);
55931
56699
  let toolsEnabled = true;
55932
56700
  const checkpointHasConfigChanges = (result) => Boolean(result.model) || result.tools === true || result.sandbox !== void 0;
55933
- const rebuildCheckpointTools = () => buildLocalTools(client, parsedSandbox, options, {
55934
- taskName,
55935
- stateDir: options.stateDir,
55936
- planPath: resolvedPlanPath
55937
- });
56701
+ const rebuildCheckpointTools = () => applyOffloadWrapping(
56702
+ buildLocalTools(client, parsedSandbox, options, {
56703
+ taskName,
56704
+ stateDir: options.stateDir,
56705
+ stateFilePath: filePath,
56706
+ planPath: resolvedPlanPath
56707
+ })
56708
+ );
55938
56709
  const applyCheckpointConfig = (result) => {
55939
56710
  if (result.model) {
55940
56711
  options.model = result.model;
@@ -55961,6 +56732,7 @@ ${rulesContext}`;
55961
56732
  let lastKnownState = null;
55962
56733
  try {
55963
56734
  const marathonDashboardBaseUrl = getDashboardUrl().replace(/\/$/, "");
56735
+ const turnAbortRef = { current: null };
55964
56736
  const marathonAppProps = {
55965
56737
  taskName,
55966
56738
  agentId,
@@ -55999,7 +56771,9 @@ ${rulesContext}`;
55999
56771
  sessions: persistedSessionSummaries,
56000
56772
  startedAt: lastKnownState?.startedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
56001
56773
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
56002
- ...persistedSessionSnapshots.length > 0 || payload.sessionSnapshots.length > 0 ? { sessionSnapshots: payload.sessionSnapshots.length > 0 ? payload.sessionSnapshots : persistedSessionSnapshots } : {},
56774
+ ...persistedSessionSnapshots.length > 0 || payload.sessionSnapshots.length > 0 ? {
56775
+ sessionSnapshots: payload.sessionSnapshots.length > 0 ? payload.sessionSnapshots : persistedSessionSnapshots
56776
+ } : {},
56003
56777
  ...priorContinuations.length > 0 ? { continuations: priorContinuations } : {},
56004
56778
  ...Object.keys(priorCostByModel).length > 0 ? { costByModel: priorCostByModel } : {},
56005
56779
  ...priorOriginalMessage ? { originalMessage: priorOriginalMessage } : {},
@@ -56012,6 +56786,14 @@ Saving state... done. Session saved to ${filePath}`);
56012
56786
  },
56013
56787
  onComplete: () => {
56014
56788
  },
56789
+ onAbortTurn: () => {
56790
+ const controller = turnAbortRef.current;
56791
+ if (controller && !controller.signal.aborted) {
56792
+ controller.abort();
56793
+ return true;
56794
+ }
56795
+ return false;
56796
+ },
56015
56797
  streamRef
56016
56798
  };
56017
56799
  setMarathonTitle();
@@ -56027,14 +56809,13 @@ Saving state... done. Session saved to ${filePath}`);
56027
56809
  await startupShellRef.current?.completeStartup();
56028
56810
  } else {
56029
56811
  exitAltScreen = enterAltScreen();
56030
- const renderedApp = render15(
56031
- React15.createElement(MarathonApp, marathonAppProps),
56032
- { exitOnCtrlC: false }
56033
- );
56812
+ const renderedApp = render15(React15.createElement(MarathonApp, marathonAppProps), {
56813
+ exitOnCtrlC: false
56814
+ });
56034
56815
  waitForUiExit = renderedApp.waitUntilExit;
56035
56816
  unmountUi = renderedApp.unmount;
56036
56817
  }
56037
- await new Promise((resolve10) => setTimeout(resolve10, 0));
56818
+ await new Promise((resolve11) => setTimeout(resolve11, 0));
56038
56819
  const streamActions = streamRef.current;
56039
56820
  if (!streamActions) {
56040
56821
  exitAltScreen();
@@ -56092,6 +56873,7 @@ Saving state... done. Session saved to ${filePath}`);
56092
56873
  let accumulatedToolCalls = 0;
56093
56874
  let lastResult = null;
56094
56875
  let lastSessionMessages = [];
56876
+ let undeliveredSteering = [];
56095
56877
  if (resumeLoadedState) {
56096
56878
  const continuationStartedAt = (/* @__PURE__ */ new Date()).toISOString();
56097
56879
  const continuation = {
@@ -56133,14 +56915,18 @@ Saving state... done. Session saved to ${filePath}`);
56133
56915
  const effectiveModelForContext = phaseModel || options.model || agentConfigModel || defaultConfiguredModel;
56134
56916
  const compactStrategy = resolveCompactStrategyForModel(effectiveModelForContext);
56135
56917
  const contextLimitTokens = resolveContextLimitForModel(effectiveModelForContext);
56136
- const autoCompactTokenThreshold = resolveCompactThresholdForModel(
56137
- effectiveModelForContext
56918
+ const autoCompactTokenThreshold = resolveCompactThresholdForModel(effectiveModelForContext);
56919
+ const existingContextSummaryIds = new Set(
56920
+ (resumeState?.contextCompactionSummaries ?? []).map((summary) => summary.id)
56138
56921
  );
56922
+ const turnAbortController = new AbortController();
56923
+ turnAbortRef.current = turnAbortController;
56139
56924
  const runTaskOptions = {
56140
56925
  message: taskMessage,
56141
56926
  maxSessions: remainingSessions - accumulatedSessions,
56142
56927
  maxCost: currentRemainingCost,
56143
56928
  model: phaseModel || options.model,
56929
+ abortSignal: turnAbortController.signal,
56144
56930
  reasoning: !options.noReasoning,
56145
56931
  debugMode: options.debug ?? true,
56146
56932
  stream: true,
@@ -56174,7 +56960,7 @@ Saving state... done. Session saved to ${filePath}`);
56174
56960
  };
56175
56961
  if (event.phase === "start") {
56176
56962
  currentActions.startContextCompaction(absoluteEvent);
56177
- await new Promise((resolve10) => setTimeout(resolve10, 0));
56963
+ await new Promise((resolve11) => setTimeout(resolve11, 0));
56178
56964
  return;
56179
56965
  }
56180
56966
  currentActions.finishContextCompaction(absoluteEvent);
@@ -56227,11 +57013,17 @@ Saving state... done. Session saved to ${filePath}`);
56227
57013
  );
56228
57014
  currentActions.appendSessionSnapshot(sessionSnapshot);
56229
57015
  }
57016
+ const contextCompactionSummaries = offsetNewContextCompactionSummaries(
57017
+ state.contextCompactionSummaries,
57018
+ existingContextSummaryIds,
57019
+ currentSessionOffset
57020
+ );
56230
57021
  const adjustedState = {
56231
57022
  ...state,
56232
57023
  sessionCount: currentSessionOffset + state.sessionCount,
56233
57024
  totalCost: priorCost + accumulatedCost + state.totalCost,
56234
57025
  sessions: persistedSessionSummaries,
57026
+ ...contextCompactionSummaries?.length ? { contextCompactionSummaries } : {},
56235
57027
  ...persistedSessionSnapshots.length > 0 ? { sessionSnapshots: persistedSessionSnapshots } : {},
56236
57028
  ...getActiveDeploySandboxId() ? { deploySandboxId: getActiveDeploySandboxId() } : {},
56237
57029
  ...getActiveDeploySandboxPreviewUrl() ? { deploySandboxPreviewUrl: getActiveDeploySandboxPreviewUrl() } : {}
@@ -56240,10 +57032,13 @@ Saving state... done. Session saved to ${filePath}`);
56240
57032
  resumeState = extractRunTaskResumeState(adjustedState);
56241
57033
  lastSessionMessages = state.messages ?? [];
56242
57034
  saveState(filePath, adjustedState, { stripSnapshotEvents: !!eventLogWriter });
56243
- if (options.sessionSearch === true) {
57035
+ if (options.sessionSearch !== false) {
56244
57036
  const latestSnapshot = persistedSessionSnapshots[persistedSessionSnapshots.length - 1];
56245
57037
  if (latestSnapshot) {
56246
- const chunks = extractSessionChunks(latestSnapshot);
57038
+ const chunks = extractSessionChunksWithLedger(latestSnapshot, {
57039
+ stateFilePath: filePath,
57040
+ summaries: adjustedState.contextCompactionSummaries
57041
+ });
56247
57042
  if (chunks.length > 0) {
56248
57043
  const sessionIdx = currentSessionOffset + state.sessionCount - 1;
56249
57044
  client.post("/session-context/index", {
@@ -56348,17 +57143,21 @@ Saving state... done. Session saved to ${filePath}`);
56348
57143
  if (resumeRequested) {
56349
57144
  streamActions.markPendingStart();
56350
57145
  }
56351
- const result2 = await retryOnNetworkError(
56352
- () => client.agents.runTask(agentId, runTaskOptions),
56353
- {
57146
+ let result2;
57147
+ try {
57148
+ result2 = await retryOnNetworkError(() => client.agents.runTask(agentId, runTaskOptions), {
56354
57149
  maxRetries: 3,
56355
57150
  baseDelayMs: 5e3,
56356
57151
  maxDelayMs: 6e4,
57152
+ // A user hard abort surfaces as an AbortError — never retry it
57153
+ signal: turnAbortController.signal,
56357
57154
  onRetry: (attempt, delayMs, error51) => {
56358
57155
  const delaySec = Math.round(delayMs / 1e3);
56359
57156
  const msg = error51 instanceof Error ? error51.message : String(error51);
56360
57157
  console.error(
56361
- chalk23.yellow(`Network error (attempt ${attempt}/3): ${msg}. Retrying in ${delaySec}s...`)
57158
+ chalk23.yellow(
57159
+ `Network error (attempt ${attempt}/3): ${msg}. Retrying in ${delaySec}s...`
57160
+ )
56362
57161
  );
56363
57162
  if (lastKnownState) {
56364
57163
  previousMessages = lastSessionMessages;
@@ -56369,8 +57168,23 @@ Saving state... done. Session saved to ${filePath}`);
56369
57168
  runTaskOptions.compact = false;
56370
57169
  }
56371
57170
  }
56372
- }
56373
- );
57171
+ });
57172
+ } catch (error51) {
57173
+ if (!turnAbortController.signal.aborted) throw error51;
57174
+ const knownState2 = lastKnownState;
57175
+ result2 = {
57176
+ status: "paused",
57177
+ sessionCount: Math.max(
57178
+ 0,
57179
+ (knownState2?.sessionCount ?? currentSessionOffset) - currentSessionOffset
57180
+ ),
57181
+ totalCost: Math.max(0, (knownState2?.totalCost ?? 0) - (priorCost + accumulatedCost)),
57182
+ lastOutput: knownState2?.lastOutput ?? "",
57183
+ sessions: []
57184
+ };
57185
+ }
57186
+ const wasAborted = turnAbortController.signal.aborted;
57187
+ turnAbortRef.current = null;
56374
57188
  persistedSessionSummaries = mergeMarathonSessionSummaries(
56375
57189
  persistedSessionSummaries,
56376
57190
  result2.sessions,
@@ -56385,7 +57199,7 @@ Saving state... done. Session saved to ${filePath}`);
56385
57199
  const completedTools = existingSnapshot.tools.map(
56386
57200
  (t) => t.status === "running" ? { ...t, status: "complete", executionTime: Date.now() - t.startedAt } : t
56387
57201
  );
56388
- const finalStatus = mapRunTaskStatusToSnapshotStatus(result2.status, existingSnapshot.status);
57202
+ const finalStatus = wasAborted ? "stopped" : mapRunTaskStatusToSnapshotStatus(result2.status, existingSnapshot.status);
56389
57203
  const updatedSnapshot = {
56390
57204
  ...existingSnapshot,
56391
57205
  status: finalStatus,
@@ -56396,7 +57210,10 @@ Saving state... done. Session saved to ${filePath}`);
56396
57210
  tools: completedTools,
56397
57211
  ...finalStatus === "error" && lastKnownState?.lastError ? { errorMessage: lastKnownState.lastError } : {}
56398
57212
  };
56399
- persistedSessionSnapshots = upsertMarathonSessionSnapshot(persistedSessionSnapshots, updatedSnapshot);
57213
+ persistedSessionSnapshots = upsertMarathonSessionSnapshot(
57214
+ persistedSessionSnapshots,
57215
+ updatedSnapshot
57216
+ );
56400
57217
  streamRef.current?.appendSessionSnapshot(updatedSnapshot);
56401
57218
  }
56402
57219
  }
@@ -56419,11 +57236,16 @@ Saving state... done. Session saved to ${filePath}`);
56419
57236
  useCompact = false;
56420
57237
  resumeState = extractRunTaskResumeState(lastKnownState);
56421
57238
  }
56422
- if (result2.status === "complete" || result2.status === "budget_exceeded" || result2.status === "max_sessions") {
56423
- if (options.noCheckpoint) break;
57239
+ if (wasAborted || result2.status === "complete" || result2.status === "budget_exceeded" || result2.status === "max_sessions") {
57240
+ if (options.noCheckpoint) {
57241
+ if (wasAborted) {
57242
+ undeliveredSteering = streamRef.current?.drainSteeringQueue?.() ?? [];
57243
+ }
57244
+ break;
57245
+ }
56424
57246
  const currentActions = streamRef.current;
56425
57247
  if (!currentActions) break;
56426
- const queuedFollowUps = currentActions.drainFollowUpQueue?.();
57248
+ const queuedFollowUps = wasAborted ? void 0 : currentActions.drainFollowUpQueue?.();
56427
57249
  if (queuedFollowUps && queuedFollowUps.length > 0) {
56428
57250
  currentActions.resetForNewSession();
56429
57251
  taskMessage = queuedFollowUps.join("\n\n");
@@ -56533,6 +57355,18 @@ Saving state... done. Session saved to ${filePath}`);
56533
57355
  if (typeof finalState.lastError === "string" && finalState.lastError.trim()) {
56534
57356
  console.log(`Last error: ${chalk23.red(finalState.lastError)}`);
56535
57357
  }
57358
+ if (undeliveredSteering.length > 0) {
57359
+ console.log(
57360
+ chalk23.yellow(
57361
+ `
57362
+ Undelivered steering (${undeliveredSteering.length} message${undeliveredSteering.length === 1 ? "" : "s"} queued before the abort):`
57363
+ )
57364
+ );
57365
+ for (const message of undeliveredSteering) {
57366
+ console.log(chalk23.gray(` - ${message}`));
57367
+ }
57368
+ console.log(chalk23.gray(' Include it when resuming, e.g. --resume "<message>".'));
57369
+ }
56536
57370
  const dashboardBaseUrl = getDashboardUrl();
56537
57371
  console.log(`Dashboard: ${chalk23.cyan(`${dashboardBaseUrl}/agents/${agentId}`)}`);
56538
57372
  if (result.recordId) {
@@ -56554,7 +57388,9 @@ Saving state... done. Session saved to ${filePath}`);
56554
57388
  const msg = c2.userMessage ? ` "${c2.userMessage.slice(0, 50)}"` : " (no message)";
56555
57389
  const modelName = c2.model ? ` [${c2.model}]` : "";
56556
57390
  console.log(
56557
- chalk23.gray(` #${i + 1}: ${c2.continuedAt}${modelName}${msg} \u2014 $${c2.segmentCost.toFixed(4)}`)
57391
+ chalk23.gray(
57392
+ ` #${i + 1}: ${c2.continuedAt}${modelName}${msg} \u2014 $${c2.segmentCost.toFixed(4)}`
57393
+ )
56558
57394
  );
56559
57395
  }
56560
57396
  }
@@ -56565,12 +57401,8 @@ Saving state... done. Session saved to ${filePath}`);
56565
57401
  }
56566
57402
  }
56567
57403
  if (isMarathonResumableStatus(result.status)) {
56568
- console.log(
56569
- chalk23.gray(
56570
- `
56571
- Resume: ${buildResumeCommand(agent, options, parsedSandbox)}`
56572
- )
56573
- );
57404
+ console.log(chalk23.gray(`
57405
+ Resume: ${buildResumeCommand(agent, options, parsedSandbox)}`));
56574
57406
  }
56575
57407
  if (options.json) {
56576
57408
  console.log();
@@ -56600,7 +57432,9 @@ Resume: ${buildResumeCommand(agent, options, parsedSandbox)}`
56600
57432
  }
56601
57433
  if (isTransientNetworkError(error51)) {
56602
57434
  console.error(chalk23.red("Network connection lost after multiple retry attempts."));
56603
- console.error(chalk23.gray("Your progress has been saved. Resume when connectivity is restored:"));
57435
+ console.error(
57436
+ chalk23.gray("Your progress has been saved. Resume when connectivity is restored:")
57437
+ );
56604
57438
  } else {
56605
57439
  for (const line of formatMarathonApiError(error51)) {
56606
57440
  console.error(line);
@@ -56648,7 +57482,9 @@ function resolveBuiltinToolIds(tools, models) {
56648
57482
  }
56649
57483
  const errors = [];
56650
57484
  if (invalid.length > 0) {
56651
- errors.push(`Unknown built-in tool(s): ${invalid.join(", ")}. Available tools: ${available.join(", ")}`);
57485
+ errors.push(
57486
+ `Unknown built-in tool(s): ${invalid.join(", ")}. Available tools: ${available.join(", ")}`
57487
+ );
56652
57488
  }
56653
57489
  if (excluded.length > 0) {
56654
57490
  errors.push(
@@ -56701,7 +57537,53 @@ function resolveSandboxWorkflowSelection(message, sandboxProvider, resumeState)
56701
57537
  };
56702
57538
  }
56703
57539
  function applyTaskOptions(cmd) {
56704
- return cmd.argument("<agent>", "Agent ID or name").option("-g, --goal <text>", "Goal message for the agent").option("--max-sessions <n>", "Maximum sessions", "50").option("--max-cost <n>", "Budget in USD").option("--model <modelId>", "Model ID to use (overrides agent config)").option("--name <name>", "Task name (used for state file, defaults to agent name)").option("--session <name>", "Resume a specific session by name").option("--state-dir <path>", "Directory for state files (default: ~/.runtype/projects/<hash>/marathons/)").option("--resume [message]", "Resume from existing local state, optionally with a new message").option("--fresh", "Start a new run and ignore any existing local state for this task").option("--compact", "Force compact-summary resume mode instead of replaying full history").option("--compact-strategy <strategy>", "Compaction strategy: auto (default), provider_native, or summary_fallback").option("--compact-threshold <value>", "Auto-compact when estimated context crosses this threshold (default: 80% fallback, 90% native; accepts percent like 90% or absolute token count like 120000)").option("--compact-instructions <text>", "Extra instructions for what a compact summary must preserve").option("--no-auto-compact", "Disable automatic context-aware history compaction").option("--track", "Sync progress to a Runtype record (visible in dashboard)").option("--debug", "Show debug output from each session").option("--json", "Output final result as JSON").option("--sandbox <provider>", "Enable sandbox code execution tool (cloudflare-worker, quickjs, or daytona)").option("--no-local-tools", "Disable built-in local tool execution (read_file, write_file, list_directory)").option("--session-search", "Enable session context indexing and search_session_history tool").option("-t, --tools <tools...>", "Enable built-in tools (e.g., exa, firecrawl, dalle, openai_web_search, anthropic_web_search)").option("--plain-text", "Disable markdown rendering in output").option("--no-reasoning", "Disable model reasoning/thinking (enabled by default for supported models)").option("--no-checkpoint", "Run all iterations without checkpoint pauses (fully autonomous)").option("--checkpoint-timeout <seconds>", "Auto-continue timeout in seconds (default: 10)", "10").option("--planning-model <modelId>", "Model to use during research/planning phases").option("--execution-model <modelId>", "Model to use during execution phase").option("--fallback-model <modelId>", "Model to fall back to when primary model fails").option("--playbook <name>", "Load a playbook from .runtype/marathons/playbooks/").option("--offload-threshold <chars>", 'Offload tool outputs larger than this to files (default: 100000; use "off" or "0" to disable guardrails)').option("--tool-context <mode>", "Tool result storage: hot-tail (default), observation-mask, or full-inline").option("--tool-window <window>", 'Compaction window: "session" (default) or a number for last-N tool results (e.g. 10)').option("--runner-char <char>", "Custom runner emoji (default: \u{1F3C3})").option("--finish-char <char>", "Custom finish line emoji (default: \u{1F3C1})").option("--no-runner", "Hide the runner emoji from the header border").option("--no-finish", "Hide the finish line emoji from the header border").action(taskAction);
57540
+ return cmd.argument("<agent>", "Agent ID or name").option("-g, --goal <text>", "Goal message for the agent").option("--max-sessions <n>", "Maximum sessions", "50").option("--max-cost <n>", "Budget in USD").option("--model <modelId>", "Model ID to use (overrides agent config)").option("--name <name>", "Task name (used for state file, defaults to agent name)").option("--session <name>", "Resume a specific session by name").option(
57541
+ "--state-dir <path>",
57542
+ "Directory for state files (default: ~/.runtype/projects/<hash>/marathons/)"
57543
+ ).option(
57544
+ "--resume [message]",
57545
+ "Resume from existing local state, optionally with a new message"
57546
+ ).option("--fresh", "Start a new run and ignore any existing local state for this task").option("--compact", "Force compact-summary resume mode instead of replaying full history").option(
57547
+ "--compact-strategy <strategy>",
57548
+ "Compaction strategy: auto (default), provider_native, or summary_fallback"
57549
+ ).option(
57550
+ "--compact-threshold <value>",
57551
+ "Auto-compact when estimated context crosses this threshold (default: 80% fallback, 90% native; accepts percent like 90% or absolute token count like 120000)"
57552
+ ).option(
57553
+ "--compact-instructions <text>",
57554
+ "Extra instructions for what a compact summary must preserve"
57555
+ ).option("--no-auto-compact", "Disable automatic context-aware history compaction").option("--track", "Sync progress to a Runtype record (visible in dashboard)").option("--debug", "Show debug output from each session").option("--json", "Output final result as JSON").option(
57556
+ "--sandbox <provider>",
57557
+ "Enable sandbox code execution tool (cloudflare-worker, quickjs, or daytona)"
57558
+ ).option(
57559
+ "--no-local-tools",
57560
+ "Disable built-in local tool execution (read_file, write_file, list_directory)"
57561
+ ).option(
57562
+ "--session-search",
57563
+ "Enable session context indexing and search_session_history tool (default)"
57564
+ ).option(
57565
+ "--no-session-search",
57566
+ "Disable session context indexing and search_session_history tool"
57567
+ ).option(
57568
+ "-t, --tools <tools...>",
57569
+ "Enable built-in tools (e.g., exa, firecrawl, dalle, openai_web_search, anthropic_web_search)"
57570
+ ).option("--plain-text", "Disable markdown rendering in output").option(
57571
+ "--no-reasoning",
57572
+ "Disable model reasoning/thinking (enabled by default for supported models)"
57573
+ ).option("--no-checkpoint", "Run all iterations without checkpoint pauses (fully autonomous)").option(
57574
+ "--checkpoint-timeout <seconds>",
57575
+ "Auto-continue timeout in seconds (default: 10)",
57576
+ "10"
57577
+ ).option("--planning-model <modelId>", "Model to use during research/planning phases").option("--execution-model <modelId>", "Model to use during execution phase").option("--fallback-model <modelId>", "Model to fall back to when primary model fails").option("--playbook <name>", "Load a playbook from .runtype/marathons/playbooks/").option(
57578
+ "--offload-threshold <chars>",
57579
+ 'Offload tool outputs larger than this to files (default: 100000; use "off" or "0" to disable guardrails)'
57580
+ ).option(
57581
+ "--tool-context <mode>",
57582
+ "Tool result storage: hot-tail (default), observation-mask, or full-inline"
57583
+ ).option(
57584
+ "--tool-window <window>",
57585
+ 'Compaction window: "session" (default) or a number for last-N tool results (e.g. 10)'
57586
+ ).option("--runner-char <char>", "Custom runner emoji (default: \u{1F3C3})").option("--finish-char <char>", "Custom finish line emoji (default: \u{1F3C1})").option("--no-runner", "Hide the runner emoji from the header border").option("--no-finish", "Hide the finish line emoji from the header border").action(taskAction);
56705
57587
  }
56706
57588
  var taskCommand = applyTaskOptions(
56707
57589
  new Command16("task").description("Run a multi-session agent task")
@@ -57865,14 +58747,14 @@ import React19 from "react";
57865
58747
  import { render as render19 } from "ink";
57866
58748
  import { useState as useState36, useEffect as useEffect30 } from "react";
57867
58749
  import { Text as Text34 } from "ink";
57868
- import { readFileSync as readFileSync15 } from "fs";
58750
+ import { readFileSync as readFileSync16 } from "fs";
57869
58751
  var evalCommand = new Command20("eval").description("Manage evaluations");
57870
58752
  evalCommand.command("submit").description("Submit an eval batch").requiredOption("-f, --flow <id>", "Flow ID to evaluate").requiredOption("-r, --records <file>", "JSON file with record IDs").option("-n, --name <name>", "Eval batch name").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
57871
58753
  const apiKey = await ensureAuth();
57872
58754
  if (!apiKey) return;
57873
58755
  let recordIds;
57874
58756
  try {
57875
- const content = readFileSync15(options.records, "utf-8");
58757
+ const content = readFileSync16(options.records, "utf-8");
57876
58758
  const parsed = JSON.parse(content);
57877
58759
  recordIds = Array.isArray(parsed) ? parsed : parsed.recordIds || parsed.records || [];
57878
58760
  } catch (error51) {
@@ -58430,13 +59312,13 @@ apiKeysCommand.command("delete <id>").description("Delete an API key").option("-
58430
59312
  await waitUntilExit2();
58431
59313
  return;
58432
59314
  }
58433
- const confirmed = await new Promise((resolve10) => {
59315
+ const confirmed = await new Promise((resolve11) => {
58434
59316
  const { unmount } = render20(
58435
59317
  React20.createElement(ConfirmPrompt, {
58436
59318
  message: `Delete API key ${id}?`,
58437
59319
  defaultValue: false,
58438
59320
  onConfirm: (result) => {
58439
- resolve10(result);
59321
+ resolve11(result);
58440
59322
  unmount();
58441
59323
  }
58442
59324
  })
@@ -58541,8 +59423,8 @@ apiKeysCommand.command("analytics").description("Show API key usage analytics").
58541
59423
  const client = createCliClient(apiKey);
58542
59424
  if (!isTTY(options) || options.json) {
58543
59425
  try {
58544
- const path17 = options.key ? `/api-keys/${options.key}/analytics` : "/api-keys/analytics";
58545
- const data = await client.get(path17);
59426
+ const path18 = options.key ? `/api-keys/${options.key}/analytics` : "/api-keys/analytics";
59427
+ const data = await client.get(path18);
58546
59428
  printJson(data);
58547
59429
  } catch (error51) {
58548
59430
  const message = error51 instanceof Error ? error51.message : "Unknown error";
@@ -58559,8 +59441,8 @@ apiKeysCommand.command("analytics").description("Show API key usage analytics").
58559
59441
  useEffect31(() => {
58560
59442
  const run2 = async () => {
58561
59443
  try {
58562
- const path17 = options.key ? `/api-keys/${options.key}/analytics` : "/api-keys/analytics";
58563
- const data = await client.get(path17);
59444
+ const path18 = options.key ? `/api-keys/${options.key}/analytics` : "/api-keys/analytics";
59445
+ const data = await client.get(path18);
58564
59446
  printJson(data);
58565
59447
  setSuccess(true);
58566
59448
  setLoading(false);
@@ -58902,13 +59784,13 @@ clientTokensCommand.command("delete <id>").description("Delete a client token").
58902
59784
  await waitUntilExit2();
58903
59785
  return;
58904
59786
  }
58905
- const confirmed = await new Promise((resolve10) => {
59787
+ const confirmed = await new Promise((resolve11) => {
58906
59788
  const { unmount } = render21(
58907
59789
  React21.createElement(ConfirmPrompt, {
58908
59790
  message: `Delete client token ${id}?`,
58909
59791
  defaultValue: false,
58910
59792
  onConfirm: (result) => {
58911
- resolve10(result);
59793
+ resolve11(result);
58912
59794
  unmount();
58913
59795
  }
58914
59796
  })
@@ -59432,8 +60314,8 @@ function defaultTokenName(agentName) {
59432
60314
  }
59433
60315
  async function promptLine(rl, question, defaultValue) {
59434
60316
  const hint = defaultValue ? chalk30.dim(` (${defaultValue})`) : "";
59435
- const answer = await new Promise((resolve10) => {
59436
- rl.question(`${question}${hint}: `, resolve10);
60317
+ const answer = await new Promise((resolve11) => {
60318
+ rl.question(`${question}${hint}: `, resolve11);
59437
60319
  });
59438
60320
  const trimmed = answer.trim();
59439
60321
  if (!trimmed && defaultValue !== void 0) {
@@ -59443,8 +60325,8 @@ async function promptLine(rl, question, defaultValue) {
59443
60325
  }
59444
60326
  async function promptConfirm2(rl, message, defaultYes = false) {
59445
60327
  const hint = defaultYes ? chalk30.dim(" (Y/n)") : chalk30.dim(" (y/N)");
59446
- const answer = await new Promise((resolve10) => {
59447
- rl.question(`${message}${hint}: `, resolve10);
60328
+ const answer = await new Promise((resolve11) => {
60329
+ rl.question(`${message}${hint}: `, resolve11);
59448
60330
  });
59449
60331
  const t = answer.trim().toLowerCase();
59450
60332
  if (t === "") return defaultYes;
@@ -59513,18 +60395,18 @@ Dashboard: ${initial.dashboardUrl}`));
59513
60395
  process.stdin.removeAllListeners("keypress");
59514
60396
  process.stdin.pause();
59515
60397
  };
59516
- await new Promise((resolve10) => {
60398
+ await new Promise((resolve11) => {
59517
60399
  const onKeypress = async (_str, key) => {
59518
60400
  if (!key) return;
59519
60401
  if (key.ctrl && key.name === "c") {
59520
60402
  cleanup();
59521
- resolve10();
60403
+ resolve11();
59522
60404
  process.exit(0);
59523
60405
  }
59524
60406
  const name = key.name;
59525
60407
  if (name === "q" || name === "escape") {
59526
60408
  cleanup();
59527
- resolve10();
60409
+ resolve11();
59528
60410
  return;
59529
60411
  }
59530
60412
  if (name === "c") {
@@ -60884,11 +61766,11 @@ async function runTail(options) {
60884
61766
  process.stderr.write(
60885
61767
  (useColor ? chalk35.gray(`Retrying in ${delay / 1e3}s (attempt ${attempt}/${MAX_ATTEMPTS})...`) : `Retrying in ${delay / 1e3}s (attempt ${attempt}/${MAX_ATTEMPTS})...`) + "\n"
60886
61768
  );
60887
- await new Promise((resolve10) => {
60888
- const timer = setTimeout(resolve10, delay);
61769
+ await new Promise((resolve11) => {
61770
+ const timer = setTimeout(resolve11, delay);
60889
61771
  const onAbort = () => {
60890
61772
  clearTimeout(timer);
60891
- resolve10();
61773
+ resolve11();
60892
61774
  };
60893
61775
  controller.signal.addEventListener("abort", onAbort, { once: true });
60894
61776
  });
@@ -60904,7 +61786,7 @@ var tailCommand = new Command28("tail").description("Stream live execution logs
60904
61786
  // src/commands/validate-product.ts
60905
61787
  import { Command as Command29, Option } from "commander";
60906
61788
  import chalk36 from "chalk";
60907
- import { readFileSync as readFileSync16 } from "fs";
61789
+ import { readFileSync as readFileSync17 } from "fs";
60908
61790
  function createValidateProductCommand() {
60909
61791
  return new Command29("validate-product").description("Validate a product (FPO) or FPO template locally (no API call)").argument(
60910
61792
  "[input]",
@@ -60984,7 +61866,7 @@ async function readInput(input) {
60984
61866
  if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
60985
61867
  return trimmed;
60986
61868
  }
60987
- return readFileSync16(input, "utf-8");
61869
+ return readFileSync17(input, "utf-8");
60988
61870
  }
60989
61871
  async function readStdin() {
60990
61872
  if (process.stdin.isTTY) {
@@ -61086,8 +61968,8 @@ function printIssues(title, issues, color) {
61086
61968
  // src/commands/deploy.ts
61087
61969
  import { Command as Command30 } from "commander";
61088
61970
  import chalk37 from "chalk";
61089
- import * as fs15 from "fs";
61090
- import * as path15 from "path";
61971
+ import * as fs16 from "fs";
61972
+ import * as path16 from "path";
61091
61973
  import { RuntypeApiError as RuntypeApiError4 } from "@runtypelabs/sdk";
61092
61974
  function bashSingleQuote(s) {
61093
61975
  return "'" + s.replace(/'/g, "'\\''") + "'";
@@ -62057,8 +62939,8 @@ var deployCommand = new Command30("deploy").description("Export an agent or flow
62057
62939
  const apiKey = await ensureAuth();
62058
62940
  if (!apiKey) return;
62059
62941
  const client = createCliClient(apiKey);
62060
- const outDir = path15.resolve(options.output);
62061
- const projectName = options.name ?? slugify2(path15.basename(outDir));
62942
+ const outDir = path16.resolve(options.output);
62943
+ const projectName = options.name ?? slugify2(path16.basename(outDir));
62062
62944
  console.log(chalk37.cyan(`
62063
62945
  Scaffolding ${target} deployment to ${outDir}
62064
62946
  `));
@@ -62123,18 +63005,18 @@ Scaffolding ${target} deployment to ${outDir}
62123
63005
  }
62124
63006
  slugSet.add(slug);
62125
63007
  }
62126
- fs15.mkdirSync(path15.join(outDir, "agents"), { recursive: true });
62127
- fs15.mkdirSync(path15.join(outDir, "packages"), { recursive: true });
63008
+ fs16.mkdirSync(path16.join(outDir, "agents"), { recursive: true });
63009
+ fs16.mkdirSync(path16.join(outDir, "packages"), { recursive: true });
62128
63010
  for (const { name, def } of agentDefs) {
62129
63011
  const filename = `${slugify2(name)}.json`;
62130
- fs15.writeFileSync(path15.join(outDir, "agents", filename), JSON.stringify(def, null, 2));
63012
+ fs16.writeFileSync(path16.join(outDir, "agents", filename), JSON.stringify(def, null, 2));
62131
63013
  console.log(` Wrote agents/${filename}`);
62132
63014
  }
62133
63015
  const agentNames = agentDefs.map((a) => a.name);
62134
63016
  let monorepoRoot = process.cwd();
62135
63017
  for (let i = 0; i < 8; i++) {
62136
- if (fs15.existsSync(path15.join(monorepoRoot, "pnpm-workspace.yaml"))) break;
62137
- const parent = path15.dirname(monorepoRoot);
63018
+ if (fs16.existsSync(path16.join(monorepoRoot, "pnpm-workspace.yaml"))) break;
63019
+ const parent = path16.dirname(monorepoRoot);
62138
63020
  if (parent === monorepoRoot) break;
62139
63021
  monorepoRoot = parent;
62140
63022
  }
@@ -62144,35 +63026,35 @@ Scaffolding ${target} deployment to ${outDir}
62144
63026
  }
62145
63027
  const secretNames = Array.from(allSecrets);
62146
63028
  if (target === "cloudflare") {
62147
- fs15.mkdirSync(path15.join(outDir, "src"), { recursive: true });
62148
- fs15.writeFileSync(path15.join(outDir, "src", "index.ts"), workerIndexTs(agentSlugs));
62149
- fs15.writeFileSync(path15.join(outDir, "wrangler.toml"), wranglerToml(projectName));
62150
- fs15.writeFileSync(path15.join(outDir, "package.json"), workerPackageJson(projectName, "workspace:*"));
62151
- fs15.writeFileSync(path15.join(outDir, "tsconfig.json"), workerTsconfigJson());
62152
- const setupPath = path15.join(outDir, "setup.sh");
62153
- fs15.writeFileSync(setupPath, workerSetupSh(monorepoRoot));
62154
- fs15.chmodSync(setupPath, 493);
62155
- fs15.writeFileSync(path15.join(outDir, "README.md"), workerReadme(agentNames, secretNames));
63029
+ fs16.mkdirSync(path16.join(outDir, "src"), { recursive: true });
63030
+ fs16.writeFileSync(path16.join(outDir, "src", "index.ts"), workerIndexTs(agentSlugs));
63031
+ fs16.writeFileSync(path16.join(outDir, "wrangler.toml"), wranglerToml(projectName));
63032
+ fs16.writeFileSync(path16.join(outDir, "package.json"), workerPackageJson(projectName, "workspace:*"));
63033
+ fs16.writeFileSync(path16.join(outDir, "tsconfig.json"), workerTsconfigJson());
63034
+ const setupPath = path16.join(outDir, "setup.sh");
63035
+ fs16.writeFileSync(setupPath, workerSetupSh(monorepoRoot));
63036
+ fs16.chmodSync(setupPath, 493);
63037
+ fs16.writeFileSync(path16.join(outDir, "README.md"), workerReadme(agentNames, secretNames));
62156
63038
  } else if (target === "vercel") {
62157
- fs15.mkdirSync(path15.join(outDir, "api"), { recursive: true });
62158
- fs15.writeFileSync(path15.join(outDir, "api", "[[...route]].ts"), vercelRouteTs(agentSlugs));
62159
- fs15.writeFileSync(path15.join(outDir, "vercel.json"), vercelJson());
62160
- fs15.writeFileSync(path15.join(outDir, "package.json"), vercelPackageJson(projectName, "workspace:*"));
62161
- fs15.writeFileSync(path15.join(outDir, "tsconfig.json"), vercelTsconfigJson());
62162
- const setupPath = path15.join(outDir, "setup.sh");
62163
- fs15.writeFileSync(setupPath, vercelSetupSh(monorepoRoot));
62164
- fs15.chmodSync(setupPath, 493);
62165
- fs15.writeFileSync(path15.join(outDir, "README.md"), vercelReadme(agentNames, secretNames));
63039
+ fs16.mkdirSync(path16.join(outDir, "api"), { recursive: true });
63040
+ fs16.writeFileSync(path16.join(outDir, "api", "[[...route]].ts"), vercelRouteTs(agentSlugs));
63041
+ fs16.writeFileSync(path16.join(outDir, "vercel.json"), vercelJson());
63042
+ fs16.writeFileSync(path16.join(outDir, "package.json"), vercelPackageJson(projectName, "workspace:*"));
63043
+ fs16.writeFileSync(path16.join(outDir, "tsconfig.json"), vercelTsconfigJson());
63044
+ const setupPath = path16.join(outDir, "setup.sh");
63045
+ fs16.writeFileSync(setupPath, vercelSetupSh(monorepoRoot));
63046
+ fs16.chmodSync(setupPath, 493);
63047
+ fs16.writeFileSync(path16.join(outDir, "README.md"), vercelReadme(agentNames, secretNames));
62166
63048
  } else {
62167
- fs15.writeFileSync(path15.join(outDir, "server.ts"), serverTs());
62168
- fs15.writeFileSync(path15.join(outDir, "Dockerfile"), dockerfile());
62169
- fs15.writeFileSync(path15.join(outDir, ".dockerignore"), dockerignore());
62170
- fs15.writeFileSync(path15.join(outDir, "tsconfig.json"), tsconfigJson());
62171
- fs15.writeFileSync(path15.join(outDir, "package.json"), packageJson(projectName, "workspace:*"));
62172
- const setupPath = path15.join(outDir, "setup.sh");
62173
- fs15.writeFileSync(setupPath, setupSh(monorepoRoot));
62174
- fs15.chmodSync(setupPath, 493);
62175
- fs15.writeFileSync(path15.join(outDir, "README.md"), readme(agentNames, secretNames));
63049
+ fs16.writeFileSync(path16.join(outDir, "server.ts"), serverTs());
63050
+ fs16.writeFileSync(path16.join(outDir, "Dockerfile"), dockerfile());
63051
+ fs16.writeFileSync(path16.join(outDir, ".dockerignore"), dockerignore());
63052
+ fs16.writeFileSync(path16.join(outDir, "tsconfig.json"), tsconfigJson());
63053
+ fs16.writeFileSync(path16.join(outDir, "package.json"), packageJson(projectName, "workspace:*"));
63054
+ const setupPath = path16.join(outDir, "setup.sh");
63055
+ fs16.writeFileSync(setupPath, setupSh(monorepoRoot));
63056
+ fs16.chmodSync(setupPath, 493);
63057
+ fs16.writeFileSync(path16.join(outDir, "README.md"), readme(agentNames, secretNames));
62176
63058
  }
62177
63059
  console.log("");
62178
63060
  console.log(chalk37.green(`\u2713 Scaffold written to ${outDir}`));
@@ -62230,19 +63112,19 @@ import { Command as Command31 } from "commander";
62230
63112
  import chalk39 from "chalk";
62231
63113
 
62232
63114
  // src/lib/skills-install.ts
62233
- import { mkdirSync as mkdirSync9, readFileSync as readFileSync17, writeFileSync as writeFileSync7 } from "fs";
62234
- import path16 from "path";
63115
+ import { mkdirSync as mkdirSync9, readFileSync as readFileSync18, writeFileSync as writeFileSync7 } from "fs";
63116
+ import path17 from "path";
62235
63117
  import readline4 from "readline";
62236
63118
  import chalk38 from "chalk";
62237
63119
  var SKILLS_REPO = "runtypelabs/skills";
62238
63120
  var SKILLS_INSTALL_RETRY_HINT = "Retry with `runtype skills install`, or install manually: npx skills add runtypelabs/skills";
62239
63121
  var METADATA_FILENAME = "agents-skills-install.json";
62240
63122
  function metadataPath() {
62241
- return path16.join(getRuntypeHomeDir(), METADATA_FILENAME);
63123
+ return path17.join(getRuntypeHomeDir(), METADATA_FILENAME);
62242
63124
  }
62243
63125
  function readSkillsInstallMetadata() {
62244
63126
  try {
62245
- const raw = readFileSync17(metadataPath(), "utf8");
63127
+ const raw = readFileSync18(metadataPath(), "utf8");
62246
63128
  const parsed = JSON.parse(raw);
62247
63129
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && parsed.version === 1 && typeof parsed.accepted === "boolean") {
62248
63130
  return parsed;
@@ -62254,7 +63136,7 @@ function readSkillsInstallMetadata() {
62254
63136
  }
62255
63137
  function writeSkillsInstallMetadata(metadata) {
62256
63138
  try {
62257
- mkdirSync9(path16.dirname(metadataPath()), { recursive: true });
63139
+ mkdirSync9(path17.dirname(metadataPath()), { recursive: true });
62258
63140
  writeFileSync7(metadataPath(), JSON.stringify(metadata, null, 2));
62259
63141
  } catch {
62260
63142
  }
@@ -62305,8 +63187,8 @@ async function promptConfirm3(message, defaultYes = true) {
62305
63187
  const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
62306
63188
  const hint = defaultYes ? chalk38.dim(" (Y/n)") : chalk38.dim(" (y/N)");
62307
63189
  try {
62308
- const answer = await new Promise((resolve10) => {
62309
- rl.question(`${message}${hint}: `, resolve10);
63190
+ const answer = await new Promise((resolve11) => {
63191
+ rl.question(`${message}${hint}: `, resolve11);
62310
63192
  });
62311
63193
  const t = answer.trim().toLowerCase();
62312
63194
  if (t === "") return defaultYes;
@@ -62510,11 +63392,265 @@ skillsCommand.command("install").description(`Install Runtype skills (${SKILLS_R
62510
63392
  }
62511
63393
  );
62512
63394
 
63395
+ // src/commands/apps.ts
63396
+ import { readdirSync as readdirSync6, readFileSync as readFileSync19, lstatSync, statSync as statSync7, existsSync as existsSync14 } from "fs";
63397
+ import { join as join12, relative as relative5 } from "path";
63398
+ import { Command as Command32 } from "commander";
63399
+ import chalk40 from "chalk";
63400
+ import { zipSync } from "fflate";
63401
+ var appsCommand = new Command32("apps").description(
63402
+ "Manage Runtype Apps (hosted AI apps on *.runtype.run)"
63403
+ );
63404
+ var MANIFEST_FILENAME = "runtype.app.json";
63405
+ function collectBundleFiles(dir) {
63406
+ const zippable = {};
63407
+ const walk = (current) => {
63408
+ for (const entry of readdirSync6(current)) {
63409
+ if (entry.startsWith(".")) continue;
63410
+ const full = join12(current, entry);
63411
+ const stat = lstatSync(full);
63412
+ if (stat.isSymbolicLink()) continue;
63413
+ if (stat.isDirectory()) {
63414
+ if (entry === "node_modules") continue;
63415
+ walk(full);
63416
+ } else {
63417
+ zippable[relative5(dir, full).split("\\").join("/")] = readFileSync19(full);
63418
+ }
63419
+ }
63420
+ };
63421
+ walk(dir);
63422
+ return zippable;
63423
+ }
63424
+ function fail(message, jsonMode, code) {
63425
+ if (jsonMode) {
63426
+ printJson({ status: "error", error: message, code });
63427
+ } else {
63428
+ console.error(chalk40.red(message));
63429
+ }
63430
+ process.exit(1);
63431
+ }
63432
+ appsCommand.command("list").description("List your apps").option("--json", "Structured JSON output").action(async (options, cmd) => {
63433
+ const globals = cmd.optsWithGlobals();
63434
+ const jsonMode = !!(options.json ?? globals.json);
63435
+ const apiKey = await ensureAuth();
63436
+ if (!apiKey) return;
63437
+ const client = createCliClient(apiKey);
63438
+ try {
63439
+ const { data } = await client.apps.list();
63440
+ if (jsonMode) {
63441
+ printJson({ data });
63442
+ return;
63443
+ }
63444
+ if (data.length === 0) {
63445
+ console.log(chalk40.yellow("No apps yet. Create one with `runtype apps create`."));
63446
+ return;
63447
+ }
63448
+ for (const app of data) {
63449
+ const status = app.status === "suspended" ? chalk40.red("suspended") : chalk40.green("active");
63450
+ const serving = app.activeVersionId ? "" : chalk40.dim(" (no active version)");
63451
+ console.log(`${chalk40.bold(app.name)} ${chalk40.dim(app.id)}`);
63452
+ console.log(` ${app.url} ${status} ${app.visibility}${serving}`);
63453
+ }
63454
+ } catch (error51) {
63455
+ fail(
63456
+ `Failed to list apps: ${error51 instanceof Error ? error51.message : String(error51)}`,
63457
+ jsonMode,
63458
+ "LIST_FAILED"
63459
+ );
63460
+ }
63461
+ });
63462
+ appsCommand.command("create").description("Create an app (the hostname is {slug}-{shortId}.runtype.run)").requiredOption("-s, --slug <slug>", "Hostname slug (lowercase, must start with a letter)").requiredOption("-n, --name <name>", "Display name").option("-d, --description <text>", "Description").option("--visibility <visibility>", "public or unlisted (default unlisted)").option("--json", "Structured JSON output").action(
63463
+ async (options, cmd) => {
63464
+ const globals = cmd.optsWithGlobals();
63465
+ const jsonMode = !!(options.json ?? globals.json);
63466
+ const apiKey = await ensureAuth();
63467
+ if (!apiKey) return;
63468
+ const client = createCliClient(apiKey);
63469
+ try {
63470
+ const app = await client.apps.create({
63471
+ slug: options.slug,
63472
+ name: options.name,
63473
+ description: options.description,
63474
+ visibility: options.visibility
63475
+ });
63476
+ if (jsonMode) {
63477
+ printJson(app);
63478
+ return;
63479
+ }
63480
+ console.log(chalk40.green(`Created ${app.name} (${app.id})`));
63481
+ console.log(` ${app.url}`);
63482
+ console.log(chalk40.dim(" Deploy a bundle with `runtype apps deploy <dir> --app " + app.id + "`"));
63483
+ } catch (error51) {
63484
+ fail(
63485
+ `Failed to create app: ${error51 instanceof Error ? error51.message : String(error51)}`,
63486
+ jsonMode,
63487
+ "CREATE_FAILED"
63488
+ );
63489
+ }
63490
+ }
63491
+ );
63492
+ appsCommand.command("deploy <dir>").description("Zip a bundle directory, upload it as a new version, and activate it").requiredOption("-a, --app <appId>", "The app id (app_...) to deploy to").option("--no-activate", "Upload without activating (what is served stays unchanged)").option("--json", "Structured JSON output").action(
63493
+ async (dir, options, cmd) => {
63494
+ const globals = cmd.optsWithGlobals();
63495
+ const jsonMode = !!(options.json ?? globals.json);
63496
+ const apiKey = await ensureAuth();
63497
+ if (!apiKey) return;
63498
+ if (!existsSync14(dir) || !statSync7(dir).isDirectory()) {
63499
+ fail(`Not a directory: ${dir}`, jsonMode, "INVALID_DIR");
63500
+ }
63501
+ let bundleFiles = {};
63502
+ try {
63503
+ bundleFiles = collectBundleFiles(dir);
63504
+ } catch (error51) {
63505
+ fail(
63506
+ `Failed to read ${dir}: ${error51 instanceof Error ? error51.message : String(error51)}`,
63507
+ jsonMode,
63508
+ "INVALID_DIR"
63509
+ );
63510
+ }
63511
+ if (!bundleFiles["index.html"]) {
63512
+ fail(
63513
+ `${dir} is missing index.html at its root (symlinked files are not bundled).`,
63514
+ jsonMode,
63515
+ "MISSING_INDEX"
63516
+ );
63517
+ }
63518
+ if (!bundleFiles[MANIFEST_FILENAME]) {
63519
+ fail(
63520
+ `${dir} is missing ${MANIFEST_FILENAME} at its root (symlinked files are not bundled). Every app bundle needs a manifest; see the build-runtype-app skill or the Runtype docs.`,
63521
+ jsonMode,
63522
+ "MISSING_MANIFEST"
63523
+ );
63524
+ }
63525
+ const client = createCliClient(apiKey);
63526
+ try {
63527
+ const zipBytes = zipSync(bundleFiles);
63528
+ if (!jsonMode) console.log(chalk40.dim(`Uploading ${(zipBytes.byteLength / 1024).toFixed(1)} KB bundle...`));
63529
+ const version2 = await client.apps.uploadVersion(options.app, zipBytes);
63530
+ let app;
63531
+ if (options.activate) {
63532
+ try {
63533
+ const activated = await client.apps.activate(options.app, version2.id);
63534
+ app = activated.app;
63535
+ } catch (error51) {
63536
+ const message = error51 instanceof Error ? error51.message : String(error51);
63537
+ if (jsonMode) {
63538
+ printJson({
63539
+ status: "error",
63540
+ error: `Activation failed: ${message}`,
63541
+ code: "ACTIVATE_FAILED",
63542
+ version: version2,
63543
+ activated: false
63544
+ });
63545
+ } else {
63546
+ console.error(chalk40.red(`Uploaded version ${version2.versionNumber}, but activation failed: ${message}`));
63547
+ console.error(chalk40.dim(` Retry with \`runtype apps activate ${options.app} ${version2.id}\` (no re-upload needed).`));
63548
+ }
63549
+ process.exit(1);
63550
+ }
63551
+ }
63552
+ if (jsonMode) {
63553
+ printJson({ version: version2, app, activated: options.activate });
63554
+ return;
63555
+ }
63556
+ console.log(
63557
+ chalk40.green(
63558
+ `Deployed version ${version2.versionNumber} (${version2.fileCount} files, ${(version2.sizeBytes / 1024).toFixed(1)} KB)`
63559
+ )
63560
+ );
63561
+ if (app) {
63562
+ console.log(` Live at ${chalk40.bold(app.url)}`);
63563
+ } else {
63564
+ console.log(chalk40.dim(` Uploaded but not activated. Activate with \`runtype apps activate ${options.app} ${version2.id}\``));
63565
+ }
63566
+ } catch (error51) {
63567
+ fail(
63568
+ `Deploy failed: ${error51 instanceof Error ? error51.message : String(error51)}`,
63569
+ jsonMode,
63570
+ "DEPLOY_FAILED"
63571
+ );
63572
+ }
63573
+ }
63574
+ );
63575
+ appsCommand.command("versions <appId>").description("List an app's versions, newest first").option("--json", "Structured JSON output").action(async (appId, options, cmd) => {
63576
+ const globals = cmd.optsWithGlobals();
63577
+ const jsonMode = !!(options.json ?? globals.json);
63578
+ const apiKey = await ensureAuth();
63579
+ if (!apiKey) return;
63580
+ const client = createCliClient(apiKey);
63581
+ try {
63582
+ const { data } = await client.apps.listVersions(appId);
63583
+ if (jsonMode) {
63584
+ printJson({ data });
63585
+ return;
63586
+ }
63587
+ if (data.length === 0) {
63588
+ console.log(chalk40.yellow("No versions uploaded yet."));
63589
+ return;
63590
+ }
63591
+ for (const version2 of data) {
63592
+ const marker = version2.status === "active" ? chalk40.green(" (active)") : "";
63593
+ console.log(
63594
+ `v${version2.versionNumber} ${chalk40.dim(version2.id)} ${version2.fileCount} files, ${(version2.sizeBytes / 1024).toFixed(1)} KB${marker}`
63595
+ );
63596
+ }
63597
+ } catch (error51) {
63598
+ fail(
63599
+ `Failed to list versions: ${error51 instanceof Error ? error51.message : String(error51)}`,
63600
+ jsonMode,
63601
+ "VERSIONS_FAILED"
63602
+ );
63603
+ }
63604
+ });
63605
+ appsCommand.command("activate <appId> <versionId>").description("Activate an uploaded version (deploy or rollback)").option("--json", "Structured JSON output").action(async (appId, versionId, options, cmd) => {
63606
+ const globals = cmd.optsWithGlobals();
63607
+ const jsonMode = !!(options.json ?? globals.json);
63608
+ const apiKey = await ensureAuth();
63609
+ if (!apiKey) return;
63610
+ const client = createCliClient(apiKey);
63611
+ try {
63612
+ const { app, version: version2 } = await client.apps.activate(appId, versionId);
63613
+ if (jsonMode) {
63614
+ printJson({ app, version: version2 });
63615
+ return;
63616
+ }
63617
+ console.log(chalk40.green(`Activated version ${version2.versionNumber}`));
63618
+ console.log(` Live at ${chalk40.bold(app.url)}`);
63619
+ } catch (error51) {
63620
+ fail(
63621
+ `Activation failed: ${error51 instanceof Error ? error51.message : String(error51)}`,
63622
+ jsonMode,
63623
+ "ACTIVATE_FAILED"
63624
+ );
63625
+ }
63626
+ });
63627
+ appsCommand.command("delete <appId>").description("Permanently delete an app, its versions, and its hosting").option("--json", "Structured JSON output").action(async (appId, options, cmd) => {
63628
+ const globals = cmd.optsWithGlobals();
63629
+ const jsonMode = !!(options.json ?? globals.json);
63630
+ const apiKey = await ensureAuth();
63631
+ if (!apiKey) return;
63632
+ const client = createCliClient(apiKey);
63633
+ try {
63634
+ await client.apps.delete(appId);
63635
+ if (jsonMode) {
63636
+ printJson({ status: "deleted", appId });
63637
+ return;
63638
+ }
63639
+ console.log(chalk40.green(`Deleted ${appId}`));
63640
+ } catch (error51) {
63641
+ fail(
63642
+ `Delete failed: ${error51 instanceof Error ? error51.message : String(error51)}`,
63643
+ jsonMode,
63644
+ "DELETE_FAILED"
63645
+ );
63646
+ }
63647
+ });
63648
+
62513
63649
  // src/index.ts
62514
63650
  init_credential_store();
62515
63651
 
62516
63652
  // src/lib/update-check.ts
62517
- import chalk40 from "chalk";
63653
+ import chalk41 from "chalk";
62518
63654
  import Conf3 from "conf";
62519
63655
  var UPDATE_CHECK_INTERVAL_MS = 12 * 60 * 60 * 1e3;
62520
63656
  var UPDATE_NOTIFY_INTERVAL_MS = 24 * 60 * 60 * 1e3;
@@ -62608,7 +63744,7 @@ function notifyFromCachedCliUpdate(args, options = {}) {
62608
63744
  console.error(message);
62609
63745
  });
62610
63746
  notify(
62611
- `${chalk40.yellow("Update available:")} ${chalk40.red(currentVersion)} ${chalk40.gray("->")} ${chalk40.green(latestVersion)} ${chalk40.gray(`(${getUpgradeCommand()})`)}`
63747
+ `${chalk41.yellow("Update available:")} ${chalk41.red(currentVersion)} ${chalk41.gray("->")} ${chalk41.green(latestVersion)} ${chalk41.gray(`(${getUpgradeCommand()})`)}`
62612
63748
  );
62613
63749
  store.set("lastNotifiedAt", now.toISOString());
62614
63750
  store.set("lastNotifiedVersion", latestVersion);
@@ -62650,7 +63786,7 @@ function maybeNotifyAboutCliUpdate(args, options = {}) {
62650
63786
  // src/index.ts
62651
63787
  loadEnv();
62652
63788
  setCliTitle();
62653
- var program = new Command32();
63789
+ var program = new Command33();
62654
63790
  program.name("runtype").description("CLI for Runtype AI Platform").version(getCliVersion()).option("-v, --verbose", "Enable verbose output").option("--api-url <url>", "Override API URL").option("--json", "Output as JSON");
62655
63791
  program.addCommand(initCommand);
62656
63792
  program.addCommand(loginCommand);
@@ -62684,6 +63820,7 @@ program.addCommand(tailCommand);
62684
63820
  program.addCommand(validateProductCommand);
62685
63821
  program.addCommand(deployCommand);
62686
63822
  program.addCommand(skillsCommand);
63823
+ program.addCommand(appsCommand);
62687
63824
  program.exitOverride();
62688
63825
  async function run() {
62689
63826
  const userArgs = process.argv.slice(2);
@@ -62701,15 +63838,15 @@ async function run() {
62701
63838
  run().catch((error51) => {
62702
63839
  const commanderError = error51;
62703
63840
  if (commanderError.code === "commander.missingArgument") {
62704
- console.error(chalk41.red(`Error: ${commanderError.message}`));
63841
+ console.error(chalk42.red(`Error: ${commanderError.message}`));
62705
63842
  process.exit(1);
62706
63843
  } else if (commanderError.code === "commander.unknownOption") {
62707
- console.error(chalk41.red(`Error: ${commanderError.message}`));
63844
+ console.error(chalk42.red(`Error: ${commanderError.message}`));
62708
63845
  process.exit(1);
62709
63846
  } else if (commanderError.code === "commander.help" || commanderError.code === "commander.version") {
62710
63847
  process.exit(0);
62711
63848
  } else {
62712
- console.error(chalk41.red("An unexpected error occurred:"));
63849
+ console.error(chalk42.red("An unexpected error occurred:"));
62713
63850
  console.error(error51);
62714
63851
  process.exit(1);
62715
63852
  }
@@ -62718,12 +63855,12 @@ async function handleNoCommand() {
62718
63855
  const store = new CredentialStore();
62719
63856
  const hasCredentials = await store.hasCredentials();
62720
63857
  if (!hasCredentials) {
62721
- console.log(chalk41.cyan("\nWelcome to Runtype CLI!\n"));
63858
+ console.log(chalk42.cyan("\nWelcome to Runtype CLI!\n"));
62722
63859
  console.log("It looks like this is your first time. Run the setup wizard:");
62723
- console.log(` ${chalk41.green("runtype init")}
63860
+ console.log(` ${chalk42.green("runtype init")}
62724
63861
  `);
62725
63862
  console.log("Or see all available commands:");
62726
- console.log(` ${chalk41.green("runtype --help")}
63863
+ console.log(` ${chalk42.green("runtype --help")}
62727
63864
  `);
62728
63865
  } else {
62729
63866
  try {