@theokit/sdk 3.2.2 → 3.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/cron.d.cts CHANGED
@@ -1,3 +1,3 @@
1
- export { V as Cron } from './cron-4u1UdmgC.cjs';
2
- import './run-CrHz9BAP.cjs';
1
+ export { V as Cron } from './cron-BxoLC-XX.cjs';
2
+ import './run-CL5Rw6a5.cjs';
3
3
  import 'zod';
package/dist/cron.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { V as Cron } from './cron-DuhVPer6.js';
2
- import './run-CrHz9BAP.js';
1
+ export { V as Cron } from './cron-DFta_5kE.js';
2
+ import './run-CL5Rw6a5.js';
3
3
  import 'zod';
package/dist/cron.js CHANGED
@@ -5160,12 +5160,23 @@ var init_objective_coerce = __esm({
5160
5160
  // src/internal/persistence/pagination.ts
5161
5161
  function paginate(items, opts) {
5162
5162
  if (opts === void 0 || opts.offset === void 0 && opts.limit === void 0) return items;
5163
- const start = Math.max(0, opts.offset ?? 0);
5164
- const end = opts.limit === void 0 ? items.length : start + Math.max(0, opts.limit);
5163
+ const start = opts.offset === void 0 ? 0 : requireNonNegativeInt(opts.offset, "offset");
5164
+ const limit = opts.limit === void 0 ? void 0 : requireNonNegativeInt(opts.limit, "limit");
5165
+ const end = limit === void 0 ? items.length : start + limit;
5165
5166
  return items.slice(start, end);
5166
5167
  }
5168
+ function requireNonNegativeInt(value, field) {
5169
+ if (!Number.isInteger(value) || value < 0) {
5170
+ throw new ConfigurationError(
5171
+ `Invalid pagination ${field}: expected a non-negative integer, got ${value}`,
5172
+ { code: "pagination_invalid" }
5173
+ );
5174
+ }
5175
+ return value;
5176
+ }
5167
5177
  var init_pagination = __esm({
5168
5178
  "src/internal/persistence/pagination.ts"() {
5179
+ init_errors();
5169
5180
  }
5170
5181
  });
5171
5182
 
@@ -8992,7 +9003,9 @@ async function vetoFromPluginPreHook(inputs, call, callId, events) {
8992
9003
  name: call.name,
8993
9004
  args: call.input,
8994
9005
  agentId: inputs.agentId,
8995
- runId: inputs.runId
9006
+ runId: inputs.runId,
9007
+ // SE1 — thread the run's permission mode so a PermissionPlugin gates per-run.
9008
+ ...inputs.permissionMode !== void 0 ? { permissionMode: inputs.permissionMode } : {}
8996
9009
  });
8997
9010
  if (pluginVeto === void 0) return void 0;
8998
9011
  emitRunEvent(inputs.runEventSink, {
@@ -10323,6 +10336,8 @@ function parseRetryAfter(headers) {
10323
10336
  if (raw === null) return void 0;
10324
10337
  const n = Number(raw);
10325
10338
  if (Number.isFinite(n) && n >= 0) return Math.ceil(n);
10339
+ const dateMs = Date.parse(raw);
10340
+ if (Number.isFinite(dateMs)) return Math.max(0, Math.ceil((dateMs - Date.now()) / 1e3));
10326
10341
  return void 0;
10327
10342
  }
10328
10343
  function truncateRaw(body) {
@@ -10643,6 +10658,7 @@ function buildAnthropicBody(request) {
10643
10658
  var AnthropicClient, AnthropicStreamAccumulator;
10644
10659
  var init_anthropic3 = __esm({
10645
10660
  "src/internal/llm/anthropic.ts"() {
10661
+ init_errors();
10646
10662
  init_anthropic2();
10647
10663
  init_anthropic_shared();
10648
10664
  init_finish();
@@ -10696,12 +10712,23 @@ var init_anthropic3 = __esm({
10696
10712
  const events = accumulator.consume(parsed);
10697
10713
  for (const event of events) yield event;
10698
10714
  }
10715
+ if (!accumulator.finishReasonSeen) {
10716
+ throw new NetworkError("Anthropic SSE stream truncated (no stop_reason)", {
10717
+ code: "stream_truncated"
10718
+ });
10719
+ }
10699
10720
  return accumulator.finish();
10700
10721
  }
10701
10722
  };
10702
10723
  AnthropicStreamAccumulator = class {
10703
10724
  text = "";
10704
10725
  stopReason = "end_turn";
10726
+ /**
10727
+ * M2 #61 — whether a `message_delta` carrying a real `stop_reason` was seen.
10728
+ * A stream that closes before it is a truncation (server FIN / proxy hiccup),
10729
+ * not a clean `end_turn` — the caller throws `stream_truncated` on `false`.
10730
+ */
10731
+ sawStopReason = false;
10705
10732
  inputTokens;
10706
10733
  outputTokens;
10707
10734
  cacheReadTokens;
@@ -10748,6 +10775,9 @@ var init_anthropic3 = __esm({
10748
10775
  * spinning the SSE parser.
10749
10776
  */
10750
10777
  handleMessageDelta(md) {
10778
+ if (md.delta.stop_reason !== void 0 && md.delta.stop_reason !== null) {
10779
+ this.sawStopReason = true;
10780
+ }
10751
10781
  this.stopReason = mapAnthropicStopReason(md.delta.stop_reason);
10752
10782
  if (md.usage?.input_tokens !== void 0) this.inputTokens = md.usage.input_tokens;
10753
10783
  if (md.usage?.output_tokens !== void 0) this.outputTokens = md.usage.output_tokens;
@@ -10758,6 +10788,10 @@ var init_anthropic3 = __esm({
10758
10788
  this.cacheReadTokens = md.usage.cache_read_input_tokens;
10759
10789
  }
10760
10790
  }
10791
+ /** M2 #61 — whether the terminal `message_delta` (stop_reason) was seen. */
10792
+ get finishReasonSeen() {
10793
+ return this.sawStopReason;
10794
+ }
10761
10795
  finish() {
10762
10796
  const toolCalls = [];
10763
10797
  for (const [index, tool] of this.toolCalls.entries()) {
@@ -12991,7 +13025,6 @@ var init_client = __esm({
12991
13025
  // concurrent request so parallel tool dispatch after a drop awaits one handshake
12992
13026
  // instead of racing (or spuriously failing with mcp_not_init).
12993
13027
  dropped = false;
12994
- reconnectAttempts = 0;
12995
13028
  reconnectPromise;
12996
13029
  get timeoutMs() {
12997
13030
  return this.config.requestTimeoutMs ?? DEFAULT_MCP_TIMEOUT_MS;
@@ -13044,15 +13077,22 @@ var init_client = __esm({
13044
13077
  return this.reconnectPromise;
13045
13078
  }
13046
13079
  async reconnect() {
13047
- if (this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
13048
- throw new NetworkError(`MCP ${this.name} reconnect exhausted`, { code: "mcp_disconnected" });
13080
+ let lastErr;
13081
+ for (let attempt = 0; attempt < MAX_RECONNECT_ATTEMPTS; attempt += 1) {
13082
+ await reconnectDelay(attempt);
13083
+ this.spawnChild();
13084
+ try {
13085
+ await super.initialize();
13086
+ this.dropped = false;
13087
+ return;
13088
+ } catch (err) {
13089
+ lastErr = err;
13090
+ }
13049
13091
  }
13050
- await reconnectDelay(this.reconnectAttempts);
13051
- this.reconnectAttempts += 1;
13052
- this.spawnChild();
13053
- await super.initialize();
13054
- this.dropped = false;
13055
- this.reconnectAttempts = 0;
13092
+ throw new NetworkError(`MCP ${this.name} reconnect exhausted`, {
13093
+ code: "mcp_disconnected",
13094
+ ...lastErr instanceof Error ? { cause: lastErr } : {}
13095
+ });
13056
13096
  }
13057
13097
  async close() {
13058
13098
  this.rejectAllPending(new NetworkError(`MCP ${this.name} closed`, { code: "mcp_closed" }));
@@ -13376,6 +13416,10 @@ function buildLoopInputs(options, runId, userText) {
13376
13416
  ...options.onDelta !== void 0 ? { onDelta: options.onDelta } : {},
13377
13417
  ...options.sendOptions.toolChoice !== void 0 ? { toolChoice: options.sendOptions.toolChoice } : {},
13378
13418
  ...options.sendOptions.activeTools !== void 0 ? { activeTools: options.sendOptions.activeTools } : {},
13419
+ // SE1 — resolve the run's permission mode: per-send wins over creation-time.
13420
+ ...(options.sendOptions.permissionMode ?? options.agentOptions.permissionMode) !== void 0 ? {
13421
+ permissionMode: options.sendOptions.permissionMode ?? options.agentOptions.permissionMode
13422
+ } : {},
13379
13423
  ...options.priorMessages !== void 0 ? { priorMessages: options.priorMessages } : {},
13380
13424
  ...options.memoryTools !== void 0 && options.memoryTools.length > 0 ? { memoryTools: options.memoryTools } : {},
13381
13425
  ...buildCustomToolsInput(