lalph 0.3.87 → 0.3.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -12350,6 +12350,22 @@ const done = done$2;
12350
12350
  */
12351
12351
  const isTimeoutError = isTimeoutError$1;
12352
12352
  /**
12353
+ * Constructs a {@link TimeoutError} with an optional message.
12354
+ *
12355
+ * **Example** (creating a TimeoutError)
12356
+ *
12357
+ * ```ts
12358
+ * import { Cause } from "effect"
12359
+ *
12360
+ * const error = new Cause.TimeoutError("Operation timed out")
12361
+ * console.log(error.message) // "Operation timed out"
12362
+ * ```
12363
+ *
12364
+ * @category constructors
12365
+ * @since 4.0.0
12366
+ */
12367
+ const TimeoutError = TimeoutError$1;
12368
+ /**
12353
12369
  * Constructs an {@link IllegalArgumentError} with an optional message.
12354
12370
  *
12355
12371
  * **Example** (creating an IllegalArgumentError)
@@ -181580,7 +181596,7 @@ var ji = Bt, Ii = Object.assign(Qe, { sync: Bt }), zi = Ut, Bi = Object.assign(e
181580
181596
  });
181581
181597
  Ze.glob = Ze;
181582
181598
  //#endregion
181583
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/ApplyPatch.js
181599
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/ApplyPatch.js
181584
181600
  /**
181585
181601
  * @since 1.0.0
181586
181602
  */
@@ -196453,7 +196469,7 @@ var StreamableHTTPClientTransport = class {
196453
196469
  }
196454
196470
  };
196455
196471
  //#endregion
196456
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/McpClient.js
196472
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/McpClient.js
196457
196473
  /**
196458
196474
  * @since 1.0.0
196459
196475
  */
@@ -196498,7 +196514,7 @@ const layer$13 = effect$1(McpClient, gen(function* () {
196498
196514
  });
196499
196515
  }));
196500
196516
  //#endregion
196501
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/ExaSearch.js
196517
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/ExaSearch.js
196502
196518
  /**
196503
196519
  * @since 1.0.0
196504
196520
  */
@@ -211448,7 +211464,7 @@ var require_lib = /* @__PURE__ */ __commonJSMin$1(((exports) => {
211448
211464
  exports.impl = impl;
211449
211465
  }));
211450
211466
  //#endregion
211451
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/WebToMarkdown.js
211467
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/WebToMarkdown.js
211452
211468
  /**
211453
211469
  * @since 1.0.0
211454
211470
  */
@@ -215066,7 +215082,7 @@ const mapProviderResults = (inputLength, results) => {
215066
215082
  return succeed$3(embeddings);
215067
215083
  };
215068
215084
  //#endregion
215069
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/ChunkRepo.js
215085
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/ChunkRepo.js
215070
215086
  /**
215071
215087
  * @since 1.0.0
215072
215088
  * @category Models
@@ -215197,7 +215213,7 @@ const layer$10 = effect$1(ChunkRepo, gen(function* () {
215197
215213
  });
215198
215214
  }));
215199
215215
  //#endregion
215200
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/CodeChunker.js
215216
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/CodeChunker.js
215201
215217
  /**
215202
215218
  * @since 1.0.0
215203
215219
  */
@@ -215790,7 +215806,7 @@ const run$1 = /* @__PURE__ */ make$25({});
215790
215806
  */
215791
215807
  const layer$7 = (options) => effectDiscard(run$1(options));
215792
215808
  //#endregion
215793
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/internal/sqlite-vector.js
215809
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/internal/sqlite-vector.js
215794
215810
  /**
215795
215811
  * Binary extension for each platform
215796
215812
  */
@@ -215907,7 +215923,7 @@ function getExtensionPath() {
215907
215923
  throw new ExtensionNotFoundError(`SQLite Vector extension not found for platform: ${getCurrentPlatform()}\n\nThe platform-specific package "${getPlatformPackageName()}" is not installed.\nThis usually happens when:\n 1. Your platform is not supported\n 2. npm failed to install optional dependencies\n 3. You're installing with --no-optional flag\n\nTry running: npm install --force`);
215908
215924
  }
215909
215925
  //#endregion
215910
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/Sqlite.js
215926
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/Sqlite.js
215911
215927
  /**
215912
215928
  * @since 1.0.0
215913
215929
  */
@@ -215935,7 +215951,7 @@ const SqliteLayer = (database) => layer$7({ loader: fromRecord({ "0001_create_ch
215935
215951
  yield* fs.makeDirectory(directory, { recursive: true });
215936
215952
  }))));
215937
215953
  //#endregion
215938
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/SemanticSearch.js
215954
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/SemanticSearch.js
215939
215955
  /**
215940
215956
  * @since 1.0.0
215941
215957
  */
@@ -216077,7 +216093,7 @@ const maybeRemoveFile = (path) => serviceOption(SemanticSearch).pipe(flatMap$4(m
216077
216093
  onSome: (service) => service.removeFile(path)
216078
216094
  })));
216079
216095
  //#endregion
216080
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/AgentTools.js
216096
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/AgentTools.js
216081
216097
  /**
216082
216098
  * @since 1.0.0
216083
216099
  */
@@ -216150,7 +216166,7 @@ const AgentTools = make$14(make$13("readFile", {
216150
216166
  }),
216151
216167
  dependencies: [CurrentDirectory]
216152
216168
  }), make$13("applyPatch", {
216153
- description: "Apply a git diff / unified diff patch, or a wrapped patch, across one or more files.",
216169
+ description: "Add, update or remove multiple files with a git diff / unified diff / wrapped patch.",
216154
216170
  parameters: String$1.annotate({ identifier: "patch" }),
216155
216171
  success: String$1,
216156
216172
  dependencies: [CurrentDirectory]
@@ -216428,7 +216444,7 @@ const AgentToolHandlers = AgentToolHandlersNoDeps.pipe(provide$3([layer$12, laye
216428
216444
  AgentToolHandlersNoDeps.pipe(provide$3([mock(ExaSearch)({}), mock(WebToMarkdown)({})]));
216429
216445
  var ApplyPatchError = class extends TaggedClass$2("ApplyPatchError") {};
216430
216446
  //#endregion
216431
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/TypeBuilder.js
216447
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/TypeBuilder.js
216432
216448
  const resolveDocumentation = resolveAt("documentation");
216433
216449
  const identifierPattern = /^[$A-Z_a-z][$0-9A-Z_a-z]*$/u;
216434
216450
  const Precedence = {
@@ -216701,7 +216717,7 @@ const render = (schema, options) => {
216701
216717
  return printNode({ text: documentation === void 0 ? rendered.text : `${renderJsDoc(documentation, 0, printerOptions)}${printerOptions.newLine}${rendered.text}` }, printerOptions);
216702
216718
  };
216703
216719
  //#endregion
216704
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/ToolkitRenderer.js
216720
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/ToolkitRenderer.js
216705
216721
  /**
216706
216722
  * @since 1.0.0
216707
216723
  */
@@ -216723,7 +216739,7 @@ declare function ${name}(${params}): Promise<${render(tool.successSchema)}>`);
216723
216739
  }) });
216724
216740
  };
216725
216741
  //#endregion
216726
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/ScriptPreprocessing.js
216742
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/ScriptPreprocessing.js
216727
216743
  const isIdentifierChar = (char) => char !== void 0 && /[A-Za-z0-9_$]/.test(char);
216728
216744
  const isIdentifierStartChar = (char) => char !== void 0 && /[A-Za-z_$]/.test(char);
216729
216745
  const hasIdentifierBoundary = (text, index, length) => !isIdentifierChar(text[index - 1]) && !isIdentifierChar(text[index + length]);
@@ -216766,20 +216782,22 @@ const needsTemplateEscaping = (text) => {
216766
216782
  }
216767
216783
  return false;
216768
216784
  };
216785
+ const normalizePatchEscapedQuotes = (text) => text.includes("*** Begin Patch") ? text.replace(/\\"([A-Za-z0-9_$.-]+)\\"/g, "\"$1\"") : text;
216769
216786
  const escapeTemplateLiteralContent = (text) => {
216770
- if (!needsTemplateEscaping(text)) return text;
216787
+ const normalized = normalizePatchEscapedQuotes(text);
216788
+ if (!needsTemplateEscaping(normalized)) return normalized;
216771
216789
  let out = "";
216772
- for (let i = 0; i < text.length; i++) {
216773
- const char = text[i];
216790
+ for (let i = 0; i < normalized.length; i++) {
216791
+ const char = normalized[i];
216774
216792
  if (char === "\\") {
216775
216793
  out += "\\\\";
216776
216794
  continue;
216777
216795
  }
216778
- if (char === "`" && !isEscaped(text, i)) {
216796
+ if (char === "`" && !isEscaped(normalized, i)) {
216779
216797
  out += "\\`";
216780
216798
  continue;
216781
216799
  }
216782
- if (char === "$" && text[i + 1] === "{" && !isEscaped(text, i)) {
216800
+ if (char === "$" && normalized[i + 1] === "{" && !isEscaped(normalized, i)) {
216783
216801
  out += "\\$";
216784
216802
  continue;
216785
216803
  }
@@ -217001,13 +217019,14 @@ const fixAssignedTemplatesForToolCalls = (script) => {
217001
217019
  const identifiers = /* @__PURE__ */ new Set();
217002
217020
  for (const functionName of ["applyPatch", "taskComplete"]) for (const identifier of collectCallArgumentIdentifiers(script, functionName)) identifiers.add(identifier);
217003
217021
  for (const identifier of collectWriteFileContentIdentifiers(script)) identifiers.add(identifier);
217022
+ if (script.includes("*** Begin Patch")) identifiers.add("patch");
217004
217023
  let out = script;
217005
217024
  for (const identifier of identifiers) out = fixAssignedTemplate(out, identifier);
217006
217025
  return out;
217007
217026
  };
217008
217027
  const preprocessScript = (script) => fixAssignedTemplatesForToolCalls(["applyPatch", "taskComplete"].reduce((current, functionName) => fixCallTemplateArgument(current, functionName), fixWriteFileContentTemplates(script)));
217009
217028
  //#endregion
217010
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/AgentExecutor.js
217029
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/AgentExecutor.js
217011
217030
  /**
217012
217031
  * @since 1.0.0
217013
217032
  */
@@ -217192,7 +217211,7 @@ var QueueWriteStream = class extends Writable {
217192
217211
  }
217193
217212
  };
217194
217213
  //#endregion
217195
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/ScriptExtraction.js
217214
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/ScriptExtraction.js
217196
217215
  const stripWrappingCodeFence = (script) => {
217197
217216
  const lines = script.split(/\r?\n/);
217198
217217
  if (lines.length < 2) return script;
@@ -218741,7 +218760,7 @@ const applySpanTransformer = (transformer, response, options) => {
218741
218760
  });
218742
218761
  };
218743
218762
  //#endregion
218744
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/Agent.js
218763
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/Agent.js
218745
218764
  /**
218746
218765
  * @since 1.0.0
218747
218766
  */
@@ -230071,7 +230090,7 @@ const transformToolCallParams = /* @__PURE__ */ fnUntraced(function* (tools, too
230071
230090
  })));
230072
230091
  });
230073
230092
  //#endregion
230074
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/CodexAuth.js
230093
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/CodexAuth.js
230075
230094
  /**
230076
230095
  * @since 1.0.0
230077
230096
  */
@@ -230291,7 +230310,7 @@ var CodexAuth = class CodexAuth extends Service$1()("clanka/CodexAuth") {
230291
230310
  static layerClient = this.layerClientNoDeps.pipe(provide$3(CodexAuth.layer));
230292
230311
  };
230293
230312
  //#endregion
230294
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/Codex.js
230313
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/Codex.js
230295
230314
  /**
230296
230315
  * @since 1.0.0
230297
230316
  */
@@ -231603,7 +231622,7 @@ const getUsageDetailNumber = (details, field) => {
231603
231622
  return typeof value === "number" ? value : void 0;
231604
231623
  };
231605
231624
  //#endregion
231606
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/CopilotAuth.js
231625
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/CopilotAuth.js
231607
231626
  /**
231608
231627
  * @since 1.0.0
231609
231628
  */
@@ -231794,7 +231813,7 @@ var GithubCopilotAuth = class GithubCopilotAuth extends Service$1()("clanka/Gith
231794
231813
  static layerClient = this.layerClientNoDeps.pipe(provide$3(GithubCopilotAuth.layer));
231795
231814
  };
231796
231815
  //#endregion
231797
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/Copilot.js
231816
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/Copilot.js
231798
231817
  /**
231799
231818
  * @since 1.0.0
231800
231819
  */
@@ -232214,7 +232233,7 @@ Object.defineProperties(createChalk.prototype, styles);
232214
232233
  const chalk = createChalk();
232215
232234
  createChalk({ level: stderrColor ? stderrColor.level : 0 });
232216
232235
  //#endregion
232217
- //#region node_modules/.pnpm/clanka@0.2.16_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_5dcb2d2797192c163d235bd5caad43db/node_modules/clanka/dist/OutputFormatter.js
232236
+ //#region node_modules/.pnpm/clanka@0.2.17_@effect+ai-openai-compat@4.0.0-beta.35_effect@https+++pkg.pr.new+Effect-T_c137ee36ffe489921e912f65ea0addc5/node_modules/clanka/dist/OutputFormatter.js
232218
232237
  /**
232219
232238
  * @since 1.0.0
232220
232239
  */
@@ -240863,7 +240882,11 @@ const runClanka = fnUntraced(function* (options) {
240863
240882
  yield* log$1(`Received steer message: ${message}`);
240864
240883
  yield* agent.steer(message);
240865
240884
  }, fromEffectDrain)), runDrain, forkScoped);
240866
- return yield* stream.pipe(runDrain, as$1(""), catchTag$1("AgentFinished", (e) => succeed$3(e.summary)));
240885
+ return yield* stream.pipe(options.maxContext ? tap((part) => {
240886
+ if (part._tag !== "Usage") return void_$2;
240887
+ if (part.contextTokens <= options.maxContext) return void_$2;
240888
+ return fail$6(new TimeoutError("Max context reached"));
240889
+ }) : identity, runDrain, as$1(""), catchTag$1("AgentFinished", (e) => succeed$3(e.summary)));
240867
240890
  }, scoped$1, (effect, options) => provide$1(effect, layerLocal({
240868
240891
  directory: options.directory,
240869
240892
  tools: options.mode === "ralph" ? void 0 : options.mode === "choose" ? TaskChooseTools : TaskTools
@@ -240892,6 +240915,7 @@ ${research}`
240892
240915
  }])
240893
240916
  }),
240894
240917
  stallTimeout: options.stallTimeout,
240918
+ maxContext: options.maxContext,
240895
240919
  steer: options.steer,
240896
240920
  mode: options.ralph ? "ralph" : "default"
240897
240921
  });
@@ -241384,6 +241408,7 @@ const runRalph = fnUntraced(function* (options) {
241384
241408
  preset,
241385
241409
  prompt: instructions,
241386
241410
  research: researchResult,
241411
+ maxContext: options.maxContext,
241387
241412
  ralph: true
241388
241413
  }).pipe(withSpan$1("Main.worker"))}`);
241389
241414
  if (options.review) {
@@ -241436,6 +241461,7 @@ const runProject = fnUntraced(function* (options) {
241436
241461
  targetBranch: options.project.targetBranch,
241437
241462
  stallTimeout: options.stallTimeout,
241438
241463
  runTimeout: options.runTimeout,
241464
+ maxContext: options.maxContext,
241439
241465
  review: options.project.reviewAgent,
241440
241466
  research: options.project.researchAgent,
241441
241467
  specFile: options.project.ralphSpec
@@ -241477,17 +241503,19 @@ const runProject = fnUntraced(function* (options) {
241477
241503
  }, (effect, options) => annotateLogs(effect, { project: options.project.id }));
241478
241504
  const iterations = integer$1("iterations").pipe(withDescription$1("Limit how many task iterations run per enabled project (default: unlimited). Use -i 1 to run a single iteration and exit."), withAlias$1("i"), withDefault(Number.POSITIVE_INFINITY));
241479
241505
  const maxIterationMinutes = integer$1("max-minutes").pipe(withDescription$1("Timeout an iteration if execution (and review, if enabled) exceeds this many minutes (default: LALPH_MAX_MINUTES or 90)."), withFallbackConfig(int$1("LALPH_MAX_MINUTES")), withDefault(90));
241506
+ const maxContext = integer$1("max-context").pipe(withDescription$1("If the context window reaches this number of tokens, try again (default: LALPH_MAX_CONTEXT or 250,000)."), withFallbackConfig(int$1("LALPH_MAX_TOKENS")), withDefault(25e4));
241480
241507
  const stallMinutes = integer$1("stall-minutes").pipe(withDescription$1("Fail an iteration if the agent stops responding for this many minutes (default: LALPH_STALL_MINUTES or 5)."), withFallbackConfig(int$1("LALPH_STALL_MINUTES")), withDefault(5));
241481
241508
  const specsDirectory = directory("specs").pipe(withDescription$1("Directory where plan specs are written and read (default: LALPH_SPECS or .specs)."), withAlias$1("s"), withFallbackConfig(string$2("LALPH_SPECS")), withDefault(".specs"));
241482
241509
  const verbose = boolean$2("verbose").pipe(withDescription$1("Increase log output for debugging. Use -v when you need detailed logs."), withAlias$1("v"));
241483
241510
  const commandRoot = make$58("lalph", {
241484
241511
  iterations,
241485
241512
  maxIterationMinutes,
241513
+ maxContext,
241486
241514
  stallMinutes
241487
241515
  }).pipe(withSharedFlags({
241488
241516
  specsDirectory,
241489
241517
  verbose
241490
- }), withDescription("Run the task loop across all enabled projects in parallel: pull issues from the current issue source and execute them with your configured agent preset(s). Use --iterations for a bounded run, and configure per-project concurrency via lalph projects edit."), withHandler(fnUntraced(function* ({ iterations, maxIterationMinutes, stallMinutes, specsDirectory }) {
241518
+ }), withDescription("Run the task loop across all enabled projects in parallel: pull issues from the current issue source and execute them with your configured agent preset(s). Use --iterations for a bounded run, and configure per-project concurrency via lalph projects edit."), withHandler(fnUntraced(function* ({ iterations, maxIterationMinutes, maxContext, stallMinutes, specsDirectory }) {
241491
241519
  yield* getDefaultCliAgentPreset;
241492
241520
  let allProjects = yield* getAllProjects;
241493
241521
  if (allProjects.length === 0) {
@@ -241501,7 +241529,8 @@ const commandRoot = make$58("lalph", {
241501
241529
  project,
241502
241530
  specsDirectory,
241503
241531
  stallTimeout: minutes(stallMinutes),
241504
- runTimeout: minutes(maxIterationMinutes)
241532
+ runTimeout: minutes(maxIterationMinutes),
241533
+ maxContext
241505
241534
  }).pipe(provideService$2(CurrentProjectId, project.id)), {
241506
241535
  concurrency: "unbounded",
241507
241536
  discard: true
@@ -241815,7 +241844,7 @@ const commandEdit = make$58("edit").pipe(withDescription("Open the selected proj
241815
241844
  const commandSource = make$58("source").pipe(withDescription("Select the issue source to use (e.g. GitHub Issues or Linear). This applies to all projects."), withHandler(() => selectIssueSource), provide(Settings.layer));
241816
241845
  //#endregion
241817
241846
  //#region package.json
241818
- var version = "0.3.87";
241847
+ var version = "0.3.89";
241819
241848
  //#endregion
241820
241849
  //#region src/commands/projects/ls.ts
241821
241850
  const commandProjectsLs = make$58("ls").pipe(withDescription("List configured projects and how they run (enabled state, concurrency, branch, git flow, review agent)."), withHandler(fnUntraced(function* () {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lalph",
3
3
  "type": "module",
4
- "version": "0.3.87",
4
+ "version": "0.3.89",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -44,8 +44,8 @@
44
44
  "@linear/sdk": "^78.0.0",
45
45
  "@octokit/plugin-rest-endpoint-methods": "^17.0.0",
46
46
  "@octokit/types": "^16.0.0",
47
- "@typescript/native-preview": "7.0.0-dev.20260318.1",
48
- "clanka": "^0.2.16",
47
+ "@typescript/native-preview": "7.0.0-dev.20260319.1",
48
+ "clanka": "^0.2.17",
49
49
  "concurrently": "^9.2.1",
50
50
  "effect": "https://pkg.pr.new/Effect-TS/effect-smol/effect@89c3e98",
51
51
  "husky": "^9.1.7",
@@ -13,6 +13,7 @@ export const agentWorker = Effect.fnUntraced(function* (options: {
13
13
  readonly prompt: string
14
14
  readonly research: Option.Option<string>
15
15
  readonly steer?: Stream.Stream<string>
16
+ readonly maxContext?: number | undefined
16
17
  readonly ralph: boolean
17
18
  }) {
18
19
  const pathService = yield* Path.Path
@@ -42,6 +43,7 @@ ${research}`,
42
43
  ]),
43
44
  }),
44
45
  stallTimeout: options.stallTimeout,
46
+ maxContext: options.maxContext,
45
47
  steer: options.steer,
46
48
  mode: options.ralph ? "ralph" : "default",
47
49
  })
package/src/Clanka.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import { Agent, OutputFormatter, SemanticSearch } from "clanka"
2
2
  import {
3
+ Cause,
3
4
  Config,
4
5
  Duration,
5
6
  Effect,
7
+ identity,
6
8
  Layer,
7
9
  Option,
8
10
  Path,
@@ -70,6 +72,7 @@ export const runClanka = Effect.fnUntraced(
70
72
  readonly prompt: Prompt.RawInput
71
73
  readonly system?: string | undefined
72
74
  readonly stallTimeout?: Duration.Input | undefined
75
+ readonly maxContext?: number | undefined
73
76
  readonly steer?: Stream.Stream<string> | undefined
74
77
  readonly mode?: "ralph" | "choose" | "default" | undefined
75
78
  }) {
@@ -101,6 +104,14 @@ export const runClanka = Effect.fnUntraced(
101
104
  }
102
105
 
103
106
  return yield* stream.pipe(
107
+ options.maxContext
108
+ ? Stream.tap((part) => {
109
+ if (part._tag !== "Usage") return Effect.void
110
+ const contextTokens = part.contextTokens
111
+ if (contextTokens <= options.maxContext!) return Effect.void
112
+ return Effect.fail(new Cause.TimeoutError("Max context reached"))
113
+ })
114
+ : identity,
104
115
  Stream.runDrain,
105
116
  Effect.as(""),
106
117
  Effect.catchTag("AgentFinished", (e) => Effect.succeed(e.summary)),
@@ -356,6 +356,7 @@ const runRalph = Effect.fnUntraced(
356
356
  readonly research: boolean
357
357
  readonly review: boolean
358
358
  readonly specFile: string
359
+ readonly maxContext: number | undefined
359
360
  }): Effect.fn.Return<
360
361
  void,
361
362
  | PlatformError.PlatformError
@@ -468,6 +469,7 @@ const runRalph = Effect.fnUntraced(
468
469
  preset,
469
470
  prompt: instructions,
470
471
  research: researchResult,
472
+ maxContext: options.maxContext,
471
473
  ralph: true,
472
474
  }).pipe(Effect.withSpan("Main.worker"))
473
475
  yield* Effect.log(`Agent exited with code: ${exitCode}`)
@@ -522,6 +524,7 @@ const runProject = Effect.fnUntraced(
522
524
  readonly specsDirectory: string
523
525
  readonly stallTimeout: Duration.Duration
524
526
  readonly runTimeout: Duration.Duration
527
+ readonly maxContext: number | undefined
525
528
  }) {
526
529
  const isFinite = Number.isFinite(options.iterations)
527
530
  const iterationsDisplay = isFinite ? options.iterations : "unlimited"
@@ -567,6 +570,7 @@ const runProject = Effect.fnUntraced(
567
570
  targetBranch: options.project.targetBranch,
568
571
  stallTimeout: options.stallTimeout,
569
572
  runTimeout: options.runTimeout,
573
+ maxContext: options.maxContext,
570
574
  review: options.project.reviewAgent,
571
575
  research: options.project.researchAgent,
572
576
  specFile: options.project.ralphSpec!,
@@ -659,6 +663,14 @@ const maxIterationMinutes = Flag.integer("max-minutes").pipe(
659
663
  Flag.withDefault(90),
660
664
  )
661
665
 
666
+ const maxContext = Flag.integer("max-context").pipe(
667
+ Flag.withDescription(
668
+ "If the context window reaches this number of tokens, try again (default: LALPH_MAX_CONTEXT or 250,000).",
669
+ ),
670
+ Flag.withFallbackConfig(Config.int("LALPH_MAX_TOKENS")),
671
+ Flag.withDefault(250000),
672
+ )
673
+
662
674
  const stallMinutes = Flag.integer("stall-minutes").pipe(
663
675
  Flag.withDescription(
664
676
  "Fail an iteration if the agent stops responding for this many minutes (default: LALPH_STALL_MINUTES or 5).",
@@ -686,6 +698,7 @@ const verbose = Flag.boolean("verbose").pipe(
686
698
  export const commandRoot = Command.make("lalph", {
687
699
  iterations,
688
700
  maxIterationMinutes,
701
+ maxContext,
689
702
  stallMinutes,
690
703
  }).pipe(
691
704
  Command.withSharedFlags({
@@ -700,6 +713,7 @@ export const commandRoot = Command.make("lalph", {
700
713
  function* ({
701
714
  iterations,
702
715
  maxIterationMinutes,
716
+ maxContext,
703
717
  stallMinutes,
704
718
  specsDirectory,
705
719
  }) {
@@ -726,6 +740,7 @@ export const commandRoot = Command.make("lalph", {
726
740
  specsDirectory,
727
741
  stallTimeout: Duration.minutes(stallMinutes),
728
742
  runTimeout: Duration.minutes(maxIterationMinutes),
743
+ maxContext,
729
744
  }).pipe(Effect.provideService(CurrentProjectId, project.id)),
730
745
  { concurrency: "unbounded", discard: true },
731
746
  )