@theokit/sdk 2.1.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.
@@ -1,4 +1,4 @@
1
- import { p as RunOperation } from './run-DrwUpFxZ.js';
1
+ import { p as RunOperation } from './run-BPRYG1Id.js';
2
2
 
3
3
  /**
4
4
  * Public type contract for the Budget enforcement primitive
@@ -1,4 +1,4 @@
1
- import { p as RunOperation } from './run-DrwUpFxZ.cjs';
1
+ import { p as RunOperation } from './run-BPRYG1Id.cjs';
2
2
 
3
3
  /**
4
4
  * Public type contract for the Budget enforcement primitive
package/dist/errors.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- export { A as AgentDisposedError, c as AgentRunError, d as AgentRunErrorCode, e as AuthenticationError, g as BudgetExceededError, C as ConfigurationError, u as CredentialPoolExhaustedError, E as ErrorCode, m as ErrorMetadata, I as IntegrationNotConnectedError, n as InvalidTaskIdError, K as KnownAgentRunErrorCode, M as MemoryAdapterError, o as MemoryAdapterErrorCode, N as NetworkError, R as RateLimitError, p as TaskNotFoundError, T as TheokitAgentError, U as UnknownAgentError, q as UnsupportedBudgetOperationError, r as UnsupportedRunOperationError, s as UnsupportedTaskOperationError, t as isTransientError } from './errors-C9xkhNEF.cjs';
2
- import './run-DrwUpFxZ.cjs';
1
+ export { A as AgentDisposedError, c as AgentRunError, d as AgentRunErrorCode, e as AuthenticationError, g as BudgetExceededError, C as ConfigurationError, u as CredentialPoolExhaustedError, E as ErrorCode, m as ErrorMetadata, I as IntegrationNotConnectedError, n as InvalidTaskIdError, K as KnownAgentRunErrorCode, M as MemoryAdapterError, o as MemoryAdapterErrorCode, N as NetworkError, R as RateLimitError, p as TaskNotFoundError, T as TheokitAgentError, U as UnknownAgentError, q as UnsupportedBudgetOperationError, r as UnsupportedRunOperationError, s as UnsupportedTaskOperationError, t as isTransientError } from './errors-QDYUPABr.cjs';
2
+ import './run-BPRYG1Id.cjs';
package/dist/eval.cjs CHANGED
@@ -1439,6 +1439,71 @@ var init_agent_factory_registry = __esm({
1439
1439
  }
1440
1440
  });
1441
1441
 
1442
+ // src/internal/runtime/lifecycle/run-to-completion.ts
1443
+ var run_to_completion_exports = {};
1444
+ __export(run_to_completion_exports, {
1445
+ classifyRound: () => classifyRound,
1446
+ runToCompletionImpl: () => runToCompletionImpl
1447
+ });
1448
+ function isEmptyRound(result) {
1449
+ return (result.result ?? "").trim() === "";
1450
+ }
1451
+ function classifyRound(result, round, maxRounds, emptyStreak) {
1452
+ if (result.stoppedAtIterationLimit !== true) return "done";
1453
+ if (isEmptyRound(result) && emptyStreak >= 1) return "no_progress";
1454
+ if (round >= maxRounds) return "step_limit";
1455
+ return "continue";
1456
+ }
1457
+ function addUsage(acc, u) {
1458
+ if (u === void 0) return acc;
1459
+ const inputTokens = (acc?.inputTokens ?? 0) + u.inputTokens;
1460
+ const outputTokens = (acc?.outputTokens ?? 0) + u.outputTokens;
1461
+ const sumOpt = (a, b) => a === void 0 && b === void 0 ? void 0 : (a ?? 0) + (b ?? 0);
1462
+ return {
1463
+ inputTokens,
1464
+ outputTokens,
1465
+ totalTokens: inputTokens + outputTokens,
1466
+ cacheReadTokens: sumOpt(acc?.cacheReadTokens, u.cacheReadTokens),
1467
+ cacheWriteTokens: sumOpt(acc?.cacheWriteTokens, u.cacheWriteTokens),
1468
+ reasoningTokens: sumOpt(acc?.reasoningTokens, u.reasoningTokens)
1469
+ };
1470
+ }
1471
+ function buildResult(terminal, rounds, lastResult, usage) {
1472
+ return { terminal, rounds, lastResult, ...usage !== void 0 ? { usage } : {} };
1473
+ }
1474
+ async function stepRound(agent, prompt, sendOptions, round, maxRounds, state2) {
1475
+ const run = await agent.send(prompt, sendOptions);
1476
+ const result = await run.wait();
1477
+ const usage = addUsage(state2.usage, result.usage);
1478
+ const decision = classifyRound(result, round, maxRounds, state2.emptyStreak);
1479
+ if (decision !== "continue") return { terminal: buildResult(decision, round, result, usage) };
1480
+ const emptyStreak = isEmptyRound(result) ? state2.emptyStreak + 1 : 0;
1481
+ return { next: { usage, emptyStreak }, lastResult: result };
1482
+ }
1483
+ async function runToCompletionImpl(agent, message, options) {
1484
+ const maxRounds = options?.maxRounds ?? DEFAULT_MAX_ROUNDS;
1485
+ const continuationPrompt = options?.continuationPrompt ?? DEFAULT_CONTINUATION_PROMPT;
1486
+ const { onTruncated, signal, sendOptions } = options ?? {};
1487
+ let state2 = { usage: void 0, emptyStreak: 0 };
1488
+ for (let round = 0; ; round += 1) {
1489
+ const prompt = round === 0 ? message : continuationPrompt;
1490
+ const outcome = await stepRound(agent, prompt, sendOptions, round, maxRounds, state2);
1491
+ if ("terminal" in outcome) return outcome.terminal;
1492
+ state2 = outcome.next;
1493
+ await onTruncated?.({ round });
1494
+ if (signal?.aborted === true) {
1495
+ return buildResult("step_limit", round, outcome.lastResult, state2.usage);
1496
+ }
1497
+ }
1498
+ }
1499
+ var DEFAULT_MAX_ROUNDS, DEFAULT_CONTINUATION_PROMPT;
1500
+ var init_run_to_completion = __esm({
1501
+ "src/internal/runtime/lifecycle/run-to-completion.ts"() {
1502
+ DEFAULT_MAX_ROUNDS = 5;
1503
+ DEFAULT_CONTINUATION_PROMPT = "Continue from where you left off and finish the task. If it is already complete, give the final answer.";
1504
+ }
1505
+ });
1506
+
1442
1507
  // src/internal/runtime/lifecycle/fork-agent.ts
1443
1508
  var fork_agent_exports = {};
1444
1509
  __export(fork_agent_exports, {
@@ -4315,8 +4380,7 @@ var FixtureRunBase = class {
4315
4380
  if (status === "error" && this.script.errorDetail !== void 0) {
4316
4381
  base.error = this.script.errorDetail;
4317
4382
  }
4318
- if (this.script.usage !== void 0) base.usage = this.script.usage;
4319
- if (this.script.cost !== void 0) base.cost = this.script.cost;
4383
+ applyScriptMetrics(base, this.script);
4320
4384
  return this.extendRunResult(applyExtraRunFields(base, this.script));
4321
4385
  }
4322
4386
  /** Subclasses override to attach runtime-specific fields (e.g. cloud git info). */
@@ -4350,6 +4414,11 @@ function makeNotifier() {
4350
4414
  });
4351
4415
  return { promise, resolve: resolve3 };
4352
4416
  }
4417
+ function applyScriptMetrics(base, script) {
4418
+ if (script.usage !== void 0) base.usage = script.usage;
4419
+ if (script.cost !== void 0) base.cost = script.cost;
4420
+ if (script.stoppedAtIterationLimit === true) base.stoppedAtIterationLimit = true;
4421
+ }
4353
4422
 
4354
4423
  // src/internal/runtime/cloud/cloud-run.ts
4355
4424
  function createCloudRun(options) {
@@ -4858,6 +4927,18 @@ var CloudAgent = class {
4858
4927
  "fork"
4859
4928
  );
4860
4929
  }
4930
+ /**
4931
+ * The continuation driver re-sends against a stateful local session; the
4932
+ * cloud runtime manages its own continuation policy server-side (M1 Phase 3).
4933
+ *
4934
+ * @public
4935
+ */
4936
+ runToCompletion() {
4937
+ throw new UnsupportedRunOperationError(
4938
+ "Agent.runToCompletion() is not supported on cloud agents. Cloud runtime manages continuation server-side. Use a local agent.",
4939
+ "runToCompletion"
4940
+ );
4941
+ }
4861
4942
  /**
4862
4943
  * Personality presets require consistent server-side enforcement that
4863
4944
  * the cloud runtime (pre-release) does not yet provide. Reject explicitly
@@ -7982,6 +8063,9 @@ var LocalRun = class extends FixtureRunBase {
7982
8063
  }
7983
8064
  };
7984
8065
 
8066
+ // src/internal/runtime/local-agent/real-local-run.ts
8067
+ init_errors();
8068
+
7985
8069
  // src/internal/runtime/budget/budget.ts
7986
8070
  var IterationBudget = class {
7987
8071
  #remaining;
@@ -9206,6 +9290,7 @@ async function runAgentLoop(inputs) {
9206
9290
  const ctx = await initLoopContext(inputs);
9207
9291
  ctxRef = ctx;
9208
9292
  const budget = inputs.budget ?? new IterationBudget({ maxIterations: inputs.maxIterations ?? 8 });
9293
+ let lastTurnDecision;
9209
9294
  while (budget.shouldContinue()) {
9210
9295
  if (inputs.budgetTracker !== void 0) {
9211
9296
  const decision2 = evaluateBudgetGate(inputs.budgetTracker);
@@ -9214,18 +9299,26 @@ async function runAgentLoop(inputs) {
9214
9299
  if (decision2.detail !== void 0) {
9215
9300
  ctx.error = { message: decision2.detail, code: decision2.reason ?? "budget" };
9216
9301
  }
9302
+ if (decision2.reason === "iteration_limit") {
9303
+ ctx.stoppedAtIterationLimit = true;
9304
+ }
9217
9305
  break;
9218
9306
  }
9219
9307
  }
9220
9308
  const usingGrace = budget.remaining <= 0 && !budget.graceCallUsed;
9221
9309
  if (usingGrace) budget.useGraceCall();
9222
9310
  const decision = await runIteration(inputs, ctx);
9311
+ lastTurnDecision = decision;
9223
9312
  if (decision === "done") break;
9224
9313
  if (decision === "error") {
9225
9314
  ctx.finalStatus = "error";
9226
9315
  break;
9227
9316
  }
9228
9317
  budget.consume();
9318
+ inputs.budgetTracker?.nextIteration?.();
9319
+ }
9320
+ if (lastTurnDecision === "continue" && budget.shouldContinue() === false) {
9321
+ ctx.stoppedAtIterationLimit = true;
9229
9322
  }
9230
9323
  if (budget.shouldContinue() === false && ctx.finalStatus === "finished" && ctx.finalText === "") {
9231
9324
  ctx.finalStatus = "error";
@@ -9256,7 +9349,8 @@ async function runAgentLoop(inputs) {
9256
9349
  conversation: ctx.conversation,
9257
9350
  ...usage !== void 0 ? { usage } : {},
9258
9351
  ...cost !== void 0 ? { cost } : {},
9259
- ...ctx.error !== void 0 ? { error: ctx.error } : {}
9352
+ ...ctx.error !== void 0 ? { error: ctx.error } : {},
9353
+ ...ctx.stoppedAtIterationLimit === true ? { stoppedAtIterationLimit: true } : {}
9260
9354
  };
9261
9355
  } finally {
9262
9356
  if (ctxRef !== void 0 && ctxRef.memoryProviderHandle !== void 0 && inputs.memoryProvider !== void 0) {
@@ -11675,6 +11769,13 @@ function resolveRunProvider(options) {
11675
11769
  return { primary, effectiveModelId };
11676
11770
  }
11677
11771
  function buildLoopInputs(options, runId, userText) {
11772
+ const maxIterations = options.sendOptions.maxIterations;
11773
+ if (maxIterations !== void 0 && (!Number.isInteger(maxIterations) || maxIterations < 1)) {
11774
+ throw new ConfigurationError(
11775
+ `SendOptions.maxIterations must be a positive integer, got ${maxIterations}`,
11776
+ { code: "invalid_max_iterations" }
11777
+ );
11778
+ }
11678
11779
  const { primary, effectiveModelId } = resolveRunProvider(options);
11679
11780
  const fallback = options.agentOptions.providers?.fallback;
11680
11781
  const apiKeys = options.agentOptions.providers?.apiKeys;
@@ -11713,6 +11814,9 @@ function buildLoopInputs(options, runId, userText) {
11713
11814
  // D318 — forward SendOptions.signal to the agent loop so streamLlmTurn
11714
11815
  // can attach it to the LLM `fetch({ signal })` call.
11715
11816
  ...options.sendOptions.signal !== void 0 ? { signal: options.sendOptions.signal } : {},
11817
+ // M1-2: per-send iteration ceiling (validated above). The loop reads
11818
+ // inputs.maxIterations (default 8 when unset).
11819
+ ...maxIterations !== void 0 ? { maxIterations } : {},
11716
11820
  // D315-D317 — tool lifecycle hooks (cost tracking + audit + retry/alert)
11717
11821
  ...options.agentOptions.onToolStart !== void 0 ? { onToolStart: options.agentOptions.onToolStart } : {},
11718
11822
  ...options.agentOptions.onToolEnd !== void 0 ? { onToolEnd: options.agentOptions.onToolEnd } : {},
@@ -11844,6 +11948,7 @@ var RealLocalRun = class extends FixtureRunBase {
11844
11948
  if (output.result.length > 0) this.script.result = output.result;
11845
11949
  if (output.usage !== void 0) this.script.usage = output.usage;
11846
11950
  if (output.cost !== void 0) this.script.cost = output.cost;
11951
+ if (output.stoppedAtIterationLimit === true) this.script.stoppedAtIterationLimit = true;
11847
11952
  if (output.error !== void 0 && this.script.errorDetail === void 0) {
11848
11953
  this.script.errorDetail = {
11849
11954
  message: output.error.message,
@@ -14314,6 +14419,13 @@ function localAgentRunUntil(agent, goal, options) {
14314
14419
  }
14315
14420
  return wrap();
14316
14421
  }
14422
+ function localAgentRunToCompletion(agent, message, options) {
14423
+ async function run() {
14424
+ const { runToCompletionImpl: runToCompletionImpl2 } = await Promise.resolve().then(() => (init_run_to_completion(), run_to_completion_exports));
14425
+ return runToCompletionImpl2({ send: (m, o) => agent.send(m, o) }, message, options);
14426
+ }
14427
+ return run();
14428
+ }
14317
14429
  async function localAgentFork(parent, options) {
14318
14430
  const { forkAgentImpl: forkAgentImpl2 } = await Promise.resolve().then(() => (init_fork_agent(), fork_agent_exports));
14319
14431
  const { getAgentFacade: getAgentFacade2 } = await Promise.resolve().then(() => (init_agent_factory_registry(), agent_factory_registry_exports));
@@ -14854,6 +14966,10 @@ var LocalAgent = class {
14854
14966
  fork(options) {
14855
14967
  return localAgentFork({ agentId: this.agentId, options: this.options, personalitySlugSnapshot: this.personalityStore.active(this.agentId) }, options);
14856
14968
  }
14969
+ // biome-ignore format: G8 budget — see runUntil comment above.
14970
+ runToCompletion(message, options) {
14971
+ return localAgentRunToCompletion(this, message, options);
14972
+ }
14857
14973
  };
14858
14974
  function resolveCwd(cwd) {
14859
14975
  return (Array.isArray(cwd) ? cwd[0] : cwd) ?? process.cwd();