@theokit/sdk 2.1.0 → 2.2.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/eval.js CHANGED
@@ -4312,8 +4312,7 @@ var FixtureRunBase = class {
4312
4312
  if (status === "error" && this.script.errorDetail !== void 0) {
4313
4313
  base.error = this.script.errorDetail;
4314
4314
  }
4315
- if (this.script.usage !== void 0) base.usage = this.script.usage;
4316
- if (this.script.cost !== void 0) base.cost = this.script.cost;
4315
+ applyScriptMetrics(base, this.script);
4317
4316
  return this.extendRunResult(applyExtraRunFields(base, this.script));
4318
4317
  }
4319
4318
  /** Subclasses override to attach runtime-specific fields (e.g. cloud git info). */
@@ -4347,6 +4346,11 @@ function makeNotifier() {
4347
4346
  });
4348
4347
  return { promise, resolve: resolve3 };
4349
4348
  }
4349
+ function applyScriptMetrics(base, script) {
4350
+ if (script.usage !== void 0) base.usage = script.usage;
4351
+ if (script.cost !== void 0) base.cost = script.cost;
4352
+ if (script.stoppedAtIterationLimit === true) base.stoppedAtIterationLimit = true;
4353
+ }
4350
4354
 
4351
4355
  // src/internal/runtime/cloud/cloud-run.ts
4352
4356
  function createCloudRun(options) {
@@ -7979,6 +7983,9 @@ var LocalRun = class extends FixtureRunBase {
7979
7983
  }
7980
7984
  };
7981
7985
 
7986
+ // src/internal/runtime/local-agent/real-local-run.ts
7987
+ init_errors();
7988
+
7982
7989
  // src/internal/runtime/budget/budget.ts
7983
7990
  var IterationBudget = class {
7984
7991
  #remaining;
@@ -9203,6 +9210,7 @@ async function runAgentLoop(inputs) {
9203
9210
  const ctx = await initLoopContext(inputs);
9204
9211
  ctxRef = ctx;
9205
9212
  const budget = inputs.budget ?? new IterationBudget({ maxIterations: inputs.maxIterations ?? 8 });
9213
+ let lastTurnDecision;
9206
9214
  while (budget.shouldContinue()) {
9207
9215
  if (inputs.budgetTracker !== void 0) {
9208
9216
  const decision2 = evaluateBudgetGate(inputs.budgetTracker);
@@ -9211,18 +9219,26 @@ async function runAgentLoop(inputs) {
9211
9219
  if (decision2.detail !== void 0) {
9212
9220
  ctx.error = { message: decision2.detail, code: decision2.reason ?? "budget" };
9213
9221
  }
9222
+ if (decision2.reason === "iteration_limit") {
9223
+ ctx.stoppedAtIterationLimit = true;
9224
+ }
9214
9225
  break;
9215
9226
  }
9216
9227
  }
9217
9228
  const usingGrace = budget.remaining <= 0 && !budget.graceCallUsed;
9218
9229
  if (usingGrace) budget.useGraceCall();
9219
9230
  const decision = await runIteration(inputs, ctx);
9231
+ lastTurnDecision = decision;
9220
9232
  if (decision === "done") break;
9221
9233
  if (decision === "error") {
9222
9234
  ctx.finalStatus = "error";
9223
9235
  break;
9224
9236
  }
9225
9237
  budget.consume();
9238
+ inputs.budgetTracker?.nextIteration?.();
9239
+ }
9240
+ if (lastTurnDecision === "continue" && budget.shouldContinue() === false) {
9241
+ ctx.stoppedAtIterationLimit = true;
9226
9242
  }
9227
9243
  if (budget.shouldContinue() === false && ctx.finalStatus === "finished" && ctx.finalText === "") {
9228
9244
  ctx.finalStatus = "error";
@@ -9253,7 +9269,8 @@ async function runAgentLoop(inputs) {
9253
9269
  conversation: ctx.conversation,
9254
9270
  ...usage !== void 0 ? { usage } : {},
9255
9271
  ...cost !== void 0 ? { cost } : {},
9256
- ...ctx.error !== void 0 ? { error: ctx.error } : {}
9272
+ ...ctx.error !== void 0 ? { error: ctx.error } : {},
9273
+ ...ctx.stoppedAtIterationLimit === true ? { stoppedAtIterationLimit: true } : {}
9257
9274
  };
9258
9275
  } finally {
9259
9276
  if (ctxRef !== void 0 && ctxRef.memoryProviderHandle !== void 0 && inputs.memoryProvider !== void 0) {
@@ -11672,6 +11689,13 @@ function resolveRunProvider(options) {
11672
11689
  return { primary, effectiveModelId };
11673
11690
  }
11674
11691
  function buildLoopInputs(options, runId, userText) {
11692
+ const maxIterations = options.sendOptions.maxIterations;
11693
+ if (maxIterations !== void 0 && (!Number.isInteger(maxIterations) || maxIterations < 1)) {
11694
+ throw new ConfigurationError(
11695
+ `SendOptions.maxIterations must be a positive integer, got ${maxIterations}`,
11696
+ { code: "invalid_max_iterations" }
11697
+ );
11698
+ }
11675
11699
  const { primary, effectiveModelId } = resolveRunProvider(options);
11676
11700
  const fallback = options.agentOptions.providers?.fallback;
11677
11701
  const apiKeys = options.agentOptions.providers?.apiKeys;
@@ -11710,6 +11734,9 @@ function buildLoopInputs(options, runId, userText) {
11710
11734
  // D318 — forward SendOptions.signal to the agent loop so streamLlmTurn
11711
11735
  // can attach it to the LLM `fetch({ signal })` call.
11712
11736
  ...options.sendOptions.signal !== void 0 ? { signal: options.sendOptions.signal } : {},
11737
+ // M1-2: per-send iteration ceiling (validated above). The loop reads
11738
+ // inputs.maxIterations (default 8 when unset).
11739
+ ...maxIterations !== void 0 ? { maxIterations } : {},
11713
11740
  // D315-D317 — tool lifecycle hooks (cost tracking + audit + retry/alert)
11714
11741
  ...options.agentOptions.onToolStart !== void 0 ? { onToolStart: options.agentOptions.onToolStart } : {},
11715
11742
  ...options.agentOptions.onToolEnd !== void 0 ? { onToolEnd: options.agentOptions.onToolEnd } : {},
@@ -11841,6 +11868,7 @@ var RealLocalRun = class extends FixtureRunBase {
11841
11868
  if (output.result.length > 0) this.script.result = output.result;
11842
11869
  if (output.usage !== void 0) this.script.usage = output.usage;
11843
11870
  if (output.cost !== void 0) this.script.cost = output.cost;
11871
+ if (output.stoppedAtIterationLimit === true) this.script.stoppedAtIterationLimit = true;
11844
11872
  if (output.error !== void 0 && this.script.errorDetail === void 0) {
11845
11873
  this.script.errorDetail = {
11846
11874
  message: output.error.message,