@theokit/sdk 2.20.0 → 2.21.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 (88) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/dist/a2a/index.cjs +592 -290
  3. package/dist/a2a/index.cjs.map +1 -1
  4. package/dist/a2a/index.js +593 -291
  5. package/dist/a2a/index.js.map +1 -1
  6. package/dist/a2a/types.d.cts +7 -0
  7. package/dist/a2a/types.d.ts +7 -0
  8. package/dist/agent-builder.d.ts +2 -1
  9. package/dist/agent-generate.d.ts +12 -0
  10. package/dist/client/index.cjs.map +1 -1
  11. package/dist/client/index.d.cts +5 -0
  12. package/dist/client/index.d.ts +5 -0
  13. package/dist/client/index.js.map +1 -1
  14. package/dist/client/theokit-client.d.cts +6 -0
  15. package/dist/client/theokit-client.d.ts +6 -0
  16. package/dist/client/types.d.cts +2 -0
  17. package/dist/client/types.d.ts +2 -0
  18. package/dist/{cron-D2yLOrk2.d.ts → cron-YrmsszEN.d.cts} +53 -3
  19. package/dist/{cron-B8fqui49.d.cts → cron-dpvtRoro.d.ts} +53 -3
  20. package/dist/cron.cjs +642 -387
  21. package/dist/cron.cjs.map +1 -1
  22. package/dist/cron.d.cts +3 -2
  23. package/dist/cron.d.ts +3 -2
  24. package/dist/cron.js +643 -388
  25. package/dist/cron.js.map +1 -1
  26. package/dist/{errors-5lj1EWgs.d.ts → errors-C4vZPqXf.d.ts} +2 -2
  27. package/dist/{errors-CE-lMBi2.d.cts → errors-DrcpYVfZ.d.cts} +2 -2
  28. package/dist/errors.d.cts +3 -2
  29. package/dist/eval.cjs +642 -387
  30. package/dist/eval.cjs.map +1 -1
  31. package/dist/eval.js +642 -387
  32. package/dist/eval.js.map +1 -1
  33. package/dist/generate-object.d.ts +4 -3
  34. package/dist/index.cjs +788 -390
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +259 -17
  37. package/dist/index.d.ts +259 -17
  38. package/dist/index.js +786 -392
  39. package/dist/index.js.map +1 -1
  40. package/dist/internal/agent-loop/loop-types.d.ts +2 -0
  41. package/dist/internal/agent-loop/tool-result-guard.d.ts +1 -0
  42. package/dist/internal/llm/tool-result-content.d.ts +40 -0
  43. package/dist/internal/llm/types.d.ts +6 -1
  44. package/dist/internal/persistence/conversation-storage-fs.d.cts +3 -1
  45. package/dist/internal/persistence/conversation-storage-fs.d.ts +3 -1
  46. package/dist/internal/persistence/conversation-storage-memory.d.cts +3 -1
  47. package/dist/internal/persistence/conversation-storage-memory.d.ts +3 -1
  48. package/dist/internal/persistence/session-meta.d.cts +13 -0
  49. package/dist/internal/persistence/session-meta.d.ts +13 -0
  50. package/dist/internal/runtime/model-selection.d.ts +14 -0
  51. package/dist/internal/structured-output-helpers.d.ts +1 -1
  52. package/dist/permission-engine.d.ts +32 -1
  53. package/dist/{run-BgfBWX-z.d.cts → run-BMo8yRwK.d.cts} +262 -19
  54. package/dist/{run-BgfBWX-z.d.ts → run-BMo8yRwK.d.ts} +262 -19
  55. package/dist/stream-object.d.ts +2 -1
  56. package/dist/tool-error.d.ts +30 -0
  57. package/dist/types/agent-prims.d.ts +10 -8
  58. package/dist/types/agent.d.ts +12 -1
  59. package/dist/types/content-blocks.d.ts +47 -0
  60. package/dist/types/conversation-storage.d.ts +38 -0
  61. package/dist/types/index.d.ts +1 -0
  62. package/dist/types/messages.d.ts +2 -9
  63. package/dist/types/run-events.d.ts +84 -0
  64. package/dist/types/run.d.ts +115 -1
  65. package/dist/types/session.d.ts +99 -0
  66. package/dist/types/workflow.d.ts +7 -0
  67. package/dist/workflow.cjs +7 -2
  68. package/dist/workflow.cjs.map +1 -1
  69. package/dist/workflow.d.cts +2 -0
  70. package/dist/workflow.d.ts +2 -0
  71. package/dist/workflow.js +7 -2
  72. package/dist/workflow.js.map +1 -1
  73. package/package.json +14 -34
  74. package/dist/internal/observability/context.d.cts +0 -23
  75. package/dist/internal/observability/context.d.ts +0 -23
  76. package/dist/internal/observability/index.cjs +0 -38
  77. package/dist/internal/observability/index.cjs.map +0 -1
  78. package/dist/internal/observability/index.d.cts +0 -8
  79. package/dist/internal/observability/index.d.ts +0 -8
  80. package/dist/internal/observability/index.js +0 -33
  81. package/dist/internal/observability/index.js.map +0 -1
  82. package/dist/internal/plugins/index.cjs +0 -363
  83. package/dist/internal/plugins/index.cjs.map +0 -1
  84. package/dist/internal/plugins/index.js +0 -357
  85. package/dist/internal/plugins/index.js.map +0 -1
  86. package/dist/internal/workflow/index.d.ts +0 -12
  87. package/dist/server/adapter/index.d.cts +0 -8
  88. package/dist/server/adapter/index.d.ts +0 -8
@@ -1,3 +1,53 @@
1
+ import * as zod from 'zod';
2
+
3
+ /**
4
+ * Leaf module for content-block types shared by `messages.ts` (assistant/user
5
+ * content) and `agent-prims.ts` (`CustomTool` handler results). Kept
6
+ * import-free so both can depend on it WITHOUT the `agent-prims ↔ messages`
7
+ * cycle (#7).
8
+ *
9
+ * @public
10
+ */
11
+ /**
12
+ * Plain text content block emitted by the assistant or user, or returned by a
13
+ * tool.
14
+ *
15
+ * @public
16
+ */
17
+ interface TextBlock {
18
+ type: "text";
19
+ text: string;
20
+ }
21
+ /**
22
+ * SE7 — a base64-encoded image block a tool can hand back as (part of) its
23
+ * result or its `ToolError`. `media_type` is a MIME type (e.g. `"image/png"`);
24
+ * `data` is the base64 payload without a data-URL prefix.
25
+ *
26
+ * Note: when a tool builds this from model- or user-influenced input, treat
27
+ * `media_type` as UNTRUSTED — validate/allow-list it before rendering it in a
28
+ * log or UI (it could carry newlines / control chars). The SDK only forwards it
29
+ * (JSON-serialized onto the wire) and never executes or path-joins it.
30
+ *
31
+ * @public
32
+ */
33
+ interface ImageBlock {
34
+ type: "image";
35
+ source: {
36
+ type: "base64";
37
+ media_type: string;
38
+ data: string;
39
+ };
40
+ }
41
+ /**
42
+ * SE7 — structured content a tool result may carry: text and/or images. A tool
43
+ * `handler` may return this (success) and a `ToolError` may carry it (failure).
44
+ * Block-capable provider wires forward it natively; string-only provider wires
45
+ * flatten text and fail fast on an image.
46
+ *
47
+ * @public
48
+ */
49
+ type ToolResultContentBlock = TextBlock | ImageBlock;
50
+
1
51
  /**
2
52
  * #57 — content-level defense for tool results before they reach the LLM.
3
53
  *
@@ -11,6 +61,7 @@
11
61
  *
12
62
  * @internal
13
63
  */
64
+
14
65
  interface ToolResultGuardOptions {
15
66
  /** Wrap tool-result content in explicit data boundaries (spotlighting). */
16
67
  delimit?: boolean;
@@ -18,6 +69,91 @@ interface ToolResultGuardOptions {
18
69
  redactPii?: boolean;
19
70
  }
20
71
 
72
+ /**
73
+ * SE2 — typed runtime EVENT stream, ADDITIVE to the `SDKMessage` content stream.
74
+ *
75
+ * `Run.stream()` yields `SDKMessage`s (the conversation content). `RunEvent`s are
76
+ * out-of-band runtime-OBSERVABILITY signals — the model's content is unaffected —
77
+ * delivered opt-in via `SendOptions.onRunEvent`. Discriminate on `type`. Mirrors
78
+ * the Anthropic `SDKMessage`-union approach (rate-limit, permission-denied, task
79
+ * lifecycle, compaction boundary).
80
+ *
81
+ * The union is the forward-compatible CONTRACT (discriminate exhaustively). As of
82
+ * SE2 the runtime EMITS `tool_progress` and `permission_denied` end-to-end (from
83
+ * the agent-loop tool-dispatch seam). `rate_limit`, `task_*`, and `compact_boundary`
84
+ * are part of the contract; their emission is wired incrementally as the sink is
85
+ * threaded into the LLM-client retry / task / session-compaction subsystems (they
86
+ * live below the loop). A consumer switching on `type` is future-proof either way.
87
+ *
88
+ * @public
89
+ */
90
+ type RunEvent = RunToolProgressEvent | RunRateLimitEvent | RunPermissionDeniedEvent | RunTaskStartedEvent | RunTaskUpdatedEvent | RunTaskCompletedEvent | RunCompactBoundaryEvent;
91
+ /** A tool call is being dispatched (before its result). */
92
+ interface RunToolProgressEvent {
93
+ readonly type: "tool_progress";
94
+ readonly toolName: string;
95
+ readonly toolCallId: string;
96
+ }
97
+ /** The provider returned a rate-limit (HTTP 429); the loop will back off + retry. */
98
+ interface RunRateLimitEvent {
99
+ readonly type: "rate_limit";
100
+ /** Retry attempt number (1-based) about to be delayed. */
101
+ readonly attempt: number;
102
+ /** Delay in ms before the retry, when the provider/policy supplied one. */
103
+ readonly retryAfterMs?: number;
104
+ }
105
+ /**
106
+ * A tool call was DENIED before dispatch — by the permission gate/plugin (SE1),
107
+ * an operator file-hook `preToolUse`, or the fork tool-whitelist. `source`
108
+ * discriminates which. `toolCallId` joins the event to the tool-call log.
109
+ */
110
+ interface RunPermissionDeniedEvent {
111
+ readonly type: "permission_denied";
112
+ readonly toolName: string;
113
+ readonly toolCallId: string;
114
+ /** Which layer blocked the call. */
115
+ readonly source: "plugin" | "file_hook" | "fork_whitelist";
116
+ /** The rejection message surfaced to the model. */
117
+ readonly message: string;
118
+ }
119
+ /** A background task/subagent started. */
120
+ interface RunTaskStartedEvent {
121
+ readonly type: "task_started";
122
+ readonly taskId: string;
123
+ readonly description?: string;
124
+ }
125
+ /** A background task/subagent changed state. */
126
+ interface RunTaskUpdatedEvent {
127
+ readonly type: "task_updated";
128
+ readonly taskId: string;
129
+ readonly status: string;
130
+ }
131
+ /** A background task/subagent finished. */
132
+ interface RunTaskCompletedEvent {
133
+ readonly type: "task_completed";
134
+ readonly taskId: string;
135
+ readonly status: "completed" | "failed" | "stopped";
136
+ }
137
+ /** The conversation crossed a compaction boundary (history was summarized). */
138
+ interface RunCompactBoundaryEvent {
139
+ readonly type: "compact_boundary";
140
+ readonly trigger: "manual" | "auto";
141
+ /** Token count before compaction, when known. */
142
+ readonly preTokens?: number;
143
+ }
144
+ /**
145
+ * SE2 — the opt-in sink for {@link RunEvent}s. Supplied via `SendOptions.onRunEvent`.
146
+ * Synchronous + best-effort: a throwing sink must never break the run (the emitter
147
+ * try-catches it), so keep it fast (push to a queue, don't await).
148
+ */
149
+ type RunEventSink = (event: RunEvent) => void;
150
+ /**
151
+ * SE2 — emit a {@link RunEvent} to an optional sink, swallowing any sink error so
152
+ * observability can never break the run (fail-safe, mirrors the EventBus EC-2
153
+ * contract). No-op when the sink is absent.
154
+ */
155
+ declare function emitRunEvent(sink: RunEventSink | undefined, event: RunEvent): void;
156
+
21
157
  /**
22
158
  * Type-leaf — primitives shared between `agent.ts`, `run.ts`, and
23
159
  * `messages.ts`. Extracted to break LOW type-only cycles #5 and #7
@@ -73,18 +209,20 @@ interface CustomTool {
73
209
  inputSchema: Record<string, unknown>;
74
210
  /**
75
211
  * Local handler invoked when the model emits `tool_use` for this tool.
76
- * Returns a string (becomes the `tool_result.content` surfaced back to the
77
- * model). Throws SDK converts to `tool_result` with `isError: true` and
78
- * the error `message` as content. #65 an optional 2nd `ToolContext`
79
- * argument carries the run's `AbortSignal`; single-argument handlers are
80
- * unaffected. M7the same `ctx` also carries an optional user `context`
81
- * (provided once via `SendOptions.context`), so shared config like a
82
- * `projectRoot` is read by every tool instead of baked into each factory.
212
+ * Returns a string OR structured content blocks (SE7 text + image, e.g. a
213
+ * screenshot) that become the `tool_result.content` surfaced back to the
214
+ * model. Throws SDK converts to `tool_result` with `isError: true` and the
215
+ * error `message` as content; throw a `ToolError` to carry a clean message or
216
+ * multimodal error content. #65 — an optional 2nd `ToolContext` argument
217
+ * carries the run's `AbortSignal`; single-argument handlers are unaffected. M7
218
+ * — the same `ctx` also carries an optional user `context` (provided once via
219
+ * `SendOptions.context`), so shared config like a `projectRoot` is read by
220
+ * every tool instead of baked into each factory.
83
221
  */
84
222
  handler: (input: Record<string, unknown>, ctx?: {
85
223
  signal?: AbortSignal;
86
224
  context?: unknown;
87
- }) => string | Promise<string>;
225
+ }) => string | ToolResultContentBlock[] | Promise<string | ToolResultContentBlock[]>;
88
226
  }
89
227
 
90
228
  /**
@@ -441,15 +579,6 @@ type McpHttpServerConfig = {
441
579
  */
442
580
  type McpServerConfig = McpStdioServerConfig | McpHttpServerConfig;
443
581
 
444
- /**
445
- * Plain text content block emitted by the assistant or user.
446
- *
447
- * @public
448
- */
449
- interface TextBlock {
450
- type: "text";
451
- text: string;
452
- }
453
582
  /**
454
583
  * Tool invocation block emitted by the assistant.
455
584
  *
@@ -685,6 +814,49 @@ interface RunGitInfo {
685
814
  prUrl?: string;
686
815
  }>;
687
816
  }
817
+ /**
818
+ * SE3 — provenance of the turn that produced a run: WHO triggered it. Stamped in
819
+ * the multi-agent path (Squad / a2a / handoff / background-delegation) and
820
+ * forwarded onto {@link RunResult.origin} — so consumers can attribute/route
821
+ * turns by their trigger. Metadata-only; discriminate on `kind`. Mirrors the
822
+ * Anthropic Agent SDK's `origin` shape.
823
+ *
824
+ * Encoding note (distinct from absence): an ABSENT origin (`undefined`) means the
825
+ * provenance was NOT stamped — the default for a plain `agent.send()`. The explicit
826
+ * `{ kind: "human" }` is a positive marker a HOST stamps to say "this turn is
827
+ * definitely from a human" (e.g. to distinguish a real user message from an
828
+ * un-attributed one in an audit UI). The two are not interchangeable: `undefined`
829
+ * = unknown/unstamped; `{ kind: "human" }` = explicitly human. Consumers writing an
830
+ * exhaustive `switch (origin?.kind)` therefore handle `undefined` (unstamped) and
831
+ * `"human"` (explicit) as separate, meaningful cases.
832
+ *
833
+ * @public
834
+ */
835
+ type MessageOrigin =
836
+ /** Explicitly a human-triggered turn — a positive marker a host stamps (NOT the
837
+ * same as an absent/unstamped origin, which is `undefined`). */
838
+ {
839
+ readonly kind: "human";
840
+ }
841
+ /** Another agent (a Squad peer or an a2a sender) triggered this turn. */
842
+ | {
843
+ readonly kind: "peer";
844
+ readonly from: string;
845
+ }
846
+ /** A background task's completion re-entered the agent as a follow-up turn. */
847
+ | {
848
+ readonly kind: "task-notification";
849
+ }
850
+ /** A delegating/handoff coordinator triggered this turn. `from` is the coordinator's
851
+ * id when known, omitted for an anonymous coordinator. */
852
+ | {
853
+ readonly kind: "coordinator";
854
+ readonly from?: string;
855
+ }
856
+ /** The loop's continuation driver re-sent to continue truncated work. */
857
+ | {
858
+ readonly kind: "auto-continuation";
859
+ };
688
860
  /**
689
861
  * Terminal result of a {@link Run}.
690
862
  *
@@ -697,6 +869,15 @@ interface RunResult {
697
869
  model?: ModelSelection;
698
870
  durationMs?: number;
699
871
  git?: RunGitInfo;
872
+ /**
873
+ * SE3 — provenance forwarded from {@link SendOptions.origin}: who triggered
874
+ * this turn (human / peer / task-notification / coordinator / auto-continuation).
875
+ * `undefined` means the provenance was not stamped (a plain `agent.send()`).
876
+ * Metadata-only — never affects routing.
877
+ *
878
+ * @public
879
+ */
880
+ origin?: MessageOrigin;
700
881
  /**
701
882
  * Structured error detail, populated when `status === "error"`. Surfaces
702
883
  * the diagnostic that emit-error-event pushes into the stream so callers
@@ -871,7 +1052,27 @@ interface SDKUserMessage {
871
1052
  * @public
872
1053
  */
873
1054
  interface SendOptions {
874
- model?: ModelSelection;
1055
+ /**
1056
+ * Per-send model override. SE8 — accepts a bare-string id shorthand
1057
+ * (`"openai/gpt-4o-mini"`, normalized to `{ id }`) OR a {@link ModelSelection}
1058
+ * object (use the object form to pass `params`).
1059
+ */
1060
+ model?: string | ModelSelection;
1061
+ /**
1062
+ * SE3 — provenance of this turn (who triggered it). Stamped by the multi-agent
1063
+ * path (Squad peer, a2a sender, coordinator/handoff, background task-notification)
1064
+ * and forwarded onto {@link RunResult.origin}. Metadata-only — the value never
1065
+ * changes routing or dispatch. Omit to leave the turn un-attributed; a host may
1066
+ * pass `{ kind: "human" }` to positively mark a human turn.
1067
+ */
1068
+ origin?: MessageOrigin;
1069
+ /**
1070
+ * SE2 — opt-in typed runtime-EVENT sink. Receives out-of-band `RunEvent`s
1071
+ * (permission_denied, tool_progress, rate_limit, task_*, compact_boundary) for
1072
+ * observability, ADDITIVE to the `SDKMessage` content stream. Best-effort: a
1073
+ * throwing sink never breaks the run. Discriminate on `event.type`.
1074
+ */
1075
+ onRunEvent?: RunEventSink;
875
1076
  /**
876
1077
  * Doom-loop guard config. The loop stops (with `terminal: "no_progress"`, `RunResult.stoppedByDoomLoop`)
877
1078
  * when the model repeats IDENTICAL tool calls to the hard threshold. On by default with generous
@@ -1009,5 +1210,47 @@ interface Run {
1009
1210
  /** Subscribe to status changes. Returns an unsubscribe function. */
1010
1211
  onDidChangeStatus(listener: (status: RunStatus) => void): () => void;
1011
1212
  }
1213
+ /**
1214
+ * SE9 — options for the integrated structured-output method `agent.generate`: the
1215
+ * {@link SendOptions} that drive the tool loop (phase 1) plus the required `output`
1216
+ * Zod schema and structuring knobs (phase 2). Co-located with `SendOptions` /
1217
+ * `RunResult` (which they extend/use) so the public `SDKAgent` interface does not
1218
+ * import the runtime `agent-generate` module (breaks the type cycle).
1219
+ *
1220
+ * @public
1221
+ */
1222
+ interface GenerateOptions<T extends zod.ZodType> extends SendOptions {
1223
+ /** Zod schema the final answer is coerced into (the structuring contract). */
1224
+ output: T;
1225
+ /** Retry budget on the structuring phase's parse-failures (reused from generateObject). Default 1. */
1226
+ maxRetries?: number;
1227
+ /**
1228
+ * What the STRUCTURING phase (phase 2) does when the model's output still fails
1229
+ * Zod validation after retries. Default `"throw"`. `"return-partial"` / `"return-raw"`
1230
+ * salvage the object; the salvaged/raw value is in {@link GenerateRunResult.raw}
1231
+ * (the pre-parse structuring input) — NOT the phase-1 text answer, which is in
1232
+ * `result.result`.
1233
+ */
1234
+ errorStrategy?: "throw" | "return-partial" | "return-raw";
1235
+ }
1236
+ /**
1237
+ * SE9 — result of `agent.generate`: the validated typed object plus the underlying
1238
+ * tool-loop {@link RunResult} (status / usage / model) and the raw pre-parse input.
1239
+ *
1240
+ * @public
1241
+ */
1242
+ interface GenerateRunResult<O> {
1243
+ /** The validated object — inferred type from the `output` schema. */
1244
+ object: O;
1245
+ /** The underlying tool-loop run (phase 1). */
1246
+ result: RunResult;
1247
+ /** Raw model input to the synthetic `output` tool, before the Zod parse. */
1248
+ raw: unknown;
1249
+ /** Combined token usage of the structuring phase. */
1250
+ usage: {
1251
+ inputTokens: number;
1252
+ outputTokens: number;
1253
+ };
1254
+ }
1012
1255
 
1013
- 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, ToolResultGuardOptions as a7, ToolUseBlock as a8, TurnEndedUpdate as a9, UserMessage as aa, UserMessageAppendedUpdate as ab, 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 };
1256
+ export { type SendOptions as $, type AgentConversationTurn as A, type RunTaskStartedEvent as B, type CustomTool as C, type DoomLoopThresholds as D, type RunTaskUpdatedEvent as E, type RunToCompletionOptions as F, type GenerateOptions as G, type RunToCompletionResult as H, type ImageBlock as I, type RunToolProgressEvent as J, type SDKAssistantMessage as K, type SDKImage as L, type ModelSelection as M, type SDKImageDimension as N, type SDKObjectDelta as O, type PartialToolCallUpdate as P, type SDKRequestMessage as Q, type RunResult as R, type SDKMessage as S, type ToolResultContentBlock as T, type SDKStatusMessage as U, type SDKSystemMessage as V, type SDKTaskMessage as W, type SDKThinkingMessage as X, type SDKToolUseMessage as Y, type SDKUserMessage as Z, type SDKUserMessageEvent as _, type McpServerConfig as a, type ShellCommand as a0, type ShellConversationTurn as a1, type ShellOutput as a2, type ShellOutputDeltaUpdate as a3, type StepCompletedUpdate as a4, type StepStartedUpdate as a5, type StreamToCompletionResult as a6, type SummaryCompletedUpdate as a7, type SummaryStartedUpdate as a8, type SummaryUpdate as a9, type TextBlock as aa, type TextDeltaUpdate as ab, type ThinkingCompletedUpdate as ac, type ThinkingDeltaUpdate as ad, type ThinkingMessage as ae, type TokenDeltaUpdate as af, type TokenUsage as ag, type ToolCall as ah, type ToolCallCompletedUpdate as ai, type ToolCallStartedUpdate as aj, type ToolResult as ak, type ToolResultGuardOptions as al, type ToolUseBlock as am, type TurnEndedUpdate as an, type UserMessage as ao, type UserMessageAppendedUpdate as ap, emitRunEvent as aq, type Run as b, type MessageOrigin as c, type AssistantMessage as d, type ConversationStep as e, type ConversationTurn as f, type CostBreakdown as g, type CostSource as h, type CostStatus as i, type GenerateRunResult as j, type InteractionUpdate as k, type McpAuthConfig as l, type McpHttpServerConfig as m, type McpOAuthConfig as n, type McpStdioServerConfig as o, type ModelParameterValue as p, type RunCompactBoundaryEvent as q, type RunErrorDetail as r, type RunEvent as s, type RunEventSink as t, type RunGitInfo as u, type RunOperation as v, type RunPermissionDeniedEvent as w, type RunRateLimitEvent as x, type RunStatus as y, type RunTaskCompletedEvent as z };
@@ -12,7 +12,8 @@ export interface StreamObjectOptions<T extends ZodType> {
12
12
  schema: T;
13
13
  prompt: string;
14
14
  systemPrompt?: string;
15
- model: ModelSelection;
15
+ /** SE8 — accepts a bare-string id shorthand or a {@link ModelSelection}. */
16
+ model: string | ModelSelection;
16
17
  apiKey?: string;
17
18
  local: LocalOptions;
18
19
  maxRetries?: number;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * SE7 — `ToolError`: thrown FROM a tool `handler` to report a failure back to
3
+ * the model with structured content (text and/or an image), not just a string.
4
+ * Kept in its own module (not `errors.ts`) so the error taxonomy file stays
5
+ * under the G8 LoC budget and this tool-shaped error lives next to the tool
6
+ * surface it serves.
7
+ *
8
+ * @public
9
+ */
10
+ import { type ErrorMetadata, TheokitAgentError } from "./errors.js";
11
+ import type { ToolResultContentBlock } from "./types/content-blocks.js";
12
+ /**
13
+ * Thrown from a tool `handler` to surface a failure to the model. The SDK turns
14
+ * it into a `tool_result` with `isError: true` carrying the content. A plain
15
+ * `Error` thrown from a handler still works (its message becomes text);
16
+ * `ToolError` is the opt-in for a clean message or a multimodal error (e.g. an
17
+ * error screenshot).
18
+ *
19
+ * @public
20
+ */
21
+ export declare class ToolError extends TheokitAgentError {
22
+ readonly name: string;
23
+ /** The error content surfaced to the model: a string, or text/image blocks. */
24
+ readonly content: string | ToolResultContentBlock[];
25
+ constructor(content: string | ToolResultContentBlock[], options?: {
26
+ code?: string;
27
+ cause?: unknown;
28
+ metadata?: ErrorMetadata;
29
+ });
30
+ }
@@ -53,16 +53,18 @@ export interface CustomTool {
53
53
  inputSchema: Record<string, unknown>;
54
54
  /**
55
55
  * Local handler invoked when the model emits `tool_use` for this tool.
56
- * Returns a string (becomes the `tool_result.content` surfaced back to the
57
- * model). Throws SDK converts to `tool_result` with `isError: true` and
58
- * the error `message` as content. #65 an optional 2nd `ToolContext`
59
- * argument carries the run's `AbortSignal`; single-argument handlers are
60
- * unaffected. M7the same `ctx` also carries an optional user `context`
61
- * (provided once via `SendOptions.context`), so shared config like a
62
- * `projectRoot` is read by every tool instead of baked into each factory.
56
+ * Returns a string OR structured content blocks (SE7 text + image, e.g. a
57
+ * screenshot) that become the `tool_result.content` surfaced back to the
58
+ * model. Throws SDK converts to `tool_result` with `isError: true` and the
59
+ * error `message` as content; throw a `ToolError` to carry a clean message or
60
+ * multimodal error content. #65 — an optional 2nd `ToolContext` argument
61
+ * carries the run's `AbortSignal`; single-argument handlers are unaffected. M7
62
+ * — the same `ctx` also carries an optional user `context` (provided once via
63
+ * `SendOptions.context`), so shared config like a `projectRoot` is read by
64
+ * every tool instead of baked into each factory.
63
65
  */
64
66
  handler: (input: Record<string, unknown>, ctx?: {
65
67
  signal?: AbortSignal;
66
68
  context?: unknown;
67
- }) => string | Promise<string>;
69
+ }) => string | import("./content-blocks.js").ToolResultContentBlock[] | Promise<string | import("./content-blocks.js").ToolResultContentBlock[]>;
68
70
  }
@@ -284,7 +284,12 @@ export interface TelemetrySettings {
284
284
  * @public
285
285
  */
286
286
  export interface AgentOptions {
287
- model?: ModelSelection;
287
+ /**
288
+ * The model to run. SE8 — accepts a bare-string id shorthand
289
+ * (`"openai/gpt-4o-mini"`, normalized to `{ id }`) OR a {@link ModelSelection}
290
+ * object (use the object form to pass `params`).
291
+ */
292
+ model?: string | ModelSelection;
288
293
  /** Falls back to `THEOKIT_API_KEY`. */
289
294
  apiKey?: string;
290
295
  name?: string;
@@ -576,6 +581,12 @@ export interface SDKAgent {
576
581
  */
577
582
  readonly plugins?: SDKAgentPlugins;
578
583
  send(message: string | SDKUserMessage, options?: SendOptions): Promise<Run>;
584
+ /**
585
+ * SE9 — integrated structured output. Runs the normal tool loop (the tools run
586
+ * first) then coerces the final answer into the `output` Zod schema, returning a
587
+ * validated, inferred-typed object. Sugar over `Agent.generateObject` (ADR D33).
588
+ */
589
+ generate<T extends import("zod").ZodType>(message: string | SDKUserMessage, options: import("./run.js").GenerateOptions<T>): Promise<import("./run.js").GenerateRunResult<import("zod").z.infer<T>>>;
579
590
  /** Fire-and-forget disposal. */
580
591
  close(): void;
581
592
  /** Re-read filesystem config (context, hooks, project MCP, subagents) without disposing. */
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Leaf module for content-block types shared by `messages.ts` (assistant/user
3
+ * content) and `agent-prims.ts` (`CustomTool` handler results). Kept
4
+ * import-free so both can depend on it WITHOUT the `agent-prims ↔ messages`
5
+ * cycle (#7).
6
+ *
7
+ * @public
8
+ */
9
+ /**
10
+ * Plain text content block emitted by the assistant or user, or returned by a
11
+ * tool.
12
+ *
13
+ * @public
14
+ */
15
+ export interface TextBlock {
16
+ type: "text";
17
+ text: string;
18
+ }
19
+ /**
20
+ * SE7 — a base64-encoded image block a tool can hand back as (part of) its
21
+ * result or its `ToolError`. `media_type` is a MIME type (e.g. `"image/png"`);
22
+ * `data` is the base64 payload without a data-URL prefix.
23
+ *
24
+ * Note: when a tool builds this from model- or user-influenced input, treat
25
+ * `media_type` as UNTRUSTED — validate/allow-list it before rendering it in a
26
+ * log or UI (it could carry newlines / control chars). The SDK only forwards it
27
+ * (JSON-serialized onto the wire) and never executes or path-joins it.
28
+ *
29
+ * @public
30
+ */
31
+ export interface ImageBlock {
32
+ type: "image";
33
+ source: {
34
+ type: "base64";
35
+ media_type: string;
36
+ data: string;
37
+ };
38
+ }
39
+ /**
40
+ * SE7 — structured content a tool result may carry: text and/or images. A tool
41
+ * `handler` may return this (success) and a `ToolError` may carry it (failure).
42
+ * Block-capable provider wires forward it natively; string-only provider wires
43
+ * flatten text and fail fast on an image.
44
+ *
45
+ * @public
46
+ */
47
+ export type ToolResultContentBlock = TextBlock | ImageBlock;
@@ -31,6 +31,31 @@ export interface StoredMessage {
31
31
  /** Optional epoch-ms timestamp. Implementations MAY default to `Date.now()` on append. */
32
32
  at?: number;
33
33
  }
34
+ /**
35
+ * SE4 — light, session-level metadata stored ALONGSIDE the transcript (title +
36
+ * tag). Distinct from {@link StoredMessage} (which is per-turn content): this is
37
+ * per-conversation display metadata a host sets to build a session UI.
38
+ *
39
+ * @public
40
+ */
41
+ export interface SessionMeta {
42
+ /** Human-facing title set via `renameSession`. Absent = untitled. */
43
+ readonly title?: string;
44
+ /** Single free-form tag set via `tagSession`. Absent = untagged. */
45
+ readonly tag?: string;
46
+ }
47
+ /**
48
+ * SE4 — a partial update to {@link SessionMeta}. An omitted field is left
49
+ * unchanged; `tag: null` explicitly CLEARS the tag (distinct from omitting it).
50
+ *
51
+ * @public
52
+ */
53
+ export interface SessionMetaPatch {
54
+ /** Set the title; `null` explicitly CLEARS it (distinct from omitting it). */
55
+ readonly title?: string | null;
56
+ /** Set the tag; `null` explicitly CLEARS it (distinct from omitting it). */
57
+ readonly tag?: string | null;
58
+ }
34
59
  /**
35
60
  * Pluggable conversation persistence contract.
36
61
  *
@@ -102,6 +127,19 @@ export interface ConversationStorageAdapter {
102
127
  * trims old turns past a soft cap; other backends typically no-op.
103
128
  */
104
129
  compact?(conversationId: string, maxTurns: number): Promise<void>;
130
+ /**
131
+ * SE4 — optional: read the session-level metadata (title/tag) for a
132
+ * conversation. MUST return `undefined` when none was set (NOT throw).
133
+ * Adapters that cannot store side metadata MAY omit this — the session
134
+ * manager then reports rename/tag as unsupported rather than throwing.
135
+ */
136
+ getSessionMeta?(conversationId: string): Promise<SessionMeta | undefined>;
137
+ /**
138
+ * SE4 — optional: apply a {@link SessionMetaPatch} to a conversation's
139
+ * session metadata (set title, set/clear tag). MUST create the metadata
140
+ * lazily. Adapters that cannot store side metadata MAY omit this.
141
+ */
142
+ setSessionMeta?(conversationId: string, patch: SessionMetaPatch): Promise<void>;
105
143
  /**
106
144
  * Optional: dispose underlying handles (close DB pool, etc.).
107
145
  * MUST be safe to call multiple times.
@@ -11,6 +11,7 @@ export type * from "./memory-adapter.js";
11
11
  export type * from "./messages.js";
12
12
  export type * from "./providers.js";
13
13
  export type * from "./run.js";
14
+ export type * from "./session.js";
14
15
  export type * from "./task.js";
15
16
  export type * from "./theokit.js";
16
17
  export type * from "./trajectory.js";
@@ -1,13 +1,6 @@
1
1
  import type { ModelSelection } from "./agent-prims.js";
2
- /**
3
- * Plain text content block emitted by the assistant or user.
4
- *
5
- * @public
6
- */
7
- export interface TextBlock {
8
- type: "text";
9
- text: string;
10
- }
2
+ import type { TextBlock } from "./content-blocks.js";
3
+ export type { ImageBlock, TextBlock, ToolResultContentBlock } from "./content-blocks.js";
11
4
  /**
12
5
  * Tool invocation block emitted by the assistant.
13
6
  *
@@ -0,0 +1,84 @@
1
+ /**
2
+ * SE2 — typed runtime EVENT stream, ADDITIVE to the `SDKMessage` content stream.
3
+ *
4
+ * `Run.stream()` yields `SDKMessage`s (the conversation content). `RunEvent`s are
5
+ * out-of-band runtime-OBSERVABILITY signals — the model's content is unaffected —
6
+ * delivered opt-in via `SendOptions.onRunEvent`. Discriminate on `type`. Mirrors
7
+ * the Anthropic `SDKMessage`-union approach (rate-limit, permission-denied, task
8
+ * lifecycle, compaction boundary).
9
+ *
10
+ * The union is the forward-compatible CONTRACT (discriminate exhaustively). As of
11
+ * SE2 the runtime EMITS `tool_progress` and `permission_denied` end-to-end (from
12
+ * the agent-loop tool-dispatch seam). `rate_limit`, `task_*`, and `compact_boundary`
13
+ * are part of the contract; their emission is wired incrementally as the sink is
14
+ * threaded into the LLM-client retry / task / session-compaction subsystems (they
15
+ * live below the loop). A consumer switching on `type` is future-proof either way.
16
+ *
17
+ * @public
18
+ */
19
+ export type RunEvent = RunToolProgressEvent | RunRateLimitEvent | RunPermissionDeniedEvent | RunTaskStartedEvent | RunTaskUpdatedEvent | RunTaskCompletedEvent | RunCompactBoundaryEvent;
20
+ /** A tool call is being dispatched (before its result). */
21
+ export interface RunToolProgressEvent {
22
+ readonly type: "tool_progress";
23
+ readonly toolName: string;
24
+ readonly toolCallId: string;
25
+ }
26
+ /** The provider returned a rate-limit (HTTP 429); the loop will back off + retry. */
27
+ export interface RunRateLimitEvent {
28
+ readonly type: "rate_limit";
29
+ /** Retry attempt number (1-based) about to be delayed. */
30
+ readonly attempt: number;
31
+ /** Delay in ms before the retry, when the provider/policy supplied one. */
32
+ readonly retryAfterMs?: number;
33
+ }
34
+ /**
35
+ * A tool call was DENIED before dispatch — by the permission gate/plugin (SE1),
36
+ * an operator file-hook `preToolUse`, or the fork tool-whitelist. `source`
37
+ * discriminates which. `toolCallId` joins the event to the tool-call log.
38
+ */
39
+ export interface RunPermissionDeniedEvent {
40
+ readonly type: "permission_denied";
41
+ readonly toolName: string;
42
+ readonly toolCallId: string;
43
+ /** Which layer blocked the call. */
44
+ readonly source: "plugin" | "file_hook" | "fork_whitelist";
45
+ /** The rejection message surfaced to the model. */
46
+ readonly message: string;
47
+ }
48
+ /** A background task/subagent started. */
49
+ export interface RunTaskStartedEvent {
50
+ readonly type: "task_started";
51
+ readonly taskId: string;
52
+ readonly description?: string;
53
+ }
54
+ /** A background task/subagent changed state. */
55
+ export interface RunTaskUpdatedEvent {
56
+ readonly type: "task_updated";
57
+ readonly taskId: string;
58
+ readonly status: string;
59
+ }
60
+ /** A background task/subagent finished. */
61
+ export interface RunTaskCompletedEvent {
62
+ readonly type: "task_completed";
63
+ readonly taskId: string;
64
+ readonly status: "completed" | "failed" | "stopped";
65
+ }
66
+ /** The conversation crossed a compaction boundary (history was summarized). */
67
+ export interface RunCompactBoundaryEvent {
68
+ readonly type: "compact_boundary";
69
+ readonly trigger: "manual" | "auto";
70
+ /** Token count before compaction, when known. */
71
+ readonly preTokens?: number;
72
+ }
73
+ /**
74
+ * SE2 — the opt-in sink for {@link RunEvent}s. Supplied via `SendOptions.onRunEvent`.
75
+ * Synchronous + best-effort: a throwing sink must never break the run (the emitter
76
+ * try-catches it), so keep it fast (push to a queue, don't await).
77
+ */
78
+ export type RunEventSink = (event: RunEvent) => void;
79
+ /**
80
+ * SE2 — emit a {@link RunEvent} to an optional sink, swallowing any sink error so
81
+ * observability can never break the run (fail-safe, mirrors the EventBus EC-2
82
+ * contract). No-op when the sink is absent.
83
+ */
84
+ export declare function emitRunEvent(sink: RunEventSink | undefined, event: RunEvent): void;