@theokit/sdk 2.14.0 → 2.15.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.
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Doom-loop guard — detects consecutive IDENTICAL tool calls (same name + same canonical input)
3
+ * and escalates `ok` → `soft` (one-time nudge) → `hard` (stop). Inspection is TOTAL — `signatureOf`
4
+ * and `inspect` never throw on any tool-call input. The constructor validates thresholds and throws
5
+ * a typed `ConfigurationError` on invalid config (fail-fast at the boundary — a 0/negative/non-integer
6
+ * threshold is a caller bug, not a loop input). Ported in shape from cline `LoopDetectionTracker`.
7
+ * Complements the empty-round `no_progress` terminal (a DIFFERENT failure mode: model stuck repeating
8
+ * vs model gone silent).
9
+ * @internal
10
+ */
11
+ /** Verdict from {@link DoomLoopTracker.inspect}. `soft` carries a guidance message, `hard` a stop message. */
12
+ export interface DoomLoopVerdict {
13
+ kind: "ok" | "soft" | "hard";
14
+ message?: string;
15
+ }
16
+ /** Consecutive-identical thresholds. `soft` fires once (at exactly the count); `hard` stops. */
17
+ export interface DoomLoopConfig {
18
+ softThreshold: number;
19
+ hardThreshold: number;
20
+ }
21
+ /** Public config on a send: `false` disables the guard; an object tunes the thresholds; absent = on. */
22
+ export type DoomLoopOption = false | Partial<DoomLoopConfig>;
@@ -32,4 +32,10 @@ export interface AgentLoopOutput {
32
32
  * `RunResult.stoppedAtIterationLimit`.
33
33
  */
34
34
  stoppedAtIterationLimit?: boolean;
35
+ /**
36
+ * Doom-loop guard: true when the loop stopped because the model repeated IDENTICAL tool calls to
37
+ * the hard threshold. Copied verbatim onto `RunResult.stoppedByDoomLoop`; the continuation driver
38
+ * classifies it as a `no_progress` terminal (a controlled stop, not a truncation to re-send).
39
+ */
40
+ stoppedByDoomLoop?: boolean;
35
41
  }
@@ -687,6 +687,28 @@ interface RunResult {
687
687
  * @public
688
688
  */
689
689
  stoppedAtIterationLimit?: boolean;
690
+ /**
691
+ * `true` when the run stopped because the **doom-loop guard** detected the model repeating
692
+ * IDENTICAL tool calls (same name + same input) to the hard threshold — making no progress (e.g.
693
+ * a tool that keeps failing and is retried unchanged). `undefined`/absent otherwise. Through the
694
+ * continuation driver this surfaces as `terminal: "no_progress"` (a controlled stop, NOT a
695
+ * truncation to re-send). Tune or disable via {@link SendOptions.doomLoop}.
696
+ *
697
+ * @public
698
+ */
699
+ stoppedByDoomLoop?: boolean;
700
+ }
701
+ /**
702
+ * Doom-loop guard thresholds (see {@link SendOptions.doomLoop}). Both are counts of CONSECUTIVE
703
+ * identical tool calls: `softThreshold` injects a one-time guidance nudge; `hardThreshold` stops.
704
+ *
705
+ * @public
706
+ */
707
+ interface DoomLoopThresholds {
708
+ /** Consecutive-identical count at which a one-time guidance nudge is injected. Default 3. */
709
+ softThreshold?: number;
710
+ /** Consecutive-identical count at which the run stops (`no_progress`). Default 5. */
711
+ hardThreshold?: number;
690
712
  }
691
713
  /**
692
714
  * Options for {@link SDKAgent.runToCompletion} (M1 Phase 3 — continuation driver).
@@ -803,6 +825,12 @@ interface SDKUserMessage {
803
825
  */
804
826
  interface SendOptions {
805
827
  model?: ModelSelection;
828
+ /**
829
+ * Doom-loop guard config. The loop stops (with `terminal: "no_progress"`, `RunResult.stoppedByDoomLoop`)
830
+ * when the model repeats IDENTICAL tool calls to the hard threshold. On by default with generous
831
+ * thresholds (soft 3 / hard 5). Set `false` to disable, or an object to tune the thresholds.
832
+ */
833
+ doomLoop?: false | DoomLoopThresholds;
806
834
  /**
807
835
  * Per-call system prompt override. Wins over `AgentOptions.systemPrompt`.
808
836
  * String only — for dynamic resolvers, configure on `AgentOptions`. An
@@ -909,4 +937,4 @@ interface Run {
909
937
  onDidChangeStatus(listener: (status: RunStatus) => void): () => void;
910
938
  }
911
939
 
912
- export type { ThinkingMessage as $, AgentConversationTurn as A, SDKTaskMessage as B, CustomTool as C, SDKThinkingMessage as D, SDKToolUseMessage as E, SDKUserMessage as F, SDKUserMessageEvent as G, SendOptions as H, InteractionUpdate as I, ShellCommand as J, ShellConversationTurn as K, ShellOutput as L, ModelSelection as M, ShellOutputDeltaUpdate as N, StepCompletedUpdate as O, PartialToolCallUpdate as P, StepStartedUpdate as Q, RunResult as R, SDKMessage as S, StreamToCompletionResult as T, SummaryCompletedUpdate as U, SummaryStartedUpdate as V, SummaryUpdate as W, TextBlock as X, TextDeltaUpdate as Y, ThinkingCompletedUpdate as Z, ThinkingDeltaUpdate as _, McpServerConfig as a, TokenDeltaUpdate as a0, TokenUsage as a1, ToolCall as a2, ToolCallCompletedUpdate as a3, ToolCallStartedUpdate as a4, ToolResult as a5, ToolUseBlock as a6, TurnEndedUpdate as a7, UserMessage as a8, UserMessageAppendedUpdate as a9, Run as b, AssistantMessage as c, ConversationStep as d, ConversationTurn as e, CostBreakdown as f, CostSource as g, CostStatus as h, McpAuthConfig as i, McpHttpServerConfig as j, McpOAuthConfig as k, McpStdioServerConfig as l, ModelParameterValue as m, RunErrorDetail as n, RunGitInfo as o, RunOperation as p, RunStatus as q, RunToCompletionOptions as r, RunToCompletionResult as s, SDKAssistantMessage as t, SDKImage as u, SDKImageDimension as v, SDKObjectDelta as w, SDKRequestMessage as x, SDKStatusMessage as y, SDKSystemMessage as z };
940
+ export type { ThinkingDeltaUpdate as $, AgentConversationTurn as A, SDKTaskMessage as B, CustomTool as C, DoomLoopThresholds as D, SDKThinkingMessage as E, SDKToolUseMessage as F, SDKUserMessage as G, SDKUserMessageEvent as H, InteractionUpdate as I, SendOptions as J, ShellCommand as K, ShellConversationTurn as L, ModelSelection as M, ShellOutput as N, ShellOutputDeltaUpdate as O, PartialToolCallUpdate as P, StepCompletedUpdate as Q, RunResult as R, SDKMessage as S, StepStartedUpdate as T, StreamToCompletionResult as U, SummaryCompletedUpdate as V, SummaryStartedUpdate as W, SummaryUpdate as X, TextBlock as Y, TextDeltaUpdate as Z, ThinkingCompletedUpdate as _, McpServerConfig as a, ThinkingMessage as a0, TokenDeltaUpdate as a1, TokenUsage as a2, ToolCall as a3, ToolCallCompletedUpdate as a4, ToolCallStartedUpdate as a5, ToolResult as a6, ToolUseBlock as a7, TurnEndedUpdate as a8, UserMessage as a9, UserMessageAppendedUpdate as aa, Run as b, AssistantMessage as c, ConversationStep as d, ConversationTurn as e, CostBreakdown as f, CostSource as g, CostStatus as h, McpAuthConfig as i, McpHttpServerConfig as j, McpOAuthConfig as k, McpStdioServerConfig as l, ModelParameterValue as m, RunErrorDetail as n, RunGitInfo as o, RunOperation as p, RunStatus as q, RunToCompletionOptions as r, RunToCompletionResult as s, SDKAssistantMessage as t, SDKImage as u, SDKImageDimension as v, SDKObjectDelta as w, SDKRequestMessage as x, SDKStatusMessage as y, SDKSystemMessage as z };
@@ -687,6 +687,28 @@ interface RunResult {
687
687
  * @public
688
688
  */
689
689
  stoppedAtIterationLimit?: boolean;
690
+ /**
691
+ * `true` when the run stopped because the **doom-loop guard** detected the model repeating
692
+ * IDENTICAL tool calls (same name + same input) to the hard threshold — making no progress (e.g.
693
+ * a tool that keeps failing and is retried unchanged). `undefined`/absent otherwise. Through the
694
+ * continuation driver this surfaces as `terminal: "no_progress"` (a controlled stop, NOT a
695
+ * truncation to re-send). Tune or disable via {@link SendOptions.doomLoop}.
696
+ *
697
+ * @public
698
+ */
699
+ stoppedByDoomLoop?: boolean;
700
+ }
701
+ /**
702
+ * Doom-loop guard thresholds (see {@link SendOptions.doomLoop}). Both are counts of CONSECUTIVE
703
+ * identical tool calls: `softThreshold` injects a one-time guidance nudge; `hardThreshold` stops.
704
+ *
705
+ * @public
706
+ */
707
+ interface DoomLoopThresholds {
708
+ /** Consecutive-identical count at which a one-time guidance nudge is injected. Default 3. */
709
+ softThreshold?: number;
710
+ /** Consecutive-identical count at which the run stops (`no_progress`). Default 5. */
711
+ hardThreshold?: number;
690
712
  }
691
713
  /**
692
714
  * Options for {@link SDKAgent.runToCompletion} (M1 Phase 3 — continuation driver).
@@ -803,6 +825,12 @@ interface SDKUserMessage {
803
825
  */
804
826
  interface SendOptions {
805
827
  model?: ModelSelection;
828
+ /**
829
+ * Doom-loop guard config. The loop stops (with `terminal: "no_progress"`, `RunResult.stoppedByDoomLoop`)
830
+ * when the model repeats IDENTICAL tool calls to the hard threshold. On by default with generous
831
+ * thresholds (soft 3 / hard 5). Set `false` to disable, or an object to tune the thresholds.
832
+ */
833
+ doomLoop?: false | DoomLoopThresholds;
806
834
  /**
807
835
  * Per-call system prompt override. Wins over `AgentOptions.systemPrompt`.
808
836
  * String only — for dynamic resolvers, configure on `AgentOptions`. An
@@ -909,4 +937,4 @@ interface Run {
909
937
  onDidChangeStatus(listener: (status: RunStatus) => void): () => void;
910
938
  }
911
939
 
912
- export type { ThinkingMessage as $, AgentConversationTurn as A, SDKTaskMessage as B, CustomTool as C, SDKThinkingMessage as D, SDKToolUseMessage as E, SDKUserMessage as F, SDKUserMessageEvent as G, SendOptions as H, InteractionUpdate as I, ShellCommand as J, ShellConversationTurn as K, ShellOutput as L, ModelSelection as M, ShellOutputDeltaUpdate as N, StepCompletedUpdate as O, PartialToolCallUpdate as P, StepStartedUpdate as Q, RunResult as R, SDKMessage as S, StreamToCompletionResult as T, SummaryCompletedUpdate as U, SummaryStartedUpdate as V, SummaryUpdate as W, TextBlock as X, TextDeltaUpdate as Y, ThinkingCompletedUpdate as Z, ThinkingDeltaUpdate as _, McpServerConfig as a, TokenDeltaUpdate as a0, TokenUsage as a1, ToolCall as a2, ToolCallCompletedUpdate as a3, ToolCallStartedUpdate as a4, ToolResult as a5, ToolUseBlock as a6, TurnEndedUpdate as a7, UserMessage as a8, UserMessageAppendedUpdate as a9, Run as b, AssistantMessage as c, ConversationStep as d, ConversationTurn as e, CostBreakdown as f, CostSource as g, CostStatus as h, McpAuthConfig as i, McpHttpServerConfig as j, McpOAuthConfig as k, McpStdioServerConfig as l, ModelParameterValue as m, RunErrorDetail as n, RunGitInfo as o, RunOperation as p, RunStatus as q, RunToCompletionOptions as r, RunToCompletionResult as s, SDKAssistantMessage as t, SDKImage as u, SDKImageDimension as v, SDKObjectDelta as w, SDKRequestMessage as x, SDKStatusMessage as y, SDKSystemMessage as z };
940
+ export type { ThinkingDeltaUpdate as $, AgentConversationTurn as A, SDKTaskMessage as B, CustomTool as C, DoomLoopThresholds as D, SDKThinkingMessage as E, SDKToolUseMessage as F, SDKUserMessage as G, SDKUserMessageEvent as H, InteractionUpdate as I, SendOptions as J, ShellCommand as K, ShellConversationTurn as L, ModelSelection as M, ShellOutput as N, ShellOutputDeltaUpdate as O, PartialToolCallUpdate as P, StepCompletedUpdate as Q, RunResult as R, SDKMessage as S, StepStartedUpdate as T, StreamToCompletionResult as U, SummaryCompletedUpdate as V, SummaryStartedUpdate as W, SummaryUpdate as X, TextBlock as Y, TextDeltaUpdate as Z, ThinkingCompletedUpdate as _, McpServerConfig as a, ThinkingMessage as a0, TokenDeltaUpdate as a1, TokenUsage as a2, ToolCall as a3, ToolCallCompletedUpdate as a4, ToolCallStartedUpdate as a5, ToolResult as a6, ToolUseBlock as a7, TurnEndedUpdate as a8, UserMessage as a9, UserMessageAppendedUpdate as aa, Run as b, AssistantMessage as c, ConversationStep as d, ConversationTurn as e, CostBreakdown as f, CostSource as g, CostStatus as h, McpAuthConfig as i, McpHttpServerConfig as j, McpOAuthConfig as k, McpStdioServerConfig as l, ModelParameterValue as m, RunErrorDetail as n, RunGitInfo as o, RunOperation as p, RunStatus as q, RunToCompletionOptions as r, RunToCompletionResult as s, SDKAssistantMessage as t, SDKImage as u, SDKImageDimension as v, SDKObjectDelta as w, SDKRequestMessage as x, SDKStatusMessage as y, SDKSystemMessage as z };
@@ -81,6 +81,28 @@ export interface RunResult {
81
81
  * @public
82
82
  */
83
83
  stoppedAtIterationLimit?: boolean;
84
+ /**
85
+ * `true` when the run stopped because the **doom-loop guard** detected the model repeating
86
+ * IDENTICAL tool calls (same name + same input) to the hard threshold — making no progress (e.g.
87
+ * a tool that keeps failing and is retried unchanged). `undefined`/absent otherwise. Through the
88
+ * continuation driver this surfaces as `terminal: "no_progress"` (a controlled stop, NOT a
89
+ * truncation to re-send). Tune or disable via {@link SendOptions.doomLoop}.
90
+ *
91
+ * @public
92
+ */
93
+ stoppedByDoomLoop?: boolean;
94
+ }
95
+ /**
96
+ * Doom-loop guard thresholds (see {@link SendOptions.doomLoop}). Both are counts of CONSECUTIVE
97
+ * identical tool calls: `softThreshold` injects a one-time guidance nudge; `hardThreshold` stops.
98
+ *
99
+ * @public
100
+ */
101
+ export interface DoomLoopThresholds {
102
+ /** Consecutive-identical count at which a one-time guidance nudge is injected. Default 3. */
103
+ softThreshold?: number;
104
+ /** Consecutive-identical count at which the run stops (`no_progress`). Default 5. */
105
+ hardThreshold?: number;
84
106
  }
85
107
  /**
86
108
  * Options for {@link SDKAgent.runToCompletion} (M1 Phase 3 — continuation driver).
@@ -197,6 +219,12 @@ export interface SDKUserMessage {
197
219
  */
198
220
  export interface SendOptions {
199
221
  model?: ModelSelection;
222
+ /**
223
+ * Doom-loop guard config. The loop stops (with `terminal: "no_progress"`, `RunResult.stoppedByDoomLoop`)
224
+ * when the model repeats IDENTICAL tool calls to the hard threshold. On by default with generous
225
+ * thresholds (soft 3 / hard 5). Set `false` to disable, or an object to tune the thresholds.
226
+ */
227
+ doomLoop?: false | DoomLoopThresholds;
200
228
  /**
201
229
  * Per-call system prompt override. Wins over `AgentOptions.systemPrompt`.
202
230
  * String only — for dynamic resolvers, configure on `AgentOptions`. An
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theokit/sdk",
3
- "version": "2.14.0",
3
+ "version": "2.15.0",
4
4
  "description": "TypeScript SDK for the Theo agent harness — same surface, local or cloud.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/usetheo/theokit-sdk#readme",