@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.js CHANGED
@@ -4740,7 +4740,14 @@ var init_env_policy = __esm({
4740
4740
  /[_-]PWD/i,
4741
4741
  /CREDENTIAL/i,
4742
4742
  /PRIVATE/i,
4743
- /_AUTH/i
4743
+ /_AUTH/i,
4744
+ // #54-a — value-embedded-secret conventions (no generic `*_URL` — see keep-list test).
4745
+ /DSN/i,
4746
+ /WEBHOOK/i,
4747
+ /COOKIE/i,
4748
+ /CONNECTION[_-]?STRING/i,
4749
+ // Known DB / message-broker connection-string vars (carry `user:pass@`).
4750
+ /(?:^|[_-])(?:DATABASE|DB|REDIS|MONGO(?:DB)?|POSTGRES(?:QL)?|MYSQL|MARIADB|AMQP|RABBITMQ|CLICKHOUSE|ELASTIC(?:SEARCH)?|CASSANDRA|COUCHDB|MEMCACHED|NATS|KAFKA)[_-]?(?:URL|URI|DSN|CONNECTION)/i
4744
4751
  ];
4745
4752
  CORE_VARS = [
4746
4753
  "PATH",
@@ -5149,12 +5156,23 @@ var init_objective_coerce = __esm({
5149
5156
  // src/internal/persistence/pagination.ts
5150
5157
  function paginate(items, opts) {
5151
5158
  if (opts === void 0 || opts.offset === void 0 && opts.limit === void 0) return items;
5152
- const start = Math.max(0, opts.offset ?? 0);
5153
- const end = opts.limit === void 0 ? items.length : start + Math.max(0, opts.limit);
5159
+ const start = opts.offset === void 0 ? 0 : requireNonNegativeInt(opts.offset, "offset");
5160
+ const limit = opts.limit === void 0 ? void 0 : requireNonNegativeInt(opts.limit, "limit");
5161
+ const end = limit === void 0 ? items.length : start + limit;
5154
5162
  return items.slice(start, end);
5155
5163
  }
5164
+ function requireNonNegativeInt(value, field) {
5165
+ if (!Number.isInteger(value) || value < 0) {
5166
+ throw new ConfigurationError(
5167
+ `Invalid pagination ${field}: expected a non-negative integer, got ${value}`,
5168
+ { code: "pagination_invalid" }
5169
+ );
5170
+ }
5171
+ return value;
5172
+ }
5156
5173
  var init_pagination = __esm({
5157
5174
  "src/internal/persistence/pagination.ts"() {
5175
+ init_errors();
5158
5176
  }
5159
5177
  });
5160
5178
 
@@ -7737,15 +7755,19 @@ async function collectChildToolResults(run) {
7737
7755
  ${lines.join("\n")}
7738
7756
  </subagent-tool-results>`;
7739
7757
  }
7740
- async function runChildAgent(spec, input, signal, maxSteps, inherited) {
7741
- const { Agent: Agent2 } = await Promise.resolve().then(() => (init_agent(), agent_exports));
7758
+ function buildChildCreateOptions(spec, inherited) {
7742
7759
  const model = spec.model ? { id: spec.model } : inherited?.model;
7743
- const agent = await Agent2.create({
7760
+ return {
7744
7761
  ...inherited?.apiKey !== void 0 ? { apiKey: inherited.apiKey } : {},
7745
7762
  ...model !== void 0 ? { model } : {},
7763
+ ...inherited?.plugins !== void 0 ? { plugins: inherited.plugins } : {},
7746
7764
  systemPrompt: spec.instructions,
7747
7765
  tools: spec.tools ?? []
7748
- });
7766
+ };
7767
+ }
7768
+ async function runChildAgent(spec, input, signal, maxSteps, inherited) {
7769
+ const { Agent: Agent2 } = await Promise.resolve().then(() => (init_agent(), agent_exports));
7770
+ const agent = await Agent2.create(buildChildCreateOptions(spec, inherited));
7749
7771
  try {
7750
7772
  const sendOptions = {
7751
7773
  ...signal !== void 0 ? { signal } : {},
@@ -9648,7 +9670,10 @@ async function runAgentLoop(inputs) {
9648
9670
  }
9649
9671
  budget.consume();
9650
9672
  inputs.budgetTracker?.nextIteration?.();
9651
- if (inputs.signal?.aborted === true) break;
9673
+ if (inputs.signal?.aborted === true) {
9674
+ ctx.finalStatus = "cancelled";
9675
+ break;
9676
+ }
9652
9677
  }
9653
9678
  if (lastTurnDecision === "continue" && budget.shouldContinue() === false) {
9654
9679
  ctx.stoppedAtIterationLimit = true;
@@ -9833,15 +9858,15 @@ async function guardAndTransformToolResults(inputs, raw, ctx) {
9833
9858
  }
9834
9859
  async function continueOrTerminate(inputs, ctx, llmOutput) {
9835
9860
  if (llmOutput.errored) return "error";
9836
- if (llmOutput.text.length > 0) {
9837
- await emitAssistantTextStep(inputs, ctx, llmOutput.text);
9861
+ const tCtx = { agentId: inputs.agentId, runId: inputs.runId };
9862
+ const text = llmOutput.text.length > 0 ? await transformLlmOutputText(inputs, llmOutput.text, tCtx) : llmOutput.text;
9863
+ if (text.length > 0) {
9864
+ await emitAssistantTextStep(inputs, ctx, text);
9838
9865
  }
9839
9866
  if (llmOutput.stopReason !== "tool_use" || llmOutput.toolCalls.length === 0) {
9840
9867
  return finishOrReflect(inputs, ctx, llmOutput);
9841
9868
  }
9842
- const tCtx = { agentId: inputs.agentId, runId: inputs.runId };
9843
- const outText = await transformLlmOutputText(inputs, llmOutput.text, tCtx);
9844
- ctx.messages.push(buildAssistantTurn(outText, llmOutput.toolCalls));
9869
+ ctx.messages.push(buildAssistantTurn(text, llmOutput.toolCalls));
9845
9870
  const rawResults = await dispatchTools(
9846
9871
  // SE12 — forward a read-only text projection of the transcript-so-far to tool
9847
9872
  // handlers via `ctx.messages` (consumed by defineSubAgent's messageFilter).
@@ -10305,6 +10330,8 @@ function parseRetryAfter(headers) {
10305
10330
  if (raw === null) return void 0;
10306
10331
  const n = Number(raw);
10307
10332
  if (Number.isFinite(n) && n >= 0) return Math.ceil(n);
10333
+ const dateMs = Date.parse(raw);
10334
+ if (Number.isFinite(dateMs)) return Math.max(0, Math.ceil((dateMs - Date.now()) / 1e3));
10308
10335
  return void 0;
10309
10336
  }
10310
10337
  function truncateRaw(body) {
@@ -10625,6 +10652,7 @@ function buildAnthropicBody(request) {
10625
10652
  var AnthropicClient, AnthropicStreamAccumulator;
10626
10653
  var init_anthropic3 = __esm({
10627
10654
  "src/internal/llm/anthropic.ts"() {
10655
+ init_errors();
10628
10656
  init_anthropic2();
10629
10657
  init_anthropic_shared();
10630
10658
  init_finish();
@@ -10678,12 +10706,23 @@ var init_anthropic3 = __esm({
10678
10706
  const events = accumulator.consume(parsed);
10679
10707
  for (const event of events) yield event;
10680
10708
  }
10709
+ if (!accumulator.finishReasonSeen) {
10710
+ throw new NetworkError("Anthropic SSE stream truncated (no stop_reason)", {
10711
+ code: "stream_truncated"
10712
+ });
10713
+ }
10681
10714
  return accumulator.finish();
10682
10715
  }
10683
10716
  };
10684
10717
  AnthropicStreamAccumulator = class {
10685
10718
  text = "";
10686
10719
  stopReason = "end_turn";
10720
+ /**
10721
+ * M2 #61 — whether a `message_delta` carrying a real `stop_reason` was seen.
10722
+ * A stream that closes before it is a truncation (server FIN / proxy hiccup),
10723
+ * not a clean `end_turn` — the caller throws `stream_truncated` on `false`.
10724
+ */
10725
+ sawStopReason = false;
10687
10726
  inputTokens;
10688
10727
  outputTokens;
10689
10728
  cacheReadTokens;
@@ -10730,6 +10769,9 @@ var init_anthropic3 = __esm({
10730
10769
  * spinning the SSE parser.
10731
10770
  */
10732
10771
  handleMessageDelta(md) {
10772
+ if (md.delta.stop_reason !== void 0 && md.delta.stop_reason !== null) {
10773
+ this.sawStopReason = true;
10774
+ }
10733
10775
  this.stopReason = mapAnthropicStopReason(md.delta.stop_reason);
10734
10776
  if (md.usage?.input_tokens !== void 0) this.inputTokens = md.usage.input_tokens;
10735
10777
  if (md.usage?.output_tokens !== void 0) this.outputTokens = md.usage.output_tokens;
@@ -10740,6 +10782,10 @@ var init_anthropic3 = __esm({
10740
10782
  this.cacheReadTokens = md.usage.cache_read_input_tokens;
10741
10783
  }
10742
10784
  }
10785
+ /** M2 #61 — whether the terminal `message_delta` (stop_reason) was seen. */
10786
+ get finishReasonSeen() {
10787
+ return this.sawStopReason;
10788
+ }
10743
10789
  finish() {
10744
10790
  const toolCalls = [];
10745
10791
  for (const [index, tool] of this.toolCalls.entries()) {
@@ -12973,7 +13019,6 @@ var init_client = __esm({
12973
13019
  // concurrent request so parallel tool dispatch after a drop awaits one handshake
12974
13020
  // instead of racing (or spuriously failing with mcp_not_init).
12975
13021
  dropped = false;
12976
- reconnectAttempts = 0;
12977
13022
  reconnectPromise;
12978
13023
  get timeoutMs() {
12979
13024
  return this.config.requestTimeoutMs ?? DEFAULT_MCP_TIMEOUT_MS;
@@ -13026,15 +13071,22 @@ var init_client = __esm({
13026
13071
  return this.reconnectPromise;
13027
13072
  }
13028
13073
  async reconnect() {
13029
- if (this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
13030
- throw new NetworkError(`MCP ${this.name} reconnect exhausted`, { code: "mcp_disconnected" });
13074
+ let lastErr;
13075
+ for (let attempt = 0; attempt < MAX_RECONNECT_ATTEMPTS; attempt += 1) {
13076
+ await reconnectDelay(attempt);
13077
+ this.spawnChild();
13078
+ try {
13079
+ await super.initialize();
13080
+ this.dropped = false;
13081
+ return;
13082
+ } catch (err) {
13083
+ lastErr = err;
13084
+ }
13031
13085
  }
13032
- await reconnectDelay(this.reconnectAttempts);
13033
- this.reconnectAttempts += 1;
13034
- this.spawnChild();
13035
- await super.initialize();
13036
- this.dropped = false;
13037
- this.reconnectAttempts = 0;
13086
+ throw new NetworkError(`MCP ${this.name} reconnect exhausted`, {
13087
+ code: "mcp_disconnected",
13088
+ ...lastErr instanceof Error ? { cause: lastErr } : {}
13089
+ });
13038
13090
  }
13039
13091
  async close() {
13040
13092
  this.rejectAllPending(new NetworkError(`MCP ${this.name} closed`, { code: "mcp_closed" }));
@@ -13165,7 +13217,12 @@ var init_client = __esm({
13165
13217
  code: "mcp_http_error"
13166
13218
  });
13167
13219
  }
13168
- return await response.json();
13220
+ try {
13221
+ return await response.json();
13222
+ } catch (cause) {
13223
+ if (isAbortLike(cause)) throw mcpTimeoutError(this.name, timeoutMs);
13224
+ throw cause;
13225
+ }
13169
13226
  }
13170
13227
  };
13171
13228
  }
@@ -13405,9 +13462,11 @@ function declarativeSubagentTools(agentOptions, parentTools) {
13405
13462
  return subAgentToolsFromDefinitions(agents2, parentTools);
13406
13463
  }
13407
13464
  function bindParentCredentials(tools, agentOptions) {
13465
+ const parentPlugins = Array.isArray(agentOptions.plugins) ? agentOptions.plugins : void 0;
13408
13466
  const credentials = {
13409
13467
  ...agentOptions.apiKey !== void 0 ? { apiKey: agentOptions.apiKey } : {},
13410
- ...typeof agentOptions.model === "object" ? { model: agentOptions.model } : {}
13468
+ ...typeof agentOptions.model === "object" ? { model: agentOptions.model } : {},
13469
+ ...parentPlugins !== void 0 ? { plugins: parentPlugins } : {}
13411
13470
  };
13412
13471
  for (const tool of tools) inheritSubAgentCredentials(tool, credentials);
13413
13472
  }
@@ -15932,10 +15991,11 @@ var init_local_agent_memory = __esm({
15932
15991
  }
15933
15992
  buildTelemetryRecallArgs(telemetry) {
15934
15993
  const userId = typeof this.options.memoryContext?.userId === "string" ? this.options.memoryContext.userId : void 0;
15994
+ const tenantId = typeof this.options.memoryContext?.tenantId === "string" ? this.options.memoryContext.tenantId : void 0;
15935
15995
  return {
15936
15996
  ...telemetry !== void 0 ? { telemetry } : {},
15937
15997
  ...userId !== void 0 ? { userId } : {},
15938
- namespace: "default",
15998
+ namespace: tenantId ?? "default",
15939
15999
  scope: "session"
15940
16000
  };
15941
16001
  }
@@ -19821,14 +19881,6 @@ async function llmJudgeScore(options) {
19821
19881
  init_env_policy();
19822
19882
 
19823
19883
  // src/sandbox/types.ts
19824
- var SandboxSecurityError = class extends Error {
19825
- code = "sandbox_security";
19826
- constructor(message) {
19827
- super(message);
19828
- this.name = "SandboxSecurityError";
19829
- }
19830
- };
19831
- var SHELL_METACHARACTERS = /[;&|`$(){}]/;
19832
19884
  var SandboxBackend = class {
19833
19885
  config;
19834
19886
  constructor(config = {}) {
@@ -19871,13 +19923,6 @@ var SandboxBackend = class {
19871
19923
  if (result.exitCode !== 0) return [];
19872
19924
  return result.stdout.trim().split("\n").filter(Boolean);
19873
19925
  }
19874
- validateCommand(command) {
19875
- if (SHELL_METACHARACTERS.test(command)) {
19876
- throw new SandboxSecurityError(
19877
- `Command contains shell metacharacters: ${command.slice(0, 80)}`
19878
- );
19879
- }
19880
- }
19881
19926
  truncateOutput(output) {
19882
19927
  const max = this.config.maxOutputBytes ?? 5 * 1024 * 1024;
19883
19928
  if (Buffer.byteLength(output) > max) {