@theokit/sdk 2.2.0 → 2.3.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.
package/dist/index.cjs CHANGED
@@ -2799,6 +2799,71 @@ var init_agent_factory_registry = __esm({
2799
2799
  }
2800
2800
  });
2801
2801
 
2802
+ // src/internal/runtime/lifecycle/run-to-completion.ts
2803
+ var run_to_completion_exports = {};
2804
+ __export(run_to_completion_exports, {
2805
+ classifyRound: () => classifyRound,
2806
+ runToCompletionImpl: () => runToCompletionImpl
2807
+ });
2808
+ function isEmptyRound(result) {
2809
+ return (result.result ?? "").trim() === "";
2810
+ }
2811
+ function classifyRound(result, round, maxRounds, emptyStreak) {
2812
+ if (result.stoppedAtIterationLimit !== true) return "done";
2813
+ if (isEmptyRound(result) && emptyStreak >= 1) return "no_progress";
2814
+ if (round >= maxRounds) return "step_limit";
2815
+ return "continue";
2816
+ }
2817
+ function addUsage(acc, u) {
2818
+ if (u === void 0) return acc;
2819
+ const inputTokens = (acc?.inputTokens ?? 0) + u.inputTokens;
2820
+ const outputTokens = (acc?.outputTokens ?? 0) + u.outputTokens;
2821
+ const sumOpt = (a, b) => a === void 0 && b === void 0 ? void 0 : (a ?? 0) + (b ?? 0);
2822
+ return {
2823
+ inputTokens,
2824
+ outputTokens,
2825
+ totalTokens: inputTokens + outputTokens,
2826
+ cacheReadTokens: sumOpt(acc?.cacheReadTokens, u.cacheReadTokens),
2827
+ cacheWriteTokens: sumOpt(acc?.cacheWriteTokens, u.cacheWriteTokens),
2828
+ reasoningTokens: sumOpt(acc?.reasoningTokens, u.reasoningTokens)
2829
+ };
2830
+ }
2831
+ function buildResult(terminal, rounds, lastResult, usage) {
2832
+ return { terminal, rounds, lastResult, ...usage !== void 0 ? { usage } : {} };
2833
+ }
2834
+ async function stepRound(agent, prompt, sendOptions, round, maxRounds, state4) {
2835
+ const run = await agent.send(prompt, sendOptions);
2836
+ const result = await run.wait();
2837
+ const usage = addUsage(state4.usage, result.usage);
2838
+ const decision = classifyRound(result, round, maxRounds, state4.emptyStreak);
2839
+ if (decision !== "continue") return { terminal: buildResult(decision, round, result, usage) };
2840
+ const emptyStreak = isEmptyRound(result) ? state4.emptyStreak + 1 : 0;
2841
+ return { next: { usage, emptyStreak }, lastResult: result };
2842
+ }
2843
+ async function runToCompletionImpl(agent, message, options) {
2844
+ const maxRounds = options?.maxRounds ?? DEFAULT_MAX_ROUNDS;
2845
+ const continuationPrompt = options?.continuationPrompt ?? DEFAULT_CONTINUATION_PROMPT;
2846
+ const { onTruncated, signal, sendOptions } = options ?? {};
2847
+ let state4 = { usage: void 0, emptyStreak: 0 };
2848
+ for (let round = 0; ; round += 1) {
2849
+ const prompt = round === 0 ? message : continuationPrompt;
2850
+ const outcome = await stepRound(agent, prompt, sendOptions, round, maxRounds, state4);
2851
+ if ("terminal" in outcome) return outcome.terminal;
2852
+ state4 = outcome.next;
2853
+ await onTruncated?.({ round });
2854
+ if (signal?.aborted === true) {
2855
+ return buildResult("step_limit", round, outcome.lastResult, state4.usage);
2856
+ }
2857
+ }
2858
+ }
2859
+ var DEFAULT_MAX_ROUNDS, DEFAULT_CONTINUATION_PROMPT;
2860
+ var init_run_to_completion = __esm({
2861
+ "src/internal/runtime/lifecycle/run-to-completion.ts"() {
2862
+ DEFAULT_MAX_ROUNDS = 5;
2863
+ DEFAULT_CONTINUATION_PROMPT = "Continue from where you left off and finish the task. If it is already complete, give the final answer.";
2864
+ }
2865
+ });
2866
+
2802
2867
  // src/internal/runtime/lifecycle/fork-agent.ts
2803
2868
  var fork_agent_exports = {};
2804
2869
  __export(fork_agent_exports, {
@@ -2887,10 +2952,10 @@ var RingBuffer;
2887
2952
  var init_ring_buffer = __esm({
2888
2953
  "src/internal/task/ring-buffer.ts"() {
2889
2954
  RingBuffer = class {
2890
- constructor(cap) {
2891
- this.cap = cap;
2892
- if (!Number.isInteger(cap) || cap < 1) {
2893
- throw new Error(`RingBuffer capacity must be a positive integer, got ${cap}`);
2955
+ constructor(cap2) {
2956
+ this.cap = cap2;
2957
+ if (!Number.isInteger(cap2) || cap2 < 1) {
2958
+ throw new Error(`RingBuffer capacity must be a positive integer, got ${cap2}`);
2894
2959
  }
2895
2960
  }
2896
2961
  cap;
@@ -7354,6 +7419,18 @@ var CloudAgent = class {
7354
7419
  "fork"
7355
7420
  );
7356
7421
  }
7422
+ /**
7423
+ * The continuation driver re-sends against a stateful local session; the
7424
+ * cloud runtime manages its own continuation policy server-side (M1 Phase 3).
7425
+ *
7426
+ * @public
7427
+ */
7428
+ runToCompletion() {
7429
+ throw new exports.UnsupportedRunOperationError(
7430
+ "Agent.runToCompletion() is not supported on cloud agents. Cloud runtime manages continuation server-side. Use a local agent.",
7431
+ "runToCompletion"
7432
+ );
7433
+ }
7357
7434
  /**
7358
7435
  * Personality presets require consistent server-side enforcement that
7359
7436
  * the cloud runtime (pre-release) does not yet provide. Reject explicitly
@@ -10125,7 +10202,7 @@ async function loadPluginManifestFromJson(manifestPath, folderName) {
10125
10202
  const record = parsed;
10126
10203
  const name = typeof record.name === "string" ? record.name : folderName;
10127
10204
  const version = typeof record.version === "string" ? record.version : "0.0.0";
10128
- const capabilities = Array.isArray(record.capabilities) ? record.capabilities.filter((cap) => typeof cap === "string") : [];
10205
+ const capabilities = Array.isArray(record.capabilities) ? record.capabilities.filter((cap2) => typeof cap2 === "string") : [];
10129
10206
  const source = manifestPath.slice(manifestPath.indexOf(".theokit/"));
10130
10207
  const metadata = { name, version, capabilities, source };
10131
10208
  if (typeof record.entry === "string") metadata.entry = record.entry;
@@ -11792,8 +11869,8 @@ function handleToolErrorContinuation(inputs, ctx, toolResults) {
11792
11869
  const hasError = toolResults.some((part) => part.type === "tool_result" && part.isError === true);
11793
11870
  if (hasError) {
11794
11871
  ctx._consecutiveToolErrors = (ctx._consecutiveToolErrors ?? 0) + 1;
11795
- const cap = inputs.maxConsecutiveToolErrors ?? 3;
11796
- if (ctx._consecutiveToolErrors >= cap) return "error";
11872
+ const cap2 = inputs.maxConsecutiveToolErrors ?? 3;
11873
+ if (ctx._consecutiveToolErrors >= cap2) return "error";
11797
11874
  return "continue";
11798
11875
  }
11799
11876
  ctx._consecutiveToolErrors = 0;
@@ -15287,7 +15364,7 @@ var MEMORY_GET_SCHEMA = {
15287
15364
  };
15288
15365
  var DEFAULT_MAX_TOTAL_CHARS = 16384;
15289
15366
  function createMemorySearchTool(opts) {
15290
- const cap = opts.maxTotalChars ?? DEFAULT_MAX_TOTAL_CHARS;
15367
+ const cap2 = opts.maxTotalChars ?? DEFAULT_MAX_TOTAL_CHARS;
15291
15368
  return {
15292
15369
  name: "memory_search",
15293
15370
  description: SEARCH_DESCRIPTION,
@@ -15304,7 +15381,7 @@ function createMemorySearchTool(opts) {
15304
15381
  ...sources !== void 0 ? { sources } : {}
15305
15382
  };
15306
15383
  const hits = await opts.index.search(query, searchOptions);
15307
- return JSON.stringify(capByTotalChars(hits, cap));
15384
+ return JSON.stringify(capByTotalChars(hits, cap2));
15308
15385
  }
15309
15386
  };
15310
15387
  }
@@ -15872,6 +15949,13 @@ function localAgentRunUntil(agent, goal, options) {
15872
15949
  }
15873
15950
  return wrap();
15874
15951
  }
15952
+ function localAgentRunToCompletion(agent, message, options) {
15953
+ async function run() {
15954
+ const { runToCompletionImpl: runToCompletionImpl2 } = await Promise.resolve().then(() => (init_run_to_completion(), run_to_completion_exports));
15955
+ return runToCompletionImpl2({ send: (m, o) => agent.send(m, o) }, message, options);
15956
+ }
15957
+ return run();
15958
+ }
15875
15959
  async function localAgentFork(parent, options) {
15876
15960
  const { forkAgentImpl: forkAgentImpl2 } = await Promise.resolve().then(() => (init_fork_agent(), fork_agent_exports));
15877
15961
  const { getAgentFacade: getAgentFacade2 } = await Promise.resolve().then(() => (init_agent_factory_registry(), agent_factory_registry_exports));
@@ -15935,8 +16019,8 @@ async function applyPreUserSendHook(args) {
15935
16019
  ...args.options.memoryContext !== void 0 ? { memoryContext: args.options.memoryContext } : {},
15936
16020
  ...args.sendOptions.signal !== void 0 ? { signal: args.sendOptions.signal } : {}
15937
16021
  };
15938
- const cap = args.options.maxRecallContextBytes ?? DEFAULT_MAX_RECALL_BYTES;
15939
- const recalled = await args.pluginManager.runPreUserSendHooks(ctx, cap);
16022
+ const cap2 = args.options.maxRecallContextBytes ?? DEFAULT_MAX_RECALL_BYTES;
16023
+ const recalled = await args.pluginManager.runPreUserSendHooks(ctx, cap2);
15940
16024
  if (recalled === void 0 || recalled.length === 0) return args.original;
15941
16025
  const wrapped = `<memory-context>
15942
16026
  ${recalled}
@@ -16412,6 +16496,10 @@ var LocalAgent = class {
16412
16496
  fork(options) {
16413
16497
  return localAgentFork({ agentId: this.agentId, options: this.options, personalitySlugSnapshot: this.personalityStore.active(this.agentId) }, options);
16414
16498
  }
16499
+ // biome-ignore format: G8 budget — see runUntil comment above.
16500
+ runToCompletion(message, options) {
16501
+ return localAgentRunToCompletion(this, message, options);
16502
+ }
16415
16503
  };
16416
16504
  function resolveCwd(cwd) {
16417
16505
  return (Array.isArray(cwd) ? cwd[0] : cwd) ?? process.cwd();
@@ -17927,6 +18015,77 @@ function createCounterBudgetTracker(options = {}) {
17927
18015
  };
17928
18016
  }
17929
18017
 
18018
+ // src/internal/runtime/context/replay-history.ts
18019
+ var CHARS_PER_TOKEN = 4;
18020
+ var DEFAULT_RESERVE_TOKENS = 8e3;
18021
+ function finiteOr(value, fallback) {
18022
+ return Number.isFinite(value) ? value : fallback;
18023
+ }
18024
+ function charBudget(options) {
18025
+ const window = finiteOr(options.contextWindowTokens, 0);
18026
+ const reserve = finiteOr(options.reserveTokens ?? DEFAULT_RESERVE_TOKENS, DEFAULT_RESERVE_TOKENS);
18027
+ return Math.max(0, window - reserve) * CHARS_PER_TOKEN;
18028
+ }
18029
+ function assistantText2(event) {
18030
+ return event.message.content.filter((block) => block.type === "text").map((block) => block.text).join("");
18031
+ }
18032
+ function stringifyPayload(value) {
18033
+ if (value === void 0) return "";
18034
+ return typeof value === "string" ? value : JSON.stringify(value) ?? "";
18035
+ }
18036
+ function cap(content, perItemCap) {
18037
+ return truncateWithMarker(content, Math.max(0, perItemCap)).finalContent;
18038
+ }
18039
+ function mapEvent(event, perItemCap) {
18040
+ if (event.type === "assistant") {
18041
+ const text = assistantText2(event);
18042
+ return text.length > 0 ? { message: { role: "assistant", content: cap(text, perItemCap) } } : null;
18043
+ }
18044
+ if (event.type === "tool_call") {
18045
+ if (event.status === "running") {
18046
+ const content2 = cap(`[tool_call ${event.name}] ${stringifyPayload(event.args)}`, perItemCap);
18047
+ return { message: { role: "tool_call", content: content2 }, pairId: event.call_id };
18048
+ }
18049
+ const content = cap(
18050
+ `[tool_result ${event.name}] ${stringifyPayload(event.result)}`,
18051
+ perItemCap
18052
+ );
18053
+ return { message: { role: "tool_result", content }, pairId: event.call_id };
18054
+ }
18055
+ return null;
18056
+ }
18057
+ function evictionIndices(turns) {
18058
+ const head = turns[0];
18059
+ if (head?.pairId === void 0) return [0];
18060
+ const indices = [];
18061
+ for (let i = 0; i < turns.length; i += 1) {
18062
+ if (turns[i]?.pairId === head.pairId) indices.push(i);
18063
+ }
18064
+ return indices;
18065
+ }
18066
+ function totalChars(turns) {
18067
+ return turns.reduce((n, t) => n + t.message.content.length, 0);
18068
+ }
18069
+ function trimToBudget(turns, budgetChars) {
18070
+ const kept = [...turns];
18071
+ while (kept.length > 1 && totalChars(kept) > budgetChars) {
18072
+ const evict = evictionIndices(kept);
18073
+ if (kept.length - evict.length < 1) break;
18074
+ for (const idx of evict.sort((a, b) => b - a)) kept.splice(idx, 1);
18075
+ }
18076
+ return kept;
18077
+ }
18078
+ function buildReplayHistory(base, events, options) {
18079
+ const budgetChars = charBudget(options);
18080
+ const perItemCap = Math.max(0, options.perItemCap ?? Math.floor(budgetChars / 2));
18081
+ const turns = base.map((message) => ({ message }));
18082
+ for (const event of events) {
18083
+ const turn = mapEvent(event, perItemCap);
18084
+ if (turn !== null) turns.push(turn);
18085
+ }
18086
+ return trimToBudget(turns, budgetChars).map((t) => t.message);
18087
+ }
18088
+
17930
18089
  // src/internal/runtime/memory/memory-provider-noop.ts
17931
18090
  var NOOP_ADAPTER_ID = "noop";
17932
18091
  var NOOP_CAPABILITIES = {
@@ -19311,6 +19470,7 @@ exports.Security = Security;
19311
19470
  exports.Task = Task;
19312
19471
  exports.Theokit = Theokit;
19313
19472
  exports.UsageAccumulator = UsageAccumulator;
19473
+ exports.buildReplayHistory = buildReplayHistory;
19314
19474
  exports.chargeAndCheckThresholds = chargeAndCheckThresholds;
19315
19475
  exports.computeCost = computeCost;
19316
19476
  exports.createAgentFactory = createAgentFactory;