@theokit/sdk 3.2.0 → 3.2.3

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.cjs CHANGED
@@ -4743,7 +4743,14 @@ var init_env_policy = __esm({
4743
4743
  /[_-]PWD/i,
4744
4744
  /CREDENTIAL/i,
4745
4745
  /PRIVATE/i,
4746
- /_AUTH/i
4746
+ /_AUTH/i,
4747
+ // #54-a — value-embedded-secret conventions (no generic `*_URL` — see keep-list test).
4748
+ /DSN/i,
4749
+ /WEBHOOK/i,
4750
+ /COOKIE/i,
4751
+ /CONNECTION[_-]?STRING/i,
4752
+ // Known DB / message-broker connection-string vars (carry `user:pass@`).
4753
+ /(?:^|[_-])(?:DATABASE|DB|REDIS|MONGO(?:DB)?|POSTGRES(?:QL)?|MYSQL|MARIADB|AMQP|RABBITMQ|CLICKHOUSE|ELASTIC(?:SEARCH)?|CASSANDRA|COUCHDB|MEMCACHED|NATS|KAFKA)[_-]?(?:URL|URI|DSN|CONNECTION)/i
4747
4754
  ];
4748
4755
  CORE_VARS = [
4749
4756
  "PATH",
@@ -5152,12 +5159,23 @@ var init_objective_coerce = __esm({
5152
5159
  // src/internal/persistence/pagination.ts
5153
5160
  function paginate(items, opts) {
5154
5161
  if (opts === void 0 || opts.offset === void 0 && opts.limit === void 0) return items;
5155
- const start = Math.max(0, opts.offset ?? 0);
5156
- const end = opts.limit === void 0 ? items.length : start + Math.max(0, opts.limit);
5162
+ const start = opts.offset === void 0 ? 0 : requireNonNegativeInt(opts.offset, "offset");
5163
+ const limit = opts.limit === void 0 ? void 0 : requireNonNegativeInt(opts.limit, "limit");
5164
+ const end = limit === void 0 ? items.length : start + limit;
5157
5165
  return items.slice(start, end);
5158
5166
  }
5167
+ function requireNonNegativeInt(value, field) {
5168
+ if (!Number.isInteger(value) || value < 0) {
5169
+ throw new ConfigurationError(
5170
+ `Invalid pagination ${field}: expected a non-negative integer, got ${value}`,
5171
+ { code: "pagination_invalid" }
5172
+ );
5173
+ }
5174
+ return value;
5175
+ }
5159
5176
  var init_pagination = __esm({
5160
5177
  "src/internal/persistence/pagination.ts"() {
5178
+ init_errors();
5161
5179
  }
5162
5180
  });
5163
5181
 
@@ -7740,15 +7758,19 @@ async function collectChildToolResults(run) {
7740
7758
  ${lines.join("\n")}
7741
7759
  </subagent-tool-results>`;
7742
7760
  }
7743
- async function runChildAgent(spec, input, signal, maxSteps, inherited) {
7744
- const { Agent: Agent2 } = await Promise.resolve().then(() => (init_agent(), agent_exports));
7761
+ function buildChildCreateOptions(spec, inherited) {
7745
7762
  const model = spec.model ? { id: spec.model } : inherited?.model;
7746
- const agent = await Agent2.create({
7763
+ return {
7747
7764
  ...inherited?.apiKey !== void 0 ? { apiKey: inherited.apiKey } : {},
7748
7765
  ...model !== void 0 ? { model } : {},
7766
+ ...inherited?.plugins !== void 0 ? { plugins: inherited.plugins } : {},
7749
7767
  systemPrompt: spec.instructions,
7750
7768
  tools: spec.tools ?? []
7751
- });
7769
+ };
7770
+ }
7771
+ async function runChildAgent(spec, input, signal, maxSteps, inherited) {
7772
+ const { Agent: Agent2 } = await Promise.resolve().then(() => (init_agent(), agent_exports));
7773
+ const agent = await Agent2.create(buildChildCreateOptions(spec, inherited));
7752
7774
  try {
7753
7775
  const sendOptions = {
7754
7776
  ...signal !== void 0 ? { signal } : {},
@@ -9651,7 +9673,10 @@ async function runAgentLoop(inputs) {
9651
9673
  }
9652
9674
  budget.consume();
9653
9675
  inputs.budgetTracker?.nextIteration?.();
9654
- if (inputs.signal?.aborted === true) break;
9676
+ if (inputs.signal?.aborted === true) {
9677
+ ctx.finalStatus = "cancelled";
9678
+ break;
9679
+ }
9655
9680
  }
9656
9681
  if (lastTurnDecision === "continue" && budget.shouldContinue() === false) {
9657
9682
  ctx.stoppedAtIterationLimit = true;
@@ -9836,15 +9861,15 @@ async function guardAndTransformToolResults(inputs, raw, ctx) {
9836
9861
  }
9837
9862
  async function continueOrTerminate(inputs, ctx, llmOutput) {
9838
9863
  if (llmOutput.errored) return "error";
9839
- if (llmOutput.text.length > 0) {
9840
- await emitAssistantTextStep(inputs, ctx, llmOutput.text);
9864
+ const tCtx = { agentId: inputs.agentId, runId: inputs.runId };
9865
+ const text = llmOutput.text.length > 0 ? await transformLlmOutputText(inputs, llmOutput.text, tCtx) : llmOutput.text;
9866
+ if (text.length > 0) {
9867
+ await emitAssistantTextStep(inputs, ctx, text);
9841
9868
  }
9842
9869
  if (llmOutput.stopReason !== "tool_use" || llmOutput.toolCalls.length === 0) {
9843
9870
  return finishOrReflect(inputs, ctx, llmOutput);
9844
9871
  }
9845
- const tCtx = { agentId: inputs.agentId, runId: inputs.runId };
9846
- const outText = await transformLlmOutputText(inputs, llmOutput.text, tCtx);
9847
- ctx.messages.push(buildAssistantTurn(outText, llmOutput.toolCalls));
9872
+ ctx.messages.push(buildAssistantTurn(text, llmOutput.toolCalls));
9848
9873
  const rawResults = await dispatchTools(
9849
9874
  // SE12 — forward a read-only text projection of the transcript-so-far to tool
9850
9875
  // handlers via `ctx.messages` (consumed by defineSubAgent's messageFilter).
@@ -10308,6 +10333,8 @@ function parseRetryAfter(headers) {
10308
10333
  if (raw === null) return void 0;
10309
10334
  const n = Number(raw);
10310
10335
  if (Number.isFinite(n) && n >= 0) return Math.ceil(n);
10336
+ const dateMs = Date.parse(raw);
10337
+ if (Number.isFinite(dateMs)) return Math.max(0, Math.ceil((dateMs - Date.now()) / 1e3));
10311
10338
  return void 0;
10312
10339
  }
10313
10340
  function truncateRaw(body) {
@@ -10628,6 +10655,7 @@ function buildAnthropicBody(request) {
10628
10655
  var AnthropicClient, AnthropicStreamAccumulator;
10629
10656
  var init_anthropic3 = __esm({
10630
10657
  "src/internal/llm/anthropic.ts"() {
10658
+ init_errors();
10631
10659
  init_anthropic2();
10632
10660
  init_anthropic_shared();
10633
10661
  init_finish();
@@ -10681,12 +10709,23 @@ var init_anthropic3 = __esm({
10681
10709
  const events = accumulator.consume(parsed);
10682
10710
  for (const event of events) yield event;
10683
10711
  }
10712
+ if (!accumulator.finishReasonSeen) {
10713
+ throw new NetworkError("Anthropic SSE stream truncated (no stop_reason)", {
10714
+ code: "stream_truncated"
10715
+ });
10716
+ }
10684
10717
  return accumulator.finish();
10685
10718
  }
10686
10719
  };
10687
10720
  AnthropicStreamAccumulator = class {
10688
10721
  text = "";
10689
10722
  stopReason = "end_turn";
10723
+ /**
10724
+ * M2 #61 — whether a `message_delta` carrying a real `stop_reason` was seen.
10725
+ * A stream that closes before it is a truncation (server FIN / proxy hiccup),
10726
+ * not a clean `end_turn` — the caller throws `stream_truncated` on `false`.
10727
+ */
10728
+ sawStopReason = false;
10690
10729
  inputTokens;
10691
10730
  outputTokens;
10692
10731
  cacheReadTokens;
@@ -10733,6 +10772,9 @@ var init_anthropic3 = __esm({
10733
10772
  * spinning the SSE parser.
10734
10773
  */
10735
10774
  handleMessageDelta(md) {
10775
+ if (md.delta.stop_reason !== void 0 && md.delta.stop_reason !== null) {
10776
+ this.sawStopReason = true;
10777
+ }
10736
10778
  this.stopReason = mapAnthropicStopReason(md.delta.stop_reason);
10737
10779
  if (md.usage?.input_tokens !== void 0) this.inputTokens = md.usage.input_tokens;
10738
10780
  if (md.usage?.output_tokens !== void 0) this.outputTokens = md.usage.output_tokens;
@@ -10743,6 +10785,10 @@ var init_anthropic3 = __esm({
10743
10785
  this.cacheReadTokens = md.usage.cache_read_input_tokens;
10744
10786
  }
10745
10787
  }
10788
+ /** M2 #61 — whether the terminal `message_delta` (stop_reason) was seen. */
10789
+ get finishReasonSeen() {
10790
+ return this.sawStopReason;
10791
+ }
10746
10792
  finish() {
10747
10793
  const toolCalls = [];
10748
10794
  for (const [index, tool] of this.toolCalls.entries()) {
@@ -12976,7 +13022,6 @@ var init_client = __esm({
12976
13022
  // concurrent request so parallel tool dispatch after a drop awaits one handshake
12977
13023
  // instead of racing (or spuriously failing with mcp_not_init).
12978
13024
  dropped = false;
12979
- reconnectAttempts = 0;
12980
13025
  reconnectPromise;
12981
13026
  get timeoutMs() {
12982
13027
  return this.config.requestTimeoutMs ?? DEFAULT_MCP_TIMEOUT_MS;
@@ -13029,15 +13074,22 @@ var init_client = __esm({
13029
13074
  return this.reconnectPromise;
13030
13075
  }
13031
13076
  async reconnect() {
13032
- if (this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
13033
- throw new NetworkError(`MCP ${this.name} reconnect exhausted`, { code: "mcp_disconnected" });
13077
+ let lastErr;
13078
+ for (let attempt = 0; attempt < MAX_RECONNECT_ATTEMPTS; attempt += 1) {
13079
+ await reconnectDelay(attempt);
13080
+ this.spawnChild();
13081
+ try {
13082
+ await super.initialize();
13083
+ this.dropped = false;
13084
+ return;
13085
+ } catch (err) {
13086
+ lastErr = err;
13087
+ }
13034
13088
  }
13035
- await reconnectDelay(this.reconnectAttempts);
13036
- this.reconnectAttempts += 1;
13037
- this.spawnChild();
13038
- await super.initialize();
13039
- this.dropped = false;
13040
- this.reconnectAttempts = 0;
13089
+ throw new NetworkError(`MCP ${this.name} reconnect exhausted`, {
13090
+ code: "mcp_disconnected",
13091
+ ...lastErr instanceof Error ? { cause: lastErr } : {}
13092
+ });
13041
13093
  }
13042
13094
  async close() {
13043
13095
  this.rejectAllPending(new NetworkError(`MCP ${this.name} closed`, { code: "mcp_closed" }));
@@ -13168,7 +13220,12 @@ var init_client = __esm({
13168
13220
  code: "mcp_http_error"
13169
13221
  });
13170
13222
  }
13171
- return await response.json();
13223
+ try {
13224
+ return await response.json();
13225
+ } catch (cause) {
13226
+ if (isAbortLike(cause)) throw mcpTimeoutError(this.name, timeoutMs);
13227
+ throw cause;
13228
+ }
13172
13229
  }
13173
13230
  };
13174
13231
  }
@@ -13408,9 +13465,11 @@ function declarativeSubagentTools(agentOptions, parentTools) {
13408
13465
  return subAgentToolsFromDefinitions(agents2, parentTools);
13409
13466
  }
13410
13467
  function bindParentCredentials(tools, agentOptions) {
13468
+ const parentPlugins = Array.isArray(agentOptions.plugins) ? agentOptions.plugins : void 0;
13411
13469
  const credentials = {
13412
13470
  ...agentOptions.apiKey !== void 0 ? { apiKey: agentOptions.apiKey } : {},
13413
- ...typeof agentOptions.model === "object" ? { model: agentOptions.model } : {}
13471
+ ...typeof agentOptions.model === "object" ? { model: agentOptions.model } : {},
13472
+ ...parentPlugins !== void 0 ? { plugins: parentPlugins } : {}
13414
13473
  };
13415
13474
  for (const tool of tools) inheritSubAgentCredentials(tool, credentials);
13416
13475
  }
@@ -15935,10 +15994,11 @@ var init_local_agent_memory = __esm({
15935
15994
  }
15936
15995
  buildTelemetryRecallArgs(telemetry) {
15937
15996
  const userId = typeof this.options.memoryContext?.userId === "string" ? this.options.memoryContext.userId : void 0;
15997
+ const tenantId = typeof this.options.memoryContext?.tenantId === "string" ? this.options.memoryContext.tenantId : void 0;
15938
15998
  return {
15939
15999
  ...telemetry !== void 0 ? { telemetry } : {},
15940
16000
  ...userId !== void 0 ? { userId } : {},
15941
- namespace: "default",
16001
+ namespace: tenantId ?? "default",
15942
16002
  scope: "session"
15943
16003
  };
15944
16004
  }
@@ -19824,14 +19884,6 @@ async function llmJudgeScore(options) {
19824
19884
  init_env_policy();
19825
19885
 
19826
19886
  // src/sandbox/types.ts
19827
- var SandboxSecurityError = class extends Error {
19828
- code = "sandbox_security";
19829
- constructor(message) {
19830
- super(message);
19831
- this.name = "SandboxSecurityError";
19832
- }
19833
- };
19834
- var SHELL_METACHARACTERS = /[;&|`$(){}]/;
19835
19887
  var SandboxBackend = class {
19836
19888
  config;
19837
19889
  constructor(config = {}) {
@@ -19874,13 +19926,6 @@ var SandboxBackend = class {
19874
19926
  if (result.exitCode !== 0) return [];
19875
19927
  return result.stdout.trim().split("\n").filter(Boolean);
19876
19928
  }
19877
- validateCommand(command) {
19878
- if (SHELL_METACHARACTERS.test(command)) {
19879
- throw new SandboxSecurityError(
19880
- `Command contains shell metacharacters: ${command.slice(0, 80)}`
19881
- );
19882
- }
19883
- }
19884
19929
  truncateOutput(output) {
19885
19930
  const max = this.config.maxOutputBytes ?? 5 * 1024 * 1024;
19886
19931
  if (Buffer.byteLength(output) > max) {