@theokit/sdk 2.2.0 → 2.4.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 (85) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/dist/a2a/index.cjs +191 -48
  3. package/dist/a2a/index.cjs.map +1 -1
  4. package/dist/a2a/index.js +192 -49
  5. package/dist/a2a/index.js.map +1 -1
  6. package/dist/compaction.cjs +78 -0
  7. package/dist/compaction.cjs.map +1 -0
  8. package/dist/compaction.d.cts +76 -0
  9. package/dist/compaction.d.ts +76 -0
  10. package/dist/compaction.js +70 -0
  11. package/dist/compaction.js.map +1 -0
  12. package/dist/{cron-JSPSFczQ.d.cts → cron-B656C3iq.d.cts} +28 -2
  13. package/dist/{cron-Aksw2Hy4.d.ts → cron-CM2M9mhB.d.ts} +28 -2
  14. package/dist/cron.cjs +192 -57
  15. package/dist/cron.cjs.map +1 -1
  16. package/dist/cron.d.cts +2 -2
  17. package/dist/cron.d.ts +2 -2
  18. package/dist/cron.js +192 -57
  19. package/dist/cron.js.map +1 -1
  20. package/dist/{errors-Bcw_Pakm.d.ts → errors-DG_7CAUg.d.ts} +1 -1
  21. package/dist/{errors-Vhg6ZV4o.d.cts → errors-QDYUPABr.d.cts} +1 -1
  22. package/dist/errors.d.cts +2 -2
  23. package/dist/eval.cjs +192 -57
  24. package/dist/eval.cjs.map +1 -1
  25. package/dist/eval.js +192 -57
  26. package/dist/eval.js.map +1 -1
  27. package/dist/index.cjs +275 -68
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +50 -7
  30. package/dist/index.d.ts +50 -7
  31. package/dist/index.js +275 -69
  32. package/dist/index.js.map +1 -1
  33. package/dist/internal/agent-loop/loop.d.ts +5 -0
  34. package/dist/internal/llm/model-capabilities.d.ts +40 -0
  35. package/dist/internal/llm/model-identifier.d.ts +9 -1
  36. package/dist/internal/llm/model-option.d.ts +38 -0
  37. package/dist/internal/runtime/compression/compression-attempt.d.ts +24 -0
  38. package/dist/internal/runtime/compression/compression-config.d.ts +33 -0
  39. package/dist/internal/runtime/compression/compression-decision.d.ts +10 -0
  40. package/dist/internal/runtime/compression/compression-helpers.d.ts +18 -0
  41. package/dist/internal/runtime/compression/compression-model-registry.d.ts +41 -0
  42. package/dist/internal/runtime/compression/compression-summarizer.d.ts +29 -0
  43. package/dist/internal/runtime/context/project-instructions.d.ts +66 -0
  44. package/dist/internal/runtime/context/replay-history.d.ts +43 -0
  45. package/dist/internal/runtime/hooks/hooks-frontmatter.d.ts +1 -1
  46. package/dist/internal/runtime/lifecycle/run-to-completion.d.ts +22 -0
  47. package/dist/internal/runtime/skills/discover-skills.d.ts +68 -0
  48. package/dist/internal/runtime/skills/skills-block.d.ts +18 -0
  49. package/dist/internal/runtime/skills/subagent-tool-scope.d.ts +25 -0
  50. package/dist/messages.cjs +24 -0
  51. package/dist/messages.cjs.map +1 -0
  52. package/dist/messages.d.cts +33 -0
  53. package/dist/messages.d.ts +33 -0
  54. package/dist/messages.js +20 -0
  55. package/dist/messages.js.map +1 -0
  56. package/dist/models.cjs +233 -0
  57. package/dist/models.cjs.map +1 -0
  58. package/dist/models.d.cts +16 -0
  59. package/dist/models.d.ts +16 -0
  60. package/dist/models.js +228 -0
  61. package/dist/models.js.map +1 -0
  62. package/dist/project.cjs +149 -0
  63. package/dist/project.cjs.map +1 -0
  64. package/dist/project.d.cts +14 -0
  65. package/dist/project.d.ts +14 -0
  66. package/dist/project.js +146 -0
  67. package/dist/project.js.map +1 -0
  68. package/dist/{run-ekGKZlmg.d.cts → run-BPRYG1Id.d.cts} +55 -2
  69. package/dist/{run-ekGKZlmg.d.ts → run-BPRYG1Id.d.ts} +55 -2
  70. package/dist/skills.cjs +282 -0
  71. package/dist/skills.cjs.map +1 -0
  72. package/dist/skills.d.cts +19 -0
  73. package/dist/skills.d.ts +19 -0
  74. package/dist/skills.js +279 -0
  75. package/dist/skills.js.map +1 -0
  76. package/dist/subagents.cjs +24 -0
  77. package/dist/subagents.cjs.map +1 -0
  78. package/dist/subagents.d.cts +14 -0
  79. package/dist/subagents.d.ts +14 -0
  80. package/dist/subagents.js +21 -0
  81. package/dist/subagents.js.map +1 -0
  82. package/dist/types/agent.d.ts +22 -0
  83. package/dist/types/conversation-storage.d.ts +5 -1
  84. package/dist/types/run.d.ts +54 -1
  85. package/package.json +62 -2
package/dist/index.js CHANGED
@@ -2796,6 +2796,71 @@ var init_agent_factory_registry = __esm({
2796
2796
  }
2797
2797
  });
2798
2798
 
2799
+ // src/internal/runtime/lifecycle/run-to-completion.ts
2800
+ var run_to_completion_exports = {};
2801
+ __export(run_to_completion_exports, {
2802
+ classifyRound: () => classifyRound,
2803
+ runToCompletionImpl: () => runToCompletionImpl
2804
+ });
2805
+ function isEmptyRound(result) {
2806
+ return (result.result ?? "").trim() === "";
2807
+ }
2808
+ function classifyRound(result, round, maxRounds, emptyStreak) {
2809
+ if (result.stoppedAtIterationLimit !== true) return "done";
2810
+ if (isEmptyRound(result) && emptyStreak >= 1) return "no_progress";
2811
+ if (round >= maxRounds) return "step_limit";
2812
+ return "continue";
2813
+ }
2814
+ function addUsage(acc, u) {
2815
+ if (u === void 0) return acc;
2816
+ const inputTokens = (acc?.inputTokens ?? 0) + u.inputTokens;
2817
+ const outputTokens = (acc?.outputTokens ?? 0) + u.outputTokens;
2818
+ const sumOpt = (a, b) => a === void 0 && b === void 0 ? void 0 : (a ?? 0) + (b ?? 0);
2819
+ return {
2820
+ inputTokens,
2821
+ outputTokens,
2822
+ totalTokens: inputTokens + outputTokens,
2823
+ cacheReadTokens: sumOpt(acc?.cacheReadTokens, u.cacheReadTokens),
2824
+ cacheWriteTokens: sumOpt(acc?.cacheWriteTokens, u.cacheWriteTokens),
2825
+ reasoningTokens: sumOpt(acc?.reasoningTokens, u.reasoningTokens)
2826
+ };
2827
+ }
2828
+ function buildResult(terminal, rounds, lastResult, usage) {
2829
+ return { terminal, rounds, lastResult, ...usage !== void 0 ? { usage } : {} };
2830
+ }
2831
+ async function stepRound(agent, prompt, sendOptions, round, maxRounds, state4) {
2832
+ const run = await agent.send(prompt, sendOptions);
2833
+ const result = await run.wait();
2834
+ const usage = addUsage(state4.usage, result.usage);
2835
+ const decision = classifyRound(result, round, maxRounds, state4.emptyStreak);
2836
+ if (decision !== "continue") return { terminal: buildResult(decision, round, result, usage) };
2837
+ const emptyStreak = isEmptyRound(result) ? state4.emptyStreak + 1 : 0;
2838
+ return { next: { usage, emptyStreak }, lastResult: result };
2839
+ }
2840
+ async function runToCompletionImpl(agent, message, options) {
2841
+ const maxRounds = options?.maxRounds ?? DEFAULT_MAX_ROUNDS;
2842
+ const continuationPrompt = options?.continuationPrompt ?? DEFAULT_CONTINUATION_PROMPT;
2843
+ const { onTruncated, signal, sendOptions } = options ?? {};
2844
+ let state4 = { usage: void 0, emptyStreak: 0 };
2845
+ for (let round = 0; ; round += 1) {
2846
+ const prompt = round === 0 ? message : continuationPrompt;
2847
+ const outcome = await stepRound(agent, prompt, sendOptions, round, maxRounds, state4);
2848
+ if ("terminal" in outcome) return outcome.terminal;
2849
+ state4 = outcome.next;
2850
+ await onTruncated?.({ round });
2851
+ if (signal?.aborted === true) {
2852
+ return buildResult("step_limit", round, outcome.lastResult, state4.usage);
2853
+ }
2854
+ }
2855
+ }
2856
+ var DEFAULT_MAX_ROUNDS, DEFAULT_CONTINUATION_PROMPT;
2857
+ var init_run_to_completion = __esm({
2858
+ "src/internal/runtime/lifecycle/run-to-completion.ts"() {
2859
+ DEFAULT_MAX_ROUNDS = 5;
2860
+ DEFAULT_CONTINUATION_PROMPT = "Continue from where you left off and finish the task. If it is already complete, give the final answer.";
2861
+ }
2862
+ });
2863
+
2799
2864
  // src/internal/runtime/lifecycle/fork-agent.ts
2800
2865
  var fork_agent_exports = {};
2801
2866
  __export(fork_agent_exports, {
@@ -2884,10 +2949,10 @@ var RingBuffer;
2884
2949
  var init_ring_buffer = __esm({
2885
2950
  "src/internal/task/ring-buffer.ts"() {
2886
2951
  RingBuffer = class {
2887
- constructor(cap) {
2888
- this.cap = cap;
2889
- if (!Number.isInteger(cap) || cap < 1) {
2890
- throw new Error(`RingBuffer capacity must be a positive integer, got ${cap}`);
2952
+ constructor(cap2) {
2953
+ this.cap = cap2;
2954
+ if (!Number.isInteger(cap2) || cap2 < 1) {
2955
+ throw new Error(`RingBuffer capacity must be a positive integer, got ${cap2}`);
2891
2956
  }
2892
2957
  }
2893
2958
  cap;
@@ -7351,6 +7416,18 @@ var CloudAgent = class {
7351
7416
  "fork"
7352
7417
  );
7353
7418
  }
7419
+ /**
7420
+ * The continuation driver re-sends against a stateful local session; the
7421
+ * cloud runtime manages its own continuation policy server-side (M1 Phase 3).
7422
+ *
7423
+ * @public
7424
+ */
7425
+ runToCompletion() {
7426
+ throw new UnsupportedRunOperationError(
7427
+ "Agent.runToCompletion() is not supported on cloud agents. Cloud runtime manages continuation server-side. Use a local agent.",
7428
+ "runToCompletion"
7429
+ );
7430
+ }
7354
7431
  /**
7355
7432
  * Personality presets require consistent server-side enforcement that
7356
7433
  * the cloud runtime (pre-release) does not yet provide. Reject explicitly
@@ -8879,6 +8956,8 @@ function parseSubagentMarkdown(raw, filename) {
8879
8956
  if (fields.model !== void 0) {
8880
8957
  definition.model = fields.model === "inherit" ? "inherit" : { id: fields.model };
8881
8958
  }
8959
+ const tools = fields.tools?.split(/[\s,]+/).map((t) => t.trim()).filter((t) => t.length > 0);
8960
+ if (tools !== void 0 && tools.length > 0) definition.tools = tools;
8882
8961
  return { name, definition };
8883
8962
  }
8884
8963
  function splitFrontmatter2(raw, filename) {
@@ -9042,21 +9121,24 @@ ${lines.join("\n")}
9042
9121
  }
9043
9122
  };
9044
9123
 
9124
+ // src/internal/runtime/skills/skills-block.ts
9125
+ function buildSkillsBlock(skills) {
9126
+ if (skills.length === 0) return void 0;
9127
+ const lines = skills.map(
9128
+ (skill) => ` - ${escapeBlockBody(skill.name)}: ${escapeBlockBody(skill.description)}`
9129
+ );
9130
+ return `<skills>
9131
+ ${lines.join("\n")}
9132
+ </skills>`;
9133
+ }
9134
+
9045
9135
  // src/internal/runtime/system-prompt/sources/skills-provider.ts
9046
9136
  var SkillsPromptProvider = class {
9047
9137
  id = "skills";
9048
9138
  priority = 20;
9049
9139
  contribute(ctx) {
9050
9140
  if (ctx.skillsAutoInject === false) return Promise.resolve(void 0);
9051
- if (ctx.skills.length === 0) return Promise.resolve(void 0);
9052
- const lines = ctx.skills.map((skill) => {
9053
- const name = escapeBlockBody(skill.name);
9054
- const description = escapeBlockBody(skill.description);
9055
- return ` - ${name}: ${description}`;
9056
- });
9057
- return Promise.resolve(`<skills>
9058
- ${lines.join("\n")}
9059
- </skills>`);
9141
+ return Promise.resolve(buildSkillsBlock(ctx.skills));
9060
9142
  }
9061
9143
  };
9062
9144
 
@@ -10122,7 +10204,7 @@ async function loadPluginManifestFromJson(manifestPath, folderName) {
10122
10204
  const record = parsed;
10123
10205
  const name = typeof record.name === "string" ? record.name : folderName;
10124
10206
  const version = typeof record.version === "string" ? record.version : "0.0.0";
10125
- const capabilities = Array.isArray(record.capabilities) ? record.capabilities.filter((cap) => typeof cap === "string") : [];
10207
+ const capabilities = Array.isArray(record.capabilities) ? record.capabilities.filter((cap2) => typeof cap2 === "string") : [];
10126
10208
  const source = manifestPath.slice(manifestPath.indexOf(".theokit/"));
10127
10209
  const metadata = { name, version, capabilities, source };
10128
10210
  if (typeof record.entry === "string") metadata.entry = record.entry;
@@ -10165,7 +10247,7 @@ async function loadPluginManifestFromMarkdown(pluginsRoot, folderName) {
10165
10247
  return metadata;
10166
10248
  }
10167
10249
 
10168
- // src/internal/runtime/skills/skills-manager.ts
10250
+ // src/internal/runtime/skills/discover-skills.ts
10169
10251
  init_errors();
10170
10252
  init_path_guard();
10171
10253
 
@@ -10238,6 +10320,61 @@ function hasContent(value) {
10238
10320
  return value !== void 0 && value.trim().length > 0;
10239
10321
  }
10240
10322
 
10323
+ // src/internal/runtime/skills/discover-skills.ts
10324
+ async function discoverSkills(dir, options) {
10325
+ let entries;
10326
+ try {
10327
+ entries = await readWorkspaceDir(dir, "skills_read_error", "skills directory");
10328
+ } catch {
10329
+ return [];
10330
+ }
10331
+ const skills = [];
10332
+ for (const entry of entries) {
10333
+ if (!entry.isDirectory()) continue;
10334
+ let skillDir;
10335
+ try {
10336
+ skillDir = safePathJoin(dir, entry.name);
10337
+ assertNoSymlinkEscape(skillDir, dir);
10338
+ } catch {
10339
+ continue;
10340
+ }
10341
+ const skillPath = join(skillDir, "SKILL.md");
10342
+ let raw;
10343
+ try {
10344
+ raw = await readFile(skillPath, "utf8");
10345
+ } catch {
10346
+ continue;
10347
+ }
10348
+ const skill = tryParseSkill(raw, entry.name, skillPath, options);
10349
+ if (skill !== void 0) skills.push(skill);
10350
+ }
10351
+ return skills;
10352
+ }
10353
+ function tryParseSkill(raw, fallbackName, source, options) {
10354
+ try {
10355
+ const frontmatter = parseSkillFrontmatter(raw, fallbackName);
10356
+ const skill = {
10357
+ name: frontmatter.name,
10358
+ description: frontmatter.description,
10359
+ source
10360
+ };
10361
+ if (frontmatter.category !== void 0) skill.category = frontmatter.category;
10362
+ if (frontmatter.dependencies !== void 0) skill.dependencies = frontmatter.dependencies;
10363
+ return skill;
10364
+ } catch (cause) {
10365
+ if (cause instanceof ConfigurationError) {
10366
+ options?.onInvalidSkill?.({
10367
+ name: fallbackName,
10368
+ source,
10369
+ code: cause.code ?? "unknown",
10370
+ message: cause.message
10371
+ });
10372
+ return void 0;
10373
+ }
10374
+ throw cause;
10375
+ }
10376
+ }
10377
+
10241
10378
  // src/internal/runtime/skills/skills-manager.ts
10242
10379
  var SkillsManager = class {
10243
10380
  constructor(cwd, _enabled, settingSourcesIncludeProject) {
@@ -10255,56 +10392,20 @@ var SkillsManager = class {
10255
10392
  await this.refresh();
10256
10393
  }
10257
10394
  async refresh() {
10258
- this.skills = [];
10259
10395
  const skillsRoot = join(this.cwd, ".theokit", "skills");
10260
- const entries = await readWorkspaceDir(skillsRoot, "skills_read_error", "skills directory");
10261
- for (const entry of entries) {
10262
- if (!entry.isDirectory()) continue;
10263
- let skillDir;
10264
- try {
10265
- skillDir = safePathJoin(skillsRoot, entry.name);
10266
- assertNoSymlinkEscape(skillDir, skillsRoot);
10267
- } catch {
10268
- continue;
10269
- }
10270
- const skillPath = join(skillDir, "SKILL.md");
10271
- let raw;
10272
- try {
10273
- raw = await readFile(skillPath, "utf8");
10274
- } catch {
10275
- continue;
10396
+ this.skills = await discoverSkills(skillsRoot, {
10397
+ onInvalidSkill: (info) => {
10398
+ process.stderr.write(
10399
+ `[theokit-sdk] skill ${info.name} skipped (${info.code}): ${info.message}
10400
+ `
10401
+ );
10276
10402
  }
10277
- const metadata = tryParseSkill(raw, entry.name, skillPath);
10278
- if (metadata !== void 0) this.skills.push(metadata);
10279
- }
10403
+ });
10280
10404
  }
10281
10405
  list() {
10282
10406
  return Promise.resolve(this.skills);
10283
10407
  }
10284
10408
  };
10285
- function tryParseSkill(raw, fallbackName, source) {
10286
- try {
10287
- const frontmatter = parseSkillFrontmatter(raw, fallbackName);
10288
- const metadata = {
10289
- name: frontmatter.name,
10290
- description: frontmatter.description,
10291
- source
10292
- };
10293
- if (frontmatter.category !== void 0) metadata.category = frontmatter.category;
10294
- if (frontmatter.dependencies !== void 0) metadata.dependencies = frontmatter.dependencies;
10295
- return metadata;
10296
- } catch (cause) {
10297
- if (cause instanceof ConfigurationError) {
10298
- const code = cause.code ?? "unknown";
10299
- process.stderr.write(
10300
- `[theokit-sdk] skill ${fallbackName} skipped (${code}): ${cause.message}
10301
- `
10302
- );
10303
- return void 0;
10304
- }
10305
- throw cause;
10306
- }
10307
- }
10308
10409
 
10309
10410
  // src/internal/runtime/local-agent/local-agent-bootstrap.ts
10310
10411
  function registerLocalAgent(args) {
@@ -10717,6 +10818,7 @@ async function initLoopContext(inputs) {
10717
10818
  finalStatus: "finished",
10718
10819
  usage: new UsageAccumulator(),
10719
10820
  nudgeAttempts: 0,
10821
+ stopFeedbackAttempts: 0,
10720
10822
  ...memoryProviderHandle !== void 0 ? { memoryProviderHandle } : {},
10721
10823
  ...memorySystemPromptAdditions !== void 0 ? { memorySystemPromptAdditions } : {}
10722
10824
  };
@@ -10861,8 +10963,9 @@ function registerLoopError(ctx, cause) {
10861
10963
  if (ctx.error !== void 0) return;
10862
10964
  const rawMessage = cause?.message;
10863
10965
  const message = typeof rawMessage === "string" ? rawMessage : cause instanceof Error ? cause.message : String(cause);
10966
+ const metaCode = cause?.metadata?.code;
10864
10967
  const rawCode = cause?.code;
10865
- const code = typeof rawCode === "string" ? rawCode : void 0;
10968
+ const code = typeof metaCode === "string" ? metaCode : typeof rawCode === "string" ? rawCode : void 0;
10866
10969
  ctx.error = code !== void 0 ? { message, code, cause } : { message, cause };
10867
10970
  }
10868
10971
  async function runCollectorLoop(generator, inputs, ctx) {
@@ -11658,6 +11761,7 @@ function computeUsageCost(inputs, usage) {
11658
11761
 
11659
11762
  // src/internal/agent-loop/loop.ts
11660
11763
  var MAX_NUDGE_ATTEMPTS = 2;
11764
+ var MAX_STOP_FEEDBACK_ATTEMPTS = 2;
11661
11765
  async function runAgentLoop(inputs) {
11662
11766
  const sendSpan = inputs.telemetry?.startSpan("agent.send", {
11663
11767
  agentId: inputs.agentId,
@@ -11789,8 +11893,8 @@ function handleToolErrorContinuation(inputs, ctx, toolResults) {
11789
11893
  const hasError = toolResults.some((part) => part.type === "tool_result" && part.isError === true);
11790
11894
  if (hasError) {
11791
11895
  ctx._consecutiveToolErrors = (ctx._consecutiveToolErrors ?? 0) + 1;
11792
- const cap = inputs.maxConsecutiveToolErrors ?? 3;
11793
- if (ctx._consecutiveToolErrors >= cap) return "error";
11896
+ const cap2 = inputs.maxConsecutiveToolErrors ?? 3;
11897
+ if (ctx._consecutiveToolErrors >= cap2) return "error";
11794
11898
  return "continue";
11795
11899
  }
11796
11900
  ctx._consecutiveToolErrors = 0;
@@ -11815,6 +11919,28 @@ function shouldNudgeAndContinue(ctx, llmOutput) {
11815
11919
  });
11816
11920
  return true;
11817
11921
  }
11922
+ async function reflectAfterStop(inputs, ctx) {
11923
+ const result = await inputs.hooks.run({
11924
+ event: "stop",
11925
+ agentId: inputs.agentId,
11926
+ runId: inputs.runId
11927
+ });
11928
+ if (result.blocked) return false;
11929
+ if (ctx.stopFeedbackAttempts >= MAX_STOP_FEEDBACK_ATTEMPTS) return false;
11930
+ const feedback = result.decisions.find(
11931
+ (d) => d.decision === "feedback" && (d.feedback ?? "").length > 0
11932
+ )?.feedback;
11933
+ if (feedback === void 0) return false;
11934
+ ctx.stopFeedbackAttempts += 1;
11935
+ ctx.messages.push({ role: "user", content: [{ type: "text", text: feedback }] });
11936
+ return true;
11937
+ }
11938
+ async function finishOrReflect(inputs, ctx, llmOutput) {
11939
+ if (shouldNudgeAndContinue(ctx, llmOutput)) return "continue";
11940
+ if (await reflectAfterStop(inputs, ctx)) return "continue";
11941
+ ctx.finalStatus = "finished";
11942
+ return "done";
11943
+ }
11818
11944
  async function runIteration(inputs, ctx) {
11819
11945
  const llmOutput = await streamLlmTurn(inputs, ctx);
11820
11946
  accumulateUsage(ctx.usage, llmOutput);
@@ -11848,9 +11974,7 @@ async function continueOrTerminate(inputs, ctx, llmOutput) {
11848
11974
  await emitAssistantTextStep(inputs, ctx, llmOutput.text);
11849
11975
  }
11850
11976
  if (llmOutput.stopReason !== "tool_use" || llmOutput.toolCalls.length === 0) {
11851
- if (shouldNudgeAndContinue(ctx, llmOutput)) return "continue";
11852
- ctx.finalStatus = "finished";
11853
- return "done";
11977
+ return finishOrReflect(inputs, ctx, llmOutput);
11854
11978
  }
11855
11979
  ctx.messages.push(buildAssistantTurn(llmOutput.text, llmOutput.toolCalls));
11856
11980
  const toolResults = await dispatchTools(inputs, ctx.tools, llmOutput.toolCalls, ctx.events);
@@ -15284,7 +15408,7 @@ var MEMORY_GET_SCHEMA = {
15284
15408
  };
15285
15409
  var DEFAULT_MAX_TOTAL_CHARS = 16384;
15286
15410
  function createMemorySearchTool(opts) {
15287
- const cap = opts.maxTotalChars ?? DEFAULT_MAX_TOTAL_CHARS;
15411
+ const cap2 = opts.maxTotalChars ?? DEFAULT_MAX_TOTAL_CHARS;
15288
15412
  return {
15289
15413
  name: "memory_search",
15290
15414
  description: SEARCH_DESCRIPTION,
@@ -15301,7 +15425,7 @@ function createMemorySearchTool(opts) {
15301
15425
  ...sources !== void 0 ? { sources } : {}
15302
15426
  };
15303
15427
  const hits = await opts.index.search(query, searchOptions);
15304
- return JSON.stringify(capByTotalChars(hits, cap));
15428
+ return JSON.stringify(capByTotalChars(hits, cap2));
15305
15429
  }
15306
15430
  };
15307
15431
  }
@@ -15869,6 +15993,13 @@ function localAgentRunUntil(agent, goal, options) {
15869
15993
  }
15870
15994
  return wrap();
15871
15995
  }
15996
+ function localAgentRunToCompletion(agent, message, options) {
15997
+ async function run() {
15998
+ const { runToCompletionImpl: runToCompletionImpl2 } = await Promise.resolve().then(() => (init_run_to_completion(), run_to_completion_exports));
15999
+ return runToCompletionImpl2({ send: (m, o) => agent.send(m, o) }, message, options);
16000
+ }
16001
+ return run();
16002
+ }
15872
16003
  async function localAgentFork(parent, options) {
15873
16004
  const { forkAgentImpl: forkAgentImpl2 } = await Promise.resolve().then(() => (init_fork_agent(), fork_agent_exports));
15874
16005
  const { getAgentFacade: getAgentFacade2 } = await Promise.resolve().then(() => (init_agent_factory_registry(), agent_factory_registry_exports));
@@ -15932,8 +16063,8 @@ async function applyPreUserSendHook(args) {
15932
16063
  ...args.options.memoryContext !== void 0 ? { memoryContext: args.options.memoryContext } : {},
15933
16064
  ...args.sendOptions.signal !== void 0 ? { signal: args.sendOptions.signal } : {}
15934
16065
  };
15935
- const cap = args.options.maxRecallContextBytes ?? DEFAULT_MAX_RECALL_BYTES;
15936
- const recalled = await args.pluginManager.runPreUserSendHooks(ctx, cap);
16066
+ const cap2 = args.options.maxRecallContextBytes ?? DEFAULT_MAX_RECALL_BYTES;
16067
+ const recalled = await args.pluginManager.runPreUserSendHooks(ctx, cap2);
15937
16068
  if (recalled === void 0 || recalled.length === 0) return args.original;
15938
16069
  const wrapped = `<memory-context>
15939
16070
  ${recalled}
@@ -16409,6 +16540,10 @@ var LocalAgent = class {
16409
16540
  fork(options) {
16410
16541
  return localAgentFork({ agentId: this.agentId, options: this.options, personalitySlugSnapshot: this.personalityStore.active(this.agentId) }, options);
16411
16542
  }
16543
+ // biome-ignore format: G8 budget — see runUntil comment above.
16544
+ runToCompletion(message, options) {
16545
+ return localAgentRunToCompletion(this, message, options);
16546
+ }
16412
16547
  };
16413
16548
  function resolveCwd(cwd) {
16414
16549
  return (Array.isArray(cwd) ? cwd[0] : cwd) ?? process.cwd();
@@ -17924,6 +18059,77 @@ function createCounterBudgetTracker(options = {}) {
17924
18059
  };
17925
18060
  }
17926
18061
 
18062
+ // src/internal/runtime/context/replay-history.ts
18063
+ var CHARS_PER_TOKEN = 4;
18064
+ var DEFAULT_RESERVE_TOKENS = 8e3;
18065
+ function finiteOr(value, fallback) {
18066
+ return Number.isFinite(value) ? value : fallback;
18067
+ }
18068
+ function charBudget(options) {
18069
+ const window = finiteOr(options.contextWindowTokens, 0);
18070
+ const reserve = finiteOr(options.reserveTokens ?? DEFAULT_RESERVE_TOKENS, DEFAULT_RESERVE_TOKENS);
18071
+ return Math.max(0, window - reserve) * CHARS_PER_TOKEN;
18072
+ }
18073
+ function assistantText2(event) {
18074
+ return event.message.content.filter((block) => block.type === "text").map((block) => block.text).join("");
18075
+ }
18076
+ function stringifyPayload(value) {
18077
+ if (value === void 0) return "";
18078
+ return typeof value === "string" ? value : JSON.stringify(value) ?? "";
18079
+ }
18080
+ function cap(content, perItemCap) {
18081
+ return truncateWithMarker(content, Math.max(0, perItemCap)).finalContent;
18082
+ }
18083
+ function mapEvent(event, perItemCap) {
18084
+ if (event.type === "assistant") {
18085
+ const text = assistantText2(event);
18086
+ return text.length > 0 ? { message: { role: "assistant", content: cap(text, perItemCap) } } : null;
18087
+ }
18088
+ if (event.type === "tool_call") {
18089
+ if (event.status === "running") {
18090
+ const content2 = cap(`[tool_call ${event.name}] ${stringifyPayload(event.args)}`, perItemCap);
18091
+ return { message: { role: "tool_call", content: content2 }, pairId: event.call_id };
18092
+ }
18093
+ const content = cap(
18094
+ `[tool_result ${event.name}] ${stringifyPayload(event.result)}`,
18095
+ perItemCap
18096
+ );
18097
+ return { message: { role: "tool_result", content }, pairId: event.call_id };
18098
+ }
18099
+ return null;
18100
+ }
18101
+ function evictionIndices(turns) {
18102
+ const head = turns[0];
18103
+ if (head?.pairId === void 0) return [0];
18104
+ const indices = [];
18105
+ for (let i = 0; i < turns.length; i += 1) {
18106
+ if (turns[i]?.pairId === head.pairId) indices.push(i);
18107
+ }
18108
+ return indices;
18109
+ }
18110
+ function totalChars(turns) {
18111
+ return turns.reduce((n, t) => n + t.message.content.length, 0);
18112
+ }
18113
+ function trimToBudget(turns, budgetChars) {
18114
+ const kept = [...turns];
18115
+ while (kept.length > 1 && totalChars(kept) > budgetChars) {
18116
+ const evict = evictionIndices(kept);
18117
+ if (kept.length - evict.length < 1) break;
18118
+ for (const idx of evict.sort((a, b) => b - a)) kept.splice(idx, 1);
18119
+ }
18120
+ return kept;
18121
+ }
18122
+ function buildReplayHistory(base, events, options) {
18123
+ const budgetChars = charBudget(options);
18124
+ const perItemCap = Math.max(0, options.perItemCap ?? Math.floor(budgetChars / 2));
18125
+ const turns = base.map((message) => ({ message }));
18126
+ for (const event of events) {
18127
+ const turn = mapEvent(event, perItemCap);
18128
+ if (turn !== null) turns.push(turn);
18129
+ }
18130
+ return trimToBudget(turns, budgetChars).map((t) => t.message);
18131
+ }
18132
+
17927
18133
  // src/internal/runtime/memory/memory-provider-noop.ts
17928
18134
  var NOOP_ADAPTER_ID = "noop";
17929
18135
  var NOOP_CAPABILITIES = {
@@ -19294,6 +19500,6 @@ function safeStringify2(v) {
19294
19500
  }
19295
19501
  }
19296
19502
 
19297
- export { Agent, AgentBuilder, AgentDisposedError, AgentRunError, AuthenticationError, Budget, BudgetExceededError, ConfigurationError, Cron, EventBus, FileSystemConversationStorage, GenerateObjectError, InMemoryConversationStorage, IntegrationNotConnectedError, InvalidTaskIdError, JobQueue, Memory, MemoryAdapterError, NetworkError, PermissionEngine, RateLimitError, Security, StreamObjectError, Task, TaskNotFoundError, Theokit, TheokitAgentError, UnknownAgentError, UnsupportedBudgetOperationError, UnsupportedRunOperationError, UnsupportedTaskOperationError, UsageAccumulator, chargeAndCheckThresholds, computeCost, createAgentFactory, createCounterBudgetTracker, createNoopMemoryProvider, createSquad, definePlugin, defineProvider, defineTool, extractRawId, getPricingEntry, inferApiMode, isTransientError, migrateSqliteToLance2 as migrateSqliteToLance, mkMemoryId, normalizeUsage, preflightCheck, toShareGptTrajectory, withCwdMutex };
19503
+ export { Agent, AgentBuilder, AgentDisposedError, AgentRunError, AuthenticationError, Budget, BudgetExceededError, ConfigurationError, Cron, EventBus, FileSystemConversationStorage, GenerateObjectError, InMemoryConversationStorage, IntegrationNotConnectedError, InvalidTaskIdError, JobQueue, Memory, MemoryAdapterError, NetworkError, PermissionEngine, RateLimitError, Security, StreamObjectError, Task, TaskNotFoundError, Theokit, TheokitAgentError, UnknownAgentError, UnsupportedBudgetOperationError, UnsupportedRunOperationError, UnsupportedTaskOperationError, UsageAccumulator, buildReplayHistory, chargeAndCheckThresholds, computeCost, createAgentFactory, createCounterBudgetTracker, createNoopMemoryProvider, createSquad, definePlugin, defineProvider, defineTool, extractRawId, getPricingEntry, inferApiMode, isTransientError, migrateSqliteToLance2 as migrateSqliteToLance, mkMemoryId, normalizeUsage, preflightCheck, toShareGptTrajectory, withCwdMutex };
19298
19504
  //# sourceMappingURL=index.js.map
19299
19505
  //# sourceMappingURL=index.js.map