@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.
@@ -1,6 +1,6 @@
1
1
  import * as zod from 'zod';
2
2
  import { ZodType } from 'zod';
3
- import { C as CustomTool, M as ModelSelection, a7 as SDKUserMessage, a9 as SendOptions, b as Run, G as GenerateOptions, k as GenerateRunResult, V as RunToCompletionOptions, W as RunToCompletionResult, S as SDKMessage, ag as StreamToCompletionResult, a as McpServerConfig, P as Processor, r as MessageOrigin } from './run-CrHz9BAP.js';
3
+ import { C as CustomTool, c as PermissionMode, M as ModelSelection, ac as SDKUserMessage, ae as SendOptions, b as Run, G as GenerateOptions, m as GenerateRunResult, _ as RunToCompletionOptions, $ as RunToCompletionResult, S as SDKMessage, al as StreamToCompletionResult, a as McpServerConfig, P as Processor, t as MessageOrigin } from './run-CL5Rw6a5.cjs';
4
4
 
5
5
  /**
6
6
  * Fork primitive public type contracts (T1.2, ADRs D110-D114).
@@ -1100,6 +1100,13 @@ interface PreToolCallContext {
1100
1100
  args: Record<string, unknown>;
1101
1101
  agentId: string;
1102
1102
  runId: string;
1103
+ /**
1104
+ * SE1 — the run's resolved `PermissionMode` (from `SendOptions.permissionMode`
1105
+ * ?? `AgentOptions.permissionMode`), threaded so a permission-style plugin can
1106
+ * gate per-run rather than at construction time. Absent ⇒ the plugin's own
1107
+ * default applies. Ignored by non-permission plugins.
1108
+ */
1109
+ permissionMode?: PermissionMode;
1103
1110
  }
1104
1111
  interface PreToolCallDecision {
1105
1112
  block: true;
@@ -1563,6 +1570,13 @@ interface AgentOptions {
1563
1570
  * The two forms are mutually exclusive — pass one or the other.
1564
1571
  */
1565
1572
  plugins?: PluginsSettings | readonly Plugin[];
1573
+ /**
1574
+ * SE1 — the default permission mode for this agent's runs, threaded to a
1575
+ * registered `PermissionPlugin`'s pre-tool gate. A per-send
1576
+ * `SendOptions.permissionMode` overrides it. Absent ⇒ the plugin's own
1577
+ * construction-time mode applies. Local runtime.
1578
+ */
1579
+ permissionMode?: PermissionMode;
1566
1580
  /**
1567
1581
  * Skills configuration. Either a static {@link SkillsSettings} object or —
1568
1582
  * SE22 — a {@link SkillsResolver} evaluated per `send()` to pick skills from
@@ -1,6 +1,6 @@
1
1
  import * as zod from 'zod';
2
2
  import { ZodType } from 'zod';
3
- import { C as CustomTool, M as ModelSelection, a7 as SDKUserMessage, a9 as SendOptions, b as Run, G as GenerateOptions, k as GenerateRunResult, V as RunToCompletionOptions, W as RunToCompletionResult, S as SDKMessage, ag as StreamToCompletionResult, a as McpServerConfig, P as Processor, r as MessageOrigin } from './run-CrHz9BAP.cjs';
3
+ import { C as CustomTool, c as PermissionMode, M as ModelSelection, ac as SDKUserMessage, ae as SendOptions, b as Run, G as GenerateOptions, m as GenerateRunResult, _ as RunToCompletionOptions, $ as RunToCompletionResult, S as SDKMessage, al as StreamToCompletionResult, a as McpServerConfig, P as Processor, t as MessageOrigin } from './run-CL5Rw6a5.js';
4
4
 
5
5
  /**
6
6
  * Fork primitive public type contracts (T1.2, ADRs D110-D114).
@@ -1100,6 +1100,13 @@ interface PreToolCallContext {
1100
1100
  args: Record<string, unknown>;
1101
1101
  agentId: string;
1102
1102
  runId: string;
1103
+ /**
1104
+ * SE1 — the run's resolved `PermissionMode` (from `SendOptions.permissionMode`
1105
+ * ?? `AgentOptions.permissionMode`), threaded so a permission-style plugin can
1106
+ * gate per-run rather than at construction time. Absent ⇒ the plugin's own
1107
+ * default applies. Ignored by non-permission plugins.
1108
+ */
1109
+ permissionMode?: PermissionMode;
1103
1110
  }
1104
1111
  interface PreToolCallDecision {
1105
1112
  block: true;
@@ -1563,6 +1570,13 @@ interface AgentOptions {
1563
1570
  * The two forms are mutually exclusive — pass one or the other.
1564
1571
  */
1565
1572
  plugins?: PluginsSettings | readonly Plugin[];
1573
+ /**
1574
+ * SE1 — the default permission mode for this agent's runs, threaded to a
1575
+ * registered `PermissionPlugin`'s pre-tool gate. A per-send
1576
+ * `SendOptions.permissionMode` overrides it. Absent ⇒ the plugin's own
1577
+ * construction-time mode applies. Local runtime.
1578
+ */
1579
+ permissionMode?: PermissionMode;
1566
1580
  /**
1567
1581
  * Skills configuration. Either a static {@link SkillsSettings} object or —
1568
1582
  * SE22 — a {@link SkillsResolver} evaluated per `send()` to pick skills from
package/dist/cron.cjs CHANGED
@@ -5163,12 +5163,23 @@ var init_objective_coerce = __esm({
5163
5163
  // src/internal/persistence/pagination.ts
5164
5164
  function paginate(items, opts) {
5165
5165
  if (opts === void 0 || opts.offset === void 0 && opts.limit === void 0) return items;
5166
- const start = Math.max(0, opts.offset ?? 0);
5167
- const end = opts.limit === void 0 ? items.length : start + Math.max(0, opts.limit);
5166
+ const start = opts.offset === void 0 ? 0 : requireNonNegativeInt(opts.offset, "offset");
5167
+ const limit = opts.limit === void 0 ? void 0 : requireNonNegativeInt(opts.limit, "limit");
5168
+ const end = limit === void 0 ? items.length : start + limit;
5168
5169
  return items.slice(start, end);
5169
5170
  }
5171
+ function requireNonNegativeInt(value, field) {
5172
+ if (!Number.isInteger(value) || value < 0) {
5173
+ throw new ConfigurationError(
5174
+ `Invalid pagination ${field}: expected a non-negative integer, got ${value}`,
5175
+ { code: "pagination_invalid" }
5176
+ );
5177
+ }
5178
+ return value;
5179
+ }
5170
5180
  var init_pagination = __esm({
5171
5181
  "src/internal/persistence/pagination.ts"() {
5182
+ init_errors();
5172
5183
  }
5173
5184
  });
5174
5185
 
@@ -8995,7 +9006,9 @@ async function vetoFromPluginPreHook(inputs, call, callId, events) {
8995
9006
  name: call.name,
8996
9007
  args: call.input,
8997
9008
  agentId: inputs.agentId,
8998
- runId: inputs.runId
9009
+ runId: inputs.runId,
9010
+ // SE1 — thread the run's permission mode so a PermissionPlugin gates per-run.
9011
+ ...inputs.permissionMode !== void 0 ? { permissionMode: inputs.permissionMode } : {}
8999
9012
  });
9000
9013
  if (pluginVeto === void 0) return void 0;
9001
9014
  emitRunEvent(inputs.runEventSink, {
@@ -10326,6 +10339,8 @@ function parseRetryAfter(headers) {
10326
10339
  if (raw === null) return void 0;
10327
10340
  const n = Number(raw);
10328
10341
  if (Number.isFinite(n) && n >= 0) return Math.ceil(n);
10342
+ const dateMs = Date.parse(raw);
10343
+ if (Number.isFinite(dateMs)) return Math.max(0, Math.ceil((dateMs - Date.now()) / 1e3));
10329
10344
  return void 0;
10330
10345
  }
10331
10346
  function truncateRaw(body) {
@@ -10646,6 +10661,7 @@ function buildAnthropicBody(request) {
10646
10661
  var AnthropicClient, AnthropicStreamAccumulator;
10647
10662
  var init_anthropic3 = __esm({
10648
10663
  "src/internal/llm/anthropic.ts"() {
10664
+ init_errors();
10649
10665
  init_anthropic2();
10650
10666
  init_anthropic_shared();
10651
10667
  init_finish();
@@ -10699,12 +10715,23 @@ var init_anthropic3 = __esm({
10699
10715
  const events = accumulator.consume(parsed);
10700
10716
  for (const event of events) yield event;
10701
10717
  }
10718
+ if (!accumulator.finishReasonSeen) {
10719
+ throw new NetworkError("Anthropic SSE stream truncated (no stop_reason)", {
10720
+ code: "stream_truncated"
10721
+ });
10722
+ }
10702
10723
  return accumulator.finish();
10703
10724
  }
10704
10725
  };
10705
10726
  AnthropicStreamAccumulator = class {
10706
10727
  text = "";
10707
10728
  stopReason = "end_turn";
10729
+ /**
10730
+ * M2 #61 — whether a `message_delta` carrying a real `stop_reason` was seen.
10731
+ * A stream that closes before it is a truncation (server FIN / proxy hiccup),
10732
+ * not a clean `end_turn` — the caller throws `stream_truncated` on `false`.
10733
+ */
10734
+ sawStopReason = false;
10708
10735
  inputTokens;
10709
10736
  outputTokens;
10710
10737
  cacheReadTokens;
@@ -10751,6 +10778,9 @@ var init_anthropic3 = __esm({
10751
10778
  * spinning the SSE parser.
10752
10779
  */
10753
10780
  handleMessageDelta(md) {
10781
+ if (md.delta.stop_reason !== void 0 && md.delta.stop_reason !== null) {
10782
+ this.sawStopReason = true;
10783
+ }
10754
10784
  this.stopReason = mapAnthropicStopReason(md.delta.stop_reason);
10755
10785
  if (md.usage?.input_tokens !== void 0) this.inputTokens = md.usage.input_tokens;
10756
10786
  if (md.usage?.output_tokens !== void 0) this.outputTokens = md.usage.output_tokens;
@@ -10761,6 +10791,10 @@ var init_anthropic3 = __esm({
10761
10791
  this.cacheReadTokens = md.usage.cache_read_input_tokens;
10762
10792
  }
10763
10793
  }
10794
+ /** M2 #61 — whether the terminal `message_delta` (stop_reason) was seen. */
10795
+ get finishReasonSeen() {
10796
+ return this.sawStopReason;
10797
+ }
10764
10798
  finish() {
10765
10799
  const toolCalls = [];
10766
10800
  for (const [index, tool] of this.toolCalls.entries()) {
@@ -12994,7 +13028,6 @@ var init_client = __esm({
12994
13028
  // concurrent request so parallel tool dispatch after a drop awaits one handshake
12995
13029
  // instead of racing (or spuriously failing with mcp_not_init).
12996
13030
  dropped = false;
12997
- reconnectAttempts = 0;
12998
13031
  reconnectPromise;
12999
13032
  get timeoutMs() {
13000
13033
  return this.config.requestTimeoutMs ?? DEFAULT_MCP_TIMEOUT_MS;
@@ -13047,15 +13080,22 @@ var init_client = __esm({
13047
13080
  return this.reconnectPromise;
13048
13081
  }
13049
13082
  async reconnect() {
13050
- if (this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
13051
- throw new NetworkError(`MCP ${this.name} reconnect exhausted`, { code: "mcp_disconnected" });
13083
+ let lastErr;
13084
+ for (let attempt = 0; attempt < MAX_RECONNECT_ATTEMPTS; attempt += 1) {
13085
+ await reconnectDelay(attempt);
13086
+ this.spawnChild();
13087
+ try {
13088
+ await super.initialize();
13089
+ this.dropped = false;
13090
+ return;
13091
+ } catch (err) {
13092
+ lastErr = err;
13093
+ }
13052
13094
  }
13053
- await reconnectDelay(this.reconnectAttempts);
13054
- this.reconnectAttempts += 1;
13055
- this.spawnChild();
13056
- await super.initialize();
13057
- this.dropped = false;
13058
- this.reconnectAttempts = 0;
13095
+ throw new NetworkError(`MCP ${this.name} reconnect exhausted`, {
13096
+ code: "mcp_disconnected",
13097
+ ...lastErr instanceof Error ? { cause: lastErr } : {}
13098
+ });
13059
13099
  }
13060
13100
  async close() {
13061
13101
  this.rejectAllPending(new NetworkError(`MCP ${this.name} closed`, { code: "mcp_closed" }));
@@ -13379,6 +13419,10 @@ function buildLoopInputs(options, runId, userText) {
13379
13419
  ...options.onDelta !== void 0 ? { onDelta: options.onDelta } : {},
13380
13420
  ...options.sendOptions.toolChoice !== void 0 ? { toolChoice: options.sendOptions.toolChoice } : {},
13381
13421
  ...options.sendOptions.activeTools !== void 0 ? { activeTools: options.sendOptions.activeTools } : {},
13422
+ // SE1 — resolve the run's permission mode: per-send wins over creation-time.
13423
+ ...(options.sendOptions.permissionMode ?? options.agentOptions.permissionMode) !== void 0 ? {
13424
+ permissionMode: options.sendOptions.permissionMode ?? options.agentOptions.permissionMode
13425
+ } : {},
13382
13426
  ...options.priorMessages !== void 0 ? { priorMessages: options.priorMessages } : {},
13383
13427
  ...options.memoryTools !== void 0 && options.memoryTools.length > 0 ? { memoryTools: options.memoryTools } : {},
13384
13428
  ...buildCustomToolsInput(