@theokit/sdk 4.19.1 → 4.19.2
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-Bhdyjl0B.d.ts +2582 -0
- package/dist/cron-M2Xz7lq2.d.cts +2582 -0
- package/dist/cron.cjs +40 -20
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.d.cts +3 -0
- package/dist/cron.d.ts +3 -0
- package/dist/cron.js +40 -20
- package/dist/cron.js.map +1 -1
- package/dist/errors-CG2RpeW-.d.ts +516 -0
- package/dist/errors-gE8612p9.d.cts +516 -0
- package/dist/errors.d.cts +3 -0
- package/dist/eval.cjs +40 -20
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +40 -20
- package/dist/eval.js.map +1 -1
- package/dist/goal-loop.d.ts +35 -0
- package/dist/index.cjs +160 -142
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2309 -0
- package/dist/index.d.ts +2309 -0
- package/dist/index.js +160 -142
- package/dist/index.js.map +1 -1
- package/dist/internal/persistence/index.cjs +3 -1
- package/dist/internal/persistence/index.cjs.map +1 -1
- package/dist/internal/persistence/index.js +3 -1
- package/dist/internal/persistence/index.js.map +1 -1
- package/dist/internal/runtime/lifecycle/run-until.d.ts +1 -1
- package/dist/persistence.cjs +3 -1
- package/dist/persistence.cjs.map +1 -1
- package/dist/persistence.js +3 -1
- package/dist/persistence.js.map +1 -1
- package/dist/provider-catalog.json +1295 -0
- package/dist/run-DFM1H2jW.d.cts +1589 -0
- package/dist/run-DFM1H2jW.d.ts +1589 -0
- package/package.json +1 -1
|
@@ -0,0 +1,2582 @@
|
|
|
1
|
+
import * as zod from 'zod';
|
|
2
|
+
import { ZodType } from 'zod';
|
|
3
|
+
import { M as ModelSelection, ac as SDKUserMessage, ae as SendOptions, b as Run, G as GenerateOptions, n as GenerateRunResult, _ as RunToCompletionOptions, $ as RunToCompletionResult, S as SDKMessage, al as StreamToCompletionResult, C as CustomTool, c as PermissionMode, a as McpServerConfig, P as Processor, u as MessageOrigin } from './run-DFM1H2jW.cjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* `SessionRecord` — the native on-disk transcript record shape (SE40).
|
|
7
|
+
*
|
|
8
|
+
* The theokit session format IS the Claude Code record shape: a
|
|
9
|
+
* `uuid`/`parentUuid` DAG of records with structured
|
|
10
|
+
* `text`/`tool_use`/`tool_result`/`thinking` blocks. This is the contract the
|
|
11
|
+
* pluggable {@link SessionStore} seam operates over.
|
|
12
|
+
*
|
|
13
|
+
* DIP-correct home (SE46): the contract lives in the domain `types/` layer;
|
|
14
|
+
* the application-layer DAG core (`internal/persistence/session-transcript.ts`)
|
|
15
|
+
* re-exports it for back-compat while owning the record builders + reader.
|
|
16
|
+
*
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
/** One transcript record (one JSONL line). `message` absent on `system` (compact_boundary) records. */
|
|
20
|
+
interface SessionRecord {
|
|
21
|
+
type: "user" | "assistant" | "system";
|
|
22
|
+
uuid: string;
|
|
23
|
+
parentUuid: string | null;
|
|
24
|
+
sessionId: string;
|
|
25
|
+
timestamp: string;
|
|
26
|
+
isSidechain?: boolean;
|
|
27
|
+
userType?: string;
|
|
28
|
+
cwd?: string;
|
|
29
|
+
version?: string;
|
|
30
|
+
subtype?: string;
|
|
31
|
+
compactMetadata?: {
|
|
32
|
+
preTokens: number;
|
|
33
|
+
trigger: string;
|
|
34
|
+
};
|
|
35
|
+
message?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* SE41 — the pluggable `SessionStore` seam over the NATIVE session transcript.
|
|
40
|
+
*
|
|
41
|
+
* A minimal, two-method port so an external store (Postgres / Redis / KV /
|
|
42
|
+
* durable object) can be the **primary store AND resume source** — the
|
|
43
|
+
* serverless (ephemeral FS) and multi-host / multi-pod use case that SE40
|
|
44
|
+
* dropped when it removed the `ConversationStorageAdapter`. This is deliberately
|
|
45
|
+
* NOT that removed ~10-method adapter: the seam is JUST record read/append over
|
|
46
|
+
* the native {@link SessionRecord} shape (no getMessages / getSessionMeta /
|
|
47
|
+
* delete / objective methods).
|
|
48
|
+
*
|
|
49
|
+
* The SDK ships a real default implementation, `FsSessionStore`, that reads and
|
|
50
|
+
* append-writes the native Claude-shaped `.jsonl` transcript — omitting
|
|
51
|
+
* `local.sessionStore` yields byte-identical current behavior (back-compat, zero
|
|
52
|
+
* consumer change). Injected via `local.sessionStore` for external stores.
|
|
53
|
+
*
|
|
54
|
+
* Consistency contract: `appendRecords` is append-only and ordering-preserving.
|
|
55
|
+
* The FS default serializes appends per agent with a cross-process file lock;
|
|
56
|
+
* external implementations own (and MUST document) their own concurrency
|
|
57
|
+
* guarantees for two hosts appending to the same `agentId`.
|
|
58
|
+
*
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The pluggable session-store seam. Exactly two methods over the native
|
|
64
|
+
* {@link SessionRecord} shape.
|
|
65
|
+
*
|
|
66
|
+
* @public
|
|
67
|
+
*/
|
|
68
|
+
interface SessionStore {
|
|
69
|
+
/**
|
|
70
|
+
* Return every persisted record for `agentId`, in append order. A session
|
|
71
|
+
* that was never written MUST resolve to `[]` (not throw) — a fresh agent has
|
|
72
|
+
* no history. The SDK reconstructs the resumable `LlmMessage[]` from these
|
|
73
|
+
* records via the native DAG reader, so the shape MUST be the exact
|
|
74
|
+
* {@link SessionRecord} the SDK writes.
|
|
75
|
+
*
|
|
76
|
+
* A store that cannot READ (e.g. the backing DB is unreachable on resume)
|
|
77
|
+
* MUST throw a typed error rather than silently returning `[]` — a silent
|
|
78
|
+
* empty read would masquerade as "no history" and drop the conversation.
|
|
79
|
+
*/
|
|
80
|
+
readRecords(agentId: string): Promise<SessionRecord[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Append `records` (the new-turn delta) to `agentId`'s session, append-only.
|
|
83
|
+
* MUST preserve order and MUST NOT drop or rewrite prior records — the native
|
|
84
|
+
* format is an append-only `parentUuid` DAG (compaction is a new-root
|
|
85
|
+
* `compact_boundary` record, still an append).
|
|
86
|
+
*
|
|
87
|
+
* Note on the write path: per-turn persistence is fire-and-forget so `send()`
|
|
88
|
+
* is never blocked by store I/O — an `appendRecords` rejection is logged to
|
|
89
|
+
* stderr, NOT thrown to the caller (best-effort write). An external store that
|
|
90
|
+
* must guarantee durability should make `appendRecords` resilient (retry /
|
|
91
|
+
* durable write) internally. This differs from {@link SessionStore.readRecords},
|
|
92
|
+
* which MUST throw on failure (a resume cannot proceed on a silent partial history).
|
|
93
|
+
*/
|
|
94
|
+
appendRecords(agentId: string, records: readonly SessionRecord[]): Promise<void>;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Public `MemoryAdapter` contract (T1.1, ADRs D141 / D147).
|
|
99
|
+
*
|
|
100
|
+
* The plugin extension point `{ kind: "memory" }` (ADR D98) declares a
|
|
101
|
+
* `createProvider` factory; this file types its return value formally.
|
|
102
|
+
* Adapters implement `write` / `recall` / `delete` plus optional methods
|
|
103
|
+
* gated by `capabilities`. `MemoryId` is a branded string prefixed with
|
|
104
|
+
* the adapter id so cross-adapter use throws on `extractRawId` (EC-B).
|
|
105
|
+
*
|
|
106
|
+
* Each provider-specific package (`@theokit-memory-supermemory`, etc)
|
|
107
|
+
* exports a factory returning a `Plugin { kind: "memory" }` whose
|
|
108
|
+
* `createProvider` resolves to a `MemoryAdapter` instance.
|
|
109
|
+
*
|
|
110
|
+
* @public
|
|
111
|
+
*/
|
|
112
|
+
/**
|
|
113
|
+
* Branded provider memory ID. Format: `${adapterId}:${rawProviderId}`.
|
|
114
|
+
* Use `mkMemoryId` / `extractRawId` from `../memory-adapter-helpers.js`
|
|
115
|
+
* to construct and unwrap with cross-adapter safety (EC-B).
|
|
116
|
+
*
|
|
117
|
+
* @public
|
|
118
|
+
*/
|
|
119
|
+
type MemoryId = string & {
|
|
120
|
+
readonly __brand: "MemoryId";
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Portable identity context. `userId` is the only required field —
|
|
124
|
+
* the lowest common denominator across Supermemory / Honcho / Mem0.
|
|
125
|
+
* Adapter implementations translate the optional fields to their
|
|
126
|
+
* provider's native primitives (Honcho session, Mem0 run_id, etc).
|
|
127
|
+
*
|
|
128
|
+
* @public
|
|
129
|
+
*/
|
|
130
|
+
interface MemoryContext {
|
|
131
|
+
/** End-user identity. */
|
|
132
|
+
userId: string;
|
|
133
|
+
/** Agent / persona writing the memory. */
|
|
134
|
+
agentId?: string;
|
|
135
|
+
/** Logical conversation / run boundary. */
|
|
136
|
+
sessionId?: string;
|
|
137
|
+
/** Tenant / workspace partition. */
|
|
138
|
+
tenantId?: string;
|
|
139
|
+
/** Free-form tags for filtering / categorization. */
|
|
140
|
+
tags?: string[];
|
|
141
|
+
/** Provider-passthrough metadata. */
|
|
142
|
+
metadata?: Record<string, unknown>;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* A single memory fact returned by `recall` or `get`.
|
|
146
|
+
*
|
|
147
|
+
* @public
|
|
148
|
+
*/
|
|
149
|
+
interface MemoryFact {
|
|
150
|
+
id: MemoryId;
|
|
151
|
+
content: string;
|
|
152
|
+
/** Semantic relevance score (provider-defined scale) when result of `recall`. */
|
|
153
|
+
score?: number;
|
|
154
|
+
/** ISO 8601 timestamp of creation. */
|
|
155
|
+
createdAt?: string;
|
|
156
|
+
metadata?: Record<string, unknown>;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Versioned snapshot of a memory's history. Only emitted by providers
|
|
160
|
+
* with `capabilities.history === true` (Mem0 today).
|
|
161
|
+
*
|
|
162
|
+
* @public
|
|
163
|
+
*/
|
|
164
|
+
interface MemoryRevision {
|
|
165
|
+
id: MemoryId;
|
|
166
|
+
content: string;
|
|
167
|
+
version: number;
|
|
168
|
+
changedAt: string;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Statically declared adapter feature flags. Consumers feature-detect
|
|
172
|
+
* at compile time via `if (adapter.capabilities.history)`.
|
|
173
|
+
*
|
|
174
|
+
* @public
|
|
175
|
+
*/
|
|
176
|
+
interface MemoryAdapterCapabilities {
|
|
177
|
+
/** Returns prior versions of a memory via `history(id)`. */
|
|
178
|
+
history: boolean;
|
|
179
|
+
/** First-class `sessionId` scoping. */
|
|
180
|
+
sessions: boolean;
|
|
181
|
+
/** First-class `tenantId` scoping. */
|
|
182
|
+
tenancy: boolean;
|
|
183
|
+
/** Provider performs reasoning over memory (e.g., Honcho dialectic). */
|
|
184
|
+
reasoning: boolean;
|
|
185
|
+
/** Exposes LLM-callable function-calling schemas. */
|
|
186
|
+
toolSchemas: boolean;
|
|
187
|
+
/** Supports background prefetch (currently informational). */
|
|
188
|
+
prefetch: boolean;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* One assistant-turn message in the canonical `{role, content}` shape
|
|
192
|
+
* an adapter may receive instead of a flat string when writing a turn.
|
|
193
|
+
*
|
|
194
|
+
* @public
|
|
195
|
+
*/
|
|
196
|
+
interface MemoryTurnMessage {
|
|
197
|
+
role: "user" | "assistant" | "system";
|
|
198
|
+
content: string;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* OpenAI-format function-calling schema exposed to the LLM.
|
|
202
|
+
*
|
|
203
|
+
* @public
|
|
204
|
+
*/
|
|
205
|
+
interface MemoryToolSchema {
|
|
206
|
+
name: string;
|
|
207
|
+
description: string;
|
|
208
|
+
parameters: Record<string, unknown>;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Portable third-party memory adapter contract. Implementations live
|
|
212
|
+
* in `@theokit-memory-*` packages; the SDK never imports them.
|
|
213
|
+
*
|
|
214
|
+
* @public
|
|
215
|
+
*/
|
|
216
|
+
interface MemoryAdapter {
|
|
217
|
+
/** Short identifier — matches the `${adapterId}` prefix in `MemoryId`. */
|
|
218
|
+
readonly id: string;
|
|
219
|
+
readonly capabilities: MemoryAdapterCapabilities;
|
|
220
|
+
/** Synchronous availability probe — no network, no I/O. */
|
|
221
|
+
isAvailable(): boolean;
|
|
222
|
+
/** One-shot initialization. Idempotent: safe to call multiple times. */
|
|
223
|
+
initialize?(): Promise<void>;
|
|
224
|
+
/**
|
|
225
|
+
* Persist a fact or full turn to memory. Returns the stored
|
|
226
|
+
* `MemoryId`. Throws `MemoryAdapterError(code: "invalid_input")` on
|
|
227
|
+
* empty content or invalid identifiers in `ctx`.
|
|
228
|
+
*/
|
|
229
|
+
write(content: string | MemoryTurnMessage[], ctx: MemoryContext): Promise<MemoryId>;
|
|
230
|
+
/**
|
|
231
|
+
* Semantic recall — top-`k` facts ordered by relevance. Returns
|
|
232
|
+
* empty array when `k === 0` or no matches.
|
|
233
|
+
*/
|
|
234
|
+
recall(query: string, ctx: MemoryContext, k?: number): Promise<MemoryFact[]>;
|
|
235
|
+
/**
|
|
236
|
+
* Delete a memory by id. Throws `MemoryAdapterError(code:
|
|
237
|
+
* "invalid_input")` when the id was minted by a different adapter
|
|
238
|
+
* (EC-B). Throws `code: "not_found"` when the id does not exist.
|
|
239
|
+
*/
|
|
240
|
+
delete(id: MemoryId): Promise<void>;
|
|
241
|
+
list?(ctx: MemoryContext, opts?: {
|
|
242
|
+
cursor?: string;
|
|
243
|
+
limit?: number;
|
|
244
|
+
}): AsyncIterable<MemoryFact>;
|
|
245
|
+
get?(id: MemoryId): Promise<MemoryFact | null>;
|
|
246
|
+
history?(id: MemoryId): Promise<MemoryRevision[]>;
|
|
247
|
+
/** Empty array when `capabilities.toolSchemas === false`. */
|
|
248
|
+
getToolSchemas?(): MemoryToolSchema[];
|
|
249
|
+
handleToolCall?(name: string, args: Record<string, unknown>, ctx: MemoryContext): Promise<string>;
|
|
250
|
+
/** Graceful shutdown — flush queues, close connections. */
|
|
251
|
+
shutdown?(): Promise<void>;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Direct memory API exposed on `SDKAgent.memory`. Resolves to whichever
|
|
255
|
+
* memory adapter(s) are registered via `Agent.create({ plugins: [...] })`.
|
|
256
|
+
*
|
|
257
|
+
* @public
|
|
258
|
+
*/
|
|
259
|
+
interface AgentMemory {
|
|
260
|
+
/**
|
|
261
|
+
* Persist a fact. Returns the first adapter's id; in multi-adapter
|
|
262
|
+
* setups all adapters receive the write (fan-out).
|
|
263
|
+
*/
|
|
264
|
+
write(content: string | MemoryTurnMessage[], ctx?: Partial<MemoryContext>): Promise<MemoryId>;
|
|
265
|
+
/** Semantic recall — merged + deduped across registered adapters. */
|
|
266
|
+
recall(query: string, ctx?: Partial<MemoryContext>, k?: number): Promise<MemoryFact[]>;
|
|
267
|
+
/** Delete a memory by id — routes to the owning adapter via prefix. */
|
|
268
|
+
delete(id: MemoryId): Promise<void>;
|
|
269
|
+
/** Returns the first registered adapter or `null` when none exists. */
|
|
270
|
+
adapter(): MemoryAdapter | null;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* A discovered skill's metadata. The skill BODY is never included — only the
|
|
275
|
+
* strict frontmatter fields plus the resolved `source` path.
|
|
276
|
+
*
|
|
277
|
+
* Public via `@theokit/sdk/skills`.
|
|
278
|
+
*
|
|
279
|
+
* @public
|
|
280
|
+
*/
|
|
281
|
+
interface Skill$1 {
|
|
282
|
+
name: string;
|
|
283
|
+
description: string;
|
|
284
|
+
/** Absolute path to the discovered `SKILL.md`. */
|
|
285
|
+
source: string;
|
|
286
|
+
category?: string;
|
|
287
|
+
dependencies?: string[];
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* M22 — `createSkill`: define a skill in TypeScript, without a `SKILL.md` file on disk.
|
|
292
|
+
*
|
|
293
|
+
* An inline skill is usable ALONGSIDE filesystem skills (`AgentOptions.skills.inline`), and points
|
|
294
|
+
* an agent at code-defined capabilities without a `.theokit/skills/<name>/SKILL.md`. Like file
|
|
295
|
+
* skills, its `name` + `description` surface in the `<skills>` system-prompt block; its
|
|
296
|
+
* `instructions` (the body) travel on the object for the consumer (the SDK injects name+description,
|
|
297
|
+
* not bodies — inline and file skills are symmetric there). Inline skills override file skills on a
|
|
298
|
+
* name conflict (mirrors the subagents-loader precedent).
|
|
299
|
+
*/
|
|
300
|
+
|
|
301
|
+
/** A code-defined skill (from {@link createSkill}) — a {@link Skill} plus its inline body. */
|
|
302
|
+
interface InlineSkill extends Skill$1 {
|
|
303
|
+
/** The skill body/instructions (inline skills carry it here instead of a SKILL.md file). */
|
|
304
|
+
instructions: string;
|
|
305
|
+
/**
|
|
306
|
+
* SE21 — supporting documents bundled with the skill (filename → content),
|
|
307
|
+
* mirroring a filesystem skill's `references/` directory. Surfaced to the app
|
|
308
|
+
* via `agent.skills.get(name)`; not injected into the model prompt.
|
|
309
|
+
*/
|
|
310
|
+
references?: Record<string, string>;
|
|
311
|
+
}
|
|
312
|
+
/** Spec accepted by {@link createSkill}. */
|
|
313
|
+
interface CreateSkillSpec {
|
|
314
|
+
name: string;
|
|
315
|
+
description: string;
|
|
316
|
+
instructions: string;
|
|
317
|
+
category?: string;
|
|
318
|
+
dependencies?: string[];
|
|
319
|
+
/** SE21 — supporting documents (filename → content), like a filesystem skill's `references/`. */
|
|
320
|
+
references?: Record<string, string>;
|
|
321
|
+
}
|
|
322
|
+
/** SE36 — `Skill.create` replaces `createSkill` (ADR 0015). @public */
|
|
323
|
+
declare class Skill {
|
|
324
|
+
private constructor();
|
|
325
|
+
static create(spec: CreateSkillSpec): InlineSkill;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* `BudgetTracker` — runtime contract for budget/usage tracking in the
|
|
330
|
+
* agent loop (SDK 2.0 Phase 2 / T2.1 — ADR D1 interface inversion).
|
|
331
|
+
*
|
|
332
|
+
* This interface is the FOUNDATION for the eventual extraction of the
|
|
333
|
+
* Budget subsystem to `@theokit/sdk-budget`. The kernel depends on this
|
|
334
|
+
* contract (not on `UsageAccumulator` / `IterationBudget` concrete classes)
|
|
335
|
+
* so the implementation can move to a separate package without circular
|
|
336
|
+
* imports.
|
|
337
|
+
*
|
|
338
|
+
* DIP-correct home (SE46): the contract types live in the domain `types/`
|
|
339
|
+
* layer; the application-layer implementation
|
|
340
|
+
* (`internal/budget/tracker/budget-tracker.ts`) re-exports them for
|
|
341
|
+
* back-compat while owning the concrete trackers.
|
|
342
|
+
*
|
|
343
|
+
* @public — surface-level interface; impl is internal-but-replaceable.
|
|
344
|
+
*/
|
|
345
|
+
/** Single usage event recorded during one LLM call. */
|
|
346
|
+
interface BudgetUsageEvent {
|
|
347
|
+
/** Token count for this event. */
|
|
348
|
+
readonly tokens: number;
|
|
349
|
+
/** Provider/model identifier (e.g., `"openai/gpt-4o-mini"`). */
|
|
350
|
+
readonly model: string;
|
|
351
|
+
/** Whether this is an input (prompt) or output (completion) measurement. */
|
|
352
|
+
readonly type: "input" | "output";
|
|
353
|
+
/** Optional ISO 8601 timestamp; defaults to now() if omitted. */
|
|
354
|
+
readonly at?: string;
|
|
355
|
+
}
|
|
356
|
+
/** Decision the tracker returns on each iteration / pre-flight check. */
|
|
357
|
+
interface BudgetCheck {
|
|
358
|
+
/** Whether the agent loop is allowed to proceed. */
|
|
359
|
+
readonly allowed: boolean;
|
|
360
|
+
/**
|
|
361
|
+
* When `allowed` is false, names the reason in a stable, codemod-friendly
|
|
362
|
+
* form. Consumers map this to retry / surface to user / abort behavior.
|
|
363
|
+
*/
|
|
364
|
+
readonly reason?: "budget_exceeded" | "iteration_limit" | "cost_limit" | "token_limit" | "custom";
|
|
365
|
+
/** Free-form details for logs / diagnostics. */
|
|
366
|
+
readonly detail?: string;
|
|
367
|
+
}
|
|
368
|
+
/** Aggregate snapshot of usage so far. */
|
|
369
|
+
interface BudgetTotal {
|
|
370
|
+
/** Sum of all input + output tokens. */
|
|
371
|
+
readonly tokens: number;
|
|
372
|
+
/** USD cost when pricing data is available; `undefined` otherwise. */
|
|
373
|
+
readonly costUsd?: number;
|
|
374
|
+
/** Iteration count if the impl tracks it. */
|
|
375
|
+
readonly iterations?: number;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* The kernel-facing contract. Implementations live OUTSIDE the agent loop
|
|
379
|
+
* (in `@theokit/sdk-budget` after Phase 2 / in `internal/budget/` until then).
|
|
380
|
+
*
|
|
381
|
+
* Implementations MUST be:
|
|
382
|
+
* - **Synchronous** — every method returns a value, never a Promise.
|
|
383
|
+
* `track()` is on the hot path (called on every iteration); async would
|
|
384
|
+
* bloat the loop with floating promises and force every call site to
|
|
385
|
+
* await.
|
|
386
|
+
* - **Non-throwing in track()** — record-only semantics. Validation
|
|
387
|
+
* failures bubble up via `check()` instead.
|
|
388
|
+
*/
|
|
389
|
+
interface BudgetTracker {
|
|
390
|
+
/** Record a single usage event. MUST be synchronous and non-throwing. */
|
|
391
|
+
track(event: BudgetUsageEvent): void;
|
|
392
|
+
/** Pre-flight check before the next iteration. */
|
|
393
|
+
check(): BudgetCheck;
|
|
394
|
+
/** Snapshot of accumulated totals (for telemetry / final reporting). */
|
|
395
|
+
getTotal(): BudgetTotal;
|
|
396
|
+
/**
|
|
397
|
+
* Advance the iteration counter by one. Called by the agent loop ONCE per
|
|
398
|
+
* completed turn (M1-1) so that trackers which gate on `maxIterations`
|
|
399
|
+
* (e.g. `createCounterBudgetTracker`) actually halt. OPTIONAL: trackers that
|
|
400
|
+
* only gate on tokens/USD omit it and the loop no-ops via optional chaining.
|
|
401
|
+
* MUST be synchronous and non-throwing.
|
|
402
|
+
*/
|
|
403
|
+
nextIteration?(): void;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Context manager backend.
|
|
408
|
+
*
|
|
409
|
+
* - `"file"` — Read `.theokit/context.json` from the workspace (local) or the
|
|
410
|
+
* cloned repo (cloud).
|
|
411
|
+
*
|
|
412
|
+
* @public
|
|
413
|
+
*/
|
|
414
|
+
type ContextManagerKind = "file";
|
|
415
|
+
/**
|
|
416
|
+
* Context configuration accepted by `Agent.create()` via {@link AgentOptions.context}.
|
|
417
|
+
*
|
|
418
|
+
* @public
|
|
419
|
+
*/
|
|
420
|
+
interface ContextSettings {
|
|
421
|
+
/** Which backend reads context. Defaults to `"file"`. */
|
|
422
|
+
manager?: ContextManagerKind;
|
|
423
|
+
/** Hard cap on tokens emitted into the agent's system prompt. */
|
|
424
|
+
maxTokens?: number;
|
|
425
|
+
/**
|
|
426
|
+
* Per-file truncation cap in characters. Default 40_000 (~10k tokens).
|
|
427
|
+
* Larger files are truncated with 70%/20% head/tail + marker (ADR D155).
|
|
428
|
+
*
|
|
429
|
+
* @public
|
|
430
|
+
*/
|
|
431
|
+
maxBytesPerFile?: number;
|
|
432
|
+
/**
|
|
433
|
+
* Aggregate cap across all context files in characters. Default 120_000.
|
|
434
|
+
* When total exceeds this, lower-priority sources are dropped (ADR D155).
|
|
435
|
+
*
|
|
436
|
+
* Note: context snapshot is **refresh-time** (EC-T); modifying context
|
|
437
|
+
* files mid-flight does not auto-update. Call `agent.reload()` to pick
|
|
438
|
+
* up changes.
|
|
439
|
+
*
|
|
440
|
+
* @public
|
|
441
|
+
*/
|
|
442
|
+
maxBytesTotal?: number;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Inclusion state of a single context source in a {@link ContextSnapshot}.
|
|
446
|
+
*
|
|
447
|
+
* @public
|
|
448
|
+
*/
|
|
449
|
+
type ContextSourceStatus = "included" | "excluded" | "summarized";
|
|
450
|
+
/**
|
|
451
|
+
* A single context source resolved by the context manager.
|
|
452
|
+
*
|
|
453
|
+
* @public
|
|
454
|
+
*/
|
|
455
|
+
interface ContextSource {
|
|
456
|
+
/** Stable identifier — usually the filename without extension. */
|
|
457
|
+
name: string;
|
|
458
|
+
/** Path relative to the workspace root, when applicable. */
|
|
459
|
+
path?: string;
|
|
460
|
+
/** Whether the source was included, dropped, or summarized to fit the budget. */
|
|
461
|
+
status: ContextSourceStatus;
|
|
462
|
+
/** Free-text reason when `status !== "included"`. */
|
|
463
|
+
reason?: string;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Token budget used by the context manager for a single agent.
|
|
467
|
+
*
|
|
468
|
+
* @public
|
|
469
|
+
*/
|
|
470
|
+
interface ContextBudget {
|
|
471
|
+
maxTokens?: number;
|
|
472
|
+
/**
|
|
473
|
+
* Either a token count or a list of token strings extracted from source
|
|
474
|
+
* content. Normalized to `<tokens>` in golden comparisons.
|
|
475
|
+
*/
|
|
476
|
+
usedTokens?: number | string[];
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Result of `agent.context.snapshot()`. Public and secret-free by design — safe
|
|
480
|
+
* to log and persist. Raw secrets, local absolute paths, and exact token values
|
|
481
|
+
* are never present.
|
|
482
|
+
*
|
|
483
|
+
* @public
|
|
484
|
+
*/
|
|
485
|
+
interface ContextSnapshot {
|
|
486
|
+
runtime: "local" | "cloud";
|
|
487
|
+
sources: ContextSource[];
|
|
488
|
+
budget?: ContextBudget;
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Public context manager handle exposed as `agent.context`.
|
|
492
|
+
*
|
|
493
|
+
* @public
|
|
494
|
+
*/
|
|
495
|
+
interface SDKContextManager {
|
|
496
|
+
/** Inspect what the context manager actually loaded for the agent. */
|
|
497
|
+
snapshot(): Promise<ContextSnapshot>;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Fork primitive public type contracts (T1.2, ADRs D110-D114).
|
|
502
|
+
*
|
|
503
|
+
* Extracted into a leaf type module (arch-review ADR 0001) so the public
|
|
504
|
+
* `types/agent.ts` barrel can reference `ForkOptions`/`ForkResult` without
|
|
505
|
+
* importing the `internal/runtime/lifecycle/fork-agent.ts` implementation — which in
|
|
506
|
+
* turn imports back from `types/agent.ts`. That mutual reference created a
|
|
507
|
+
* type-only `madge` cycle. These interfaces are self-contained (no SDKAgent
|
|
508
|
+
* / AgentOptions references), so co-locating them here breaks the cycle with
|
|
509
|
+
* no runtime change. `fork-agent.ts` re-exports them for back-compat.
|
|
510
|
+
*/
|
|
511
|
+
/**
|
|
512
|
+
* Caller-supplied fork configuration. See `forkAgentImpl`.
|
|
513
|
+
*
|
|
514
|
+
* @public
|
|
515
|
+
*/
|
|
516
|
+
interface ForkOptions {
|
|
517
|
+
/**
|
|
518
|
+
* Tool subset visible to the fork. Names must match the canonical (post-repair)
|
|
519
|
+
* tool name — typically lowercase. Tools not in this set return a `tool_result`
|
|
520
|
+
* with `"Tool blocked by fork whitelist"` content (EC-H).
|
|
521
|
+
*/
|
|
522
|
+
allowedTools: Set<string>;
|
|
523
|
+
/** Task prompt sent to the fork. */
|
|
524
|
+
prompt: string;
|
|
525
|
+
/** Override system prompt. Default: byte-identical inheritance from parent (D112). */
|
|
526
|
+
systemPrompt?: string;
|
|
527
|
+
/** Memory write provenance tag (D114). Default `"fork"`. */
|
|
528
|
+
forkOrigin?: string;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Outcome of a fork run.
|
|
532
|
+
*
|
|
533
|
+
* @public
|
|
534
|
+
*/
|
|
535
|
+
interface ForkResult {
|
|
536
|
+
/** Final agent response text (`undefined` when the fork produced no result). */
|
|
537
|
+
result: string | undefined;
|
|
538
|
+
/** Tool calls executed inside the fork. */
|
|
539
|
+
toolCalls: ReadonlyArray<{
|
|
540
|
+
name: string;
|
|
541
|
+
input: Record<string, unknown>;
|
|
542
|
+
}>;
|
|
543
|
+
/** Aggregate token usage reported by the run. */
|
|
544
|
+
usage: {
|
|
545
|
+
inputTokens: number;
|
|
546
|
+
outputTokens: number;
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Public event types emitted by {@link SDKAgent.runUntil} (ADRs D115-D117).
|
|
552
|
+
*
|
|
553
|
+
* Discriminated union by `type` field so consumers can `switch (event.type)`
|
|
554
|
+
* with full TypeScript exhaustiveness. Mirrors the
|
|
555
|
+
* {@link import("../stream-object.js").StreamObjectEvent} pattern (ADR D39).
|
|
556
|
+
*
|
|
557
|
+
* @public
|
|
558
|
+
*/
|
|
559
|
+
/**
|
|
560
|
+
* Single event emitted while iterating a goal-driven loop. Five variants:
|
|
561
|
+
*
|
|
562
|
+
* - `turn_start` — the agent is about to invoke `send()`. Emitted once
|
|
563
|
+
* per turn.
|
|
564
|
+
* - `agent_response` — the agent's `send()` resolved; carries the text
|
|
565
|
+
* reply.
|
|
566
|
+
* - `judge_verdict` — the auxiliary judge model evaluated the response.
|
|
567
|
+
* `parseFailed: true` indicates the judge returned a malformed reply
|
|
568
|
+
* (fail-safe verdict = `continue`, see ADR D121).
|
|
569
|
+
* - `continuation` — the judge ruled `continue`; carries the prompt that
|
|
570
|
+
* was sent on THIS turn (i.e., the input that produced the agent
|
|
571
|
+
* response just yielded). Useful for consumers who want to audit the
|
|
572
|
+
* exact continuation message that drove each iteration. The prompt
|
|
573
|
+
* for the NEXT turn is composed lazily at the start of that turn
|
|
574
|
+
* from the latest `agent_response.content`.
|
|
575
|
+
* - `status_change` — transition of the overall goal state. Always
|
|
576
|
+
* emitted once at start (`active`) and once at end
|
|
577
|
+
* (`completed | failed | paused`).
|
|
578
|
+
*
|
|
579
|
+
* @public
|
|
580
|
+
*/
|
|
581
|
+
type GoalEvent = {
|
|
582
|
+
type: "turn_start";
|
|
583
|
+
turn: number;
|
|
584
|
+
goal: string;
|
|
585
|
+
} | {
|
|
586
|
+
type: "agent_response";
|
|
587
|
+
turn: number;
|
|
588
|
+
content: string;
|
|
589
|
+
} | {
|
|
590
|
+
type: "judge_verdict";
|
|
591
|
+
turn: number;
|
|
592
|
+
verdict: "done" | "continue" | "skipped";
|
|
593
|
+
reason: string;
|
|
594
|
+
parseFailed: boolean;
|
|
595
|
+
} | {
|
|
596
|
+
type: "continuation";
|
|
597
|
+
turn: number;
|
|
598
|
+
prompt: string;
|
|
599
|
+
} | {
|
|
600
|
+
type: "status_change";
|
|
601
|
+
status: "active" | "paused" | "completed" | "failed" | "budget_limited" | "blocked";
|
|
602
|
+
reason: string;
|
|
603
|
+
};
|
|
604
|
+
/**
|
|
605
|
+
* Return value of the `runUntil` async generator. Consumer reads via
|
|
606
|
+
* `const { value } = await gen.next()` (when `done: true`).
|
|
607
|
+
*
|
|
608
|
+
* @public
|
|
609
|
+
*/
|
|
610
|
+
interface GoalResult {
|
|
611
|
+
status: "completed" | "failed" | "paused" | "budget_limited" | "blocked";
|
|
612
|
+
turnsUsed: number;
|
|
613
|
+
/** M55 — tokens somados ao longo do loop (0 quando `usage` esteve ausente — fail-open). */
|
|
614
|
+
tokensUsed: number;
|
|
615
|
+
finalResponse: string | undefined;
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Return type of {@link import("../internal/local-agent/local-agent.js").LocalAgent.runUntil}.
|
|
619
|
+
* Extracted so the LocalAgent method signature stays a single line (G8 LoC budget).
|
|
620
|
+
*
|
|
621
|
+
* @public
|
|
622
|
+
*/
|
|
623
|
+
type RunUntilIterator = AsyncGenerator<GoalEvent, GoalResult, void>;
|
|
624
|
+
/**
|
|
625
|
+
* Per-call configuration for `Agent.runUntil`.
|
|
626
|
+
*
|
|
627
|
+
* @public
|
|
628
|
+
*/
|
|
629
|
+
interface GoalOptions {
|
|
630
|
+
/** Hard cap on iterations (safety net against runaway). Default `20`. */
|
|
631
|
+
maxTurns?: number;
|
|
632
|
+
/**
|
|
633
|
+
* M55 — token budget (Codex ext/goal parity, tool.rs:454-465). Soma `run.wait().usage.totalTokens`
|
|
634
|
+
* por turno; ao cruzar, o loop para com status `budget_limited`. Omitido ⇒ ilimitado (só maxTurns).
|
|
635
|
+
* `usage` ausente nunca estoura o budget (fail-open).
|
|
636
|
+
*/
|
|
637
|
+
tokenBudget?: number;
|
|
638
|
+
/** Bail after N consecutive judge parse failures. Default `3` (ADR D121). */
|
|
639
|
+
maxConsecutiveJudgeFailures?: number;
|
|
640
|
+
/** Judge model identifier. Default `"openai/gpt-4o-mini"` (ADR D119). */
|
|
641
|
+
judgeModel?: string;
|
|
642
|
+
/** Override env for the judge auxiliary agent. Default `OPENROUTER_API_KEY` (EC-A). */
|
|
643
|
+
judgeApiKey?: string;
|
|
644
|
+
/** Optional subgoals fed to the judge prompt. */
|
|
645
|
+
subgoals?: string[];
|
|
646
|
+
/**
|
|
647
|
+
* Cancel mid-loop via `AbortController.signal`. The generator yields
|
|
648
|
+
* a `status_change: paused` event and returns at the next turn
|
|
649
|
+
* boundary (ADR D117).
|
|
650
|
+
*/
|
|
651
|
+
signal?: AbortSignal;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* Capability slot a provider can fulfill.
|
|
656
|
+
*
|
|
657
|
+
* @public
|
|
658
|
+
*/
|
|
659
|
+
type ProviderCapability = "chat" | "web_search" | "image" | "embedding";
|
|
660
|
+
/**
|
|
661
|
+
* A single user-declared routing rule. Maps a capability to a provider, and
|
|
662
|
+
* optionally pins a specific model.
|
|
663
|
+
*
|
|
664
|
+
* @public
|
|
665
|
+
*/
|
|
666
|
+
interface ProviderRoute {
|
|
667
|
+
capability: ProviderCapability;
|
|
668
|
+
provider: string;
|
|
669
|
+
model?: string;
|
|
670
|
+
/**
|
|
671
|
+
* Opt-in leaked-dialect safe-parse for this route's provider (theokit#58
|
|
672
|
+
* follow-up). When `true`, a `chat_completions` finish that carries ZERO
|
|
673
|
+
* native `tool_calls` has its assistant text scanned for the Hermes
|
|
674
|
+
* `<function=…></tool_call>` dialect, and any recovered calls are surfaced as
|
|
675
|
+
* real `tool_calls` so the loop executes them — for models (qwen3-coder via
|
|
676
|
+
* OpenRouter) that intermittently leak tool calls as text. Default `false`;
|
|
677
|
+
* fail-open (a partial/unclosed block never fabricates a call). Scoped to the
|
|
678
|
+
* resolved chat chain, so a non-leaking route is unaffected.
|
|
679
|
+
*/
|
|
680
|
+
extractToolCallsFromContent?: boolean;
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* Provider routing configuration accepted by `Agent.create()` via
|
|
684
|
+
* {@link AgentOptions.providers}.
|
|
685
|
+
*
|
|
686
|
+
* @public
|
|
687
|
+
*/
|
|
688
|
+
interface ProviderRoutingSettings {
|
|
689
|
+
/** Explicit `{ capability → provider }` map. First match wins per capability. */
|
|
690
|
+
routes: ProviderRoute[];
|
|
691
|
+
/** Provider names to try in order when a route has no provider available. */
|
|
692
|
+
fallback?: string[];
|
|
693
|
+
/**
|
|
694
|
+
* Multiple API keys per provider for same-provider key rotation
|
|
695
|
+
* (credential pool — ADRs D123-D133). When a key hits HTTP 429, 402,
|
|
696
|
+
* or 401, the SDK rotates to the next entry transparently before
|
|
697
|
+
* falling back to a different provider.
|
|
698
|
+
*
|
|
699
|
+
* Example:
|
|
700
|
+
* ```ts
|
|
701
|
+
* apiKeys: { openrouter: ["sk-or-...", "sk-or-..."], anthropic: ["..."] }
|
|
702
|
+
* ```
|
|
703
|
+
*
|
|
704
|
+
* Empty arrays and empty strings are filtered out. If a provider has
|
|
705
|
+
* exactly 1 effective key, the pool is transparent (no rotation behavior).
|
|
706
|
+
*
|
|
707
|
+
* Conflicts with the single-key shape `AgentOptions.apiKey: "..."` —
|
|
708
|
+
* use one OR the other, not both.
|
|
709
|
+
*
|
|
710
|
+
* @public
|
|
711
|
+
*/
|
|
712
|
+
apiKeys?: Record<string, string[]>;
|
|
713
|
+
/**
|
|
714
|
+
* Rotation strategy per provider for the credential pool. Default is
|
|
715
|
+
* `"fill_first"` (use entries[0] until exhausted). Only consulted when
|
|
716
|
+
* `apiKeys[provider]` has ≥2 entries.
|
|
717
|
+
*
|
|
718
|
+
* @public
|
|
719
|
+
*/
|
|
720
|
+
credentialPoolStrategy?: Record<string, "fill_first" | "round_robin" | "least_used" | "random">;
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Plugins configuration accepted by `Agent.create()` via
|
|
724
|
+
* {@link AgentOptions.plugins}.
|
|
725
|
+
*
|
|
726
|
+
* @public
|
|
727
|
+
*/
|
|
728
|
+
interface PluginsSettings {
|
|
729
|
+
/** Plugin names to enable. Plugin discovery is plugin-provider specific. */
|
|
730
|
+
enabled?: string[];
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Resolved routing decision returned by `agent.providers.routes()`. Public and
|
|
734
|
+
* secret-free by design — safe to log.
|
|
735
|
+
*
|
|
736
|
+
* @public
|
|
737
|
+
*/
|
|
738
|
+
interface ResolvedProviderRoute {
|
|
739
|
+
capability: string;
|
|
740
|
+
provider: string;
|
|
741
|
+
model?: string;
|
|
742
|
+
/** Why the runtime picked this provider (e.g. `"explicit-model-provider"`). */
|
|
743
|
+
reason: string;
|
|
744
|
+
}
|
|
745
|
+
/**
|
|
746
|
+
* Public providers manager handle exposed as `agent.providers`.
|
|
747
|
+
*
|
|
748
|
+
* @public
|
|
749
|
+
*/
|
|
750
|
+
interface SDKProvidersManager {
|
|
751
|
+
/** Inspect which provider serves each capability for this agent. */
|
|
752
|
+
routes(): Promise<ResolvedProviderRoute[]>;
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* Provider catalog entry returned by `Theokit.providers.list()`.
|
|
756
|
+
*
|
|
757
|
+
* @public
|
|
758
|
+
*/
|
|
759
|
+
interface SDKProvider {
|
|
760
|
+
name: string;
|
|
761
|
+
displayName: string;
|
|
762
|
+
capabilities: string[];
|
|
763
|
+
isAvailable: boolean;
|
|
764
|
+
/** JSON Schema describing the env vars / fields needed to enable this provider. */
|
|
765
|
+
setupSchema: object;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* Public skill metadata exposed to the system-prompt resolver. Mirrors the
|
|
770
|
+
* shape returned by `agent.skills.list()` — name + description only, never
|
|
771
|
+
* full skill bodies.
|
|
772
|
+
*
|
|
773
|
+
* @public
|
|
774
|
+
*/
|
|
775
|
+
interface SystemPromptSkillRef {
|
|
776
|
+
name: string;
|
|
777
|
+
description: string;
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* A skill resolved WITH its body, returned by {@link SDKAgentSkills.get}. Unlike
|
|
781
|
+
* {@link SystemPromptSkillRef} (name + description only), this carries the full
|
|
782
|
+
* `instructions` — read from the SKILL.md for filesystem skills or the inline
|
|
783
|
+
* `createSkill` body. @public
|
|
784
|
+
*/
|
|
785
|
+
interface SDKAgentSkillDetail {
|
|
786
|
+
name: string;
|
|
787
|
+
description: string;
|
|
788
|
+
instructions: string;
|
|
789
|
+
/** SE21 — supporting documents bundled with the skill (filename → content), when present. */
|
|
790
|
+
references?: Record<string, string>;
|
|
791
|
+
}
|
|
792
|
+
interface SDKAgentSkills {
|
|
793
|
+
list(): Promise<ReadonlyArray<SystemPromptSkillRef>>;
|
|
794
|
+
/**
|
|
795
|
+
* SE20 — resolve a skill by name INCLUDING its body (`instructions`). Returns
|
|
796
|
+
* `undefined` when no enabled skill matches. `list()` stays lean (name +
|
|
797
|
+
* description); full bodies come only through `get`.
|
|
798
|
+
*/
|
|
799
|
+
get(name: string): Promise<SDKAgentSkillDetail | undefined>;
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Public plugin metadata returned by `agent.plugins.list()`. Mirrors the
|
|
803
|
+
* `.theokit/plugins/<name>/MANIFEST.json` allow-listed shape; never exposes
|
|
804
|
+
* raw plugin bodies, credentials, or internal hooks.
|
|
805
|
+
*
|
|
806
|
+
* @public
|
|
807
|
+
*/
|
|
808
|
+
interface SDKPluginMetadata {
|
|
809
|
+
name: string;
|
|
810
|
+
description?: string;
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Public plugin listing handle exposed as `agent.plugins`. Populated when
|
|
814
|
+
* `settingSources` includes `"plugins"` OR when `plugins.enabled` is set
|
|
815
|
+
* on the agent options.
|
|
816
|
+
*
|
|
817
|
+
* @public
|
|
818
|
+
*/
|
|
819
|
+
interface SDKAgentPlugins {
|
|
820
|
+
list(): Promise<ReadonlyArray<SDKPluginMetadata>>;
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Artifact produced inside an agent's workspace. Cloud-only.
|
|
824
|
+
*
|
|
825
|
+
* @public
|
|
826
|
+
*/
|
|
827
|
+
interface SDKArtifact {
|
|
828
|
+
path: string;
|
|
829
|
+
sizeBytes: number;
|
|
830
|
+
updatedAt: string;
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Handle returned by `Agent.create()` and `Agent.resume()`.
|
|
834
|
+
*
|
|
835
|
+
* @public
|
|
836
|
+
*/
|
|
837
|
+
interface SDKAgent {
|
|
838
|
+
readonly agentId: string;
|
|
839
|
+
readonly model: ModelSelection | undefined;
|
|
840
|
+
/**
|
|
841
|
+
* Context manager for this agent. Populated when context is enabled via
|
|
842
|
+
* {@link AgentOptions.context}. See {@link SDKContextManager}.
|
|
843
|
+
*/
|
|
844
|
+
readonly context?: SDKContextManager;
|
|
845
|
+
/**
|
|
846
|
+
* Provider routing inspector for this agent. Populated when at least one
|
|
847
|
+
* provider route is configured (via {@link AgentOptions.providers}, plugins,
|
|
848
|
+
* or model-implied providers). See {@link SDKProvidersManager}.
|
|
849
|
+
*/
|
|
850
|
+
readonly providers?: SDKProvidersManager;
|
|
851
|
+
/**
|
|
852
|
+
* Skill listing for this agent. Populated when project-scoped skills are
|
|
853
|
+
* enabled (`settingSources: ["project"]`) or when `skills.enabled` is set.
|
|
854
|
+
* See {@link SDKAgentSkills}.
|
|
855
|
+
*/
|
|
856
|
+
readonly skills?: SDKAgentSkills;
|
|
857
|
+
/**
|
|
858
|
+
* Plugin listing for this agent. Populated when project-scoped plugins are
|
|
859
|
+
* enabled (`settingSources: ["plugins"]`) or when `plugins.enabled` is set.
|
|
860
|
+
* See {@link SDKAgentPlugins}.
|
|
861
|
+
*/
|
|
862
|
+
readonly plugins?: SDKAgentPlugins;
|
|
863
|
+
send(message: string | SDKUserMessage, options?: SendOptions): Promise<Run>;
|
|
864
|
+
/**
|
|
865
|
+
* SE9 — integrated structured output. Runs the normal tool loop (the tools run
|
|
866
|
+
* first) then coerces the final answer into the `output` Zod schema, returning a
|
|
867
|
+
* validated, inferred-typed object. Sugar over `Agent.generateObject` (ADR D33).
|
|
868
|
+
*/
|
|
869
|
+
generate<T extends zod.ZodType>(message: string | SDKUserMessage, options: GenerateOptions<T>): Promise<GenerateRunResult<zod.z.infer<T>>>;
|
|
870
|
+
/** Fire-and-forget disposal. */
|
|
871
|
+
close(): void;
|
|
872
|
+
/** Re-read filesystem config (context, hooks, project MCP, subagents) without disposing. */
|
|
873
|
+
reload(): Promise<void>;
|
|
874
|
+
/**
|
|
875
|
+
* Async disposal. Idempotent — calling more than once is a no-op (per ADR D5).
|
|
876
|
+
* Prefer `await using agent = await Agent.create(...)` over explicit
|
|
877
|
+
* `dispose()` for resource safety.
|
|
878
|
+
*/
|
|
879
|
+
dispose(): Promise<void>;
|
|
880
|
+
/**
|
|
881
|
+
* `await using` support per ADR D5. Identical semantics to `dispose()` —
|
|
882
|
+
* idempotent across both surfaces.
|
|
883
|
+
*/
|
|
884
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
885
|
+
/** Cloud-only. Local returns an empty array. */
|
|
886
|
+
listArtifacts(): Promise<SDKArtifact[]>;
|
|
887
|
+
/** Cloud-only. Local throws `UnsupportedRunOperationError`. */
|
|
888
|
+
downloadArtifact(path: string): Promise<Buffer>;
|
|
889
|
+
/**
|
|
890
|
+
* Signal that prompt cache should be invalidated. By default deferred —
|
|
891
|
+
* applied at the start of the next `send()`. Pass `{ applyNow: true }` to
|
|
892
|
+
* force immediate disposal (caller must `Agent.create()` again to use).
|
|
893
|
+
*
|
|
894
|
+
* Cache invalidation is a cost regression (provider charges full price
|
|
895
|
+
* for the rebuilt cache; see ADRs D94-D95). Use sparingly and deliberately.
|
|
896
|
+
*
|
|
897
|
+
* Cloud agents: no-op (cloud runtime reconstructs state per request).
|
|
898
|
+
*
|
|
899
|
+
* @public
|
|
900
|
+
*/
|
|
901
|
+
invalidateCache?(reason: string, options?: InvalidateCacheOptions): Promise<void>;
|
|
902
|
+
/**
|
|
903
|
+
* Goal-driven Ralph loop (ADRs D115-D121). Iterates `agent.send` →
|
|
904
|
+
* judge → continuation until the auxiliary judge model returns `done`,
|
|
905
|
+
* the judge fails too many times in a row, max turns are exhausted,
|
|
906
|
+
* or the caller aborts via `AbortSignal`.
|
|
907
|
+
*
|
|
908
|
+
* Yields {@link import("./goal-events.js").GoalEvent} per state
|
|
909
|
+
* transition; returns a {@link import("./goal-events.js").GoalResult}
|
|
910
|
+
* summary as the generator's final value.
|
|
911
|
+
*
|
|
912
|
+
* Cloud agents throw {@link import("../errors.js").UnsupportedRunOperationError}
|
|
913
|
+
* **synchronously** (no AsyncGenerator returned) — wrap in try/catch
|
|
914
|
+
* if you support both runtimes.
|
|
915
|
+
*
|
|
916
|
+
* Caveat: do not call `agent.dispose()` mid-iteration; the next `send`
|
|
917
|
+
* propagates the disposal error through the generator to the consumer.
|
|
918
|
+
*
|
|
919
|
+
* @public
|
|
920
|
+
*/
|
|
921
|
+
runUntil?(goal?: string, options?: GoalOptions): RunUntilIterator;
|
|
922
|
+
/**
|
|
923
|
+
* Fork a short-lived sub-agent with parent's credentials + system
|
|
924
|
+
* prompt byte-identical (ADR D112 — cache hit) and a restricted tool
|
|
925
|
+
* whitelist (ADR D111 — AsyncLocalStorage isolation).
|
|
926
|
+
*
|
|
927
|
+
* Cloud agents throw {@link import("../errors.js").UnsupportedRunOperationError}.
|
|
928
|
+
*
|
|
929
|
+
* @public
|
|
930
|
+
*/
|
|
931
|
+
fork?(options: ForkOptions): Promise<ForkResult>;
|
|
932
|
+
/**
|
|
933
|
+
* Drive `send` to completion across iteration-ceiling truncations (M1 Phase 3).
|
|
934
|
+
* When a `send` stops at the loop's iteration cap (`RunResult.stoppedAtIterationLimit`),
|
|
935
|
+
* this re-sends a short continuation prompt — the agent's stateful session
|
|
936
|
+
* preserves the conversation — until a genuine terminal: `done` (finished),
|
|
937
|
+
* `step_limit` (`maxRounds` exhausted), or `no_progress` (two empty rounds).
|
|
938
|
+
*
|
|
939
|
+
* Local agents only. Cloud agents throw
|
|
940
|
+
* {@link import("../errors.js").UnsupportedRunOperationError} (the cloud
|
|
941
|
+
* runtime manages its own continuation policy server-side).
|
|
942
|
+
*
|
|
943
|
+
* @public
|
|
944
|
+
*/
|
|
945
|
+
runToCompletion?(message: string, options?: RunToCompletionOptions): Promise<RunToCompletionResult>;
|
|
946
|
+
/**
|
|
947
|
+
* STREAMING continuation driver (V3-4) — the streaming twin of
|
|
948
|
+
* {@link SDKAgent.runToCompletion}. Returns an `AsyncGenerator` that yields each
|
|
949
|
+
* round's {@link import("./messages.js").SDKMessage}s LIVE (for a UI), reusing the
|
|
950
|
+
* same terminal policy (`done`/`step_limit`/`no_progress` + bounded re-prompt).
|
|
951
|
+
*
|
|
952
|
+
* The {@link import("./run.js").StreamToCompletionResult} is the generator's RETURN
|
|
953
|
+
* value — read it via a manual `gen.next()` loop (`while (!res.done) res = await
|
|
954
|
+
* gen.next()` → `res.value`); a plain `for await...of` consumes the yielded
|
|
955
|
+
* messages but discards the return value.
|
|
956
|
+
*
|
|
957
|
+
* Local agents only. Cloud agents throw
|
|
958
|
+
* {@link import("../errors.js").UnsupportedRunOperationError}.
|
|
959
|
+
*
|
|
960
|
+
* @public
|
|
961
|
+
*/
|
|
962
|
+
streamToCompletion?(message: string, options?: RunToCompletionOptions): AsyncGenerator<SDKMessage, StreamToCompletionResult>;
|
|
963
|
+
/**
|
|
964
|
+
* Direct API to third-party memory adapter(s) registered via
|
|
965
|
+
* `plugins: [...]` (ADR D141 / D142). Returns `null` when no adapter
|
|
966
|
+
* is registered. In multi-adapter setups `write` fans out to all;
|
|
967
|
+
* `recall` merges + dedupes; `delete` routes by `MemoryId` prefix.
|
|
968
|
+
*
|
|
969
|
+
* @public
|
|
970
|
+
*/
|
|
971
|
+
memory?: AgentMemory;
|
|
972
|
+
/**
|
|
973
|
+
* Activate a personality preset for the next `send` (Hermes #26).
|
|
974
|
+
* Reserved names `"none"`, `"default"`, and `"neutral"` clear the
|
|
975
|
+
* active preset. Returns the resolved preset (or `null` when cleared).
|
|
976
|
+
*
|
|
977
|
+
* Persistence: pass `{ save: true }` to persist across process
|
|
978
|
+
* restarts (stored under `$THEOKIT_HOME/personality.json`).
|
|
979
|
+
*
|
|
980
|
+
* History: by default the conversation history is preserved across
|
|
981
|
+
* the switch. Pass `{ reset: true }` to also clear the session.
|
|
982
|
+
*
|
|
983
|
+
* Cloud agents throw {@link import("../errors.js").UnsupportedRunOperationError}.
|
|
984
|
+
*
|
|
985
|
+
* @public
|
|
986
|
+
*/
|
|
987
|
+
usePersonality?(name: string, opts?: {
|
|
988
|
+
save?: boolean;
|
|
989
|
+
reset?: boolean;
|
|
990
|
+
}): Promise<PersonalityPreset | null>;
|
|
991
|
+
}
|
|
992
|
+
/**
|
|
993
|
+
* Resolved personality preset surfaced via {@link SDKAgent.usePersonality}
|
|
994
|
+
* (Hermes #26, ADRs D160-D169). Re-declared here so the public DTS bundle
|
|
995
|
+
* never crosses the `internal/` path boundary. The implementation type in
|
|
996
|
+
* `internal/personality/types.ts` is structurally identical.
|
|
997
|
+
*
|
|
998
|
+
* @public
|
|
999
|
+
*/
|
|
1000
|
+
interface PersonalityPreset {
|
|
1001
|
+
readonly name: string;
|
|
1002
|
+
readonly description: string | undefined;
|
|
1003
|
+
readonly tools: ReadonlyArray<string> | undefined;
|
|
1004
|
+
readonly model: string | undefined;
|
|
1005
|
+
readonly tags: ReadonlyArray<string> | undefined;
|
|
1006
|
+
readonly systemPrompt: string;
|
|
1007
|
+
readonly source: "project" | "user";
|
|
1008
|
+
readonly sourcePath: string;
|
|
1009
|
+
}
|
|
1010
|
+
/**
|
|
1011
|
+
* Options for {@link SDKAgent.invalidateCache}.
|
|
1012
|
+
*
|
|
1013
|
+
* @public
|
|
1014
|
+
*/
|
|
1015
|
+
interface InvalidateCacheOptions {
|
|
1016
|
+
/**
|
|
1017
|
+
* When `true`, dispose the agent immediately so caller must recreate it
|
|
1018
|
+
* to continue. Default `false` (deferred — applied on next `send()`).
|
|
1019
|
+
*/
|
|
1020
|
+
applyNow?: boolean;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
/**
|
|
1024
|
+
* `MemoryProvider` — kernel-facing port for the memory subsystem
|
|
1025
|
+
* (SDK 2.0 Phase 1 / T1.1 — Hexagonal Architecture / Ports & Adapters,
|
|
1026
|
+
* SOLID Dependency Inversion).
|
|
1027
|
+
*
|
|
1028
|
+
* The agent loop kernel depends on THIS CONTRACT — not on the concrete
|
|
1029
|
+
* `internal/memory/*` modules. Default adapter ships with `@theokit/sdk`
|
|
1030
|
+
* (no-op for back-compat); rich impl ships in `@theokit/sdk-memory`.
|
|
1031
|
+
* Consumers opt-in via `Agent.create({ memoryProvider: ... })`.
|
|
1032
|
+
*
|
|
1033
|
+
* DIP-correct home (SE46): the port + companion contract types live in the
|
|
1034
|
+
* domain `types/` layer; the application-layer module
|
|
1035
|
+
* (`internal/runtime/memory/memory-provider.ts`) re-exports them for
|
|
1036
|
+
* back-compat while the concrete providers live under `internal/`.
|
|
1037
|
+
*
|
|
1038
|
+
* Layered model (mirrors Budget):
|
|
1039
|
+
* - `MemoryAdapter` (in `types/memory-adapter.ts`) — LOW-LEVEL data port:
|
|
1040
|
+
* write / recall / delete primitives.
|
|
1041
|
+
* - `MemoryProvider` (THIS FILE) — HIGH-LEVEL lifecycle port: init,
|
|
1042
|
+
* tool factories, active memory pass, embedding runtime selection.
|
|
1043
|
+
*
|
|
1044
|
+
* @public — surface-level interface; impls are internal-but-replaceable.
|
|
1045
|
+
*/
|
|
1046
|
+
|
|
1047
|
+
/** Result of `MemoryProvider.runActivePass(...)` — what the kernel injects into the LLM call. */
|
|
1048
|
+
interface ActiveMemoryPassResult {
|
|
1049
|
+
/** Compressed memory facts to seed the LLM's context window for this turn. */
|
|
1050
|
+
readonly facts: ReadonlyArray<MemoryFact>;
|
|
1051
|
+
/** Optional system-prompt enrichment derived from the recalled facts. */
|
|
1052
|
+
readonly systemPromptAdditions?: string;
|
|
1053
|
+
/** Whether the active-memory circuit breaker tripped (degraded mode). */
|
|
1054
|
+
readonly breakerTripped?: boolean;
|
|
1055
|
+
}
|
|
1056
|
+
/** Arguments for `MemoryProvider.runActivePass(...)`. */
|
|
1057
|
+
interface ActiveMemoryPassArgs {
|
|
1058
|
+
/** The current user message — used as the recall query. */
|
|
1059
|
+
readonly userMessage: string;
|
|
1060
|
+
/** Conversation history (most recent first). */
|
|
1061
|
+
readonly history: ReadonlyArray<{
|
|
1062
|
+
role: "user" | "assistant";
|
|
1063
|
+
content: string;
|
|
1064
|
+
}>;
|
|
1065
|
+
/** Agent identity for scope. */
|
|
1066
|
+
readonly agentId: string;
|
|
1067
|
+
}
|
|
1068
|
+
/**
|
|
1069
|
+
* Arguments for `MemoryProvider.recordSessionSummary(...)`
|
|
1070
|
+
* (SDK 2.0 Phase 1 physical Stage 3 prep — iter 27).
|
|
1071
|
+
*
|
|
1072
|
+
* The "session summary" is the markdown that gets written to disk
|
|
1073
|
+
* after a finished run + indexed under `corpus="sessions"`. This
|
|
1074
|
+
* port method lets sdk-core's `post-run-lifecycle.ts` delegate the
|
|
1075
|
+
* write to the provider instead of importing
|
|
1076
|
+
* `internal/memory/storage/session-summary-writer.ts` directly.
|
|
1077
|
+
*
|
|
1078
|
+
* @public
|
|
1079
|
+
*/
|
|
1080
|
+
interface RecordSessionSummaryArgs {
|
|
1081
|
+
/**
|
|
1082
|
+
* Workspace cwd where on-disk artefacts live. Included on the args
|
|
1083
|
+
* (not on a handle) because `recordSessionSummary` is STATELESS — it
|
|
1084
|
+
* runs AFTER `runAgentLoop`'s `dispose()` releases the per-run handle.
|
|
1085
|
+
* The kernel passes its own `workspaceCwd`; the impl uses it to
|
|
1086
|
+
* compute the markdown file path.
|
|
1087
|
+
*/
|
|
1088
|
+
readonly cwd: string;
|
|
1089
|
+
/** Run id used as the filename key. */
|
|
1090
|
+
readonly runId: string;
|
|
1091
|
+
/** Agent identity for scope (foldering). */
|
|
1092
|
+
readonly agentId: string;
|
|
1093
|
+
/** Verbatim user message that started the run. */
|
|
1094
|
+
readonly userText: string;
|
|
1095
|
+
/** Final assistant text the run produced. */
|
|
1096
|
+
readonly assistantText: string;
|
|
1097
|
+
/** Final run status (only "finished" is recorded today). */
|
|
1098
|
+
readonly status: "finished" | "error" | "cancelled";
|
|
1099
|
+
/** Wall-clock ms at write time. */
|
|
1100
|
+
readonly at: number;
|
|
1101
|
+
}
|
|
1102
|
+
/** Options for `MemoryProvider.init(...)`. */
|
|
1103
|
+
interface MemoryProviderInitOptions {
|
|
1104
|
+
/** Workspace cwd where on-disk artefacts live (`.theokit/memory/...`). */
|
|
1105
|
+
readonly cwd: string;
|
|
1106
|
+
/** Embedding-provider id (`"openai" | "ollama" | ...`); when omitted the impl picks a default. */
|
|
1107
|
+
readonly embeddingProviderId?: string;
|
|
1108
|
+
}
|
|
1109
|
+
/**
|
|
1110
|
+
* Opaque handle returned by `init()`. Carried back into other methods so
|
|
1111
|
+
* the impl can stash per-agent state (index, breaker, cache, …) without
|
|
1112
|
+
* exposing it to the kernel.
|
|
1113
|
+
*/
|
|
1114
|
+
interface MemoryProviderHandle {
|
|
1115
|
+
/** Adapter interface for direct read/write — matches existing `MemoryAdapter` shape. */
|
|
1116
|
+
readonly adapter: MemoryAdapter;
|
|
1117
|
+
/** Implementation-defined opaque field (private state pointer / index handle). */
|
|
1118
|
+
readonly [implState: symbol]: unknown;
|
|
1119
|
+
}
|
|
1120
|
+
/**
|
|
1121
|
+
* The kernel-facing contract. Implementations live OUTSIDE the agent loop
|
|
1122
|
+
* (in `@theokit/sdk-memory` after Phase 1; in `internal/memory/` until then).
|
|
1123
|
+
*
|
|
1124
|
+
* Implementations MUST be:
|
|
1125
|
+
* - **Lazy** — `init()` may be called once per agent; subsequent calls
|
|
1126
|
+
* return the same handle (impl decides via cache). Heavy work
|
|
1127
|
+
* (loading the index, opening SQLite) deferred until first use.
|
|
1128
|
+
* - **Non-throwing on the hot path** — `runActivePass()` returns an
|
|
1129
|
+
* empty `facts: []` on degradation rather than throwing. Errors
|
|
1130
|
+
* surface via the breakerTripped flag + telemetry.
|
|
1131
|
+
*/
|
|
1132
|
+
interface MemoryProvider {
|
|
1133
|
+
/** Construct or fetch the per-agent handle. Lazy + idempotent. */
|
|
1134
|
+
init(opts: MemoryProviderInitOptions): Promise<MemoryProviderHandle>;
|
|
1135
|
+
/** Build the LLM-facing tool catalog (memory_search, memory_get, …). */
|
|
1136
|
+
buildTools(handle: MemoryProviderHandle, agent: SDKAgent): ReadonlyArray<CustomTool>;
|
|
1137
|
+
/** Run the active-memory pre-LLM pass — recall + compress + format. */
|
|
1138
|
+
runActivePass(handle: MemoryProviderHandle, args: ActiveMemoryPassArgs): Promise<ActiveMemoryPassResult>;
|
|
1139
|
+
/**
|
|
1140
|
+
* Optional post-run hook (SDK 2.0 Phase 1 physical Stage 1 — iter 19).
|
|
1141
|
+
* Called by the agent loop AFTER a successful send so the impl can
|
|
1142
|
+
* incorporate the session summary into its index (e.g., re-index the
|
|
1143
|
+
* `sessions` corpus so the next recall sees it).
|
|
1144
|
+
*
|
|
1145
|
+
* Fire-and-forget at the call site; impl MUST be idempotent +
|
|
1146
|
+
* non-throwing. Optional so existing impls (createNoopMemoryProvider,
|
|
1147
|
+
* sdk-memory@0.1.0) keep working without modification.
|
|
1148
|
+
*
|
|
1149
|
+
* Mirrors the role of `LocalAgentMemory.syncIfReady()` in sdk-core's
|
|
1150
|
+
* legacy memory path — exposing it via the port is the seam that
|
|
1151
|
+
* unblocks moving LocalAgentMemory's logic out to sdk-memory.
|
|
1152
|
+
*/
|
|
1153
|
+
sync?(handle: MemoryProviderHandle): Promise<void> | void;
|
|
1154
|
+
/**
|
|
1155
|
+
* Optional session-summary write hook (SDK 2.0 Phase 1 physical
|
|
1156
|
+
* Stage 3 prep — iter 27, refined iter 28).
|
|
1157
|
+
*
|
|
1158
|
+
* Called by `post-run-lifecycle.ts` AFTER a finished run to persist
|
|
1159
|
+
* the run's session-summary markdown under `corpus="sessions"`. When
|
|
1160
|
+
* defined, the kernel delegates the write to the provider; when
|
|
1161
|
+
* undefined, post-run-lifecycle falls back to the direct
|
|
1162
|
+
* `writeSessionSummary` import (legacy path, until Stage 3 source
|
|
1163
|
+
* move drops that import entirely).
|
|
1164
|
+
*
|
|
1165
|
+
* STATELESS — does NOT take a `MemoryProviderHandle` because post-run-
|
|
1166
|
+
* lifecycle runs AFTER `runAgentLoop` disposed the per-run handle.
|
|
1167
|
+
* `cwd` lives on `args` instead. Impls that need per-agent state can
|
|
1168
|
+
* cache it via closure inside the provider factory.
|
|
1169
|
+
*
|
|
1170
|
+
* Impl MUST be non-throwing on the hot path. The kernel swallows
|
|
1171
|
+
* any throw + emits a stderr warning.
|
|
1172
|
+
*
|
|
1173
|
+
* Optional so existing impls (createNoopMemoryProvider,
|
|
1174
|
+
* createInMemoryMarkdownProvider) keep working without modification.
|
|
1175
|
+
*/
|
|
1176
|
+
recordSessionSummary?(args: RecordSessionSummaryArgs): Promise<void> | void;
|
|
1177
|
+
/** Release the handle (close index, flush caches). Idempotent + non-throwing. */
|
|
1178
|
+
dispose(handle: MemoryProviderHandle): Promise<void> | void;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
/**
|
|
1182
|
+
* ProviderProfile + ApiMode + AuthType contract types (T3.1, ADR D105).
|
|
1183
|
+
*
|
|
1184
|
+
* Profile is **data-only** — no methods. Adding a provider is declaring an
|
|
1185
|
+
* object literal; the Transport layer (D106) consumes `apiMode` to pick
|
|
1186
|
+
* the HTTP dialect.
|
|
1187
|
+
*
|
|
1188
|
+
* SE45/SE46 — relocated from `internal/providers/types.ts` into `types/` so the
|
|
1189
|
+
* public contract (embedded in the `Plugin` type) lives above the DIP boundary;
|
|
1190
|
+
* `internal/providers/types.ts` re-exports these names for back-compat.
|
|
1191
|
+
*
|
|
1192
|
+
* @public
|
|
1193
|
+
*/
|
|
1194
|
+
type ApiMode = "chat_completions" | "anthropic_messages" | "responses_api" | "bedrock" | "bedrock_anthropic";
|
|
1195
|
+
type AuthType = "api_key" | "oauth_device_code" | "oauth_external" | "aws_sdk" | "aws_bearer" | "gcp_oauth" | "none";
|
|
1196
|
+
/**
|
|
1197
|
+
* M41 (agent-builder provider framework) — the context a provider's `transform` receives per request. An
|
|
1198
|
+
* object from day one so it can grow without breaking (M42 adds the resolved `credential`).
|
|
1199
|
+
*
|
|
1200
|
+
* @public
|
|
1201
|
+
*/
|
|
1202
|
+
interface ProviderTransformContext {
|
|
1203
|
+
/** The bearer the router resolved for this request (env var, injected key, or an oauth access token). */
|
|
1204
|
+
apiKey: string;
|
|
1205
|
+
}
|
|
1206
|
+
/**
|
|
1207
|
+
* M41 — the one OPTIONAL behavior seam on a provider profile. It lets a provider own its per-request auth:
|
|
1208
|
+
* `fetch` is the universal seam (a provider that returns its own fetch fully controls headers + refresh, for
|
|
1209
|
+
* every transport that accepts a fetch); `headers` is a convenience merged over `extraHeaders` on transports
|
|
1210
|
+
* that carry them (responses_api). This is the CONTRACT-shape adaptation of OpenCode's provider `auth.loader`
|
|
1211
|
+
* (MIT © 2025 opencode — `packages/core/src/plugin/provider/*.ts`), retargeted to theokit's transport model.
|
|
1212
|
+
* Closes the gap where a `ProviderProfile` could only declare STATIC headers.
|
|
1213
|
+
*
|
|
1214
|
+
* @public
|
|
1215
|
+
*/
|
|
1216
|
+
interface ProviderTransform {
|
|
1217
|
+
/**
|
|
1218
|
+
* Dynamic per-request headers, merged OVER the profile's static `extraHeaders`, and spread AFTER the
|
|
1219
|
+
* transport's base `authorization`/`content-type`. A provider that owns its auth MAY intentionally set
|
|
1220
|
+
* `authorization` here to override the resolved bearer — but a stray `authorization`/`content-type` key
|
|
1221
|
+
* will silently replace the base header, so return only the headers you mean to add.
|
|
1222
|
+
*/
|
|
1223
|
+
headers?(ctx: ProviderTransformContext): Record<string, string>;
|
|
1224
|
+
/** A fetch to use for this provider's requests (refresh-aware / fully provider-controlled). */
|
|
1225
|
+
fetch?(ctx: ProviderTransformContext): typeof fetch;
|
|
1226
|
+
}
|
|
1227
|
+
interface ProviderProfile {
|
|
1228
|
+
name: string;
|
|
1229
|
+
apiMode: ApiMode;
|
|
1230
|
+
aliases?: ReadonlyArray<string>;
|
|
1231
|
+
displayName?: string;
|
|
1232
|
+
description?: string;
|
|
1233
|
+
signupUrl?: string;
|
|
1234
|
+
envVars: ReadonlyArray<string>;
|
|
1235
|
+
authType: AuthType;
|
|
1236
|
+
baseUrl: string;
|
|
1237
|
+
modelsUrl?: string;
|
|
1238
|
+
hostname?: string;
|
|
1239
|
+
fallbackModels: ReadonlyArray<string>;
|
|
1240
|
+
extraHeaders?: Record<string, string>;
|
|
1241
|
+
/**
|
|
1242
|
+
* M45 — explicit chat-completions path override (data-only). Absent, the transport derives it: a baseUrl
|
|
1243
|
+
* whose path already carries a version segment (`/v1`, `/v2beta`, …) gets `/chat/completions` appended;
|
|
1244
|
+
* a host-only baseUrl keeps the legacy `/v1/chat/completions`. Set this for shapes neither rule expresses
|
|
1245
|
+
* (e.g. Perplexity's unversioned `/chat/completions`).
|
|
1246
|
+
*/
|
|
1247
|
+
chatCompletionsPath?: string;
|
|
1248
|
+
bodyOverrides?: Record<string, unknown>;
|
|
1249
|
+
/**
|
|
1250
|
+
* M41 — the optional per-request behavior seam (dynamic headers + refresh-aware fetch). Absent ⇒ the profile
|
|
1251
|
+
* is pure data and takes the static path byte-for-byte. See {@link ProviderTransform}.
|
|
1252
|
+
*/
|
|
1253
|
+
transform?: ProviderTransform;
|
|
1254
|
+
/**
|
|
1255
|
+
* Opt-in leaked-dialect safe-parse (theokit#58 follow-up). When `true`, a chat_completions finish
|
|
1256
|
+
* with ZERO native `tool_calls` has its assistant content scanned for the Hermes
|
|
1257
|
+
* `<function=…></tool_call>` dialect and any recovered calls are surfaced as real `tool_calls`.
|
|
1258
|
+
* Default off — only enable for routes/models known to leak (e.g. a qwen3-coder profile variant).
|
|
1259
|
+
*/
|
|
1260
|
+
extractToolCallsFromContent?: boolean;
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
type HookName = "pre_tool_call" | "post_tool_call" | "pre_llm_call" | "post_llm_call" | "on_session_start" | "on_session_end" | "transform_tool_result" | "transform_llm_output" | "pre_user_send" | "post_assistant_reply";
|
|
1264
|
+
interface PreToolCallContext {
|
|
1265
|
+
name: string;
|
|
1266
|
+
args: Record<string, unknown>;
|
|
1267
|
+
agentId: string;
|
|
1268
|
+
runId: string;
|
|
1269
|
+
/**
|
|
1270
|
+
* SE1 — the run's resolved `PermissionMode` (from `SendOptions.permissionMode`
|
|
1271
|
+
* ?? `AgentOptions.permissionMode`), threaded so a permission-style plugin can
|
|
1272
|
+
* gate per-run rather than at construction time. Absent ⇒ the plugin's own
|
|
1273
|
+
* default applies. Ignored by non-permission plugins.
|
|
1274
|
+
*/
|
|
1275
|
+
permissionMode?: PermissionMode;
|
|
1276
|
+
}
|
|
1277
|
+
interface PreToolCallDecision {
|
|
1278
|
+
block: true;
|
|
1279
|
+
message: string;
|
|
1280
|
+
}
|
|
1281
|
+
/**
|
|
1282
|
+
* Context passed to `pre_user_send` hook handlers (ADR D145).
|
|
1283
|
+
*
|
|
1284
|
+
* @public
|
|
1285
|
+
*/
|
|
1286
|
+
interface PreUserSendContext {
|
|
1287
|
+
prompt: string;
|
|
1288
|
+
agentId: string;
|
|
1289
|
+
runId: string;
|
|
1290
|
+
/** Caller-supplied memory context, flowing through from `AgentOptions.memoryContext`. */
|
|
1291
|
+
memoryContext?: MemoryContext;
|
|
1292
|
+
/** Forwarded `AbortSignal` so adapter recall HTTP can be cancelled mid-flight (EC-H). */
|
|
1293
|
+
signal?: AbortSignal;
|
|
1294
|
+
}
|
|
1295
|
+
/**
|
|
1296
|
+
* Optional result returned by `pre_user_send` handlers. The agent loop
|
|
1297
|
+
* concatenates `recalledContext` from all handlers and injects it as a
|
|
1298
|
+
* `<memory-context>...</memory-context>` block before the user prompt.
|
|
1299
|
+
*
|
|
1300
|
+
* @public
|
|
1301
|
+
*/
|
|
1302
|
+
interface PreUserSendResult {
|
|
1303
|
+
recalledContext?: string;
|
|
1304
|
+
}
|
|
1305
|
+
/**
|
|
1306
|
+
* Context passed to `post_assistant_reply` hook handlers (ADR D145).
|
|
1307
|
+
* Fire-and-forget — exceptions are caught and surfaced to stderr; the
|
|
1308
|
+
* caller's `wait()` never blocks on this dispatch.
|
|
1309
|
+
*
|
|
1310
|
+
* @public
|
|
1311
|
+
*/
|
|
1312
|
+
interface PostAssistantReplyContext {
|
|
1313
|
+
prompt: string;
|
|
1314
|
+
reply: string;
|
|
1315
|
+
agentId: string;
|
|
1316
|
+
runId: string;
|
|
1317
|
+
memoryContext?: MemoryContext;
|
|
1318
|
+
}
|
|
1319
|
+
type HookHandler = (ctx: unknown) => unknown | Promise<unknown>;
|
|
1320
|
+
type CommandHandler = (args: Record<string, unknown>) => Promise<string> | string;
|
|
1321
|
+
interface CommandOptions {
|
|
1322
|
+
description?: string;
|
|
1323
|
+
}
|
|
1324
|
+
interface PluginContext {
|
|
1325
|
+
/** Register a custom tool. Equivalent to passing in `AgentOptions.tools`. */
|
|
1326
|
+
registerTool(tool: CustomTool): void;
|
|
1327
|
+
/** Register a slash-command-style handler. Consumed by CLI/bot wrappers; NOT used by the agent loop. */
|
|
1328
|
+
registerCommand(name: string, handler: CommandHandler, opts?: CommandOptions): void;
|
|
1329
|
+
/** Attach a hook handler. `pre_tool_call` supports veto via `PreToolCallDecision`. */
|
|
1330
|
+
on(hook: HookName, handler: HookHandler): void;
|
|
1331
|
+
/** Inject a user/system message into the next agent turn. v1 supports only `on_session_start` context. */
|
|
1332
|
+
injectMessage(content: string, role?: "user" | "system"): void;
|
|
1333
|
+
}
|
|
1334
|
+
interface BasePlugin {
|
|
1335
|
+
name: string;
|
|
1336
|
+
version: string;
|
|
1337
|
+
}
|
|
1338
|
+
type Plugin = (BasePlugin & {
|
|
1339
|
+
kind: "general";
|
|
1340
|
+
register: (ctx: PluginContext) => void | Promise<void>;
|
|
1341
|
+
}) | (BasePlugin & {
|
|
1342
|
+
kind: "model-provider";
|
|
1343
|
+
profile: ProviderProfile;
|
|
1344
|
+
}) | (BasePlugin & {
|
|
1345
|
+
kind: "memory";
|
|
1346
|
+
createProvider: MemoryProviderFactory;
|
|
1347
|
+
});
|
|
1348
|
+
|
|
1349
|
+
/**
|
|
1350
|
+
* Which on-disk settings layers a local agent loads.
|
|
1351
|
+
*
|
|
1352
|
+
* @public
|
|
1353
|
+
*/
|
|
1354
|
+
type SettingSource = "project" | "user" | "team" | "mdm" | "plugins" | "all";
|
|
1355
|
+
/**
|
|
1356
|
+
* Local agent configuration.
|
|
1357
|
+
*
|
|
1358
|
+
* @public
|
|
1359
|
+
*/
|
|
1360
|
+
interface LocalOptions {
|
|
1361
|
+
cwd?: string | string[];
|
|
1362
|
+
settingSources?: SettingSource[];
|
|
1363
|
+
sandboxOptions?: {
|
|
1364
|
+
enabled: boolean;
|
|
1365
|
+
};
|
|
1366
|
+
/**
|
|
1367
|
+
* SE40 — base directory for the native Claude-shaped session transcript
|
|
1368
|
+
* (`<baseDir>/projects/<encoded-cwd>/<agentId>.jsonl`). Default `~/.theokit`.
|
|
1369
|
+
* Set to `~/.claude` to write sessions the Claude Code CLI can `--continue`.
|
|
1370
|
+
*/
|
|
1371
|
+
baseDir?: string;
|
|
1372
|
+
/**
|
|
1373
|
+
* SE41 — inject an external {@link import("./session-store.js").SessionStore}
|
|
1374
|
+
* (Postgres / Redis / KV / durable object) as the PRIMARY session store and
|
|
1375
|
+
* resume source. Omit for the default FS transcript store (`baseDir` above) —
|
|
1376
|
+
* byte-identical to SE40. Use this for serverless (ephemeral FS) or multi-host /
|
|
1377
|
+
* multi-pod deployments where a resumed agent must read its history from a shared
|
|
1378
|
+
* store instead of local disk. The records stay the native Claude-shaped shape,
|
|
1379
|
+
* so `--continue` interop is preserved (a store may also mirror to `~/.claude`).
|
|
1380
|
+
*/
|
|
1381
|
+
sessionStore?: SessionStore;
|
|
1382
|
+
}
|
|
1383
|
+
/**
|
|
1384
|
+
* Repo to clone into a cloud agent's VM.
|
|
1385
|
+
*
|
|
1386
|
+
* @public
|
|
1387
|
+
*/
|
|
1388
|
+
interface CloudRepo {
|
|
1389
|
+
url: string;
|
|
1390
|
+
startingRef?: string;
|
|
1391
|
+
prUrl?: string;
|
|
1392
|
+
}
|
|
1393
|
+
/**
|
|
1394
|
+
* Cloud execution environment.
|
|
1395
|
+
*
|
|
1396
|
+
* @public
|
|
1397
|
+
*/
|
|
1398
|
+
interface CloudEnv {
|
|
1399
|
+
type: "cloud" | "pool" | "machine";
|
|
1400
|
+
name?: string;
|
|
1401
|
+
}
|
|
1402
|
+
/**
|
|
1403
|
+
* Cloud agent configuration.
|
|
1404
|
+
*
|
|
1405
|
+
* @public
|
|
1406
|
+
*/
|
|
1407
|
+
interface CloudOptions {
|
|
1408
|
+
env?: CloudEnv;
|
|
1409
|
+
repos?: CloudRepo[];
|
|
1410
|
+
workOnCurrentBranch?: boolean;
|
|
1411
|
+
autoCreatePR?: boolean;
|
|
1412
|
+
skipReviewerRequest?: boolean;
|
|
1413
|
+
/**
|
|
1414
|
+
* Short-lived credentials scoped to the agent. Encrypted at rest, deleted
|
|
1415
|
+
* with the agent. Names must not start with `THEOKIT_`.
|
|
1416
|
+
*/
|
|
1417
|
+
envVars?: Record<string, string>;
|
|
1418
|
+
}
|
|
1419
|
+
/**
|
|
1420
|
+
* Subagent definition. The parent agent spawns these via its Agent tool.
|
|
1421
|
+
*
|
|
1422
|
+
* @public
|
|
1423
|
+
*/
|
|
1424
|
+
interface AgentDefinition {
|
|
1425
|
+
description: string;
|
|
1426
|
+
prompt: string;
|
|
1427
|
+
model?: ModelSelection | "inherit";
|
|
1428
|
+
mcpServers?: Array<string | Record<string, McpServerConfig>>;
|
|
1429
|
+
/**
|
|
1430
|
+
* Tool whitelist (M4-6). When set, the sub-agent may ONLY call tools whose
|
|
1431
|
+
* canonical (post-repair, lowercase) name is in this list — any other tool
|
|
1432
|
+
* call is vetoed at dispatch via the same `withToolWhitelist` enforcement
|
|
1433
|
+
* forks use (NOT `PermissionEngine`). Absent/empty → unscoped (inherits the
|
|
1434
|
+
* parent's full toolset). Apply with `withSubagentToolScope`.
|
|
1435
|
+
*/
|
|
1436
|
+
tools?: string[];
|
|
1437
|
+
/**
|
|
1438
|
+
* Per-subagent shell sandbox toggle. When `true`, the spawned child runs with
|
|
1439
|
+
* `local.sandboxOptions.enabled = true` (the SDK's boolean shell sandbox). Absent
|
|
1440
|
+
* ⇒ inherit the parent's sandbox posture. The SDK has no granular sandbox *mode*
|
|
1441
|
+
* (read-only / workspace-write / danger); a mode string in the disk frontmatter is
|
|
1442
|
+
* a typed load error, not a silent boolean coercion. Reasoning effort is NOT a
|
|
1443
|
+
* field here — it rides inside `model.params` (e.g. `[{ id: "thinking", value: "low" }]`).
|
|
1444
|
+
*/
|
|
1445
|
+
sandbox?: boolean;
|
|
1446
|
+
}
|
|
1447
|
+
/**
|
|
1448
|
+
* Public view of a recalled memory fact exposed to the system-prompt resolver.
|
|
1449
|
+
*
|
|
1450
|
+
* @public
|
|
1451
|
+
*/
|
|
1452
|
+
interface SystemPromptMemoryFact {
|
|
1453
|
+
text: string;
|
|
1454
|
+
}
|
|
1455
|
+
/**
|
|
1456
|
+
* Context passed to a {@link SystemPromptResolver}. Field order is a
|
|
1457
|
+
* compatibility contract: new fields are appended, never reordered.
|
|
1458
|
+
*
|
|
1459
|
+
* @public
|
|
1460
|
+
*/
|
|
1461
|
+
interface SystemPromptContext {
|
|
1462
|
+
agentId: string;
|
|
1463
|
+
cwd: string | undefined;
|
|
1464
|
+
model: ModelSelection | undefined;
|
|
1465
|
+
skills: ReadonlyArray<SystemPromptSkillRef>;
|
|
1466
|
+
userMessage: string;
|
|
1467
|
+
/** Recalled durable facts when memory is enabled. Appended in v1.1. */
|
|
1468
|
+
memory: ReadonlyArray<SystemPromptMemoryFact>;
|
|
1469
|
+
}
|
|
1470
|
+
/**
|
|
1471
|
+
* Resolver function that produces the system prompt dynamically. Receives
|
|
1472
|
+
* the {@link SystemPromptContext} and returns a string (or a Promise of one).
|
|
1473
|
+
*
|
|
1474
|
+
* The SDK does NOT impose a timeout on the resolver — wrap your own
|
|
1475
|
+
* `Promise.race` if you call into slow resources. Errors propagate to the
|
|
1476
|
+
* caller of `agent.send()`.
|
|
1477
|
+
*
|
|
1478
|
+
* @public
|
|
1479
|
+
*/
|
|
1480
|
+
type SystemPromptResolver = (ctx: SystemPromptContext) => string | Promise<string>;
|
|
1481
|
+
/**
|
|
1482
|
+
* Skills configuration accepted by `Agent.create()` via
|
|
1483
|
+
* {@link AgentOptions.skills}.
|
|
1484
|
+
*
|
|
1485
|
+
* Skills are discovered from `.theokit/skills/<name>/SKILL.md` when
|
|
1486
|
+
* `local.settingSources` includes `"project"`.
|
|
1487
|
+
*
|
|
1488
|
+
* @public
|
|
1489
|
+
*/
|
|
1490
|
+
interface SkillsSettings {
|
|
1491
|
+
/**
|
|
1492
|
+
* Names of skills the parent agent may invoke. When omitted, every
|
|
1493
|
+
* discovered skill is enabled.
|
|
1494
|
+
*/
|
|
1495
|
+
enabled?: string[];
|
|
1496
|
+
/**
|
|
1497
|
+
* Whether the SDK auto-injects the loaded skill list (name + description) as a
|
|
1498
|
+
* `<skills>` block in the LLM system prompt. Default `true`.
|
|
1499
|
+
*
|
|
1500
|
+
* Set to `false` when supplying a custom `systemPrompt` resolver that formats
|
|
1501
|
+
* skills itself.
|
|
1502
|
+
*/
|
|
1503
|
+
autoInject?: boolean;
|
|
1504
|
+
/**
|
|
1505
|
+
* M22 — discover skills from a CUSTOM directory (containing `<name>/SKILL.md`) instead of the
|
|
1506
|
+
* default `<cwd>/.theokit/skills`. Absent ⇒ the default root.
|
|
1507
|
+
*/
|
|
1508
|
+
skillsDir?: string;
|
|
1509
|
+
/**
|
|
1510
|
+
* M22 — code-defined skills (from `createSkill`) merged with the discovered ones. An inline skill
|
|
1511
|
+
* overrides a discovered file skill of the same name.
|
|
1512
|
+
*/
|
|
1513
|
+
inline?: InlineSkill[];
|
|
1514
|
+
}
|
|
1515
|
+
/**
|
|
1516
|
+
* SE22 — context passed to a {@link SkillsResolver}. Mirrors
|
|
1517
|
+
* {@link SystemPromptContext} MINUS `skills`: the resolver runs BEFORE skills
|
|
1518
|
+
* are assembled, so the resolved list does not exist yet.
|
|
1519
|
+
*
|
|
1520
|
+
* @public
|
|
1521
|
+
*/
|
|
1522
|
+
interface SkillsResolverContext {
|
|
1523
|
+
agentId: string;
|
|
1524
|
+
/** Workspace cwd. `string | undefined` mirrors {@link SystemPromptContext}; a local agent always passes a concrete path. */
|
|
1525
|
+
cwd: string | undefined;
|
|
1526
|
+
model: ModelSelection | undefined;
|
|
1527
|
+
userMessage: string;
|
|
1528
|
+
/** Recalled durable facts when memory is enabled. */
|
|
1529
|
+
memory: ReadonlyArray<SystemPromptMemoryFact>;
|
|
1530
|
+
}
|
|
1531
|
+
/**
|
|
1532
|
+
* SE22 — a resolver that produces {@link SkillsSettings} per run from runtime
|
|
1533
|
+
* context (e.g. the user's role). Mirrors the {@link SystemPromptResolver}
|
|
1534
|
+
* pattern: evaluated per `send()` BEFORE skill assembly, so a cached
|
|
1535
|
+
* `getOrCreate` agent re-resolves on every run.
|
|
1536
|
+
*
|
|
1537
|
+
* The SDK imposes NO timeout — wrap your own `Promise.race` for slow sources. A
|
|
1538
|
+
* throwing resolver fails the run (no silent fallback — Rule 8). Cloud agents
|
|
1539
|
+
* reject a function resolver (it can't run on PaaS); resolve to a static
|
|
1540
|
+
* {@link SkillsSettings} object before `Agent.create()`.
|
|
1541
|
+
*
|
|
1542
|
+
* @public
|
|
1543
|
+
*/
|
|
1544
|
+
type SkillsResolver = (ctx: SkillsResolverContext) => SkillsSettings | Promise<SkillsSettings>;
|
|
1545
|
+
/**
|
|
1546
|
+
* Memory configuration accepted by `Agent.create()` via {@link AgentOptions.memory}.
|
|
1547
|
+
*
|
|
1548
|
+
* Persists durable facts under `.theokit/memory/<namespace>/<scope>-<userId>.json`.
|
|
1549
|
+
*
|
|
1550
|
+
* @public
|
|
1551
|
+
*/
|
|
1552
|
+
interface MemorySettings {
|
|
1553
|
+
enabled: boolean;
|
|
1554
|
+
namespace?: string;
|
|
1555
|
+
userId?: string;
|
|
1556
|
+
scope?: "agent" | "user" | "team";
|
|
1557
|
+
storePath?: string;
|
|
1558
|
+
/**
|
|
1559
|
+
* Whether the SDK auto-injects recalled facts as a `<memory>` block in the
|
|
1560
|
+
* LLM system prompt. Default `true`.
|
|
1561
|
+
*/
|
|
1562
|
+
autoInject?: boolean;
|
|
1563
|
+
/**
|
|
1564
|
+
* Index + tools configuration (memory-system-peer-project-parity).
|
|
1565
|
+
*
|
|
1566
|
+
* When `tools !== false`, the SDK registers `memory_search` and
|
|
1567
|
+
* `memory_get` with the LLM. Backed by SQLite + FTS5 (and sqlite-vec
|
|
1568
|
+
* when an embedding provider is configured).
|
|
1569
|
+
*/
|
|
1570
|
+
index?: {
|
|
1571
|
+
/** Whether to register `memory_search` + `memory_get` tools. Default `true`. */
|
|
1572
|
+
tools?: boolean;
|
|
1573
|
+
/**
|
|
1574
|
+
* Vector index backend (ADR D43). Default `"sqlite-vec"`. Set to
|
|
1575
|
+
* `"lance"` to use `@lancedb/lancedb` (optional peer dep) for scale.
|
|
1576
|
+
*/
|
|
1577
|
+
backend?: "sqlite-vec" | "lance";
|
|
1578
|
+
/** Embedding provider config. When omitted, the index runs in FTS-only mode. */
|
|
1579
|
+
embedding?: {
|
|
1580
|
+
provider: "openai" | "mistral" | "openrouter" | "voyage" | "deepinfra";
|
|
1581
|
+
model?: string;
|
|
1582
|
+
};
|
|
1583
|
+
};
|
|
1584
|
+
/**
|
|
1585
|
+
* Active Memory blocking recall (Phase 7). When `enabled: true`, runs
|
|
1586
|
+
* before each `send()` and prepends an `<active-memory>` block.
|
|
1587
|
+
*/
|
|
1588
|
+
activeRecall?: {
|
|
1589
|
+
enabled?: boolean;
|
|
1590
|
+
queryMode?: "message" | "recent" | "full";
|
|
1591
|
+
timeoutMs?: number;
|
|
1592
|
+
maxSummaryChars?: number;
|
|
1593
|
+
persistTranscripts?: boolean;
|
|
1594
|
+
};
|
|
1595
|
+
}
|
|
1596
|
+
/**
|
|
1597
|
+
* Telemetry configuration for an agent. When `enabled: true`, the SDK emits
|
|
1598
|
+
* OpenTelemetry spans for `agent.send`, `llm.call`, `tool.call`, and
|
|
1599
|
+
* `memory.search`. See ADR D34.
|
|
1600
|
+
*
|
|
1601
|
+
* Privacy: content (prompts, responses, tool args) is OMITTED by default —
|
|
1602
|
+
* only timing/counts/IDs are recorded. Opt in via `includeContent: true`
|
|
1603
|
+
* to add prompt/response/args events to the spans (consumer's
|
|
1604
|
+
* responsibility to sanitize PII).
|
|
1605
|
+
*
|
|
1606
|
+
* `@opentelemetry/api` is an OPTIONAL peer dependency. Without it
|
|
1607
|
+
* installed, telemetry is a no-op even when `enabled: true`.
|
|
1608
|
+
*
|
|
1609
|
+
* @public
|
|
1610
|
+
*/
|
|
1611
|
+
interface TelemetrySettings {
|
|
1612
|
+
/** Master switch. Default `false`. */
|
|
1613
|
+
enabled: boolean;
|
|
1614
|
+
/** Whether to include prompts/responses/tool args as span events. Default `false`. */
|
|
1615
|
+
includeContent?: boolean;
|
|
1616
|
+
/** Exporter selection. Default `"console"`. Custom exporters are passed-through. */
|
|
1617
|
+
exporter?: "console" | "otlp" | unknown;
|
|
1618
|
+
/** Service name on emitted spans. Default `"theokit-sdk"`. */
|
|
1619
|
+
serviceName?: string;
|
|
1620
|
+
/**
|
|
1621
|
+
* Auto-detect and register OTel exporters for installed observability
|
|
1622
|
+
* libs (Langfuse, Sentry, PostHog) via `createRequire` feature-detect.
|
|
1623
|
+
* Default `true`. See ADR D42.
|
|
1624
|
+
*/
|
|
1625
|
+
autoDetect?: boolean;
|
|
1626
|
+
/**
|
|
1627
|
+
* Per-adapter opt-out. Lowercase names: `"langfuse" | "sentry" | "posthog"`.
|
|
1628
|
+
* Default `[]`.
|
|
1629
|
+
*/
|
|
1630
|
+
disable?: string[];
|
|
1631
|
+
}
|
|
1632
|
+
/**
|
|
1633
|
+
* Top-level options accepted by `Agent.create()`.
|
|
1634
|
+
*
|
|
1635
|
+
* Pass either `local` or `cloud` to pick a runtime.
|
|
1636
|
+
*
|
|
1637
|
+
* @public
|
|
1638
|
+
*/
|
|
1639
|
+
interface AgentOptions {
|
|
1640
|
+
/**
|
|
1641
|
+
* The model to run. SE8 — accepts a bare-string id shorthand
|
|
1642
|
+
* (`"openai/gpt-4o-mini"`, normalized to `{ id }`) OR a {@link ModelSelection}
|
|
1643
|
+
* object (use the object form to pass `params`).
|
|
1644
|
+
*/
|
|
1645
|
+
model?: string | ModelSelection;
|
|
1646
|
+
/** Falls back to `THEOKIT_API_KEY`. */
|
|
1647
|
+
apiKey?: string;
|
|
1648
|
+
name?: string;
|
|
1649
|
+
/**
|
|
1650
|
+
* When `true`, `Agent.prompt` (and any helper that goes through `run.wait()`)
|
|
1651
|
+
* rejects with `AgentRunError` instead of resolving with `{ status: 'error' }`.
|
|
1652
|
+
* Cancelled runs (`status: 'cancelled'`) still resolve — cancel ≠ error.
|
|
1653
|
+
* If `result.error` is undefined despite `status: 'error'` (malformed RunResult),
|
|
1654
|
+
* the defensive guard resolves normally (no throw).
|
|
1655
|
+
*
|
|
1656
|
+
* Default `false` (backwards-compatible).
|
|
1657
|
+
*
|
|
1658
|
+
* @public
|
|
1659
|
+
*/
|
|
1660
|
+
throwOnError?: boolean;
|
|
1661
|
+
/**
|
|
1662
|
+
* System prompt for the agent. Either a plain string or a resolver
|
|
1663
|
+
* function that receives the {@link SystemPromptContext} and returns the
|
|
1664
|
+
* prompt dynamically. Override per-call via {@link SendOptions.systemPrompt}.
|
|
1665
|
+
*
|
|
1666
|
+
* Subagents do NOT inherit this — they use {@link AgentDefinition.prompt}.
|
|
1667
|
+
*/
|
|
1668
|
+
systemPrompt?: string | SystemPromptResolver;
|
|
1669
|
+
local?: LocalOptions;
|
|
1670
|
+
cloud?: CloudOptions;
|
|
1671
|
+
mcpServers?: Record<string, McpServerConfig>;
|
|
1672
|
+
agents?: Record<string, AgentDefinition>;
|
|
1673
|
+
agentId?: string;
|
|
1674
|
+
/** Context manager configuration. See `agent.context`. */
|
|
1675
|
+
context?: ContextSettings;
|
|
1676
|
+
/** Provider routing configuration. See `agent.providers`. */
|
|
1677
|
+
providers?: ProviderRoutingSettings;
|
|
1678
|
+
/**
|
|
1679
|
+
* Plugins for this agent, in one of two forms:
|
|
1680
|
+
*
|
|
1681
|
+
* - **Named-enable settings** — `{ enabled: ["name", ...] }`. Selects which
|
|
1682
|
+
* file-discovered plugin providers (under `.theokit/plugins/`) are active.
|
|
1683
|
+
* Plugin sources must also be active via `local.settingSources`.
|
|
1684
|
+
* - **Code `Plugin` objects** — an array of `Plugin` instances, e.g.
|
|
1685
|
+
* `plugins: [Handoff.asPlugin({ ... })]`. These are registered directly by
|
|
1686
|
+
* the runtime (`extractCodePlugins`); no `settingSources` entry is needed.
|
|
1687
|
+
*
|
|
1688
|
+
* The two forms are mutually exclusive — pass one or the other.
|
|
1689
|
+
*/
|
|
1690
|
+
plugins?: PluginsSettings | readonly Plugin[];
|
|
1691
|
+
/**
|
|
1692
|
+
* SE1 — the default permission mode for this agent's runs, threaded to a
|
|
1693
|
+
* registered `PermissionPlugin`'s pre-tool gate. A per-send
|
|
1694
|
+
* `SendOptions.permissionMode` overrides it. Absent ⇒ the plugin's own
|
|
1695
|
+
* construction-time mode applies. Local runtime.
|
|
1696
|
+
*/
|
|
1697
|
+
permissionMode?: PermissionMode;
|
|
1698
|
+
/**
|
|
1699
|
+
* Skills configuration. Either a static {@link SkillsSettings} object or —
|
|
1700
|
+
* SE22 — a {@link SkillsResolver} evaluated per `send()` to pick skills from
|
|
1701
|
+
* runtime context (e.g. user role). A cached agent re-resolves each run. The
|
|
1702
|
+
* agent-scoped `agent.skills` handle reflects the STATIC/base config; the
|
|
1703
|
+
* resolver drives the per-send `<skills>` block.
|
|
1704
|
+
*/
|
|
1705
|
+
skills?: SkillsSettings | SkillsResolver;
|
|
1706
|
+
/**
|
|
1707
|
+
* SE24 — guardrail processors. `inputProcessors` run in order before the LLM
|
|
1708
|
+
* (normalize / validate / block / rewrite the user message); `outputProcessors`
|
|
1709
|
+
* run on the model's final text before it reaches the caller (redact / block).
|
|
1710
|
+
* A processor that `abort()`s stops the run with a {@link RunResult.tripwire}
|
|
1711
|
+
* (+ a `tripwire` run-event). Empty/absent ⇒ unchanged behavior. See
|
|
1712
|
+
* {@link Processor}.
|
|
1713
|
+
*/
|
|
1714
|
+
inputProcessors?: readonly Processor[];
|
|
1715
|
+
outputProcessors?: readonly Processor[];
|
|
1716
|
+
/** Memory configuration. Persists durable facts; auto-recalled on send. */
|
|
1717
|
+
memory?: MemorySettings;
|
|
1718
|
+
/**
|
|
1719
|
+
* Inline custom tools. Local runtime only — cloud agents reject any non-empty
|
|
1720
|
+
* `tools` array. Handlers are not persisted; pass them again on resume.
|
|
1721
|
+
* See {@link CustomTool}.
|
|
1722
|
+
*/
|
|
1723
|
+
tools?: CustomTool[];
|
|
1724
|
+
/**
|
|
1725
|
+
* SE37 — opt-in reasoning. When `true`, the agent gets a chain-of-thought
|
|
1726
|
+
* preamble prepended to its system prompt AND the `think` reasoning tool
|
|
1727
|
+
* auto-attached, turning a non-reasoning model into a reason -> act ->
|
|
1728
|
+
* observe loop (same model; reuses the existing tool loop). Default `false` —
|
|
1729
|
+
* byte-identical behaviour when unset. Inert (with a one-time warn) when a
|
|
1730
|
+
* native reasoning model is configured (`model.params: [{ id: "thinking" }]`),
|
|
1731
|
+
* so native and prompt-based reasoning never stack. See `ReasoningTools` in `@theokit/sdk-tools`.
|
|
1732
|
+
*/
|
|
1733
|
+
reasoning?: boolean;
|
|
1734
|
+
/**
|
|
1735
|
+
* Telemetry (OpenTelemetry) configuration. Default disabled. See
|
|
1736
|
+
* {@link TelemetrySettings} and ADR D34.
|
|
1737
|
+
*/
|
|
1738
|
+
telemetry?: TelemetrySettings;
|
|
1739
|
+
/**
|
|
1740
|
+
* Arbitrary metadata bag for caller-supplied provenance. Currently used by
|
|
1741
|
+
* the fork primitive (ADR D114) to tag `metadata.forkOrigin` and
|
|
1742
|
+
* `metadata.parentAgentId` so memory writes downstream can be attributed.
|
|
1743
|
+
*
|
|
1744
|
+
* Not persisted to the agent registry — informational only at runtime.
|
|
1745
|
+
*
|
|
1746
|
+
* @public
|
|
1747
|
+
*/
|
|
1748
|
+
metadata?: Record<string, unknown>;
|
|
1749
|
+
/**
|
|
1750
|
+
* Default `MemoryContext` for third-party memory adapter plugins
|
|
1751
|
+
* (ADR D141). When set, `pre_user_send` / `post_assistant_reply`
|
|
1752
|
+
* hooks receive this context unless the caller overrides it. The
|
|
1753
|
+
* `agent.memory` direct API also defaults to it.
|
|
1754
|
+
*
|
|
1755
|
+
* @public
|
|
1756
|
+
*/
|
|
1757
|
+
memoryContext?: MemoryContext;
|
|
1758
|
+
/**
|
|
1759
|
+
* Maximum byte length of the `<memory-context>` block injected by
|
|
1760
|
+
* `pre_user_send` adapter hooks (EC-A). Larger recalls are sliced
|
|
1761
|
+
* with `…[truncated]`. Default 16_000 (~4k tokens). Set lower for
|
|
1762
|
+
* cheaper turns; higher for longer-context models.
|
|
1763
|
+
*
|
|
1764
|
+
* @public
|
|
1765
|
+
*/
|
|
1766
|
+
maxRecallContextBytes?: number;
|
|
1767
|
+
/**
|
|
1768
|
+
* Declarative handoff destinations (Adoption Roadmap #4; ADRs D214-D229).
|
|
1769
|
+
* Each entry is either a raw `SDKAgent` (auto-wrapped with defaults) OR a
|
|
1770
|
+
* `HandoffDescriptor` from `Handoff.create(target, opts?)`.
|
|
1771
|
+
*
|
|
1772
|
+
* Runtime injects synthetic `transfer_to_<receiver.name>` tools per
|
|
1773
|
+
* destination (D214/D215). When the LLM invokes one, the receiver takes
|
|
1774
|
+
* over the next turn (peer-to-peer, D217).
|
|
1775
|
+
*
|
|
1776
|
+
* @public
|
|
1777
|
+
*/
|
|
1778
|
+
handoffs?: ReadonlyArray<SDKAgent | unknown>;
|
|
1779
|
+
/**
|
|
1780
|
+
* Maximum chain depth across handoffs per `agent.send()` call (D218).
|
|
1781
|
+
* Default 5. Exceeding throws `HandoffLoopError`. Set to 0 to disable
|
|
1782
|
+
* the handoff tools entirely (EC-8 / handoffs never fire).
|
|
1783
|
+
*
|
|
1784
|
+
* @public
|
|
1785
|
+
*/
|
|
1786
|
+
maxHandoffDepth?: number;
|
|
1787
|
+
/**
|
|
1788
|
+
* Production-Readiness #6 — quota / abuse gates (ADRs D322-D323).
|
|
1789
|
+
*
|
|
1790
|
+
* `onBeforeCreate` fires BEFORE the agent is registered or persisted —
|
|
1791
|
+
* throw to block creation. `onBeforeSend` fires BEFORE each `agent.send`
|
|
1792
|
+
* (after `pre_user_send` adapter hooks, before any LLM call or storage
|
|
1793
|
+
* write) — throw to block the send.
|
|
1794
|
+
*
|
|
1795
|
+
* Unlike `onTool*` (observation), these hooks are BLOCKERS — errors
|
|
1796
|
+
* propagate as rejection on `Agent.create` / `agent.send`. Use them for
|
|
1797
|
+
* per-user conversation caps, per-conversation message caps, abuse
|
|
1798
|
+
* detection.
|
|
1799
|
+
*
|
|
1800
|
+
* @public
|
|
1801
|
+
*/
|
|
1802
|
+
onBeforeCreate?: (event: {
|
|
1803
|
+
conversationId: string;
|
|
1804
|
+
userId?: string;
|
|
1805
|
+
}) => Promise<void> | void;
|
|
1806
|
+
/**
|
|
1807
|
+
* Fires before each `agent.send`. `previousMessageCount` is the count of
|
|
1808
|
+
* messages already persisted BEFORE the current send adds the user
|
|
1809
|
+
* message. Throw to block.
|
|
1810
|
+
*
|
|
1811
|
+
* @public
|
|
1812
|
+
*/
|
|
1813
|
+
onBeforeSend?: (event: {
|
|
1814
|
+
conversationId: string;
|
|
1815
|
+
previousMessageCount: number;
|
|
1816
|
+
}) => Promise<void> | void;
|
|
1817
|
+
/**
|
|
1818
|
+
* Production-Readiness #4 — tool lifecycle hooks (ADRs D315-D317).
|
|
1819
|
+
*
|
|
1820
|
+
* `onToolStart` fires BEFORE the handler runs. `onToolEnd` fires after a
|
|
1821
|
+
* successful handler return. `onToolError` fires when validation fails OR
|
|
1822
|
+
* the handler throws — `event.error` is always an `Error` instance.
|
|
1823
|
+
*
|
|
1824
|
+
* Hook errors are SWALLOWED with a stderr warn (do not abort the run).
|
|
1825
|
+
* The `callId` is unique per tool invocation and identical across the
|
|
1826
|
+
* start/end (or start/error) pair, so consumers can correlate.
|
|
1827
|
+
*
|
|
1828
|
+
* Use cases: cost tracking, audit logs, per-tool retry/alerting,
|
|
1829
|
+
* latency telemetry.
|
|
1830
|
+
*
|
|
1831
|
+
* @public
|
|
1832
|
+
*/
|
|
1833
|
+
onToolStart?: (event: {
|
|
1834
|
+
toolName: string;
|
|
1835
|
+
args: unknown;
|
|
1836
|
+
conversationId: string;
|
|
1837
|
+
callId: string;
|
|
1838
|
+
}) => void | Promise<void>;
|
|
1839
|
+
/** Fires when a tool handler returns successfully. */
|
|
1840
|
+
onToolEnd?: (event: {
|
|
1841
|
+
toolName: string;
|
|
1842
|
+
args: unknown;
|
|
1843
|
+
result: unknown;
|
|
1844
|
+
conversationId: string;
|
|
1845
|
+
callId: string;
|
|
1846
|
+
durationMs: number;
|
|
1847
|
+
}) => void | Promise<void>;
|
|
1848
|
+
/**
|
|
1849
|
+
* Fires when a tool handler throws OR schema validation rejects the args.
|
|
1850
|
+
* `event.error` is always an `Error` instance (D315/EC-6 — validation
|
|
1851
|
+
* reasons are wrapped in `new Error(reason)`).
|
|
1852
|
+
*
|
|
1853
|
+
* `attempt` is always `1` in v1 (D317 — reserved for future retry policy).
|
|
1854
|
+
*/
|
|
1855
|
+
onToolError?: (event: {
|
|
1856
|
+
toolName: string;
|
|
1857
|
+
args: unknown;
|
|
1858
|
+
error: Error;
|
|
1859
|
+
conversationId: string;
|
|
1860
|
+
callId: string;
|
|
1861
|
+
durationMs: number;
|
|
1862
|
+
attempt: number;
|
|
1863
|
+
}) => void | Promise<void>;
|
|
1864
|
+
/**
|
|
1865
|
+
* Pluggable budget/usage tracker (SDK 2.0 Phase 2 / T2.1 — ADR D1 interface
|
|
1866
|
+
* inversion). When provided, the agent loop calls `tracker.track(...)`
|
|
1867
|
+
* after each LLM completion and `tracker.check()` before each iteration.
|
|
1868
|
+
*
|
|
1869
|
+
* **Status (Phase 2 incremental):** the option is wired to the type
|
|
1870
|
+
* surface only. Agent-loop runtime wiring is additive and lands in a
|
|
1871
|
+
* subsequent iteration — for now, the kernel still uses the legacy
|
|
1872
|
+
* `UsageAccumulator` + `IterationBudget` from `internal/budget/`.
|
|
1873
|
+
* Consumers passing a custom tracker today get the type guarantee but
|
|
1874
|
+
* NOT runtime enforcement.
|
|
1875
|
+
*
|
|
1876
|
+
* Default impls available today via `@theokit/sdk`:
|
|
1877
|
+
* - `createCounterBudgetTracker({ maxTokens, maxIterations })`
|
|
1878
|
+
*
|
|
1879
|
+
* Future: post-Phase-2, `@theokit/sdk-budget` ships a richer impl with
|
|
1880
|
+
* USD pricing.
|
|
1881
|
+
*
|
|
1882
|
+
* @public
|
|
1883
|
+
*/
|
|
1884
|
+
budgetTracker?: BudgetTracker;
|
|
1885
|
+
/**
|
|
1886
|
+
* Pluggable memory subsystem (SDK 2.0 Phase 1 / T1.3 — Hexagonal
|
|
1887
|
+
* Architecture interface inversion). When provided, the agent loop
|
|
1888
|
+
* calls `provider.init(...)` once per agent, surfaces tools from
|
|
1889
|
+
* `provider.buildTools(...)` to the LLM, runs `provider.runActivePass(...)`
|
|
1890
|
+
* pre-LLM to inject recalled facts, and `provider.dispose(...)` on
|
|
1891
|
+
* Agent shutdown.
|
|
1892
|
+
*
|
|
1893
|
+
* **Status (Phase 1 incremental):** the option is wired to the type
|
|
1894
|
+
* surface only. Agent-loop runtime wiring is additive and lands in
|
|
1895
|
+
* subsequent iterations (T1.4 plumbing, T1.5 runtime hooks). For now,
|
|
1896
|
+
* the kernel still uses the legacy `Memory` class + `internal/memory/*`
|
|
1897
|
+
* runtime files. Consumers passing a custom provider today get the type
|
|
1898
|
+
* guarantee but NOT runtime enforcement.
|
|
1899
|
+
*
|
|
1900
|
+
* Default impls available today via `@theokit/sdk`:
|
|
1901
|
+
* - `createNoopMemoryProvider()` — degenerate fallback / worked example
|
|
1902
|
+
*
|
|
1903
|
+
* Future: post-Phase-1, `@theokit/sdk-memory` ships a rich impl with
|
|
1904
|
+
* LanceDB / embeddings / circuit breaker / active-memory cache.
|
|
1905
|
+
*
|
|
1906
|
+
* @public
|
|
1907
|
+
*/
|
|
1908
|
+
memoryProvider?: MemoryProvider;
|
|
1909
|
+
}
|
|
1910
|
+
/**
|
|
1911
|
+
* Metadata returned by `Agent.list()` and `Agent.get()`.
|
|
1912
|
+
*
|
|
1913
|
+
* @public
|
|
1914
|
+
*/
|
|
1915
|
+
type SDKAgentInfo = {
|
|
1916
|
+
agentId: string;
|
|
1917
|
+
name: string;
|
|
1918
|
+
summary: string;
|
|
1919
|
+
lastModified: number;
|
|
1920
|
+
status?: "running" | "finished" | "error";
|
|
1921
|
+
createdAt?: number;
|
|
1922
|
+
archived?: boolean;
|
|
1923
|
+
} & ({
|
|
1924
|
+
runtime?: undefined;
|
|
1925
|
+
} | {
|
|
1926
|
+
runtime: "local";
|
|
1927
|
+
cwd?: string;
|
|
1928
|
+
} | {
|
|
1929
|
+
runtime: "cloud";
|
|
1930
|
+
env?: CloudEnv;
|
|
1931
|
+
repos?: string[];
|
|
1932
|
+
});
|
|
1933
|
+
/**
|
|
1934
|
+
* Options for `Agent.list()`.
|
|
1935
|
+
*
|
|
1936
|
+
* @public
|
|
1937
|
+
*/
|
|
1938
|
+
type ListAgentsOptions = {
|
|
1939
|
+
limit?: number;
|
|
1940
|
+
cursor?: string;
|
|
1941
|
+
} & ({
|
|
1942
|
+
runtime?: undefined;
|
|
1943
|
+
} | {
|
|
1944
|
+
runtime: "local";
|
|
1945
|
+
cwd?: string;
|
|
1946
|
+
} | {
|
|
1947
|
+
runtime: "cloud";
|
|
1948
|
+
prUrl?: string;
|
|
1949
|
+
includeArchived?: boolean;
|
|
1950
|
+
apiKey?: string;
|
|
1951
|
+
});
|
|
1952
|
+
/**
|
|
1953
|
+
* Options for `Agent.get()`.
|
|
1954
|
+
*
|
|
1955
|
+
* @public
|
|
1956
|
+
*/
|
|
1957
|
+
interface GetAgentOptions {
|
|
1958
|
+
cwd?: string;
|
|
1959
|
+
apiKey?: string;
|
|
1960
|
+
}
|
|
1961
|
+
/**
|
|
1962
|
+
* Options for `Agent.listRuns()`.
|
|
1963
|
+
*
|
|
1964
|
+
* @public
|
|
1965
|
+
*/
|
|
1966
|
+
type ListRunsOptions = {
|
|
1967
|
+
limit?: number;
|
|
1968
|
+
cursor?: string;
|
|
1969
|
+
} & ({
|
|
1970
|
+
runtime?: "local";
|
|
1971
|
+
cwd?: string;
|
|
1972
|
+
} | {
|
|
1973
|
+
runtime: "cloud";
|
|
1974
|
+
apiKey?: string;
|
|
1975
|
+
});
|
|
1976
|
+
/**
|
|
1977
|
+
* Options for `Agent.getRun()`. Cloud requires the parent `agentId`.
|
|
1978
|
+
*
|
|
1979
|
+
* @public
|
|
1980
|
+
*/
|
|
1981
|
+
type GetRunOptions = {
|
|
1982
|
+
runtime?: "local";
|
|
1983
|
+
cwd?: string;
|
|
1984
|
+
} | {
|
|
1985
|
+
runtime: "cloud";
|
|
1986
|
+
agentId: string;
|
|
1987
|
+
apiKey?: string;
|
|
1988
|
+
};
|
|
1989
|
+
/**
|
|
1990
|
+
* Options for archive/unarchive/delete.
|
|
1991
|
+
*
|
|
1992
|
+
* @public
|
|
1993
|
+
*/
|
|
1994
|
+
interface AgentOperationOptions {
|
|
1995
|
+
cwd?: string;
|
|
1996
|
+
apiKey?: string;
|
|
1997
|
+
}
|
|
1998
|
+
/**
|
|
1999
|
+
* Paginated list shape.
|
|
2000
|
+
*
|
|
2001
|
+
* @public
|
|
2002
|
+
*/
|
|
2003
|
+
interface ListResult<T> {
|
|
2004
|
+
items: T[];
|
|
2005
|
+
nextCursor?: string;
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
/**
|
|
2009
|
+
* Public type contract for `Workflow.create / .run / .resume` (Adoption
|
|
2010
|
+
* Roadmap #5; ADRs D230-D248).
|
|
2011
|
+
*
|
|
2012
|
+
* Step types form a discriminated union by `kind`. Helper factory functions
|
|
2013
|
+
* (`fn()`, `agentStep()`) live in `workflow.ts` and hide the discriminator
|
|
2014
|
+
* from end users.
|
|
2015
|
+
*
|
|
2016
|
+
* @public
|
|
2017
|
+
*/
|
|
2018
|
+
|
|
2019
|
+
type Step = FnStep | AgentStep | ParallelStep | BranchStep | ForeachStep | DowhileStep | SleepStep | SuspendStep;
|
|
2020
|
+
/** A pure function step. */
|
|
2021
|
+
interface FnStep {
|
|
2022
|
+
readonly kind: "fn";
|
|
2023
|
+
readonly id: string;
|
|
2024
|
+
readonly fn: (input: unknown, ctx: StepContext) => Promise<unknown> | unknown;
|
|
2025
|
+
readonly inputSchema?: ZodType;
|
|
2026
|
+
readonly outputSchema?: ZodType;
|
|
2027
|
+
readonly retry?: RetryPolicy;
|
|
2028
|
+
/** D238 — slot reserved; runtime throws if engine not yet implemented. */
|
|
2029
|
+
readonly compensate?: (input: unknown, output: unknown, error: Error) => Promise<void> | void;
|
|
2030
|
+
}
|
|
2031
|
+
/** An agent.send-driven step. */
|
|
2032
|
+
interface AgentStep {
|
|
2033
|
+
readonly kind: "agent";
|
|
2034
|
+
readonly id: string;
|
|
2035
|
+
readonly agent: SDKAgent;
|
|
2036
|
+
readonly promptTemplate: string | ((input: unknown) => string);
|
|
2037
|
+
readonly retry?: RetryPolicy;
|
|
2038
|
+
/**
|
|
2039
|
+
* SE3 — provenance stamped onto this step's `agent.send()` (forwarded to
|
|
2040
|
+
* `RunResult.origin`). Squad sets `{ kind: "peer", from: "agent-<i-1>" }` on
|
|
2041
|
+
* every step after the first so a peer-driven turn is attributable.
|
|
2042
|
+
*/
|
|
2043
|
+
readonly origin?: MessageOrigin;
|
|
2044
|
+
}
|
|
2045
|
+
/** N concurrent branches, each its own mini-step-list. */
|
|
2046
|
+
interface ParallelStep {
|
|
2047
|
+
readonly kind: "parallel";
|
|
2048
|
+
readonly id: string;
|
|
2049
|
+
readonly branches: ReadonlyArray<ReadonlyArray<Step>>;
|
|
2050
|
+
readonly concurrency?: number;
|
|
2051
|
+
readonly errorPolicy?: "fail-fast" | "collect";
|
|
2052
|
+
}
|
|
2053
|
+
/** First-match-wins predicates + optional fallback. */
|
|
2054
|
+
interface BranchStep {
|
|
2055
|
+
readonly kind: "branch";
|
|
2056
|
+
readonly id: string;
|
|
2057
|
+
readonly predicates: ReadonlyArray<readonly [(input: unknown) => boolean | Promise<boolean>, ReadonlyArray<Step>]>;
|
|
2058
|
+
readonly fallback?: ReadonlyArray<Step>;
|
|
2059
|
+
}
|
|
2060
|
+
/** Map a step over an upstream array output. */
|
|
2061
|
+
interface ForeachStep {
|
|
2062
|
+
readonly kind: "foreach";
|
|
2063
|
+
readonly id: string;
|
|
2064
|
+
/** ID of an upstream top-level step whose output is iterable. */
|
|
2065
|
+
readonly iterableFrom: string;
|
|
2066
|
+
readonly step: Step;
|
|
2067
|
+
readonly concurrency?: number;
|
|
2068
|
+
}
|
|
2069
|
+
/** Loop a step until condFn returns false. */
|
|
2070
|
+
interface DowhileStep {
|
|
2071
|
+
readonly kind: "dowhile";
|
|
2072
|
+
readonly id: string;
|
|
2073
|
+
readonly step: Step;
|
|
2074
|
+
readonly condFn: (output: unknown, iteration: number) => boolean | Promise<boolean>;
|
|
2075
|
+
readonly maxIterations?: number;
|
|
2076
|
+
}
|
|
2077
|
+
/** Pause for a fixed duration. */
|
|
2078
|
+
interface SleepStep {
|
|
2079
|
+
readonly kind: "sleep";
|
|
2080
|
+
readonly id: string;
|
|
2081
|
+
readonly durationMs: number;
|
|
2082
|
+
}
|
|
2083
|
+
/** Standalone explicit suspend point. */
|
|
2084
|
+
interface SuspendStep {
|
|
2085
|
+
readonly kind: "suspend";
|
|
2086
|
+
readonly id: string;
|
|
2087
|
+
readonly payloadSchema?: ZodType;
|
|
2088
|
+
}
|
|
2089
|
+
/** D237 — retry policy applied per fn/agent step. */
|
|
2090
|
+
interface RetryPolicy {
|
|
2091
|
+
/** Total attempts (MIN 1, MAX 20). `1` = no retry. */
|
|
2092
|
+
readonly maxAttempts: number;
|
|
2093
|
+
readonly initialBackoffMs?: number;
|
|
2094
|
+
readonly backoffCoefficient?: number;
|
|
2095
|
+
readonly maximumBackoffMs?: number;
|
|
2096
|
+
readonly nonRetryableErrors?: ReadonlyArray<string>;
|
|
2097
|
+
}
|
|
2098
|
+
/** D247 — context handed to every step.fn. */
|
|
2099
|
+
interface StepContext {
|
|
2100
|
+
readonly runId: string;
|
|
2101
|
+
readonly signal: AbortSignal;
|
|
2102
|
+
readonly log: {
|
|
2103
|
+
debug: (msg: string, attrs?: Record<string, unknown>) => void;
|
|
2104
|
+
info: (msg: string, attrs?: Record<string, unknown>) => void;
|
|
2105
|
+
warn: (msg: string, attrs?: Record<string, unknown>) => void;
|
|
2106
|
+
};
|
|
2107
|
+
/** Pause the workflow; resume via `Workflow.resume({...})`. */
|
|
2108
|
+
readonly suspend: (payload?: unknown) => Promise<never>;
|
|
2109
|
+
/**
|
|
2110
|
+
* SE29 — the workflow's shared state (from `WorkflowOptions.initialState`,
|
|
2111
|
+
* mutated by {@link setState}), visible to every subsequent step in the run.
|
|
2112
|
+
* `undefined` when no `initialState`/`setState` has run. Persisted across
|
|
2113
|
+
* suspend/resume.
|
|
2114
|
+
*/
|
|
2115
|
+
readonly state: unknown;
|
|
2116
|
+
/**
|
|
2117
|
+
* SE29 — update the shared state for subsequent steps. Validated against
|
|
2118
|
+
* `WorkflowOptions.stateSchema` when set (a mismatch throws
|
|
2119
|
+
* {@link WorkflowStateError}, which fails the step/run — Rule 8).
|
|
2120
|
+
*/
|
|
2121
|
+
readonly setState: (next: unknown) => void;
|
|
2122
|
+
}
|
|
2123
|
+
interface StepResult {
|
|
2124
|
+
readonly stepId: string;
|
|
2125
|
+
readonly kind: Step["kind"];
|
|
2126
|
+
readonly status: "completed" | "failed" | "skipped" | "suspended";
|
|
2127
|
+
readonly attempts: number;
|
|
2128
|
+
readonly durationMs: number;
|
|
2129
|
+
readonly output?: unknown;
|
|
2130
|
+
readonly error?: {
|
|
2131
|
+
name: string;
|
|
2132
|
+
message: string;
|
|
2133
|
+
};
|
|
2134
|
+
}
|
|
2135
|
+
interface WorkflowRun<TOutput = unknown> {
|
|
2136
|
+
readonly id: string;
|
|
2137
|
+
readonly name: string;
|
|
2138
|
+
readonly status: "running" | "completed" | "failed" | "suspended" | "cancelled";
|
|
2139
|
+
readonly output?: TOutput;
|
|
2140
|
+
readonly error?: {
|
|
2141
|
+
name: string;
|
|
2142
|
+
message: string;
|
|
2143
|
+
};
|
|
2144
|
+
readonly startedAt: number;
|
|
2145
|
+
readonly endedAt?: number;
|
|
2146
|
+
readonly stepResults: ReadonlyArray<StepResult>;
|
|
2147
|
+
}
|
|
2148
|
+
/**
|
|
2149
|
+
* SE28 — a step-level workflow event emitted by `Workflow.stream()` as top-level
|
|
2150
|
+
* steps run. Coarse-grained (one event per top-level step; nested
|
|
2151
|
+
* parallel/branch/foreach emit as their single wrapping step), distinct from the
|
|
2152
|
+
* token-delta agent stream. Discriminate on `type`.
|
|
2153
|
+
*
|
|
2154
|
+
* @public
|
|
2155
|
+
*/
|
|
2156
|
+
type WorkflowEvent = {
|
|
2157
|
+
readonly type: "step_started";
|
|
2158
|
+
readonly stepId: string;
|
|
2159
|
+
} | {
|
|
2160
|
+
readonly type: "step_completed";
|
|
2161
|
+
readonly stepId: string;
|
|
2162
|
+
readonly output: unknown;
|
|
2163
|
+
} | {
|
|
2164
|
+
readonly type: "step_failed";
|
|
2165
|
+
readonly stepId: string;
|
|
2166
|
+
readonly error: {
|
|
2167
|
+
readonly name: string;
|
|
2168
|
+
readonly message: string;
|
|
2169
|
+
};
|
|
2170
|
+
} | {
|
|
2171
|
+
readonly type: "workflow_suspended";
|
|
2172
|
+
readonly stepId: string;
|
|
2173
|
+
} | {
|
|
2174
|
+
readonly type: "workflow_completed";
|
|
2175
|
+
};
|
|
2176
|
+
/**
|
|
2177
|
+
* SE28 — the async iterator returned by `Workflow.stream()`. Yields
|
|
2178
|
+
* {@link WorkflowEvent}s in execution order; `result` resolves to the same
|
|
2179
|
+
* terminal {@link WorkflowRun} the `run()` path returns (the authoritative
|
|
2180
|
+
* outcome — the stream ends when the run terminates).
|
|
2181
|
+
*
|
|
2182
|
+
* @public
|
|
2183
|
+
*/
|
|
2184
|
+
type WorkflowStream<TOutput = unknown> = AsyncIterableIterator<WorkflowEvent> & {
|
|
2185
|
+
readonly result: Promise<WorkflowRun<TOutput>>;
|
|
2186
|
+
};
|
|
2187
|
+
interface WorkflowPersistenceOptions {
|
|
2188
|
+
readonly backend: "memory" | "json";
|
|
2189
|
+
/** Required for `backend: "json"`. */
|
|
2190
|
+
readonly dir?: string;
|
|
2191
|
+
}
|
|
2192
|
+
interface WorkflowOptions {
|
|
2193
|
+
readonly name: string;
|
|
2194
|
+
readonly persistence?: WorkflowPersistenceOptions;
|
|
2195
|
+
/**
|
|
2196
|
+
* SE27 — Zod schema for the WHOLE workflow's input. When set, `run(input)`
|
|
2197
|
+
* validates `input` BEFORE step 1; a mismatch yields `status: "failed"` with a
|
|
2198
|
+
* typed {@link WorkflowInputError} in `error` (fail-fast, no step runs, no
|
|
2199
|
+
* silent coerce). Absent ⇒ no whole-workflow input validation (unchanged).
|
|
2200
|
+
*/
|
|
2201
|
+
readonly inputSchema?: ZodType;
|
|
2202
|
+
/**
|
|
2203
|
+
* SE27 — Zod schema for the workflow's final output. When set, the terminal
|
|
2204
|
+
* `completed` output is validated before `WorkflowRun.output` is populated; a
|
|
2205
|
+
* mismatch yields `status: "failed"` with a typed {@link WorkflowOutputError}.
|
|
2206
|
+
* Only validated on the `completed` path (suspended/failed runs skip it).
|
|
2207
|
+
*/
|
|
2208
|
+
readonly outputSchema?: ZodType;
|
|
2209
|
+
/**
|
|
2210
|
+
* SE29 — Zod schema for the workflow's shared state (see `StepContext.state` /
|
|
2211
|
+
* `setState`). When set, `initialState` and every `setState(next)` are
|
|
2212
|
+
* validated against it (a mismatch throws {@link WorkflowStateError}). When
|
|
2213
|
+
* `initialState` is absent, `state` starts as `undefined` and validation fires
|
|
2214
|
+
* on the first `setState` call.
|
|
2215
|
+
*/
|
|
2216
|
+
readonly stateSchema?: ZodType;
|
|
2217
|
+
/**
|
|
2218
|
+
* SE29 — the initial shared state, seeded onto `StepContext.state` before
|
|
2219
|
+
* step 1. Validated against `stateSchema` when both are set. Persisted across
|
|
2220
|
+
* suspend/resume.
|
|
2221
|
+
*/
|
|
2222
|
+
readonly initialState?: unknown;
|
|
2223
|
+
/** Internal — minted at `.commit()`. Not user-facing. */
|
|
2224
|
+
readonly workflowId?: string;
|
|
2225
|
+
}
|
|
2226
|
+
interface WorkflowRunOptions {
|
|
2227
|
+
readonly signal?: AbortSignal;
|
|
2228
|
+
/** Override run ID for deterministic resume (advanced; default = mintRunId). */
|
|
2229
|
+
readonly runId?: string;
|
|
2230
|
+
/**
|
|
2231
|
+
* Opt-in Task wrapping (ADRs D363, D374). Registers the workflow run
|
|
2232
|
+
* as a `Task` (kind="workflow") with a `wf-` namespaced id (D368,
|
|
2233
|
+
* EC-5). The task transitions terminal when `Workflow.run` resolves.
|
|
2234
|
+
*
|
|
2235
|
+
* Auto-id: `wf-{runId}`.
|
|
2236
|
+
*
|
|
2237
|
+
* @public
|
|
2238
|
+
*/
|
|
2239
|
+
readonly task?: true | {
|
|
2240
|
+
id?: string;
|
|
2241
|
+
meta?: Record<string, unknown>;
|
|
2242
|
+
};
|
|
2243
|
+
}
|
|
2244
|
+
interface WorkflowResumeOptions<TI = unknown> {
|
|
2245
|
+
readonly runId: string;
|
|
2246
|
+
readonly workflow: {
|
|
2247
|
+
run: (input: TI, opts?: WorkflowRunOptions) => Promise<WorkflowRun>;
|
|
2248
|
+
};
|
|
2249
|
+
readonly payload?: unknown;
|
|
2250
|
+
readonly signal?: AbortSignal;
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
/**
|
|
2254
|
+
* Public `Workflow` class — declarative multi-step orchestration over
|
|
2255
|
+
* `Agent.send`, `Handoff`, `Agent.batch` and friends (Adoption Roadmap #5;
|
|
2256
|
+
* ADRs D230-D248).
|
|
2257
|
+
*
|
|
2258
|
+
* Usage:
|
|
2259
|
+
*
|
|
2260
|
+
* import { Agent } from "@theokit/sdk";
|
|
2261
|
+
* import { Workflow, fn, agentStep } from "@theokit/sdk/workflow";
|
|
2262
|
+
*
|
|
2263
|
+
* const classifier = await Agent.create({ ... });
|
|
2264
|
+
* const wf = Workflow.create({ name: "demo" })
|
|
2265
|
+
* .then(fn("validate", (input: { id: string }) => {
|
|
2266
|
+
* if (!input.id) throw new Error("missing id");
|
|
2267
|
+
* return input;
|
|
2268
|
+
* }))
|
|
2269
|
+
* .then(agentStep("classify", classifier, (i) => `Classify: ${JSON.stringify(i)}`))
|
|
2270
|
+
* .commit();
|
|
2271
|
+
*
|
|
2272
|
+
* const run = await wf.run({ id: "x" });
|
|
2273
|
+
* console.log(run.status, run.output);
|
|
2274
|
+
*
|
|
2275
|
+
* @public
|
|
2276
|
+
*/
|
|
2277
|
+
|
|
2278
|
+
declare class WorkflowBuilder<TInput = unknown, TOutput = unknown> {
|
|
2279
|
+
private readonly options;
|
|
2280
|
+
private readonly _steps;
|
|
2281
|
+
private _committed;
|
|
2282
|
+
then<TO = unknown>(step: Step): WorkflowBuilder<TInput, TO>;
|
|
2283
|
+
parallel(branches: ReadonlyArray<ReadonlyArray<Step>>, opts?: {
|
|
2284
|
+
id?: string;
|
|
2285
|
+
concurrency?: number;
|
|
2286
|
+
errorPolicy?: "fail-fast" | "collect";
|
|
2287
|
+
}): WorkflowBuilder<TInput, unknown[]>;
|
|
2288
|
+
branch(predicates: BranchStep["predicates"], opts?: {
|
|
2289
|
+
id?: string;
|
|
2290
|
+
fallback?: ReadonlyArray<Step>;
|
|
2291
|
+
}): WorkflowBuilder<TInput, unknown>;
|
|
2292
|
+
foreach(iterableFrom: string, step: Step, opts?: {
|
|
2293
|
+
id?: string;
|
|
2294
|
+
concurrency?: number;
|
|
2295
|
+
}): WorkflowBuilder<TInput, unknown[]>;
|
|
2296
|
+
dowhile(step: Step, condFn: DowhileStep["condFn"], opts?: {
|
|
2297
|
+
id?: string;
|
|
2298
|
+
maxIterations?: number;
|
|
2299
|
+
}): WorkflowBuilder<TInput, unknown>;
|
|
2300
|
+
sleep(durationMs: number, id?: string): WorkflowBuilder<TInput, TOutput>;
|
|
2301
|
+
suspend(opts?: {
|
|
2302
|
+
id?: string;
|
|
2303
|
+
payloadSchema?: ZodType;
|
|
2304
|
+
}): WorkflowBuilder<TInput, unknown>;
|
|
2305
|
+
commit(): Workflow<TInput, TOutput>;
|
|
2306
|
+
private validateUniqueIds;
|
|
2307
|
+
private assertNotCommitted;
|
|
2308
|
+
}
|
|
2309
|
+
declare class Workflow<TInput = unknown, TOutput = unknown> {
|
|
2310
|
+
private readonly _options;
|
|
2311
|
+
private readonly _steps;
|
|
2312
|
+
/**
|
|
2313
|
+
* Construct a workflow builder. Validate options via Zod and return a
|
|
2314
|
+
* `WorkflowBuilder` for fluent chaining. Call `.commit()` to obtain the
|
|
2315
|
+
* immutable `Workflow`.
|
|
2316
|
+
*/
|
|
2317
|
+
static create<TI = unknown, TO = unknown>(options: WorkflowOptions): WorkflowBuilder<TI, TO>;
|
|
2318
|
+
/**
|
|
2319
|
+
* Run this workflow with the given input. Returns a populated
|
|
2320
|
+
* `WorkflowRun`. Errors inside a step DO NOT throw — they propagate via
|
|
2321
|
+
* `run.status === "failed"`.
|
|
2322
|
+
*/
|
|
2323
|
+
run(input: TInput, opts?: WorkflowRunOptions): Promise<WorkflowRun<TOutput>>;
|
|
2324
|
+
/**
|
|
2325
|
+
* SE28 — run the workflow and STREAM step-level events as they happen. Returns
|
|
2326
|
+
* an async iterator of {@link WorkflowEvent}s (`step_started` / `step_completed`
|
|
2327
|
+
* / `step_failed` / `workflow_suspended` / `workflow_completed`, top-level
|
|
2328
|
+
* steps) plus a `result` promise resolving to the same terminal
|
|
2329
|
+
* {@link WorkflowRun} `run()` returns. Iterate for progress; await `result` for
|
|
2330
|
+
* the outcome. The stream ends when the run terminates.
|
|
2331
|
+
*
|
|
2332
|
+
* `result` is the AUTHORITATIVE terminal status. Not every terminal state has a
|
|
2333
|
+
* closing event: a step failure emits `step_failed`, but an `outputSchema`
|
|
2334
|
+
* rejection (SE27) or an abort ends the stream WITHOUT `workflow_completed` —
|
|
2335
|
+
* always `await result` to read the final `status`. Consuming order is free:
|
|
2336
|
+
* awaiting `result` without draining, or draining without awaiting `result`,
|
|
2337
|
+
* both work (breaking out of `for await` stops the buffering early).
|
|
2338
|
+
*/
|
|
2339
|
+
stream(input: TInput, opts?: WorkflowRunOptions): WorkflowStream<TOutput>;
|
|
2340
|
+
/**
|
|
2341
|
+
* Resume a suspended workflow from its snapshot. Throws
|
|
2342
|
+
* `WorkflowSnapshotNotFoundError` if `runId` is unknown.
|
|
2343
|
+
*/
|
|
2344
|
+
static resume<TO = unknown>(opts: WorkflowResumeOptions): Promise<WorkflowRun<TO>>;
|
|
2345
|
+
}
|
|
2346
|
+
|
|
2347
|
+
/**
|
|
2348
|
+
* Runtime hosting a cron job. Mirrors the agent runtime split.
|
|
2349
|
+
*
|
|
2350
|
+
* - `local` — the in-process scheduler activated via `Cron.start()` fires the
|
|
2351
|
+
* job while the host process is alive.
|
|
2352
|
+
* - `cloud` — Theo PaaS schedules the job server-side; fires independent of
|
|
2353
|
+
* any SDK process.
|
|
2354
|
+
*
|
|
2355
|
+
* @public
|
|
2356
|
+
*/
|
|
2357
|
+
type CronRuntime = "local" | "cloud";
|
|
2358
|
+
/**
|
|
2359
|
+
* Lifecycle state reported by `Cron.list()` / `Cron.get()`.
|
|
2360
|
+
*
|
|
2361
|
+
* @public
|
|
2362
|
+
*/
|
|
2363
|
+
type CronJobStatus = "scheduled" | "running" | "paused" | "errored";
|
|
2364
|
+
/**
|
|
2365
|
+
* Persistent cron-scheduled invocation of the Theo agent or a workflow.
|
|
2366
|
+
*
|
|
2367
|
+
* Exactly one target is set: {@link CronJob.agent} (ephemeral agent created on
|
|
2368
|
+
* each fire), {@link CronJob.agentId} (bound to an existing agent for context
|
|
2369
|
+
* continuity), or {@link CronJob.workflow} (a committed workflow run per fire;
|
|
2370
|
+
* SE35). Agent targets carry a `message`; a workflow target carries `inputData`.
|
|
2371
|
+
*
|
|
2372
|
+
* @public
|
|
2373
|
+
*/
|
|
2374
|
+
interface CronJob {
|
|
2375
|
+
id: string;
|
|
2376
|
+
name?: string;
|
|
2377
|
+
/** Standard 5-field POSIX cron expression or shorthand (`@hourly`, `@daily`, ...). */
|
|
2378
|
+
cron: string;
|
|
2379
|
+
/** IANA timezone identifier. Defaults to `"UTC"`. */
|
|
2380
|
+
timezone?: string;
|
|
2381
|
+
/** Message sent to the agent on each fire. Present for agent targets; absent for a workflow target. */
|
|
2382
|
+
message?: string | SDKUserMessage;
|
|
2383
|
+
/** Ephemeral agent options. Mutually exclusive with `agentId`/`workflow`. */
|
|
2384
|
+
agent?: AgentOptions;
|
|
2385
|
+
/** ID of an existing agent to reuse for context continuity. Mutually exclusive with `agent`/`workflow`. */
|
|
2386
|
+
agentId?: string;
|
|
2387
|
+
/**
|
|
2388
|
+
* SE35 — a committed {@link Workflow} run on each fire (`workflow.run(inputData)`).
|
|
2389
|
+
* Mutually exclusive with `agent`/`agentId`. Held in-memory (local runtime only —
|
|
2390
|
+
* a workflow instance cannot cross the cloud process boundary). ADR 0014.
|
|
2391
|
+
*/
|
|
2392
|
+
workflow?: Workflow;
|
|
2393
|
+
/** SE35 — input passed to `workflow.run(inputData)` on each fire. Workflow targets only. */
|
|
2394
|
+
inputData?: unknown;
|
|
2395
|
+
/** Whether the scheduler will fire this job on schedule. */
|
|
2396
|
+
enabled: boolean;
|
|
2397
|
+
/** Current status. */
|
|
2398
|
+
status: CronJobStatus;
|
|
2399
|
+
/** Runtime that hosts this job. Inferred from `agent`/`agentId`/`workflow` at create time (a `workflow` target is always `local`). */
|
|
2400
|
+
runtime: CronRuntime;
|
|
2401
|
+
/** Unix ms of the last successful fire, if any. */
|
|
2402
|
+
lastRunAt?: number;
|
|
2403
|
+
/** Unix ms of the next scheduled fire, computed by the scheduler. */
|
|
2404
|
+
nextRunAt?: number;
|
|
2405
|
+
/** Unix ms when the job was created. */
|
|
2406
|
+
createdAt: number;
|
|
2407
|
+
}
|
|
2408
|
+
/**
|
|
2409
|
+
* Options for `Cron.create()`.
|
|
2410
|
+
*
|
|
2411
|
+
* Pass exactly ONE target: `agent` (ephemeral agent fresh per fire), `agentId`
|
|
2412
|
+
* (reuse an existing agent — preserves conversation context), or `workflow`
|
|
2413
|
+
* (SE35 — run a committed workflow per fire). Agent targets REQUIRE `message`;
|
|
2414
|
+
* a workflow target takes `inputData` and MUST NOT set `message`. Violations are
|
|
2415
|
+
* a `ConfigurationError`.
|
|
2416
|
+
*
|
|
2417
|
+
* @public
|
|
2418
|
+
*/
|
|
2419
|
+
interface CronCreateOptions {
|
|
2420
|
+
cron: string;
|
|
2421
|
+
/** Message for an agent target. Required with `agent`/`agentId`; forbidden with `workflow`. */
|
|
2422
|
+
message?: string | SDKUserMessage;
|
|
2423
|
+
agent?: AgentOptions;
|
|
2424
|
+
agentId?: string;
|
|
2425
|
+
/** SE35 — a committed {@link Workflow} to run per fire. Mutually exclusive with `agent`/`agentId`. */
|
|
2426
|
+
workflow?: Workflow;
|
|
2427
|
+
/** SE35 — input for `workflow.run(inputData)`. Workflow targets only. */
|
|
2428
|
+
inputData?: unknown;
|
|
2429
|
+
name?: string;
|
|
2430
|
+
timezone?: string;
|
|
2431
|
+
/** Defaults to `true`. */
|
|
2432
|
+
enabled?: boolean;
|
|
2433
|
+
/** Falls back to `THEOKIT_API_KEY`. */
|
|
2434
|
+
apiKey?: string;
|
|
2435
|
+
}
|
|
2436
|
+
/**
|
|
2437
|
+
* Options for `Cron.list()`.
|
|
2438
|
+
*
|
|
2439
|
+
* @public
|
|
2440
|
+
*/
|
|
2441
|
+
type CronListOptions = {
|
|
2442
|
+
limit?: number;
|
|
2443
|
+
cursor?: string;
|
|
2444
|
+
} & ({
|
|
2445
|
+
runtime?: undefined;
|
|
2446
|
+
} | {
|
|
2447
|
+
runtime: "local";
|
|
2448
|
+
cwd?: string;
|
|
2449
|
+
} | {
|
|
2450
|
+
runtime: "cloud";
|
|
2451
|
+
apiKey?: string;
|
|
2452
|
+
});
|
|
2453
|
+
/**
|
|
2454
|
+
* Options for `Cron.get()`.
|
|
2455
|
+
*
|
|
2456
|
+
* @public
|
|
2457
|
+
*/
|
|
2458
|
+
interface CronGetOptions {
|
|
2459
|
+
cwd?: string;
|
|
2460
|
+
apiKey?: string;
|
|
2461
|
+
}
|
|
2462
|
+
/**
|
|
2463
|
+
* Options for `Cron.delete()` / `Cron.enable()` / `Cron.disable()`.
|
|
2464
|
+
*
|
|
2465
|
+
* @public
|
|
2466
|
+
*/
|
|
2467
|
+
interface CronOperationOptions {
|
|
2468
|
+
cwd?: string;
|
|
2469
|
+
apiKey?: string;
|
|
2470
|
+
}
|
|
2471
|
+
/**
|
|
2472
|
+
* Options for `Cron.run()` — manually trigger a job off-schedule.
|
|
2473
|
+
*
|
|
2474
|
+
* @public
|
|
2475
|
+
*/
|
|
2476
|
+
interface CronRunOptions {
|
|
2477
|
+
cwd?: string;
|
|
2478
|
+
apiKey?: string;
|
|
2479
|
+
}
|
|
2480
|
+
/**
|
|
2481
|
+
* Options for `Cron.start()` — activates the in-process scheduler for local
|
|
2482
|
+
* jobs.
|
|
2483
|
+
*
|
|
2484
|
+
* @public
|
|
2485
|
+
*/
|
|
2486
|
+
interface CronStartOptions {
|
|
2487
|
+
/** Local workspace whose `.theokit/cron/jobs.json` to load. Defaults to `process.cwd()`. */
|
|
2488
|
+
cwd?: string;
|
|
2489
|
+
/** Override the env API key. */
|
|
2490
|
+
apiKey?: string;
|
|
2491
|
+
}
|
|
2492
|
+
/**
|
|
2493
|
+
* Snapshot of the local scheduler returned by `Cron.status()`.
|
|
2494
|
+
*
|
|
2495
|
+
* @public
|
|
2496
|
+
*/
|
|
2497
|
+
interface CronSchedulerStatus {
|
|
2498
|
+
/** Whether the in-process scheduler is currently running. */
|
|
2499
|
+
running: boolean;
|
|
2500
|
+
/** Number of jobs loaded into the scheduler. */
|
|
2501
|
+
jobCount: number;
|
|
2502
|
+
/** Unix ms of the next scheduled fire across all jobs, if any. */
|
|
2503
|
+
nextFireAt?: number;
|
|
2504
|
+
/** Last error observed in the scheduler, if any. */
|
|
2505
|
+
lastError?: {
|
|
2506
|
+
jobId: string;
|
|
2507
|
+
message: string;
|
|
2508
|
+
at: number;
|
|
2509
|
+
};
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2512
|
+
/**
|
|
2513
|
+
* Static façade for scheduling Theo agent runs on a cron expression.
|
|
2514
|
+
*
|
|
2515
|
+
* @public
|
|
2516
|
+
*/
|
|
2517
|
+
declare class Cron {
|
|
2518
|
+
private constructor();
|
|
2519
|
+
/**
|
|
2520
|
+
* Create and persist a cron job.
|
|
2521
|
+
*
|
|
2522
|
+
* @public
|
|
2523
|
+
*/
|
|
2524
|
+
static create(options: CronCreateOptions): Promise<CronJob>;
|
|
2525
|
+
/**
|
|
2526
|
+
* List cron jobs (local, cloud, or both).
|
|
2527
|
+
*
|
|
2528
|
+
* @public
|
|
2529
|
+
*/
|
|
2530
|
+
static list(options?: CronListOptions): Promise<ListResult<CronJob>>;
|
|
2531
|
+
/**
|
|
2532
|
+
* Get a single cron job by ID.
|
|
2533
|
+
*
|
|
2534
|
+
* @public
|
|
2535
|
+
*/
|
|
2536
|
+
static get(jobId: string, _options?: CronGetOptions): Promise<CronJob>;
|
|
2537
|
+
/**
|
|
2538
|
+
* Delete a cron job permanently.
|
|
2539
|
+
*
|
|
2540
|
+
* @public
|
|
2541
|
+
*/
|
|
2542
|
+
static delete(jobId: string, _options?: CronOperationOptions): Promise<void>;
|
|
2543
|
+
/**
|
|
2544
|
+
* Re-enable a paused cron job.
|
|
2545
|
+
*
|
|
2546
|
+
* @public
|
|
2547
|
+
*/
|
|
2548
|
+
static enable(jobId: string, _options?: CronOperationOptions): Promise<CronJob>;
|
|
2549
|
+
/**
|
|
2550
|
+
* Pause a cron job without deleting it.
|
|
2551
|
+
*
|
|
2552
|
+
* @public
|
|
2553
|
+
*/
|
|
2554
|
+
static disable(jobId: string, _options?: CronOperationOptions): Promise<CronJob>;
|
|
2555
|
+
/**
|
|
2556
|
+
* Manually trigger a cron job off-schedule. Returns the resulting `Run`
|
|
2557
|
+
* (agent target) or `WorkflowRun` (workflow target — SE35).
|
|
2558
|
+
*
|
|
2559
|
+
* @public
|
|
2560
|
+
*/
|
|
2561
|
+
static run(jobId: string, _options?: CronRunOptions): Promise<Run | WorkflowRun>;
|
|
2562
|
+
/**
|
|
2563
|
+
* Activate the in-process scheduler for local cron jobs.
|
|
2564
|
+
*
|
|
2565
|
+
* @public
|
|
2566
|
+
*/
|
|
2567
|
+
static start(options?: CronStartOptions): Promise<void>;
|
|
2568
|
+
/**
|
|
2569
|
+
* Stop the in-process scheduler. Jobs are preserved.
|
|
2570
|
+
*
|
|
2571
|
+
* @public
|
|
2572
|
+
*/
|
|
2573
|
+
static stop(): Promise<void>;
|
|
2574
|
+
/**
|
|
2575
|
+
* Snapshot of the local scheduler.
|
|
2576
|
+
*
|
|
2577
|
+
* @public
|
|
2578
|
+
*/
|
|
2579
|
+
static status(_options?: CronStartOptions): Promise<CronSchedulerStatus>;
|
|
2580
|
+
}
|
|
2581
|
+
|
|
2582
|
+
export { type CronSchedulerStatus as $, type AgentOptions as A, type BudgetTracker as B, type CloudOptions as C, type BudgetUsageEvent as D, type CloudEnv as E, type CloudRepo as F, type GetAgentOptions as G, type ContextBudget as H, type InlineSkill as I, type ContextManagerKind as J, type ContextSnapshot as K, type LocalOptions as L, type MemorySettings as M, type ContextSource as N, type ContextSourceStatus as O, type ProviderRoutingSettings as P, type CreateSkillSpec as Q, Cron as R, type SystemPromptResolver as S, type CronCreateOptions as T, type CronGetOptions as U, type CronJob as V, type CronJobStatus as W, type CronListOptions as X, type CronOperationOptions as Y, type CronRunOptions as Z, type CronRuntime as _, type AgentDefinition as a, type CronStartOptions as a0, type HookName as a1, type InvalidateCacheOptions as a2, type MemoryAdapter as a3, type MemoryAdapterCapabilities as a4, type MemoryContext as a5, type MemoryFact as a6, type MemoryProviderHandle as a7, type MemoryProviderInitOptions as a8, type MemoryRevision as a9, type SkillsResolver as aA, type SkillsResolverContext as aB, type SystemPromptContext as aC, type SystemPromptMemoryFact as aD, type SystemPromptSkillRef as aE, type TelemetrySettings as aF, type MemoryToolSchema as aa, type MemoryTurnMessage as ab, type PersonalityPreset as ac, type PluginContext as ad, type PostAssistantReplyContext as ae, type PreToolCallContext as af, type PreUserSendContext as ag, type PreUserSendResult as ah, type ProviderCapability as ai, type ProviderRoute as aj, type ProviderTransform as ak, type ProviderTransformContext as al, type RecordSessionSummaryArgs as am, type ResolvedProviderRoute as an, type RunUntilIterator as ao, type SDKAgentPlugins as ap, type SDKAgentSkillDetail as aq, type SDKAgentSkills as ar, type SDKArtifact as as, type SDKContextManager as at, type SDKPluginMetadata as au, type SDKProvidersManager as av, type SessionRecord as aw, type SessionStore as ax, type SettingSource as ay, Skill as az, type ContextSettings as b, type PluginsSettings as c, type SkillsSettings as d, type SDKAgent as e, type ListAgentsOptions as f, type ListResult as g, type SDKAgentInfo as h, type ListRunsOptions as i, type GetRunOptions as j, type AgentOperationOptions as k, type Plugin as l, type ProviderProfile as m, type GoalOptions as n, type GoalEvent as o, type GoalResult as p, type MemoryProvider as q, type MemoryId as r, type PreToolCallDecision as s, type StepResult as t, type SDKProvider as u, type ActiveMemoryPassArgs as v, type ActiveMemoryPassResult as w, type AgentMemory as x, type BudgetCheck as y, type BudgetTotal as z };
|