@theokit/agents 10.1.0 → 11.1.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.
Files changed (56) hide show
  1. package/CHANGELOG.md +356 -0
  2. package/LICENSE +2 -2
  3. package/README.md +6 -5
  4. package/dist/{agent-compiler-CIPQkehU.d.ts → agent-compiler-tetgj6zR.d.ts} +3 -172
  5. package/dist/{agent-handle-Dgi4ZGbg.d.ts → agent-handle-rEWdERuv.d.ts} +113 -2
  6. package/dist/auth.js +1 -1
  7. package/dist/{bridge-entry-emr2PSXC.d.ts → bridge-entry-DPm1C5li.d.ts} +83 -200
  8. package/dist/bridge.d.ts +8 -7
  9. package/dist/bridge.js +4 -3
  10. package/dist/{chunk-CKRM5Q2K.js → chunk-2I6DQUJP.js} +249 -47
  11. package/dist/chunk-2I6DQUJP.js.map +1 -0
  12. package/dist/{chunk-M6HMASZC.js → chunk-7PNUTDBQ.js} +109 -14
  13. package/dist/chunk-7PNUTDBQ.js.map +1 -0
  14. package/dist/{chunk-QXGSF6WX.js → chunk-D2EFYZBV.js} +1 -1
  15. package/dist/{chunk-QXGSF6WX.js.map → chunk-D2EFYZBV.js.map} +1 -1
  16. package/dist/{chunk-4VHCH6IZ.js → chunk-LLIERPF3.js} +14 -1
  17. package/dist/chunk-LLIERPF3.js.map +1 -0
  18. package/dist/chunk-OXNDJSAJ.js +59 -0
  19. package/dist/chunk-OXNDJSAJ.js.map +1 -0
  20. package/dist/{chunk-QJN2LLPF.js → chunk-ZQOKIZCI.js} +284 -164
  21. package/dist/chunk-ZQOKIZCI.js.map +1 -0
  22. package/dist/client-react.d.ts +24 -2
  23. package/dist/client-react.js +2 -1
  24. package/dist/client-react.js.map +1 -1
  25. package/dist/client.d.ts +99 -5
  26. package/dist/client.js +3 -1
  27. package/dist/config.d.ts +2 -2
  28. package/dist/config.js +2 -2
  29. package/dist/{define-agent-BO5QSjV8.d.ts → define-agent-BnH1MBxs.d.ts} +16 -1
  30. package/dist/{delegation-scoring-CDvtrYKd.d.ts → delegation-scoring-CQtF2Zaf.d.ts} +345 -11
  31. package/dist/hooks.js +2 -2
  32. package/dist/hooks.js.map +1 -1
  33. package/dist/index.d.ts +54 -9
  34. package/dist/index.js +17 -3
  35. package/dist/index.js.map +1 -1
  36. package/dist/mcp-health.d.ts +66 -1
  37. package/dist/mcp-health.js +32 -1
  38. package/dist/mcp-health.js.map +1 -1
  39. package/dist/pty.js.map +1 -1
  40. package/dist/session.d.ts +58 -1
  41. package/dist/session.js +34 -1
  42. package/dist/session.js.map +1 -1
  43. package/dist/testing.d.ts +3 -2
  44. package/dist/testing.js +1 -1
  45. package/dist/tools.d.ts +4 -2
  46. package/dist/tools.js +5 -4
  47. package/dist/tools.js.map +1 -1
  48. package/dist/types-C16Wuh9E.d.ts +173 -0
  49. package/dist/usage.d.ts +94 -1
  50. package/dist/usage.js +5 -1
  51. package/dist/usage.js.map +1 -1
  52. package/package.json +23 -10
  53. package/dist/chunk-4VHCH6IZ.js.map +0 -1
  54. package/dist/chunk-CKRM5Q2K.js.map +0 -1
  55. package/dist/chunk-M6HMASZC.js.map +0 -1
  56. package/dist/chunk-QJN2LLPF.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { WireMessage } from '@theokit/presenter/wire';
2
- import { R as RequestContext, U as UseAgentStatus, A as ApprovalDecision, a as AgentHandle, b as AgentTransport } from './agent-handle-Dgi4ZGbg.js';
2
+ import { R as RequestContext, U as UseAgentStatus, P as PendingApproval, A as ApprovalDecision, a as AgentHandle, b as AgentTransport } from './agent-handle-rEWdERuv.js';
3
3
  import '@theokit/sdk/errors';
4
4
 
5
5
  interface UseAgentReturn<TInput = unknown, TToolNames extends string = string> {
@@ -20,6 +20,28 @@ interface UseAgentReturn<TInput = unknown, TToolNames extends string = string> {
20
20
  abort: () => void;
21
21
  /** Clear messages + error, back to idle. */
22
22
  reset: () => void;
23
+ /**
24
+ * The HITL decisions this turn is parked on — empty whenever nothing is outstanding
25
+ * (usetheokit/theokit#392).
26
+ *
27
+ * Each entry carries the id `approve` takes plus what a prompt needs to name the action: the
28
+ * tool, its resolved input, the declared question and the window. Render it directly:
29
+ *
30
+ * ```tsx
31
+ * {pendingApprovals.map((a) => (
32
+ * <div key={a.approvalId}>
33
+ * {a.question ?? `Run ${a.toolName}?`}
34
+ * <button onClick={() => void approve(a.approvalId, { approved: true })}>Approve</button>
35
+ * <button onClick={() => void approve(a.approvalId, { approved: false })}>Deny</button>
36
+ * </div>
37
+ * ))}
38
+ * ```
39
+ *
40
+ * The same decision is on the transcript too — the gated tool's part sits in
41
+ * `state: 'approval-requested'` with the id under `approval.id` — so a surface that renders tool
42
+ * parts inline can read it there instead. This field exists so one does not have to.
43
+ */
44
+ pendingApprovals: PendingApproval[];
23
45
  /** Settle a paused HITL approval (HTTP `POST /approve/<id>` for web; the inline callback in-process). */
24
46
  approve: (approvalId: string, decision: ApprovalDecision) => Promise<void>;
25
47
  /** Resume an interrupted stream (M37 durable transport for web; a no-op in-process). */
@@ -55,4 +77,4 @@ interface UseAgentOptions {
55
77
  */
56
78
  declare function useAgent<TInput = unknown>(binding: string | AgentHandle<TInput> | AgentTransport, options?: UseAgentOptions): UseAgentReturn<TInput>;
57
79
 
58
- export { type UseAgentOptions, type UseAgentReturn, UseAgentStatus, useAgent };
80
+ export { PendingApproval, type UseAgentOptions, type UseAgentReturn, UseAgentStatus, useAgent };
@@ -2,7 +2,7 @@ import {
2
2
  AgentClient,
3
3
  HttpTransport,
4
4
  isAgentHandle
5
- } from "./chunk-M6HMASZC.js";
5
+ } from "./chunk-7PNUTDBQ.js";
6
6
  import {
7
7
  __name
8
8
  } from "./chunk-Z4QWC7IK.js";
@@ -41,6 +41,7 @@ function useAgent(binding, options = {}) {
41
41
  thread: state.thread,
42
42
  status: state.status,
43
43
  error: state.error,
44
+ pendingApprovals: state.pendingApprovals,
44
45
  send: client.send,
45
46
  abort: client.abort,
46
47
  reset: client.reset,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/use-agent.ts"],"mappings":";;;;;;;;;;AACA,SAASA,SAASC,QAAQC,4BAA4B;AAyE/C,SAASC,SACdC,SACAC,UAA2B,CAAC,GAAC;AAI7B,QAAMC,aAAaC,OAAOF,OAAAA;AAC1BC,aAAWE,UAAUH;AAIrB,MAAII;AACJ,MAAI,OAAOL,YAAY,SAAUK,OAAML;WAC9BM,cAAcN,OAAAA,EAAUK,OAAML,QAAQO;AAE/C,QAAMC,kBAAkBH,OAAOL;AAE/B,QAAMS,SAASC;IACb,MACE,IAAIC;MACFN,QAAQO,SACJ,IAAIC,cAAc;QAChBR;QACAS,SAAS,6BAAMZ,WAAWE,QAAQU,SAAzB;QACTC,OAAOb,WAAWE,QAAQW;MAC5B,CAAA,IACCf;;MAEL,MAAA;AACE,cAAMgB,MAAMd,WAAWE,QAAQa;AAC/B,eAAO,OAAOD,QAAQ,aAAaA,IAAAA,IAAQA;MAC7C;IAAA;;;IAIJ;MAACR;;EAAgB;AAGnB,QAAMU,QAAQC,qBAAqBV,OAAOW,WAAWX,OAAOY,aAAaZ,OAAOY,WAAW;AAE3F,SAAO;IACLC,UAAUJ,MAAMI;IAChBC,QAAQL,MAAMK;IACdC,QAAQN,MAAMM;IACdC,OAAOP,MAAMO;IACbC,MAAMjB,OAAOiB;IACbC,OAAOlB,OAAOkB;IACdC,OAAOnB,OAAOmB;IACdC,SAASpB,OAAOoB;IAChBC,WAAWrB,OAAOqB;EACpB;AACF;AAnDgB/B;","names":["useMemo","useRef","useSyncExternalStore","useAgent","binding","options","optionsRef","useRef","current","api","isAgentHandle","path","bindingIdentity","client","useMemo","AgentClient","undefined","HttpTransport","headers","fetch","ctx","context","state","useSyncExternalStore","subscribe","getSnapshot","messages","thread","status","error","send","abort","reset","approve","reconnect"]}
1
+ {"version":3,"sources":["../src/client/use-agent.ts"],"mappings":";;;;;;;;;;AACA,SAASA,SAASC,QAAQC,4BAA4B;AA+F/C,SAASC,SACdC,SACAC,UAA2B,CAAC,GAAC;AAI7B,QAAMC,aAAaC,OAAOF,OAAAA;AAC1BC,aAAWE,UAAUH;AAIrB,MAAII;AACJ,MAAI,OAAOL,YAAY,SAAUK,OAAML;WAC9BM,cAAcN,OAAAA,EAAUK,OAAML,QAAQO;AAE/C,QAAMC,kBAAkBH,OAAOL;AAE/B,QAAMS,SAASC;IACb,MACE,IAAIC;MACFN,QAAQO,SACJ,IAAIC,cAAc;QAChBR;QACAS,SAAS,6BAAMZ,WAAWE,QAAQU,SAAzB;QACTC,OAAOb,WAAWE,QAAQW;MAC5B,CAAA,IACCf;;MAEL,MAAA;AACE,cAAMgB,MAAMd,WAAWE,QAAQa;AAC/B,eAAO,OAAOD,QAAQ,aAAaA,IAAAA,IAAQA;MAC7C;IAAA;;;IAIJ;MAACR;;EAAgB;AAGnB,QAAMU,QAAQC,qBAAqBV,OAAOW,WAAWX,OAAOY,aAAaZ,OAAOY,WAAW;AAE3F,SAAO;IACLC,UAAUJ,MAAMI;IAChBC,QAAQL,MAAMK;IACdC,QAAQN,MAAMM;IACdC,OAAOP,MAAMO;IACbC,kBAAkBR,MAAMQ;IACxBC,MAAMlB,OAAOkB;IACbC,OAAOnB,OAAOmB;IACdC,OAAOpB,OAAOoB;IACdC,SAASrB,OAAOqB;IAChBC,WAAWtB,OAAOsB;EACpB;AACF;AApDgBhC;","names":["useMemo","useRef","useSyncExternalStore","useAgent","binding","options","optionsRef","useRef","current","api","isAgentHandle","path","bindingIdentity","client","useMemo","AgentClient","undefined","HttpTransport","headers","fetch","ctx","context","state","useSyncExternalStore","subscribe","getSnapshot","messages","thread","status","error","pendingApprovals","send","abort","reset","approve","reconnect"]}
package/dist/client.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { b as AgentTransport, A as ApprovalDecision } from './agent-handle-Dgi4ZGbg.js';
2
- export { c as AgentClient, d as AgentClientOptions, e as AgentClientState, a as AgentHandle, f as ApprovalAbortedError, C as ChannelPushSource, g as ChannelTransport, h as ChannelTransportOptions, i as ChannelTurnHandlers, I as InProcessApprovalRequestLike, j as InProcessAwaitApproval, k as InProcessRunInput, l as InProcessRunner, m as InProcessTransport, n as InProcessTransportOptions, R as RequestContext, U as UseAgentStatus, o as agentHandle, p as isAgentHandle } from './agent-handle-Dgi4ZGbg.js';
1
+ import { b as AgentTransport, A as ApprovalDecision } from './agent-handle-rEWdERuv.js';
2
+ export { c as AgentClient, d as AgentClientOptions, e as AgentClientState, a as AgentHandle, f as AgentStreamInterruptedError, g as ApprovalAbortedError, C as ChannelPushSource, h as ChannelTransport, i as ChannelTransportOptions, j as ChannelTurnHandlers, I as InProcessApprovalRequestLike, k as InProcessAwaitApproval, l as InProcessRunInput, m as InProcessRunner, n as InProcessTransport, o as InProcessTransportOptions, P as PendingApproval, R as RequestContext, U as UseAgentStatus, p as agentHandle, q as isAgentHandle } from './agent-handle-rEWdERuv.js';
3
3
  import { WireTransport, WireChunk, WireMessage } from '@theokit/presenter/wire';
4
4
  import '@theokit/sdk/errors';
5
5
 
@@ -16,6 +16,48 @@ interface HttpTransportOptions {
16
16
  headers?: HeadersResolver;
17
17
  /** Override fetch (primarily for tests / non-browser hosts) — static; resolved once at construction. */
18
18
  fetch?: typeof fetch;
19
+ /**
20
+ * Where the server-minted run id lives between requests — the key `reconnectToStream` needs
21
+ * (usetheokit/theokit#387).
22
+ *
23
+ * Defaults to an in-memory cell, which is what this transport always did and what keeps a
24
+ * reconnect working within one page lifetime. That default is also why a RELOAD could not
25
+ * reconnect: the new page builds a fresh transport with an empty cell, so `reconnectToStream`
26
+ * returns `null` before it reaches the network — while the server still holds the run in its
27
+ * cache and would replay it.
28
+ *
29
+ * The medium is the CONSUMER's decision, not this package's. `sessionStorage` matches a run's
30
+ * lifetime better than `localStorage`, and either would be a client library writing to browser
31
+ * storage nobody asked it to write to, with privacy and SSR consequences. So the seam is injected
32
+ * and the package stores nothing it was not handed a place for:
33
+ *
34
+ * ```ts
35
+ * new HttpTransport({
36
+ * api: '/api/agents/support',
37
+ * runIdStore: {
38
+ * get: () => sessionStorage.getItem('theo.runId') ?? undefined,
39
+ * set: (id) => {
40
+ * if (id === undefined) sessionStorage.removeItem('theo.runId')
41
+ * else sessionStorage.setItem('theo.runId', id)
42
+ * },
43
+ * },
44
+ * })
45
+ * ```
46
+ *
47
+ * Deliberately NOT included: reconnecting automatically on load. This makes a cached run
48
+ * REACHABLE; reaching for it is a product decision nobody has asked for.
49
+ */
50
+ runIdStore?: RunIdStore;
51
+ }
52
+ /**
53
+ * Where the reconnect key is kept.
54
+ *
55
+ * Two methods rather than a storage object, so a consumer can back it with `sessionStorage`, a
56
+ * cookie, a router param, or a test double — the transport never learns which.
57
+ */
58
+ interface RunIdStore {
59
+ get: () => string | undefined;
60
+ set: (runId: string | undefined) => void;
19
61
  }
20
62
  /**
21
63
  * M41 (ADR-0050 D3) — `ChatTransport` over the web agent path.
@@ -68,13 +110,55 @@ type UIMessageChunk = WireChunk;
68
110
  * `onMessage` is invoked on every reconstruction step with the latest snapshot of the assistant
69
111
  * message, so a caller (the `useAgent` hook) can render streaming updates.
70
112
  */
71
- declare function consumeUIMessageStream(response: Response, onMessage: (message: UIMessage) => void): Promise<void>;
113
+ declare function consumeUIMessageStream(response: Response, onMessage: (message: UIMessage) => void): Promise<ChunkStreamOutcome>;
72
114
  /**
73
115
  * A UIMessageStream SSE `Response` → `ReadableStream<UIMessageChunk>`. This is precisely what a
74
116
  * `ChatTransport.sendMessages` returns, so `HttpTransport` builds on it directly. A body-less
75
117
  * response yields an empty stream.
76
118
  */
77
119
  declare function responseToChunkStream(response: Response): Promise<ReadableStream<UIMessageChunk>>;
120
+ /**
121
+ * How a chunk stream ENDED — theokit#384.
122
+ *
123
+ * ## Why this exists at all
124
+ *
125
+ * The reader used to return `void`, which left its caller exactly two outcomes to choose between:
126
+ * it threw, or it did not. A stream that simply STOPS — a socket closed mid-run — throws nothing,
127
+ * so `AgentClient` read "did not throw" as "the agent finished" and settled a truncated answer in
128
+ * `status: 'done'` with no error. The information needed to tell the two apart was on the wire and
129
+ * nothing carried it out of the reader.
130
+ *
131
+ * ## What counts as an ending, and what does not
132
+ *
133
+ * The stream's own terminal chunk, `finish`, is the marker — NOT the SSE `[DONE]` sentinel:
134
+ *
135
+ * - `finish` is emitted by `presentUIMessageStream` on EVERY framework path, including the error
136
+ * path, so it is the one terminator that exists on all three transports. `[DONE]` is written
137
+ * only by the durable SSE encoder, so an in-process or channel stream has none to look for.
138
+ * - `[DONE]` is also the WEAKER claim of the two. `durableUiMessageStreamResponse` flushes it from
139
+ * a `finally` even when the source aborted mid-run, so a run cut on the SERVER carries `[DONE]`
140
+ * and no `finish`. Keying on `finish` reports that case too; keying on `[DONE]` would miss it.
141
+ *
142
+ * `finish` also cannot lie in the other direction: nothing can truncate a run after its terminal
143
+ * chunk has been written, so a stream that carried one carried a complete turn even if the socket
144
+ * died a byte later.
145
+ */
146
+ interface ChunkStreamOutcome {
147
+ /**
148
+ * `true` iff the terminal `finish` chunk crossed before the stream ended.
149
+ *
150
+ * `false` means the producer stopped talking mid-run: a dropped connection, a killed server, a
151
+ * proxy timeout. It does NOT mean the run failed — a failure arrives as an `error` chunk, which
152
+ * the reader raises instead of returning.
153
+ */
154
+ readonly terminated: boolean;
155
+ /**
156
+ * How many chunks crossed. Diagnostic only, and it earns its place: it separates "the server
157
+ * accepted the request and then said nothing" (`0`) from "the answer was cut mid-sentence"
158
+ * (`n > 0`), which are different failures with different first suspects.
159
+ */
160
+ readonly chunksReceived: number;
161
+ }
78
162
  /**
79
163
  * Read a `ReadableStream<UIMessageChunk>` into reconstructed assistant messages. Shared by
80
164
  * {@link consumeUIMessageStream} (Response path) and the framework-agnostic `AgentClient` store
@@ -84,8 +168,18 @@ declare function responseToChunkStream(response: Response): Promise<ReadableStre
84
168
  * A provider failure (401/429/5xx) arrives as a `{ type: 'error', errorText }` chunk rather than a
85
169
  * thrown rejection — both the in-process runner and the SSE path emit it as data. The reader
86
170
  * rejects on it, so `AgentClient.#drive`'s existing catch surfaces it (`status='error'`).
171
+ *
172
+ * theokit#384 — it also RETURNS how the stream ended. See {@link ChunkStreamOutcome}.
173
+ *
174
+ * The observation happens in a `TransformStream` rather than inside `readMessageStream`, because a
175
+ * bare `finish` reconstructs to nothing: the reader yields a snapshot for it only when it carries
176
+ * `messageMetadata`, so the terminal chunk is invisible at the message level by design (measured
177
+ * against the ai-sdk oracle — see `read-message-stream.ts`). Watching the CHUNKS is the only place
178
+ * the terminator is observable without changing what the reader emits. The cost is one queue hop
179
+ * per chunk on a path that already spends 3.274 ms per emit deriving the timeline (M86) — real,
180
+ * and three orders of magnitude below the work it sits next to.
87
181
  */
88
- declare function consumeChunkStream(stream: ReadableStream<UIMessageChunk>, onMessage: (message: UIMessage) => void): Promise<void>;
182
+ declare function consumeChunkStream(stream: ReadableStream<UIMessageChunk>, onMessage: (message: UIMessage) => void): Promise<ChunkStreamOutcome>;
89
183
 
90
184
  /**
91
185
  * M41/M42 — extract the turn text from the last user message's text parts. Shared by the transports
@@ -94,4 +188,4 @@ declare function consumeChunkStream(stream: ReadableStream<UIMessageChunk>, onMe
94
188
  */
95
189
  declare function extractLastUserText(messages: readonly WireMessage[]): string;
96
190
 
97
- export { AgentTransport, ApprovalDecision, type HeadersResolver, HttpTransport, type HttpTransportOptions, consumeChunkStream, consumeUIMessageStream, extractLastUserText, responseToChunkStream };
191
+ export { AgentTransport, ApprovalDecision, type ChunkStreamOutcome, type HeadersResolver, HttpTransport, type HttpTransportOptions, consumeChunkStream, consumeUIMessageStream, extractLastUserText, responseToChunkStream };
package/dist/client.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  AgentClient,
3
+ AgentStreamInterruptedError,
3
4
  ApprovalAbortedError,
4
5
  ChannelTransport,
5
6
  HttpTransport,
@@ -10,10 +11,11 @@ import {
10
11
  extractLastUserText,
11
12
  isAgentHandle,
12
13
  responseToChunkStream
13
- } from "./chunk-M6HMASZC.js";
14
+ } from "./chunk-7PNUTDBQ.js";
14
15
  import "./chunk-Z4QWC7IK.js";
15
16
  export {
16
17
  AgentClient,
18
+ AgentStreamInterruptedError,
17
19
  ApprovalAbortedError,
18
20
  ChannelTransport,
19
21
  HttpTransport,
package/dist/config.d.ts CHANGED
@@ -191,7 +191,7 @@ declare class TrustStore {
191
191
  * draft called them synchronously and `trust()` returned before the bytes landed, so an immediate
192
192
  * `read()` saw an empty store. Same shape as the M71 pointer bug, and same cause — the SDK's
193
193
  * `.d.ts` does not declare these, so nothing at compile time says they return a Promise
194
- * (usetheodev/theokit-sdk#280).
194
+ * (usetheokit/theokit-sdk#280).
195
195
  */
196
196
  trust(record: TrustRecord): Promise<void>;
197
197
  /**
@@ -310,7 +310,7 @@ interface LoadInstructionTreeInput {
310
310
  * Which files to load. Defaults to the conventional two.
311
311
  *
312
312
  * A list matches basenames exactly; a predicate answers the question a list cannot. A rules
313
- * DIRECTORY `.claude/rules/`, `.cursor/rules/`, `.theokit/rules/` — holds files the caller
313
+ * DIRECTORY —, `.cursor/rules/`, `.theokit/rules/` — holds files the caller
314
314
  * cannot name in advance, because the user chooses the names. With only a list on offer, the
315
315
  * closest consumer wrote its own 112-line walk (budget, depth ceiling, cycle guard and all) to
316
316
  * ask `entry.endsWith('.md')`. The walk was ours; only the question was theirs.
package/dist/config.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ensureSecureDir
3
- } from "./chunk-QXGSF6WX.js";
3
+ } from "./chunk-D2EFYZBV.js";
4
4
  import {
5
5
  __name
6
6
  } from "./chunk-Z4QWC7IK.js";
@@ -154,7 +154,7 @@ var TrustStore = class {
154
154
  * draft called them synchronously and `trust()` returned before the bytes landed, so an immediate
155
155
  * `read()` saw an empty store. Same shape as the M71 pointer bug, and same cause — the SDK's
156
156
  * `.d.ts` does not declare these, so nothing at compile time says they return a Promise
157
- * (usetheodev/theokit-sdk#280).
157
+ * (usetheokit/theokit-sdk#280).
158
158
  */
159
159
  async trust(record) {
160
160
  ensureSecureDir(this.file);
@@ -1,6 +1,7 @@
1
1
  import { TrustPosture, SettingSource, CustomTool, MemorySettings } from '@theokit/sdk';
2
2
  import { z } from 'zod';
3
- import { R as ReasoningEffort, G as Guardrail, H as HumanInTheLoopOptions, S as SkillsSelection, M as McpServersMap, C as CompiledAgentOptions } from './agent-compiler-CIPQkehU.js';
3
+ import { G as Guardrail, S as SkillsSelection, C as CompiledAgentOptions } from './agent-compiler-tetgj6zR.js';
4
+ import { R as ReasoningEffort, H as HumanInTheLoopOptions, M as McpServersMap } from './types-C16Wuh9E.js';
4
5
  import { H as HookHandlers } from './hook-handlers-Cw2FsnE5.js';
5
6
  import { TheokitAgentError } from '@theokit/sdk/errors';
6
7
 
@@ -127,6 +128,20 @@ interface DefineAgentConfig<TInput extends z.ZodType = z.ZodType> {
127
128
  system?: string;
128
129
  /** Extended-thinking effort. */
129
130
  reasoningEffort?: ReasoningEffort;
131
+ /**
132
+ * theokit#363 — hard ceiling on the agent's tool-calling turns within ONE run. Reaching it ends
133
+ * the turn instead of letting the model keep calling tools; absent ⇒ the SDK's own ceiling (8).
134
+ *
135
+ * Named `maxIterations`, not `maxSteps`, because the concept already has exactly one name here —
136
+ * `@Agent({ maxIterations })`, `@MainLoop({ maxIterations })`, `AgentRunner.stream({ maxIterations })`,
137
+ * `delegate({ maxIterations })` — and one name in the SDK it lowers to (`SendOptions.maxIterations`).
138
+ * A second name would be the only place needing translation, and the translation is invisible where
139
+ * it costs most: the SDK rejects an invalid value with a message naming `SendOptions.maxIterations`,
140
+ * which an author who typed `.maxSteps()` has no way to connect to what they wrote. Familiarity
141
+ * argues for the ai-sdk spelling, but ai-sdk's own name is `stopWhen: stepCountIs(n)` — borrowing
142
+ * "steps" would buy recognition of a word, not of an API.
143
+ */
144
+ maxIterations?: number;
130
145
  /**
131
146
  * Pre-built tools. Accepts the `@theokit/sdk` `CustomTool` that `defineAgentTool`
132
147
  * (theokit/server) and every `@theokit/sdk-tools` factory return (issue #81) — they are