@orkestrel/agent 0.0.18 → 0.0.20

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.
@@ -4,8 +4,9 @@ import { DriverInterface } from '@orkestrel/database';
4
4
  import { EmitterErrorHandler } from '@orkestrel/emitter';
5
5
  import { EmitterHooks } from '@orkestrel/emitter';
6
6
  import { EmitterInterface } from '@orkestrel/emitter';
7
+ import { FileInterface } from '@orkestrel/workspace';
7
8
  import { JSONValue } from '@orkestrel/contract';
8
- import { QueueExecution } from '@orkestrel/queue';
9
+ import { QueueContext } from '@orkestrel/queue';
9
10
  import { QueueInterface } from '@orkestrel/queue';
10
11
  import { QueueStoreInterface } from '@orkestrel/queue';
11
12
  import { RunnerInterface } from '@orkestrel/workflow';
@@ -20,15 +21,15 @@ import { ToolResult } from '@orkestrel/tool';
20
21
  import { WorkspaceManagerInterface } from '@orkestrel/workspace';
21
22
 
22
23
  /**
23
- * The agent loop — composes a {@link ProviderInterface}, an {@link AgentContext}, and
24
- * a {@link ToolManagerInterface} into a bounded context → provider → tools → repeat
24
+ * Composes a {@link ProviderInterface}, an {@link AgentContext}, and a
25
+ * {@link ToolManagerInterface} into a bounded context → provider → tools → repeat
25
26
  * turn, exposed as both a one-shot `generate` and a live `stream`.
26
27
  *
27
28
  * @remarks
28
29
  * - **One loop, two faces.** A single private async generator (`#run`) drives the
29
30
  * whole turn. `stream` kicks off an eager pump that iterates `#run` into a private
30
31
  * {@link Channel}, settling `result` from the run's outcome — so `result` settles
31
- * whether or not the live `events` are drained; `generate` simply awaits that same
32
+ * whether or not the live `events` are drained; `generate` awaits that same
32
33
  * settled `result` — so the two can never diverge.
33
34
  * - **The turn.** `#run` builds the provider input once (`context.build()` into a
34
35
  * working array) then loops up to `limit`: drive `provider.stream(...)` accumulating
@@ -37,7 +38,7 @@ import { WorkspaceManagerInterface } from '@orkestrel/workspace';
37
38
  * tools, append the assistant turn, `execute` them, yield a `tool` chunk per call,
38
39
  * append each tool result message, and continue; otherwise append the final
39
40
  * assistant message and stop.
40
- * - **Bounded.** Each run arms one cancel via `createAbort({ signal: AbortSignal.any([
41
+ * - **Bounded.** Each run arms one cancel through `createAbort({ signal: AbortSignal.any([
41
42
  * …]) })` folding the external `signal`, the `timeout` deadline, and the `budget`
42
43
  * signal; `abort()` fires it. Any trip stops the loop and commits a PARTIAL result
43
44
  * (the `result` promise RESOLVES, never rejects, on a cancel) — only a genuine
@@ -61,8 +62,8 @@ import { WorkspaceManagerInterface } from '@orkestrel/workspace';
61
62
  */
62
63
  export declare class Agent implements AgentInterface {
63
64
  #private;
64
- readonly id: string;
65
65
  constructor(provider: ProviderInterface, options?: AgentOptions);
66
+ get id(): string;
66
67
  get emitter(): EmitterInterface<AgentEventMap>;
67
68
  get status(): AgentStatus;
68
69
  get context(): AgentContextInterface;
@@ -72,8 +73,8 @@ export declare class Agent implements AgentInterface {
72
73
  }
73
74
 
74
75
  /**
75
- * A streamed step of an agent turn — the discriminated union the loop yields as it
76
- * runs.
76
+ * Represents a streamed step of an agent turn — the union the loop yields as it runs, discriminated
77
+ * by the `category` of step it carries.
77
78
  *
78
79
  * @remarks
79
80
  * - `token` — a content delta the provider streamed (the `'content'`
@@ -89,23 +90,23 @@ export declare class Agent implements AgentInterface {
89
90
  * provider response that reported it (folded into the running total + any budget).
90
91
  */
91
92
  export declare type AgentChunk = {
92
- readonly type: 'token';
93
+ readonly category: 'token';
93
94
  readonly content: string;
94
95
  } | {
95
- readonly type: 'think';
96
+ readonly category: 'think';
96
97
  readonly content: string;
97
98
  } | {
98
- readonly type: 'tool';
99
+ readonly category: 'tool';
99
100
  readonly call: ToolCall;
100
101
  readonly result: ToolResult;
101
102
  } | {
102
- readonly type: 'usage';
103
+ readonly category: 'usage';
103
104
  readonly usage: TokenUsage;
104
105
  };
105
106
 
106
107
  /**
107
- * The richer turn context the agent loop assembles a provider request from — the optional
108
- * system prompt, the observable context managers (instructions / workspaces), the
108
+ * Assembles a provider request from the richer turn context — the optional system prompt, the
109
+ * observable context managers (instructions / workspaces), the
109
110
  * {@link ConversationManagerInterface} message source (whose active conversation IS `messages`),
110
111
  * the {@link ToolManagerInterface} registry, and an active {@link ScopeInterface} changed through
111
112
  * {@link AgentContextInterface.apply}.
@@ -126,7 +127,7 @@ export declare type AgentChunk = {
126
127
  * {@link MessageManagerInterface} structurally — the same reference, no duplication), and
127
128
  * `build()` folds that conversation's `view()` (its per-section summaries + live tail) as the
128
129
  * AUTHORITATIVE message inclusion — the scope does NOT filter the conversation (it owns inclusion
129
- * via compaction; scope filters only instructions / tools / workspace files). Because `messages`
130
+ * through compaction; scope filters only instructions / tools / workspace files). Because `messages`
130
131
  * is read dynamically, an agent SWITCHES the active
131
132
  * conversation BETWEEN runs (`conversations.switch(id)`) to serve MANY threads (the real
132
133
  * multi-conversation pattern); switch between runs, not during a run, and use separate agents
@@ -136,31 +137,31 @@ export declare type AgentChunk = {
136
137
  * (each as a block: the section's resolved `open` text, each item's resolved rendering, then
137
138
  * any resolved `close` text) into ONE leading `system` message (prepended only when at least
138
139
  * one part exists), then appends the ACTIVE conversation's `view()` (the conversation owns
139
- * message inclusion via compaction — the scope does NOT filter the conversation). Each
140
+ * message inclusion through compaction — the scope does NOT filter the conversation). Each
140
141
  * `open` / item / `close`
141
142
  * resolves INDEPENDENTLY, MOST-SPECIFIC-FIRST — `build()`'s optional `format` (a provider's
142
143
  * per-section default) is the PROVIDER level: `open` = manager-options-override > provider >
143
144
  * built-in; per item = item-override > manager-options-override > provider > built-in; `close` =
144
145
  * manager-options-override > provider (NO built-in ⇒ no closing line when unset) (see
145
146
  * {@link AgentContextInterface.build}). Passing NO `format` (and with no overrides / no per-item
146
- * format) reproduces the built-in framing byte-for-byte (each section is its built-in header +
147
- * items, no closing line). The active workspace's scoped-in image files' `data` is attached to
147
+ * override) reproduces the built-in framing byte-for-byte (each section is its built-in header +
148
+ * items, no closing line). The active workspace's scoped-in image files' `base64` payload is attached to
148
149
  * the LAST user message (a vision provider reads images off a user turn); when no user message
149
150
  * exists the attachment is skipped. Built fresh each call (recomputed, never cached), so it
150
151
  * always reflects the current managers / messages / scope / active workspace; it never mutates a
151
152
  * manager or the stored messages.
152
153
  * - **The ACTIVE workspace, rendered BY CARRIER — the SOLE document/image context.**
153
- * `workspaces.active` (when set) has its {@link FileInterface}s scope-filtered by `scope.files`,
154
+ * `workspaces.active` (when set) has its {@link import('@orkestrel/workspace').FileInterface}s scope-filtered by `scope.files`,
154
155
  * then split: TEXT files fold into a dedicated `## Workspace` system section (fenced reference
155
- * blocks — placed right after the instructions section), and IMAGE files' base64 `data` attaches
156
+ * blocks — placed right after the instructions section), and IMAGE files' `base64` payload attaches
156
157
  * to the last user message. ACTIVE-ONLY — never the other registered workspaces; with no active
157
158
  * workspace nothing renders for workspaces. `build()` OWNS this render (a `Workspace` /
158
159
  * `WorkspaceManager` stays file-focused).
159
160
  * - **Tools are structural, not in the prompt.** The registry is advertised to the provider
160
- * via `tools.definitions()` (scope-filtered by the loop), NEVER serialized into the
161
+ * through `tools.definitions()` (scope-filtered by the loop), NEVER serialized into the
161
162
  * message array — so `build()`'s output carries no tool content, scoped or not.
162
163
  * - **Event-free context; observable managers.** The context itself owns no Emitter; the
163
- * context managers each carry their own (the §13 observation surface).
164
+ * context managers each carry their own (the push observation surface).
164
165
  *
165
166
  * @example
166
167
  * ```ts
@@ -181,7 +182,7 @@ export declare class AgentContext implements AgentContextInterface {
181
182
  get tools(): ToolManagerInterface;
182
183
  get scope(): ScopeInterface | undefined;
183
184
  apply(scope: ScopeInterface | undefined): void;
184
- build(format?: ContextFormatInterface): readonly MessageInterface[];
185
+ build(format?: ContextFormat): readonly Message[];
185
186
  }
186
187
 
187
188
  /**
@@ -193,12 +194,12 @@ export declare class AgentContext implements AgentContextInterface {
193
194
  * (`instructions` / `workspaces` / `conversations`), `messages` (the active
194
195
  * conversation's live tail, satisfying {@link MessageManagerInterface}), and the current `scope`
195
196
  * (the active {@link ScopeInterface} filter, or `undefined` for no filtering). `build()` folds the
196
- * scoped instructions into ONE leading `system` message (under the manager's `description`,
197
- * each item via its `format`) — PLUS the ACTIVE workspace's scope-filtered text files
197
+ * scoped instructions into ONE leading `system` message (under the manager's `open`,
198
+ * each item through its `render`) — PLUS the ACTIVE workspace's scope-filtered text files
198
199
  * (rendered as fenced reference blocks) — and appends the ACTIVE conversation's `view()`, attaching
199
- * the active workspace's scope-filtered image files' base64 `data` to the LAST user message. The
200
+ * the active workspace's scope-filtered image files' `base64` payload to the LAST user message. The
200
201
  * active workspace is the SOLE document/image context. Tools are advertised to the provider
201
- * STRUCTURALLY (via `tools.definitions()`, scope-filtered by the loop), NOT serialized into
202
+ * STRUCTURALLY (through `tools.definitions()`, scope-filtered by the loop), NOT serialized into
202
203
  * the prompt, so they never appear in `build()`'s output. The context managers are observable
203
204
  * (their own `emitter`s); the context itself is event-free.
204
205
  */
@@ -206,9 +207,9 @@ export declare interface AgentContextInterface {
206
207
  readonly system: string | undefined;
207
208
  readonly instructions: InstructionManagerInterface;
208
209
  /**
209
- * The {@link WorkspaceManagerInterface} whose ACTIVE workspace `build()` renders by carrier —
210
+ * Holds the {@link WorkspaceManagerInterface} whose ACTIVE workspace `build()` renders by carrier —
210
211
  * its text files folded into the system block (fenced reference blocks) and its image files'
211
- * base64 `data` attached to the LAST user message. The active workspace is the SOLE
212
+ * `base64` payload attached to the LAST user message. The active workspace is the SOLE
212
213
  * document/image context. ALWAYS present (a fresh empty manager when none was supplied).
213
214
  * `build()` reads its `active` (and the active workspace's `files()`) FRESH each call. With NO
214
215
  * active workspace, nothing is rendered for workspaces. Active-only — never the other registered
@@ -216,7 +217,7 @@ export declare interface AgentContextInterface {
216
217
  */
217
218
  readonly workspaces: WorkspaceManagerInterface;
218
219
  /**
219
- * The active conversation's LIVE tail — the agent's message source, ALWAYS defined (the
220
+ * Holds the active conversation's LIVE tail — the agent's message source, ALWAYS defined (the
220
221
  * {@link conversations} registry always has an active conversation; a default is added at
221
222
  * construction). It IS the active {@link ConversationInterface} itself (which satisfies
222
223
  * {@link MessageManagerInterface} structurally), so appends through `messages` route to the
@@ -226,24 +227,23 @@ export declare interface AgentContextInterface {
226
227
  */
227
228
  readonly messages: MessageManagerInterface;
228
229
  /**
229
- * The {@link ConversationManagerInterface} the message source flows from — `messages` IS its
230
+ * Holds the {@link ConversationManagerInterface} the message source flows from — `messages` IS its
230
231
  * ACTIVE conversation's live tail and `build()` folds that conversation's `view()`. ALWAYS holds
231
232
  * an active conversation (a default is added at construction when none was supplied), so
232
233
  * `messages` is always defined. Switch the active conversation through
233
234
  * `conversations.switch(id)` — so one agent can serve MANY conversations (set the active one per
234
- * request). Switch BETWEEN runs, not during one; for CONCURRENT threads use separate agents (see
235
- * clause 23).
235
+ * request). Switch BETWEEN runs, not during one; for CONCURRENT threads use separate agents.
236
236
  */
237
237
  readonly conversations: ConversationManagerInterface;
238
238
  /**
239
- * The loop's tool registry for provider advertising and call dispatch. Tools are structural
239
+ * Holds the loop's tool registry for provider advertising and call dispatch. Tools are structural
240
240
  * loop machinery and never render into `build()`'s prompt.
241
241
  */
242
242
  readonly tools: ToolManagerInterface;
243
- /** The active scope applied at `build()` time + the loop's tool-advertise step (`undefined` ⇒ no filtering). */
243
+ /** Holds the active scope applied at `build()` time + the loop's tool-advertise step (`undefined` ⇒ no filtering). */
244
244
  readonly scope: ScopeInterface | undefined;
245
245
  /**
246
- * Apply the active per-turn scope filter. Passing `undefined` removes filtering.
246
+ * Applies the active per-turn scope filter. Passing `undefined` removes filtering.
247
247
  *
248
248
  * @param scope - The scope to apply, or `undefined` to remove the active filter
249
249
  *
@@ -255,10 +255,10 @@ export declare interface AgentContextInterface {
255
255
  */
256
256
  apply(scope: ScopeInterface | undefined): void;
257
257
  /**
258
- * The provider input for the next turn: a leading `system` message folding the prompt
258
+ * Builds the provider input for the next turn: a leading `system` message folding the prompt
259
259
  * + the scoped instructions + the ACTIVE workspace's scoped-in TEXT files (rendered as
260
260
  * fenced reference blocks), then the ACTIVE conversation's `view()` (with the active workspace's
261
- * scoped-in IMAGE files' `data` attached to the last user message). Tools are advertised
261
+ * scoped-in IMAGE files' `base64` payload attached to the last user message). Tools are advertised
262
262
  * structurally, not in the prompt. Built fresh on each call.
263
263
  *
264
264
  * @remarks
@@ -268,8 +268,8 @@ export declare interface AgentContextInterface {
268
268
  * `scope.files` (a three-way allow-list; `undefined` ⇒ all active files), then split by
269
269
  * carrier: TEXT files ({@link import('@orkestrel/workspace').isText}) render into a dedicated
270
270
  * `## Workspace` section in the system block — each a fenced
271
- * `` File: <path>\n```<language>\n<text>\n``` `` block — placed just after the instructions
272
- * section; binary files whose MIME starts with `image/` have their base64 `data`
271
+ * `` File: <path>\n```<language>\n<text>\n``` `` block — placed immediately after the instructions
272
+ * section; binary files whose MIME starts with `image/` have their `base64` payload
273
273
  * attached to the LAST user message (a vision provider reads images off a user turn).
274
274
  * ACTIVE-ONLY — never the other registered workspaces; with NO active workspace nothing is
275
275
  * rendered for workspaces.
@@ -279,40 +279,40 @@ export declare interface AgentContextInterface {
279
279
  * leading text), each item's `render`, and the `close` (the section's trailing text)
280
280
  * resolve INDEPENDENTLY, MOST-SPECIFIC-FIRST, from a {@link ContextSectionFormat} at each
281
281
  * level — an item override, a manager-options override, the provider `format` default,
282
- * and the manager's built-in. For a section kind `K` (currently `instructions`), manager
282
+ * and the manager's built-in. For the `instructions` section kind `K`, manager
283
283
  * `M`, and the supplied `format` `F`:
284
- * - **open** = `M.optionsFormat?.open ?? F?.[K]?.open ?? M.builtInOpen` — i.e.
284
+ * - **open** = `M.format?.open ?? F?.[K]?.open ?? M.open` — that is,
285
285
  * **manager-options override > provider default > built-in** (the leading text has no
286
286
  * per-item level). The manager ENCAPSULATES the `[options-override → built-in]` half:
287
- * `M.description` already returns the options override's `open` when one is set, else
287
+ * `M.open` already returns the options override's `open` when one is set, else
288
288
  * the built-in header — so `build()` only layers the provider default BETWEEN them.
289
- * - **item** `I` = `I.format ?? M.optionsFormat?.render?.(I) ?? F?.[K]?.render?.(I) ?? M.builtInFormat(I)`
290
- * — i.e. **item override > manager-options override > provider default > built-in**.
291
- * Again `M.format(I)` already returns the options override when set, else the
292
- * built-in, so `build()` layers the per-item `I.format` ON TOP and the provider
289
+ * - **item** `I` = `I.override ?? M.format?.render?.(I) ?? F?.[K]?.render?.(I) ?? M.render(I)`
290
+ * — that is, **item override > manager-options override > provider default > built-in**.
291
+ * Again `M.render(I)` already returns the options override when set, else the
292
+ * built-in, so `build()` layers the per-item `I.override` ON TOP and the provider
293
293
  * default BETWEEN.
294
- * - **close** = `M.optionsFormat?.close ?? F?.[K]?.close` — i.e. **manager-options
294
+ * - **close** = `M.format?.close ?? F?.[K]?.close` — that is, **manager-options
295
295
  * override > provider default**, with NO built-in floor (the trailing text has no
296
296
  * per-item level): unset at both levels ⇒ `undefined` ⇒ no closing line. Paired with
297
297
  * `open`, it lets a level WRAP the group (`open: '<instructions>'` … `close: '</instructions>'`).
298
298
  *
299
299
  * Passing NO `format` (the default) leaves the provider-default level empty, so the
300
- * output is BYTE-FOR-BYTE the managers' built-in framing — every section is just its
300
+ * output is BYTE-FOR-BYTE the managers' built-in framing — every section is its
301
301
  * built-in header + items, with no closing line (the regression contract). Scope
302
302
  * filtering runs BEFORE formatting (unchanged); the workspace image-data attachment to the
303
303
  * last user message is unchanged.
304
304
  *
305
- * @param format - The provider's optional {@link ContextFormatInterface} default
305
+ * @param format - The provider's optional {@link ContextFormat} default
306
306
  * (typically `provider.format`); omitted ⇒ only the manager-options / item / built-in
307
307
  * levels apply, reproducing the prior built-in output exactly
308
308
  * @returns The scoped conversation, prefixed by the assembled `system` message when any
309
309
  * of (the prompt, the scoped instructions, the active workspace's text files) is non-empty
310
310
  */
311
- build(format?: ContextFormatInterface): readonly MessageInterface[];
311
+ build(format?: ContextFormat): readonly Message[];
312
312
  }
313
313
 
314
314
  /**
315
- * Options for `createAgentContext` — the richer context's configuration.
315
+ * Configures `createAgentContext` — the richer context's configuration.
316
316
  *
317
317
  * @remarks
318
318
  * `system` is the optional system prompt prepended to the turn's input. `instructions` /
@@ -331,29 +331,29 @@ export declare interface AgentContextInterface {
331
331
  export declare interface AgentContextOptions {
332
332
  readonly system?: string;
333
333
  /**
334
- * The loop's pre-built tool registry for provider advertising and call dispatch; an empty one is
334
+ * Holds the loop's pre-built tool registry for provider advertising and call dispatch; an empty one is
335
335
  * created when omitted. Tools never render into `build()`'s prompt.
336
336
  */
337
337
  readonly tools?: ToolManagerInterface;
338
- /** A pre-built instruction registry to reuse; an empty one is created when omitted. */
338
+ /** Reuses a pre-built instruction registry; an empty one is created when omitted. */
339
339
  readonly instructions?: InstructionManagerInterface;
340
340
  /**
341
- * A pre-built {@link WorkspaceManagerInterface} to reuse; a fresh empty one is created when
341
+ * Reuses a pre-built {@link WorkspaceManagerInterface}; a fresh empty one is created when
342
342
  * omitted (so `context.workspaces` is ALWAYS present). `build()` renders the ACTIVE workspace's
343
343
  * files by carrier — text files into the system block (fenced), image files attached to the last
344
344
  * user message. The registry is structural; change its active workspace through
345
345
  * `workspaces.switch(id)`. The active workspace is the SOLE document/image context.
346
346
  */
347
347
  readonly workspaces?: WorkspaceManagerInterface;
348
- /** The initial active scope (the build-time filter); `undefined` ⇒ no filtering. */
348
+ /** Sets the initial active scope (the build-time filter); `undefined` ⇒ no filtering. */
349
349
  readonly scope?: ScopeInterface;
350
350
  /**
351
- * A pre-built {@link ConversationManagerInterface} to reuse as the message source; a fresh
351
+ * Reuses a pre-built {@link ConversationManagerInterface} as the message source; a fresh
352
352
  * empty one is created when omitted. The context ENSURES an active conversation at construction
353
353
  * (it `add`s a default when the manager has none), so `messages` — the manager's ACTIVE
354
354
  * conversation's LIVE tail — is ALWAYS defined. `build()` folds the active conversation's
355
355
  * `view()` (the per-section summaries + the live tail) as its AUTHORITATIVE message inclusion —
356
- * the scope does NOT filter the conversation (it owns inclusion via compaction; scope filters
356
+ * the scope does NOT filter the conversation (it owns inclusion through compaction; scope filters
357
357
  * only instructions / tools / workspace files). The registry is structural; change its active
358
358
  * conversation through the manager's `switch(id)`.
359
359
  */
@@ -361,25 +361,28 @@ export declare interface AgentContextOptions {
361
361
  }
362
362
 
363
363
  /**
364
- * Thrown synchronously by an {@link AgentInterface}'s `stream()` when a concurrent run would
365
- * corrupt SHARED per-agent accounting — carries a machine-readable `code`.
364
+ * Reports a concurrent run that would corrupt SHARED per-agent accounting, or a rehydration
365
+ * name absent from its registry pool — thrown synchronously by an {@link AgentInterface}'s
366
+ * `stream()` and by an {@link AgentRegistryInterface}'s accessors, carrying a machine-readable
367
+ * `code`.
366
368
  *
367
369
  * @remarks
368
- * A run already in flight on the same agent, PLUS a construction-level `window` (a shared
369
- * context budget) or a construction-level `budget` with no per-run override (a shared cost
370
- * budget), means a second concurrent `stream()` would race its charges against the same
371
- * shared instance — corrupting the accounting. `code` is `'CONCURRENCY'` (the only condition
372
- * so far). Use separate agents, or per-run `budget` overrides with no `window`, for genuinely
373
- * concurrent runs. Narrow a caught value with {@link isAgentError} and branch on `error.code`.
370
+ * `'CONCURRENCY'` reports a run already in flight on the same agent, PLUS a construction-level
371
+ * `window` (a shared context budget) or a construction-level `budget` with no per-run override
372
+ * (a shared cost budget) — a second concurrent `stream()` would race its charges against the
373
+ * same shared instance, corrupting the accounting. Use separate agents, or per-run `budget`
374
+ * overrides with no `window`, for genuinely concurrent runs. `'REGISTRY'` reports a rehydration
375
+ * name absent from its registry pool, on `provider` / `tool` / `authority` / `scheduler` /
376
+ * `build`. Narrow a caught value with {@link isAgentError} and branch on `error.code`.
374
377
  */
375
378
  export declare class AgentError extends Error {
376
- /** The machine-readable condition — `'CONCURRENCY'`: a concurrent run on a shared accounting agent. */
377
- readonly code: 'CONCURRENCY';
378
- constructor(code: 'CONCURRENCY', message: string);
379
+ /** Names the machine-readable condition — `'CONCURRENCY'`: a concurrent run on a shared accounting agent; `'REGISTRY'`: a rehydration name absent from its registry pool. */
380
+ readonly code: 'CONCURRENCY' | 'REGISTRY';
381
+ constructor(code: 'CONCURRENCY' | 'REGISTRY', message: string);
379
382
  }
380
383
 
381
384
  /**
382
- * The push observation surface of an {@link AgentInterface} (AGENTS §13) — the
385
+ * Maps the push observation surface of an {@link AgentInterface} — the
383
386
  * lifecycle + usage/tool moments a fire-and-forget observer (logging, metrics,
384
387
  * tracing) subscribes to, ALONGSIDE the pull {@link AgentChunk} stream.
385
388
  *
@@ -389,10 +392,10 @@ export declare class AgentError extends Error {
389
392
  * the chunk stream can't express (a `deny` never reaches the stream) or that a
390
393
  * fire-and-forget observer wants without draining the stream. PER-TOKEN deltas stay
391
394
  * EXCLUSIVELY the {@link AgentChunk} stream's job (the pull surface) — there is
392
- * deliberately NO `token` event here. Subscribe via `agent.emitter.on(...)`.
395
+ * deliberately NO `token` event here. Subscribe through `agent.emitter.on(...)`.
393
396
  *
394
- * Observation is provably side-effect-free on the loop: listener isolation is the emitter's
395
- * (§13) — every event is emitted directly and a listener throw is routed to the emitter's OWN
397
+ * Observation is side-effect-free on the loop: listener isolation is the emitter's
398
+ * — every event is emitted directly and a listener throw is routed to the emitter's OWN
396
399
  * `error` handler (the `error` option), never onto this domain map and never into the
397
400
  * settle-once / wake-park engine — so a buggy observer can never reorder, throw into, or
398
401
  * corrupt the run.
@@ -401,55 +404,80 @@ export declare class AgentError extends Error {
401
404
  * PARTIAL result) — so an observer sees both that the run was cancelled and the partial
402
405
  * outcome it committed; a genuine error emits `error` instead of `finish`.
403
406
  *
404
- * Declared as a `type` alias (not `interface extends EventMap`, §4.5 — `EventMap` is a
407
+ * Declared as a `type` alias (not `interface extends EventMap` — `EventMap` is a
405
408
  * `type` kind): a type-literal satisfies the `EventMap` constraint
406
409
  * (`Record<string, readonly unknown[]>`) structurally, whereas an interface lacks the
407
410
  * required index signature.
408
411
  */
409
412
  export declare type AgentEventMap = {
410
- /** A run begins — emitted at the top of `stream()` once `status` is `running`. */
413
+ /** Reports a run beginning — emitted at the top of `stream()` once `status` is `running`. */
411
414
  readonly start: readonly [id: string];
412
- /** Each `#run` loop iteration begins — the zero-based turn index. */
415
+ /** Reports each `#run` loop iteration beginning — the zero-based turn index. */
413
416
  readonly turn: readonly [index: number];
414
- /** A dispatched {@link ToolCall} paired with its {@link ToolResult} (executed or a denial). */
417
+ /** Reports a dispatched {@link ToolCall} paired with its {@link ToolResult} (executed or a denial). */
415
418
  readonly tool: readonly [call: ToolCall, result: ToolResult];
416
- /** A turn reported {@link TokenUsage} — emitted after a usage-bearing provider call. */
419
+ /** Reports a turn's {@link TokenUsage} — emitted after a usage-bearing provider call. */
417
420
  readonly usage: readonly [usage: TokenUsage];
418
- /** The authority DENIED a call — the call + the optional reason (NOT in the chunk stream). */
421
+ /** Reports a call the authority DENIED — the call + the optional reason (NOT in the chunk stream). */
419
422
  readonly deny: readonly [call: ToolCall, reason: string | undefined];
420
- /** The run settled successfully (a natural finish OR a cancel's partial) — the {@link AgentResult}. */
423
+ /** Reports the run settled successfully (a natural finish OR a cancel's partial) — the {@link AgentResult}. */
421
424
  readonly finish: readonly [result: AgentResult];
422
- /** The run settled with a genuine (non-cancel) error — the thrown value (always `unknown`). */
425
+ /** Reports the run settled with a genuine (non-cancel) error — the thrown value (always `unknown`). */
423
426
  readonly error: readonly [error: unknown];
424
- /** The run was cancelled (external signal / timeout / budget / `abort()`) — the cancel reason. */
427
+ /** Reports the run cancelled (external signal / timeout / budget / `abort()`) — the cancel reason. */
425
428
  readonly abort: readonly [reason: unknown];
426
429
  /**
427
- * The loop exhausted its `limit` while still holding unresolved tool intent (the model
430
+ * Reports the loop exhausting its `limit` while still holding unresolved tool intent (the model
428
431
  * requested tools on the very last allowed turn) — the turn count reached. Distinct from
429
432
  * `abort`: exhaustion is NOT a cancel (no external signal / timeout / budget tripped), so
430
433
  * this fires INSTEAD of `abort`, still followed by `finish` carrying the partial result.
431
434
  */
432
435
  readonly exhaust: readonly [turns: number];
433
436
  /**
434
- * AUTOMATIC compaction's summarizer THREW — a NON-FATAL warn channel (the run continues; see
437
+ * Reports AUTOMATIC compaction's summarizer THROWING — a NON-FATAL warn channel (the run continues; see
435
438
  * {@link AgentOptions.window}). When the loop's between-turns / pre-first-turn auto-compaction
436
439
  * (`conversation.compact()`) rejects, the run does NOT crash: the loop skips compaction that
437
440
  * turn and surfaces the caught error here so the failure is observable, never silently lost.
438
- * Distinct from `error` (a GENUINE provider/tool failure that REJECTS the run) — this is a
439
- * best-effort optimization that failed. A MANUAL `conversation.compact()` still propagates its
440
- * own error; only the agent's AUTO path is resilient. A DOMAIN event (the emitter isolates a
441
- * listener throw separately, routing it to its `error` handler).
441
+ * The run still SETTLES through the other events — `finish` for the lenient default, and
442
+ * `error` when {@link AgentOptions.strict} rethrows the same caught value — so `fault` reports
443
+ * the best-effort optimization that failed and never the run's own outcome. A MANUAL
444
+ * `conversation.compact()` still propagates its own error; only the agent's AUTO path is
445
+ * resilient. A DOMAIN event (the emitter isolates a listener throw separately, routing it to
446
+ * its `error` handler).
442
447
  */
443
- readonly compactError: readonly [error: unknown];
448
+ readonly fault: readonly [error: unknown];
444
449
  };
445
450
 
451
+ /**
452
+ * Composes a {@link ProviderInterface}, an {@link AgentContextInterface}, and a
453
+ * {@link ToolManagerInterface} into a bounded context → provider → tools → repeat turn.
454
+ *
455
+ * @remarks
456
+ * - **One loop, two faces.** `generate` and `stream` share ONE private run, so they
457
+ * can never diverge: `generate` drains the same stream `stream` exposes, then
458
+ * resolves its settled {@link AgentResult}.
459
+ * - **Bounded.** Each turn arms a single cancel folded from the external `signal`, the
460
+ * `timeout` deadline, and the `budget` signal (through `AbortSignal.any`); any of them —
461
+ * or `abort()` — stops the loop and settles the result `partial: true`.
462
+ * - **Paced + capped.** The `scheduler` (when given) yields between turns; tool
463
+ * iteration is capped at `limit` so the loop always terminates.
464
+ * - **Two observation surfaces.** PULL: the {@link AgentChunk} stream (`stream().events`)
465
+ * carries per-token answer deltas, per-think reasoning deltas, and usage/tool chunks for a live consumer. PUSH: the
466
+ * {@link emitter} ({@link AgentEventMap}) carries lifecycle + usage/tool/deny moments
467
+ * for fire-and-forget observers — the emitter isolates a listener throw and routes it to
468
+ * its `error` handler (the `error` option), so a buggy observer can NEVER corrupt the
469
+ * loop. Per-token / per-thinking deltas are the stream's job exclusively; there is no
470
+ * `token` or `think` event.
471
+ * - **Per-run overrides.** Both faces accept an optional {@link AgentRunOptions} bag whose
472
+ * members override the construction {@link AgentOptions} for that one run.
473
+ */
446
474
  export declare interface AgentInterface {
447
475
  readonly emitter: EmitterInterface<AgentEventMap>;
448
476
  readonly id: string;
449
477
  readonly status: AgentStatus;
450
478
  readonly context: AgentContextInterface;
451
479
  /**
452
- * Run the turn to completion, discarding the live chunks — drains the shared
480
+ * Runs the turn to completion, discarding the live chunks — drains the shared
453
481
  * stream and resolves the settled outcome.
454
482
  *
455
483
  * @remarks
@@ -460,13 +488,13 @@ export declare interface AgentInterface {
460
488
  * itself, ahead of the `.catch` ever attaching) — `await` the call (inside a `try`/`catch`)
461
489
  * or wrap the call expression itself in `try`/`catch`.
462
490
  *
463
- * @param options - Optional per-run {@link AgentRunOptions} (e.g. `think`); omitted ⇒ defaults
491
+ * @param options - Optional per-run {@link AgentRunOptions} (for example `think`); omitted ⇒ defaults
464
492
  * @returns The settled {@link AgentResult} (`partial: true` when cancelled)
465
493
  * @throws {AgentError} Synchronously, with `code: 'CONCURRENCY'`, for a concurrent run
466
494
  */
467
495
  generate(options?: AgentRunOptions): Promise<AgentResult>;
468
496
  /**
469
- * Run the turn as a live stream — iterate `events` for {@link AgentChunk}s and
497
+ * Runs the turn as a live stream — iterate `events` for {@link AgentChunk}s and
470
498
  * `await result` for the settled outcome.
471
499
  *
472
500
  * @remarks
@@ -475,13 +503,13 @@ export declare interface AgentInterface {
475
503
  * {@link AgentStreamInterface} handle is even returned, so it cannot be caught by chaining
476
504
  * off the (never-produced) handle; wrap the call itself in `try`/`catch`.
477
505
  *
478
- * @param options - Optional per-run {@link AgentRunOptions} (e.g. `think`); omitted ⇒ defaults
506
+ * @param options - Optional per-run {@link AgentRunOptions} (for example `think`); omitted ⇒ defaults
479
507
  * @returns A live {@link AgentStreamInterface} handle (events + result + abort)
480
508
  * @throws {AgentError} Synchronously, with `code: 'CONCURRENCY'`, for a concurrent run
481
509
  */
482
510
  stream(options?: AgentRunOptions): AgentStreamInterface;
483
511
  /**
484
- * Cancel the in-flight turn — fires the turn's signal; the `result` settles
512
+ * Cancels the in-flight turn — fires the turn's signal; the `result` settles
485
513
  * `partial: true` with whatever content accumulated.
486
514
  *
487
515
  * @param reason - An optional cancellation reason propagated to the signal
@@ -490,9 +518,9 @@ export declare interface AgentInterface {
490
518
  }
491
519
 
492
520
  /**
493
- * Thrown by an agent-job handler (a `createAgentQueue` / `createAgentRunner` job) when
494
- * its {@link AgentInterface} run ended {@link AgentResult.partial} and the job's
495
- * `allowPartial` policy is `false` (the default) — carries the partial
521
+ * Reports an {@link AgentInterface} run that ended {@link AgentResult.partial} under a
522
+ * `partial` policy of `false` (the default) — thrown by an agent-job handler (a
523
+ * `createAgentQueue` / `createAgentRunner` job), carrying the partial
496
524
  * {@link AgentResult} so the failure stays inspectable.
497
525
  *
498
526
  * @remarks
@@ -500,18 +528,22 @@ export declare interface AgentInterface {
500
528
  * runner abort threaded in, a `timeout` deadline, or an exhausted token `budget`) rather
501
529
  * than finishing naturally. For a durable JOB that is a failure by default: throwing this
502
530
  * lets the Queue's retries re-run the job and a Runner's fail-fast abort its siblings.
503
- * Set `allowPartial: true` (see `AgentQueueOptions` / `AgentRunnerOptions`) to treat a
531
+ * Set `partial: true` (see `AgentQueueOptions` / `AgentRunnerOptions`) to treat a
504
532
  * partial as success instead, in which case this is never thrown. Narrow a caught value
505
- * with {@link isAgentJobError} to read `partial`.
533
+ * with {@link isAgentJobError} to read `partial`. `code` is the machine-readable condition
534
+ * (`'PARTIAL'` — the only one this error reports), so a `catch` branches on it rather than on
535
+ * the message string.
506
536
  */
507
537
  export declare class AgentJobError extends Error {
508
- /** The partial {@link AgentResult} the cancelled job produced. */
538
+ /** Names the machine-readable condition — `'PARTIAL'`: a job that ended partial under a disallowing policy. */
539
+ readonly code: "PARTIAL";
540
+ /** Holds the partial {@link AgentResult} the cancelled job produced. */
509
541
  readonly partial: AgentResult;
510
542
  constructor(message: string, partial: AgentResult);
511
543
  }
512
544
 
513
545
  /**
514
- * A JSON-serializable agent job — the descriptor a durable queue / runner runs. Its
546
+ * Represents a JSON-serializable agent job — the descriptor a durable queue / runner runs. Its
515
547
  * non-serializable pieces (the provider, tools, authority, scheduler) are referenced by
516
548
  * NAME and resolved to live objects through an {@link AgentRegistryInterface} at handler
517
549
  * time; its data fields (the seed `messages`, `system`, `limit`, `timeout`, and a token
@@ -528,26 +560,26 @@ export declare class AgentJobError extends Error {
528
560
  * `budget` is a token ceiling rebuilt into a `createTokenBudget({ max })`.
529
561
  */
530
562
  export declare interface AgentJobInput {
531
- /** The registry key of the {@link ProviderInterface} the job runs against. */
563
+ /** Names the registry key of the {@link ProviderInterface} the job runs against. */
532
564
  readonly provider: string;
533
- /** The seed conversation added to the rehydrated agent's context (serializable). */
565
+ /** Holds the seed conversation added to the rehydrated agent's context (serializable). */
534
566
  readonly messages: readonly MessageInput[];
535
- /** An optional system prompt seeding the agent's context. */
567
+ /** Holds an optional system prompt seeding the agent's context. */
536
568
  readonly system?: string;
537
- /** Registry keys of the {@link ToolInterface}s loaded into the agent's tool manager. */
569
+ /** Names the registry keys of the {@link ToolInterface}s loaded into the agent's tool manager. */
538
570
  readonly tools?: readonly string[];
539
- /** The registry key of an optional {@link AuthorityInterface} policy gate. */
571
+ /** Names the registry key of an optional {@link AuthorityInterface} policy gate. */
540
572
  readonly authority?: string;
541
- /** The registry key of an optional {@link SchedulerInterface} pacing the loop. */
573
+ /** Names the registry key of an optional {@link SchedulerInterface} pacing the loop. */
542
574
  readonly scheduler?: string;
543
- /** Max tool-iteration turns before the loop stops (see {@link AgentOptions.limit}). */
575
+ /** Caps the tool-iteration turns before the loop stops (see {@link AgentOptions.limit}). */
544
576
  readonly limit?: number;
545
- /** A wall-clock deadline (ms) for the whole turn (see {@link AgentOptions.timeout}). */
577
+ /** Sets a wall-clock deadline (ms) for the whole turn (see {@link AgentOptions.timeout}). */
546
578
  readonly timeout?: number;
547
- /** A token ceiling rebuilt into a `createTokenBudget({ max })` cost bound. */
579
+ /** Sets a token ceiling rebuilt into a `createTokenBudget({ max })` cost bound. */
548
580
  readonly budget?: number;
549
581
  /**
550
- * Sub-agent jobs this job fans out — each a nested {@link AgentJobInput} (so the whole
582
+ * Lists the sub-agent jobs this job fans out — each a nested {@link AgentJobInput} (so the whole
551
583
  * tree stays serializable). On a `createAgentRunner`, the handler `controller.spawn`s
552
584
  * each child through the same bounded queue BEFORE running this (parent) job, so the
553
585
  * children run as sibling sub-agents and their results join the run after the declared
@@ -557,7 +589,7 @@ export declare interface AgentJobInput {
557
589
  }
558
590
 
559
591
  /**
560
- * Options for `createAgent` — bounds and pacing for the agent loop.
592
+ * Configures `createAgent` — bounds and pacing for the agent loop.
561
593
  *
562
594
  * @remarks
563
595
  * - `system` — an optional system prompt prepended to the turn (seeds the context).
@@ -582,12 +614,12 @@ export declare interface AgentJobInput {
582
614
  * the ACTIVE conversation when it is summarizable.
583
615
  * - `window` — an optional CONTEXT {@link BudgetInterface} for AUTOMATIC conversation
584
616
  * compaction: when set, the loop measures the CURRENT FULL prompt against this budget each turn
585
- * (its `consume` is a token estimator, its `max` the context window) and, when the prompt
617
+ * (its `consumer` is a token estimator, its `max` the context window) and, when the prompt
586
618
  * reaches the window AND the active conversation is summarizable, COMPACTS the active
587
619
  * conversation + continues on the rebuilt smaller view — compact-and-continue, distinct from
588
620
  * `budget`'s hard abort. Omitted ⇒ no auto-compaction.
589
621
  * - `strict` — when `true`, a summarizer failure during AUTOMATIC compaction ABORTS the run
590
- * (rethrown after the `compactError` event, propagating through `#run` to a genuine `error`
622
+ * (rethrown after the `fault` event, propagating through `#run` to a genuine `error`
591
623
  * settle) instead of skipping compaction and continuing over-window. Defaults to `false`
592
624
  * (lenient — the prior, byte-for-byte behavior).
593
625
  * - `instructions` — an optional pre-built {@link InstructionManagerInterface} forwarded to the
@@ -596,34 +628,34 @@ export declare interface AgentJobInput {
596
628
  * agent's context; a fresh empty one is created when omitted (mirrors {@link AgentContextOptions.workspaces}).
597
629
  * - `scope` — an optional initial active {@link ScopeInterface} forwarded to the agent's context
598
630
  * (the build-time filter); `undefined` ⇒ no filtering (mirrors {@link AgentContextOptions.scope}).
599
- * - `on` — the reserved {@link EmitterHooks} key (§8): initial listeners for the agent's
600
- * {@link AgentEventMap}, wired at construction (e.g. `{ finish: (r) => log(r) }`).
631
+ * - `on` — the reserved {@link EmitterHooks} key: initial listeners for the agent's
632
+ * {@link AgentEventMap}, wired at construction (for example `{ finish: (r) => log(r) }`).
601
633
  */
602
634
  export declare interface AgentOptions {
603
635
  readonly on?: EmitterHooks<AgentEventMap>;
604
- /** The emitter's listener-error handler (AGENTS §13) — a listener throw routes here, not to a domain event. */
636
+ /** Holds the emitter's listener-error handler — a listener throw routes here, not to a domain event. */
605
637
  readonly error?: EmitterErrorHandler;
606
638
  readonly system?: string;
607
- /** A pre-built tool registry the loop dispatches calls through; an empty one is created when omitted. */
639
+ /** Reuses a pre-built tool registry the loop dispatches calls through; an empty one is created when omitted. */
608
640
  readonly tools?: ToolManagerInterface;
609
- /** A pre-built instruction registry forwarded to the agent's context; an empty one is created when omitted. */
641
+ /** Reuses a pre-built instruction registry forwarded to the agent's context; an empty one is created when omitted. */
610
642
  readonly instructions?: InstructionManagerInterface;
611
- /** A pre-built workspace registry forwarded to the agent's context; a fresh empty one is created when omitted. */
643
+ /** Reuses a pre-built workspace registry forwarded to the agent's context; a fresh empty one is created when omitted. */
612
644
  readonly workspaces?: WorkspaceManagerInterface;
613
- /** The initial active scope forwarded to the agent's context (the build-time filter); `undefined` ⇒ no filtering. */
645
+ /** Sets the initial active scope forwarded to the agent's context (the build-time filter); `undefined` ⇒ no filtering. */
614
646
  readonly scope?: ScopeInterface;
615
- /** Max tool-iteration turns before the loop stops; defaults to `DEFAULT_AGENT_LIMIT`. */
647
+ /** Caps the tool-iteration turns before the loop stops; defaults to `DEFAULT_AGENT_LIMIT`. */
616
648
  readonly limit?: number;
617
- /** A wall-clock deadline (ms) for the whole turn; its abort commits a partial result. */
649
+ /** Sets a wall-clock deadline (ms) for the whole turn; its abort commits a partial result. */
618
650
  readonly timeout?: number;
619
- /** A token cost bound; each provider call's usage is charged and its abort commits a partial. */
651
+ /** Bounds the token cost; each provider call's usage is charged and its abort commits a partial. */
620
652
  readonly budget?: BudgetInterface<TokenUsage>;
621
653
  /** Paces the loop — `yield`ed between turns so the host regains control. */
622
654
  readonly scheduler?: SchedulerInterface;
623
- /** An external cancel; its abort commits a partial result. */
655
+ /** Carries an external cancel; its abort commits a partial result. */
624
656
  readonly signal?: AbortSignal;
625
657
  /**
626
- * An optional policy gate consulted before each tool call runs — a denied call is
658
+ * Holds an optional policy gate consulted before each tool call runs — a denied call is
627
659
  * fed back to the model as a denial {@link ToolResult} (a `tool` chunk + a tool
628
660
  * message) rather than executed (no tool run, no budget cost), so the model sees the
629
661
  * denial and can react; an allowed call dispatches normally. Omitted ⇒ every call
@@ -631,7 +663,7 @@ export declare interface AgentOptions {
631
663
  */
632
664
  readonly authority?: AuthorityInterface;
633
665
  /**
634
- * An optional {@link ConversationManagerInterface} that becomes the agent context's MESSAGE
666
+ * Holds an optional {@link ConversationManagerInterface} that becomes the agent context's MESSAGE
635
667
  * SOURCE — forwarded to the {@link AgentContextInterface} the agent builds, so
636
668
  * `agent.context.messages` IS its ACTIVE conversation's live tail and `build()` folds that
637
669
  * conversation's `view()` (the per-section summaries + the live tail). Omitted ⇒ a fresh
@@ -640,18 +672,18 @@ export declare interface AgentOptions {
640
672
  */
641
673
  readonly conversations?: ConversationManagerInterface;
642
674
  /**
643
- * An optional CONTEXT {@link BudgetInterface} for AUTOMATIC compaction. Its `consume` is a
644
- * token estimator (e.g. the exported {@link import('./helpers.js').estimateMessages}) and
675
+ * Holds an optional CONTEXT {@link BudgetInterface} for AUTOMATIC compaction. Its `consumer` is a
676
+ * token estimator (for example the exported {@link import('./helpers.js').estimateMessages}) and
645
677
  * its `max` is the context window. When set, the loop measures the CURRENT FULL prompt (the
646
678
  * next provider request) against this budget each turn; when that prompt reaches the window AND
647
679
  * the active conversation is summarizable, it **compacts the active conversation + continues on
648
680
  * the rebuilt smaller view** (compact-and-continue) — the same consume-to-a-ceiling primitive
649
681
  * as the cost `budget`, but compaction is the ceiling action instead of abort. Omit to disable.
650
682
  */
651
- readonly window?: BudgetInterface<readonly MessageInterface[]>;
683
+ readonly window?: BudgetInterface<readonly Message[]>;
652
684
  /**
653
- * When `true`, a summarizer failure during AUTOMATIC compaction ABORTS the run — the
654
- * `compactError` event still fires, then the caught error is RETHROWN so the run settles
685
+ * If `true`, a summarizer failure during AUTOMATIC compaction ABORTS the run — the
686
+ * `fault` event still fires, then the caught error is RETHROWN so the run settles
655
687
  * `error` instead of continuing over-window. Defaults to `false` (lenient — the run
656
688
  * continues over-window, byte-for-byte the prior behavior).
657
689
  */
@@ -659,13 +691,13 @@ export declare interface AgentOptions {
659
691
  }
660
692
 
661
693
  /**
662
- * Options for `createAgentQueue` — the registry that rehydrates jobs, the partial-result
694
+ * Configures `createAgentQueue` — the registry that rehydrates jobs, the partial-result
663
695
  * policy, and the substrate knobs threaded into the backing `createQueue`.
664
696
  *
665
697
  * @remarks
666
698
  * - `registry` — the {@link AgentRegistryInterface} the handler rehydrates each job
667
699
  * through (required).
668
- * - `allowPartial` — the partial policy. A partial {@link AgentResult} (a job committed
700
+ * - `partial` — the partial policy. A partial {@link AgentResult} (a job committed
669
701
  * early from an abort / budget / timeout) is by DEFAULT a FAILURE: the handler THROWS
670
702
  * an {@link import('./errors.js').AgentJobError}, so the Queue's retries (and a
671
703
  * Runner's fail-fast) engage. Set `true` to treat a partial as SUCCESS instead — the
@@ -676,8 +708,8 @@ export declare interface AgentOptions {
676
708
  */
677
709
  export declare interface AgentQueueOptions {
678
710
  readonly registry: AgentRegistryInterface;
679
- /** A partial `AgentResult` THROWS by default (retries engage); `true` resolves it as success. */
680
- readonly allowPartial?: boolean;
711
+ /** If `true`, a partial `AgentResult` resolves as success; if `false` (the default), it THROWS and retries engage. */
712
+ readonly partial?: boolean;
681
713
  readonly concurrency?: number;
682
714
  readonly retries?: number;
683
715
  readonly timeout?: number;
@@ -685,10 +717,9 @@ export declare interface AgentQueueOptions {
685
717
  }
686
718
 
687
719
  /**
688
- * The bridge that makes a durable, JSON-serializable {@link AgentJobInput} runnable —
689
- * it holds the named pools of live, non-serializable pieces (providers, tools,
690
- * authorities, schedulers) and rehydrates a seeded, signal-wired {@link Agent} from a
691
- * job's names + data.
720
+ * Makes a durable, JSON-serializable {@link AgentJobInput} runnable — holds the named
721
+ * pools of live, non-serializable pieces (providers, tools, authorities, schedulers) and
722
+ * rehydrates a seeded, signal-wired {@link Agent} from a job's names + data.
692
723
  *
693
724
  * @remarks
694
725
  * - **Why it exists.** An `AgentJobInput` is serializable so it can survive a crash in a
@@ -696,18 +727,18 @@ export declare interface AgentQueueOptions {
696
727
  * schedulers carrying functions) cannot serialize. The registry closes that gap:
697
728
  * construct it once with the live pools, then a queue / runner handler calls `build`
698
729
  * on each (possibly restored) job to get a ready agent.
699
- * - **Accessors throw on a miss (§9.1 + §12).** `provider` / `tool` / `authority` /
700
- * `scheduler` resolve a name against their pool and THROW `unknown <category>: <name>`
701
- * when it is absent — an unknown name in a rehydrated job is a programmer / config
702
- * error that must fail LOUDLY at build time, never silently resolve to `undefined` and
703
- * run an agent missing a dependency.
730
+ * - **Accessors throw on a miss.** `provider` / `tool` / `authority` / `scheduler` resolve a
731
+ * name against their pool and THROW an {@link AgentError} carrying `code: 'REGISTRY'` and
732
+ * the message `unknown <category>: <name>` when it is absent — an unknown name in a
733
+ * rehydrated job is a programmer / config error that must fail LOUDLY at build time, never
734
+ * silently resolve to `undefined` and run an agent missing a dependency.
704
735
  * - **`build` rehydrates.** Resolve the job's `provider`; assemble a fresh
705
736
  * {@link ToolManager} from the `tools` names; rebuild the token `budget` from its
706
737
  * ceiling (`createTokenBudget({ max })`); resolve the optional `authority` /
707
738
  * `scheduler` names; construct the {@link Agent} with `system` / `limit` / `timeout` /
708
739
  * the threaded `signal`; seed its context with the job's `messages`; return it. The
709
740
  * `signal` is the queue attempt's / runner unit's cancel, so a bounded abort propagates
710
- * into the agent (which commits a partial — the job's `allowPartial` policy then
741
+ * into the agent (which commits a partial — the job's `partial` policy then
711
742
  * decides success vs. retry).
712
743
  * - **Event-free.** A pure resolver — no Emitter, no events.
713
744
  *
@@ -735,11 +766,11 @@ export declare class AgentRegistry implements AgentRegistryInterface {
735
766
  * durable, serializable job runnable.
736
767
  *
737
768
  * @remarks
738
- * - **Accessors throw on a miss (§9.1 + §12).** `provider` / `tool` / `authority` /
739
- * `scheduler` look one up by name and THROW a clear `Error` (`unknown provider:
740
- * <name>`, etc.) when the name is unregistered — an unknown name in a rehydrated job
741
- * must fail loudly, never silently resolve to `undefined`, so a misconfigured job
742
- * surfaces at once rather than running with a missing dependency.
769
+ * - **Accessors throw on a miss.** `provider` / `tool` / `authority` / `scheduler` look one
770
+ * up by name and THROW an {@link AgentError} carrying `code: 'REGISTRY'` and the message
771
+ * `unknown <category>: <name>` when the name is unregistered — an unknown name in a
772
+ * rehydrated job must fail loudly, never silently resolve to `undefined`, so a
773
+ * misconfigured job surfaces at once rather than running with a missing dependency.
743
774
  * - **`build` rehydrates.** It resolves the job's `provider`, assembles a
744
775
  * {@link ToolManagerInterface} from the `tools` names, rebuilds the token `budget`
745
776
  * from its ceiling, resolves the `authority` / `scheduler` names, seeds the agent's
@@ -749,7 +780,7 @@ export declare class AgentRegistry implements AgentRegistryInterface {
749
780
  */
750
781
  export declare interface AgentRegistryInterface {
751
782
  /**
752
- * Resolve a registered {@link ProviderInterface} by name.
783
+ * Resolves a registered {@link ProviderInterface} by name.
753
784
  *
754
785
  * @param name - The provider's registry key
755
786
  * @returns The live provider
@@ -757,7 +788,7 @@ export declare interface AgentRegistryInterface {
757
788
  */
758
789
  provider(name: string): ProviderInterface;
759
790
  /**
760
- * Resolve a registered {@link ToolInterface} by name.
791
+ * Resolves a registered {@link ToolInterface} by name.
761
792
  *
762
793
  * @param name - The tool's registry key
763
794
  * @returns The live tool
@@ -765,7 +796,7 @@ export declare interface AgentRegistryInterface {
765
796
  */
766
797
  tool(name: string): ToolInterface;
767
798
  /**
768
- * Resolve a registered {@link AuthorityInterface} by name.
799
+ * Resolves a registered {@link AuthorityInterface} by name.
769
800
  *
770
801
  * @param name - The authority's registry key
771
802
  * @returns The live authority
@@ -773,7 +804,7 @@ export declare interface AgentRegistryInterface {
773
804
  */
774
805
  authority(name: string): AuthorityInterface;
775
806
  /**
776
- * Resolve a registered {@link SchedulerInterface} by name.
807
+ * Resolves a registered {@link SchedulerInterface} by name.
777
808
  *
778
809
  * @param name - The scheduler's registry key
779
810
  * @returns The live scheduler
@@ -781,7 +812,7 @@ export declare interface AgentRegistryInterface {
781
812
  */
782
813
  scheduler(name: string): SchedulerInterface;
783
814
  /**
784
- * Rehydrate a live, seeded {@link AgentInterface} from a serializable job — resolving
815
+ * Rehydrates a live, seeded {@link AgentInterface} from a serializable job — resolving
785
816
  * its names, rebuilding its budget, seeding its conversation, and wiring `signal`.
786
817
  *
787
818
  * @param input - The serializable {@link AgentJobInput} to rehydrate
@@ -793,18 +824,18 @@ export declare interface AgentRegistryInterface {
793
824
  }
794
825
 
795
826
  /**
796
- * Options for `createAgentRegistry` — the named pools of live, non-serializable pieces
827
+ * Configures `createAgentRegistry` — the named pools of live, non-serializable pieces
797
828
  * a {@link AgentJobInput}'s names resolve against.
798
829
  *
799
830
  * @remarks
800
831
  * `providers` is required (a job always names a provider); `tools` / `authorities` /
801
- * `schedulers` are optional pools, each an entity-keyed record (§8) mapping a registry
832
+ * `schedulers` are optional pools, each an entity-keyed record mapping a registry
802
833
  * name to its live object. A name absent from its pool throws when resolved (see
803
834
  * {@link AgentRegistryInterface}). `store` is the durable {@link ConversationStoreInterface}
804
835
  * every agent this registry builds carries: each built agent gets its OWN store-backed
805
836
  * {@link ConversationManagerInterface} over THIS shared store — a fresh conversation id per
806
837
  * build (minted by the seeded `add`), so concurrent builds never collide, and the store
807
- * simply accumulates one snapshot per built agent that later calls `save`. Persistence
838
+ * accumulates one snapshot per built agent that later calls `save`. Persistence
808
839
  * stays caller-triggered (`open` / `save`) — `build` never hydrates, so `build` stays
809
840
  * SYNCHRONOUS. Omitted ⇒ every built agent gets a registry-only manager, byte-identical
810
841
  * to today.
@@ -818,7 +849,7 @@ export declare interface AgentRegistryOptions {
818
849
  }
819
850
 
820
851
  /**
821
- * The settled outcome of an agent turn — the assembled assistant `content`, the
852
+ * Holds the settled outcome of an agent turn — the assembled assistant `content`, the
822
853
  * `usage` summed across the turn's provider calls, and whether it was committed
823
854
  * `partial`.
824
855
  *
@@ -834,7 +865,7 @@ export declare interface AgentRegistryOptions {
834
865
  * present only when at least one provider call reported usage — an aborted run's `usage`
835
866
  * INCLUDES the cancelled turn's tokens when the provider reports partial usage on the
836
867
  * abort (folded in exactly like a completed turn's); a provider that cannot observe
837
- * usage mid-stream (e.g. a daemon whose final counts never arrive before the cancel)
868
+ * usage mid-stream (for example a daemon whose final counts never arrive before the cancel)
838
869
  * reports none for that turn, and none is fabricated. `thinking` is present
839
870
  * only when a provider call surfaced reasoning it separated from the answer
840
871
  * ({@link ProviderResult.thinking}, joined across the run's calls) — display/audit
@@ -842,15 +873,15 @@ export declare interface AgentRegistryOptions {
842
873
  */
843
874
  export declare interface AgentResult {
844
875
  readonly content: string;
845
- /** Reasoning the run's provider calls separated from the answer (present when any surfaced it). */
876
+ /** Carries reasoning the run's provider calls separated from the answer (present when any surfaced it). */
846
877
  readonly thinking?: string;
847
- /** The summed {@link TokenUsage} across the turn's provider calls (present when any reported it). */
878
+ /** Holds the summed {@link TokenUsage} across the turn's provider calls (present when any reported it). */
848
879
  readonly usage?: TokenUsage;
849
880
  readonly partial: boolean;
850
881
  }
851
882
 
852
883
  /**
853
- * Project an unknown value onto the canonical JSON representation of an
884
+ * Projects an unknown value onto the canonical JSON representation of an
854
885
  * {@link AgentResult}.
855
886
  *
856
887
  * @remarks
@@ -876,11 +907,11 @@ export declare interface AgentResult {
876
907
  export declare function agentResultToJSON(value: unknown): JSONValue | undefined;
877
908
 
878
909
  /**
879
- * Options for `createAgentRunner` — the registry that rehydrates jobs, the partial-result
910
+ * Configures `createAgentRunner` — the registry that rehydrates jobs, the partial-result
880
911
  * policy, and the substrate knobs threaded into the backing `createRunner`.
881
912
  *
882
913
  * @remarks
883
- * Identical partial policy to {@link AgentQueueOptions} (`allowPartial` — a partial
914
+ * Identical partial policy to {@link AgentQueueOptions} (`partial` — a partial
884
915
  * `AgentResult` THROWS by default so the run's fail-fast engages, `true` resolves it as
885
916
  * success). `concurrency` / `retries` / `timeout` pass straight to the backing
886
917
  * `RunnerInterface` (see `RunnerOptions`). The runner enables sub-agent fan-out: a
@@ -889,38 +920,29 @@ export declare function agentResultToJSON(value: unknown): JSONValue | undefined
889
920
  */
890
921
  export declare interface AgentRunnerOptions {
891
922
  readonly registry: AgentRegistryInterface;
892
- /** A partial `AgentResult` THROWS by default (fail-fast engages); `true` resolves it as success. */
893
- readonly allowPartial?: boolean;
923
+ /** If `true`, a partial `AgentResult` resolves as success; if `false` (the default), it THROWS and fail-fast engages. */
924
+ readonly partial?: boolean;
894
925
  readonly concurrency?: number;
895
926
  readonly retries?: number;
896
927
  readonly timeout?: number;
897
928
  }
898
929
 
899
930
  /**
900
- * The agent loop — composes a {@link ProviderInterface}, an
901
- * {@link AgentContextInterface}, and a {@link ToolManagerInterface} into a bounded
902
- * context → provider → tools → repeat turn.
931
+ * Carries the per-run override bag an {@link AgentInterface}'s `generate` / `stream` accepts — each
932
+ * member overrides the matching {@link AgentOptions} value for ONE run.
903
933
  *
904
934
  * @remarks
905
- * - **One loop, two faces.** `generate` and `stream` share ONE private run, so they
906
- * can never diverge: `generate` drains the same stream `stream` exposes, then
907
- * resolves its settled {@link AgentResult}.
908
- * - **Bounded.** Each turn arms a single cancel folded from the external `signal`, the
909
- * `timeout` deadline, and the `budget` signal (via `AbortSignal.any`); any of them —
910
- * or `abort()` — stops the loop and settles the result `partial: true`.
911
- * - **Paced + capped.** The `scheduler` (when given) yields between turns; tool
912
- * iteration is capped at `limit` so the loop always terminates.
913
- * - **Two observation surfaces.** PULL: the {@link AgentChunk} stream (`stream().events`)
914
- * carries per-token answer deltas, per-think reasoning deltas, and usage/tool chunks for a live consumer. PUSH: the
915
- * {@link emitter} ({@link AgentEventMap}) carries lifecycle + usage/tool/deny moments
916
- * for fire-and-forget observers — the emitter isolates a listener throw and routes it to
917
- * its `error` handler (the `error` option, §13), so a buggy observer can NEVER corrupt the
918
- * loop. Per-token / per-thinking deltas are the stream's job exclusively; there is no
919
- * `token` or `think` event.
935
+ * Every member is optional and resolved independently, so an omitted member leaves the
936
+ * agent's constructed value in force and a caller that passes no options runs exactly the
937
+ * agent it configured. `think` / `schema` ride through to the provider as
938
+ * {@link ProviderStreamOptions}; `limit` / `timeout` / `budget` replace their construction
939
+ * defaults for this run only; `signal` COMPOSES with the constructed `signal` (both fold into
940
+ * the run's bound abort) rather than replacing it. Nothing here mutates the agent — the next
941
+ * run reads the construction defaults again.
920
942
  */
921
943
  export declare interface AgentRunOptions {
922
944
  /**
923
- * The per-run reasoning preference forwarded to the provider's `stream` as
945
+ * Sets the per-run reasoning preference forwarded to the provider's `stream` as
924
946
  * {@link ProviderStreamOptions.think} — `true` asks the backend to separate reasoning
925
947
  * (surfaced as `think` {@link AgentChunk}s + the settled `thinking`), `false` suppresses
926
948
  * it. Omitted ⇒ the provider's own default applies (the loop is byte-for-byte the prior
@@ -928,7 +950,7 @@ export declare interface AgentRunOptions {
928
950
  */
929
951
  readonly think?: boolean;
930
952
  /**
931
- * Constrain the response to this JSON-Schema shape, forwarded to the provider's `stream`
953
+ * Constrains the response to this JSON-Schema shape, forwarded to the provider's `stream`
932
954
  * as {@link ProviderStreamOptions.schema} — a per-run structured-output request. Omitted ⇒
933
955
  * no constraint (the loop is byte-for-byte the prior behaviour).
934
956
  */
@@ -950,29 +972,93 @@ export declare interface AgentRunOptions {
950
972
  */
951
973
  readonly budget?: BudgetInterface<TokenUsage>;
952
974
  /**
953
- * An additional per-run external cancel, COMPOSED with {@link AgentOptions.signal} (both
954
- * fold into the run's bound abort via `AbortSignal.any` — neither is dropped). Omitted ⇒
975
+ * Carries an additional per-run external cancel, COMPOSED with {@link AgentOptions.signal} (both
976
+ * fold into the run's bound abort through `AbortSignal.any` — neither is dropped). Omitted ⇒
955
977
  * only the agent's constructed `signal` (if any) applies.
956
978
  */
957
979
  readonly signal?: AbortSignal;
958
980
  }
959
981
 
960
982
  /**
961
- * The lifecycle state of an {@link AgentInterface} turn — `idle` before a run,
983
+ * Names the lifecycle state of an {@link AgentInterface} turn — `idle` before a run,
962
984
  * `running` while the loop is in flight, then the settled `done` (a normal finish or
963
985
  * a cancel) or `error` (a genuine provider / tool failure).
964
986
  */
965
987
  export declare type AgentStatus = 'idle' | 'running' | 'done' | 'error';
966
988
 
967
989
  /**
968
- * The agent turn's live handle — a {@link StreamInterface} of {@link AgentChunk}s
990
+ * Names the agent turn's live handle — a {@link StreamInterface} of {@link AgentChunk}s
969
991
  * resolving an {@link AgentResult}.
970
992
  */
971
993
  export declare type AgentStreamInterface = StreamInterface<AgentChunk, AgentResult>;
972
994
 
973
995
  /**
974
- * The synchronous policy gate the agent loop consults before each tool call runs —
975
- * it turns one {@link AuthorityContextInterface} into an {@link AuthorityDecision}.
996
+ * Assembles the settled {@link AgentResult} from a run's {@link RunOutcome} — `thinking` and
997
+ * `usage` are carried only when the run surfaced them.
998
+ *
999
+ * @remarks
1000
+ * Pure and total. An absent optional is OMITTED rather than stored as `undefined` (the
1001
+ * present-when-given convention the message store follows), so a settled result JSON
1002
+ * round-trips without an explicit `undefined` field. `exhausted` is loop bookkeeping and does
1003
+ * not reach the public result — the `exhaust` event carries it instead.
1004
+ *
1005
+ * @param outcome - The run's settled outcome
1006
+ * @returns The public {@link AgentResult}
1007
+ *
1008
+ * @example
1009
+ * ```ts
1010
+ * assembleResult({ content: 'hi', thinking: undefined, usage: undefined, partial: false, exhausted: false })
1011
+ * // { content: 'hi', partial: false }
1012
+ * ```
1013
+ */
1014
+ export declare function assembleResult(outcome: RunOutcome): AgentResult;
1015
+
1016
+ /**
1017
+ * Copies a message with image data merged onto its `images` — the message's own images
1018
+ * first, then the attached data.
1019
+ *
1020
+ * @remarks
1021
+ * Pure and total: the original message is NEVER mutated. `calls` is carried only when the
1022
+ * source message has one (kept omitted otherwise, mirroring the store's present-when-given
1023
+ * convention).
1024
+ *
1025
+ * @param message - The message to copy (left unchanged)
1026
+ * @param data - The base64 image data to attach
1027
+ * @returns A new message carrying the merged `images`
1028
+ *
1029
+ * @example
1030
+ * ```ts
1031
+ * attachImages({ id: '1', role: 'user', content: 'Describe' }, ['<payload>'])
1032
+ * // { id: '1', role: 'user', content: 'Describe', images: ['<payload>'] }
1033
+ * ```
1034
+ */
1035
+ export declare function attachImages(message: Message, data: readonly string[]): Message;
1036
+
1037
+ /**
1038
+ * Attaches image data to a conversation's LAST user message — the turn a vision provider
1039
+ * reads images off.
1040
+ *
1041
+ * @remarks
1042
+ * Pure and total: the conversation and its messages are NEVER mutated, and the returned array
1043
+ * replaces exactly the one target message with the copy {@link attachImages} builds. Empty
1044
+ * data returns the conversation unchanged; a conversation with NO user message returns it
1045
+ * unchanged too (there is nowhere to attach, and the images already rode the system block).
1046
+ *
1047
+ * @param conversation - The messages to attach into (left unchanged)
1048
+ * @param data - The base64 image data to attach
1049
+ * @returns The conversation with its last user message replaced by the carrying copy
1050
+ *
1051
+ * @example
1052
+ * ```ts
1053
+ * attachUserImages([{ id: '1', role: 'user', content: 'Describe' }], ['<payload>'])
1054
+ * // [{ id: '1', role: 'user', content: 'Describe', images: ['<payload>'] }]
1055
+ * ```
1056
+ */
1057
+ export declare function attachUserImages(conversation: readonly Message[], data: readonly string[]): readonly Message[];
1058
+
1059
+ /**
1060
+ * Gates the agent loop's tool calls — the synchronous policy consulted before each call
1061
+ * runs, turning one {@link AuthorityContext} into an {@link AuthorityDecision}.
976
1062
  *
977
1063
  * @remarks
978
1064
  * - **Ordered, first-match-wins.** `evaluate` walks the configured rules in order and
@@ -989,8 +1075,7 @@ export declare type AgentStreamInterface = StreamInterface<AgentChunk, AgentResu
989
1075
  * back to the model as a denial {@link import('@orkestrel/tool').ToolResult} (a `tool`
990
1076
  * chunk + a tool message) instead of being executed — no tool run, no budget cost —
991
1077
  * so the model sees the denial and can react.
992
- * - **Synchronous now.** The async human-approval handshake (request / grant / deny) is
993
- * deferred to a later chunk; `evaluate` returns a verdict directly.
1078
+ * - **Synchronous.** `evaluate` returns the verdict directly.
994
1079
  * - **Event-free.** A purely functional gate — no Emitter, no events.
995
1080
  *
996
1081
  * @example
@@ -1006,28 +1091,27 @@ export declare type AgentStreamInterface = StreamInterface<AgentChunk, AgentResu
1006
1091
  export declare class Authority implements AuthorityInterface {
1007
1092
  #private;
1008
1093
  constructor(options?: AuthorityOptions);
1009
- evaluate(context: AuthorityContextInterface): AuthorityDecision;
1094
+ evaluate(context: AuthorityContext): AuthorityDecision;
1010
1095
  }
1011
1096
 
1012
1097
  /**
1013
- * What an {@link AuthorityInterface} evaluates for one tool call — the call under
1098
+ * Carries what an {@link AuthorityInterface} evaluates for one tool call — the call under
1014
1099
  * consideration.
1015
1100
  *
1016
1101
  * @remarks
1017
- * Lean by design: it carries only the {@link ToolCall} now (the tool `name` and its
1102
+ * Lean by design: it carries the {@link ToolCall} (the tool `name` and its
1018
1103
  * parsed `arguments`), which is enough for a rule to branch on what is being called
1019
- * and with what. It is a seam for richer policy inputs (call history, agent state)
1020
- * later WITHOUT changing the `evaluate` signature — those would join as new fields.
1104
+ * and with what.
1021
1105
  */
1022
- export declare interface AuthorityContextInterface {
1106
+ export declare interface AuthorityContext {
1023
1107
  readonly call: ToolCall;
1024
1108
  }
1025
1109
 
1026
1110
  /**
1027
- * An {@link AuthorityInterface}'s verdict on one tool call.
1111
+ * Holds an {@link AuthorityInterface}'s verdict on one tool call.
1028
1112
  *
1029
1113
  * @remarks
1030
- * `zone` is a project-defined classification (e.g. `'default'` / `'sensitive'` /
1114
+ * `zone` is a project-defined classification (for example `'default'` / `'sensitive'` /
1031
1115
  * `'restricted'`) carried for routing + observability; `allowed` is the gate decision
1032
1116
  * (a denied call is fed back to the model, never executed); `reason` is an optional
1033
1117
  * human-readable explanation surfaced in the denial {@link ToolResult}.
@@ -1039,27 +1123,26 @@ export declare interface AuthorityDecision {
1039
1123
  }
1040
1124
 
1041
1125
  /**
1042
- * A synchronous policy gate consulted before each tool call runs — it turns one
1043
- * {@link AuthorityContextInterface} into an {@link AuthorityDecision}.
1126
+ * Gates each tool call before it runs — the synchronous policy that turns one
1127
+ * {@link AuthorityContext} into an {@link AuthorityDecision}.
1044
1128
  *
1045
1129
  * @remarks
1046
1130
  * Ordered first-match-wins over the configured rules, falling back to the configured
1047
- * default when none match (see {@link AuthorityOptions}). Synchronous by design now;
1048
- * the async human-approval handshake (request / grant / deny) is deferred to a later
1049
- * chunk. Event-free — no Emitter, no events.
1131
+ * default when none match (see {@link AuthorityOptions}). `evaluate` is synchronous and
1132
+ * returns the verdict directly. Event-free — no Emitter, no events.
1050
1133
  */
1051
1134
  export declare interface AuthorityInterface {
1052
1135
  /**
1053
- * Evaluate one tool call against the ordered rules.
1136
+ * Evaluates one tool call against the ordered rules.
1054
1137
  *
1055
- * @param context - The call under consideration (see {@link AuthorityContextInterface})
1138
+ * @param context - The call under consideration (see {@link AuthorityContext})
1056
1139
  * @returns The first matching rule's verdict, or the fallback when none match
1057
1140
  */
1058
- evaluate(context: AuthorityContextInterface): AuthorityDecision;
1141
+ evaluate(context: AuthorityContext): AuthorityDecision;
1059
1142
  }
1060
1143
 
1061
1144
  /**
1062
- * Options for `createAuthority` — the ordered rules and the no-match fallback.
1145
+ * Configures `createAuthority` — the ordered rules and the no-match fallback.
1063
1146
  *
1064
1147
  * @remarks
1065
1148
  * `rules` are evaluated in order, first match wins (see {@link AuthorityRule}).
@@ -1075,7 +1158,7 @@ export declare interface AuthorityOptions {
1075
1158
  }
1076
1159
 
1077
1160
  /**
1078
- * One ordered policy rule an {@link AuthorityInterface} evaluates.
1161
+ * Represents one ordered policy rule an {@link AuthorityInterface} evaluates.
1079
1162
  *
1080
1163
  * @remarks
1081
1164
  * The FIRST rule whose `match` returns true decides; if none match, the authority's
@@ -1085,16 +1168,59 @@ export declare interface AuthorityOptions {
1085
1168
  * into the denial {@link ToolResult}).
1086
1169
  */
1087
1170
  export declare interface AuthorityRule {
1088
- readonly match: (context: AuthorityContextInterface) => boolean;
1171
+ readonly match: (context: AuthorityContext) => boolean;
1089
1172
  readonly zone: string;
1090
1173
  readonly allowed?: boolean;
1091
1174
  readonly reason?: string;
1092
1175
  }
1093
1176
 
1094
1177
  /**
1095
- * A minimal unbounded async channel — the eager pump WRITES chunks into it (`push`)
1096
- * and ends it (`close` / `fail`) regardless of consumption; a consumer READS them back
1097
- * live via the `drain` async-iterator. Decoupling write from read is what lets a
1178
+ * Builds the FRAMED recap message for one compacted section — the same role and stable `id`
1179
+ * as {@link buildSummaryMessage}, with the content prefixed by
1180
+ * {@link import('./constants.js').CONVERSATION_RECAP_PREFIX}.
1181
+ *
1182
+ * @remarks
1183
+ * Pure and total. The prefix is what makes a small model read the message as a CONDENSED
1184
+ * RECAP of earlier turns rather than a literal assistant turn to echo or answer from. It is a
1185
+ * fixed handful of tokens, so a conversation's `view()` stays lean however many sections it
1186
+ * carries.
1187
+ *
1188
+ * @param section - The compacted section to render
1189
+ * @returns The framed recap message
1190
+ *
1191
+ * @example
1192
+ * ```ts
1193
+ * buildRecapMessage({ id: 's1', summary: 'recap', messages: [] })
1194
+ * // { id: 's1', role: 'assistant', content: `${CONVERSATION_RECAP_PREFIX}recap` }
1195
+ * ```
1196
+ */
1197
+ export declare function buildRecapMessage(section: Section): Message;
1198
+
1199
+ /**
1200
+ * Builds the RAW synthetic summary message for one compacted section — role `'assistant'`,
1201
+ * the section's stable `id`, its `summary` VERBATIM as content.
1202
+ *
1203
+ * @remarks
1204
+ * Pure and total. This is the unframed form the rollup regeneration digests (a
1205
+ * summary-of-summaries over the section summaries); the recap LABEL is a `view()`
1206
+ * presentation concern kept out of what the summarizer re-reads — see
1207
+ * {@link buildRecapMessage}.
1208
+ *
1209
+ * @param section - The compacted section to render
1210
+ * @returns The synthetic summary message
1211
+ *
1212
+ * @example
1213
+ * ```ts
1214
+ * buildSummaryMessage({ id: 's1', summary: 'recap', messages: [] })
1215
+ * // { id: 's1', role: 'assistant', content: 'recap' }
1216
+ * ```
1217
+ */
1218
+ export declare function buildSummaryMessage(section: Section): Message;
1219
+
1220
+ /**
1221
+ * Buffers chunks in a minimal unbounded async channel — the eager pump WRITES them in
1222
+ * (`push`) and ends it (`close` / `fail`) regardless of consumption; a consumer READS them back
1223
+ * live through the `drain` async-iterator. Decoupling write from read is what lets a
1098
1224
  * producer make progress without a consumer pulling.
1099
1225
  *
1100
1226
  * @remarks
@@ -1115,7 +1241,7 @@ export declare interface AuthorityRule {
1115
1241
  * }
1116
1242
  * ```
1117
1243
  */
1118
- export declare class Channel<T> {
1244
+ export declare class Channel<T> implements ChannelInterface<T> {
1119
1245
  #private;
1120
1246
  push(value: T): void;
1121
1247
  close(): void;
@@ -1124,23 +1250,66 @@ export declare class Channel<T> {
1124
1250
  }
1125
1251
 
1126
1252
  /**
1127
- * The PER-RUN auto-compaction state threaded through an {@link AgentInterface}'s loop —
1128
- * a tiny immutable value replaced within a holder created fresh per run (so no state leaks across runs or a
1129
- * conversation switch), mirroring how {@link RunOutcome} is the per-run sink.
1253
+ * Buffers values in an unbounded async channel — a producer WRITES them in (`push`) and
1254
+ * ends it (`close` / `fail`) regardless of consumption, while a consumer READS them back
1255
+ * live through `drain`.
1130
1256
  *
1131
1257
  * @remarks
1132
- * `futile` latches once the loop's between-turns `compact()` resolves `undefined` while
1133
- * the prompt is still over the context window (the v1 single-level limit — the live tail
1134
- * is at/below `keep` and the over-window is structural), so auto-compaction STOPS for the
1135
- * rest of that run (no per-turn churn). Like {@link RunOutcome}, it is INTERNAL loop state
1136
- * — the loop reads + replaces it as it runs, not a caller-facing shape.
1258
+ * Decoupling the write from the read is what lets a producer make progress with nobody
1259
+ * pulling: an agent's eager pump writes each {@link AgentChunk} into one, so the run's
1260
+ * `result` settles whether or not `events` is ever drained. A waiting `drain` parks on a
1261
+ * resolver the next `push` / `close` / `fail` fires, so a value pushed at a parked reader is
1262
+ * delivered rather than dropped. Buffered values are always yielded BEFORE the end is
1263
+ * reported, so a `close` arriving alongside the last values still delivers them. The FIRST
1264
+ * failure wins — a later `close` / `fail` cannot override a recorded error. Event-free.
1265
+ *
1266
+ * @typeParam T - The value type the channel carries
1137
1267
  */
1138
- export declare interface CompactionState {
1139
- readonly futile: boolean;
1268
+ export declare interface ChannelInterface<T> {
1269
+ /**
1270
+ * Writes one value — buffered, then handed to a parked consumer.
1271
+ *
1272
+ * @param value - The value to enqueue
1273
+ */
1274
+ push(value: T): void;
1275
+ /** Ends the channel normally — a draining consumer returns once the buffer is empty. */
1276
+ close(): void;
1277
+ /**
1278
+ * Ends the channel with a failure — a draining consumer throws it once the buffer is empty.
1279
+ *
1280
+ * @param error - The failure to surface (the first one recorded wins)
1281
+ */
1282
+ fail(error: unknown): void;
1283
+ /**
1284
+ * Reads the values back live, in write order.
1285
+ *
1286
+ * @returns A generator yielding each pushed value, returning on `close` and throwing on `fail`
1287
+ */
1288
+ drain(): AsyncGenerator<T, void>;
1140
1289
  }
1141
1290
 
1142
1291
  /**
1143
- * Per-compaction options for {@link ConversationInterface.compact} — overrides for ONE fold.
1292
+ * Collects the `base64` payload of the IMAGE files in a workspace file list — the data an
1293
+ * agent context attaches to the last user message.
1294
+ *
1295
+ * @remarks
1296
+ * Pure and total. `isBinary` NARROWS the tagless content to its binary arm (a total guard,
1297
+ * never an assertion), then the MIME prefix gates it to an image, so a text file and a non-image
1298
+ * binary (a PDF) are both skipped. Order follows the file list.
1299
+ *
1300
+ * @param files - The (already scope-filtered) workspace files
1301
+ * @returns The `base64` payload of each image file, in file order
1302
+ *
1303
+ * @example
1304
+ * ```ts
1305
+ * collectImageData([createFile({ path: 'a.png', content: { base64: '<payload>', mime: 'image/png' } })])
1306
+ * // ['<payload>']
1307
+ * ```
1308
+ */
1309
+ export declare function collectImageData(files: readonly FileInterface[]): readonly string[];
1310
+
1311
+ /**
1312
+ * Configures one {@link ConversationInterface.compact} call — overrides for ONE fold.
1144
1313
  *
1145
1314
  * @remarks
1146
1315
  * `keep` overrides the conversation's configured retained-tail size for THIS compaction only
@@ -1152,52 +1321,52 @@ export declare interface CompactionState {
1152
1321
  * conversation's own `sections` cap (or unlimited) applies.
1153
1322
  */
1154
1323
  export declare interface CompactOptions {
1155
- /** Override the retained-tail size for this compaction; omitted ⇒ the conversation's own `keep`. */
1324
+ /** Overrides the retained-tail size for this compaction; omitted ⇒ the conversation's own `keep`. */
1156
1325
  readonly keep?: number;
1157
- /** Override the `sections` cap for this compaction; omitted ⇒ the conversation's own cap (or unlimited). */
1326
+ /** Overrides the `sections` cap for this compaction; omitted ⇒ the conversation's own cap (or unlimited). */
1158
1327
  readonly sections?: number;
1159
1328
  }
1160
1329
 
1161
1330
  /**
1162
- * A provider's OPTIONAL context-framing default, keyed by section kind — the framing a
1163
- * model prefers (e.g. XML tags vs. Markdown headers), declared by a
1331
+ * Holds a provider's OPTIONAL context-framing default, keyed by section kind — the framing a
1332
+ * model prefers (for example XML tags against Markdown headers), declared by a
1164
1333
  * {@link ProviderInterface} that opts in.
1165
1334
  *
1166
1335
  * @remarks
1167
1336
  * Each key is a {@link ContextSectionFormat} for one of the observable context sections
1168
- * (currently `instructions`), so a provider can frame each section independently — and any
1337
+ * (the `instructions` section), so a provider can frame each section independently — and any
1169
1338
  * it omits falls through to that manager's built-in default. It is the PROVIDER-DEFAULT
1170
1339
  * level of the {@link import('./AgentContext.js').AgentContext} build cascade: it BEATS a
1171
1340
  * manager's built-in default but is BEATEN by a manager-options override and by a per-item
1172
1341
  * override (see {@link AgentContextInterface.build}). It references the ABSTRACT core
1173
1342
  * item interface ({@link InstructionInterface}), so a provider opting in imports it from
1174
- * `@src/core` — the type is provider-agnostic, with no backend coupling. Omitting it
1343
+ * `@orkestrel/agent` — the type is provider-agnostic, with no backend coupling. Omitting it
1175
1344
  * entirely (the default for an agnostic provider) leaves every section on its manager's
1176
1345
  * built-in framing.
1177
1346
  */
1178
- export declare interface ContextFormatInterface {
1179
- /** The framing for the instructions section; omitted ⇒ that manager's built-in. */
1347
+ export declare interface ContextFormat {
1348
+ /** Frames the instructions section; omitted ⇒ that manager's built-in. */
1180
1349
  readonly instructions?: ContextSectionFormat<InstructionInterface>;
1181
1350
  }
1182
1351
 
1183
1352
  /**
1184
- * One context section's optional format override — an `open` / `render` / `close` trio
1353
+ * Overrides one context section's format — an `open` / `render` / `close` trio
1185
1354
  * that frames a section in the {@link import('./AgentContext.js').AgentContext} build
1186
1355
  * cascade: a top line rendered once before the items, a per-item rendering, and a bottom
1187
1356
  * line rendered once after the items.
1188
1357
  *
1189
1358
  * @remarks
1190
- * All three members are OPTIONAL and resolved INDEPENDENTLY (so an override may set only
1359
+ * `open`, `render`, and `close` are OPTIONAL and resolved INDEPENDENTLY (so an override may set only
1191
1360
  * the top, only the per-item rendering, only the bottom, or any mix). A section assembles
1192
1361
  * as `[open, ...items.map(render), close]` with empty / absent slots dropped, the survivors
1193
1362
  * blank-line (`\n\n`) joined — so `open` + `close` together let a developer WRAP the whole
1194
- * group (e.g. `open: '<instructions>'` … `close: '</instructions>'`). `open` is the section's
1195
- * leading text (the header, or a group's opening tag); `render` turns one section item (an
1196
- * {@link InstructionInterface}) into its prompt text; `close` is the trailing text. `open`
1197
- * and `render` cascade through the
1363
+ * group (for example `open: '<instructions>'` … `close: '</instructions>'`). `open` is the
1364
+ * section's leading text (the header, or a group's opening tag); `render` turns one section
1365
+ * item (an {@link InstructionInterface}) into its prompt text; `close` is the trailing text.
1366
+ * `open` and `render` cascade through the
1198
1367
  * built-in floor (`open` ⇒ the manager's built-in header, `render` ⇒ the manager's built-in
1199
- * rendering); `close` has NO built-in, so an unset `close` simply yields no closing line.
1200
- * It is the unit BOTH a provider's {@link ContextFormatInterface} (a per-section-kind
1368
+ * rendering); `close` has NO built-in, so an unset `close` yields no closing line.
1369
+ * It is the unit BOTH a provider's {@link ContextFormat} (a per-section-kind
1201
1370
  * default) and a manager's `Options` carry — see {@link AgentContextInterface.build} for
1202
1371
  * the full precedence.
1203
1372
  *
@@ -1205,29 +1374,54 @@ export declare interface ContextFormatInterface {
1205
1374
  */
1206
1375
  export declare interface ContextSectionFormat<T> {
1207
1376
  /**
1208
- * Text rendered ONCE before the section's items — the section header or a group's
1209
- * opening wrapper, e.g. `'<instructions>'`; omitted ⇒ the next cascade level decides
1377
+ * Holds text rendered ONCE before the section's items — the section header or a group's
1378
+ * opening wrapper, for example `'<instructions>'`; omitted ⇒ the next cascade level decides
1210
1379
  * (defaulting to the built-in header).
1211
1380
  */
1212
1381
  readonly open?: string;
1213
- /** Override one item's rendering; omitted ⇒ the next cascade level decides. */
1382
+ /** Overrides one item's rendering; omitted ⇒ the next cascade level decides. */
1214
1383
  readonly render?: (item: T) => string;
1215
1384
  /**
1216
- * Text rendered ONCE after the section's items — a group's closing wrapper, e.g.
1217
- * `'</instructions>'`; omitted ⇒ no closing line (there is no built-in close).
1385
+ * Holds text rendered ONCE after the section's items — a group's closing wrapper, for
1386
+ * example `'</instructions>'`; omitted ⇒ no closing line (there is no built-in close).
1218
1387
  */
1219
1388
  readonly close?: string;
1220
1389
  }
1221
1390
 
1222
1391
  /**
1223
- * A conversation grouping messages ABOVE a flat message store — a live uncompacted tail it
1224
- * OWNS DIRECTLY plus compacted, summarized {@link SectionInterface}s and a regenerated rollup
1392
+ * Exposes the manager surface one context section's format cascade reads — its built-in
1393
+ * `open` / `render`, plus the raw options override the cascade layers a provider
1394
+ * default beneath.
1395
+ *
1396
+ * @remarks
1397
+ * The narrow contract the cascade resolvers
1398
+ * ({@link import('./helpers.js').resolveOpen} / {@link import('./helpers.js').resolveClose} /
1399
+ * {@link import('./helpers.js').resolveItem}) take, so they stay independent of WHICH manager
1400
+ * supplies the section: an {@link InstructionManagerInterface} satisfies it structurally.
1401
+ * `open` and `render` already encapsulate `[options-override → built-in]` (so a manager
1402
+ * used standalone renders correctly), and `format` exposes the raw override so `build()` can
1403
+ * interleave the provider default BENEATH it.
1404
+ *
1405
+ * @typeParam T - The section item this source renders
1406
+ */
1407
+ export declare interface ContextSectionSourceInterface<T> {
1408
+ /** Names the built-in section header (already resolved against the manager-options override). */
1409
+ readonly open: string;
1410
+ /** Holds the raw manager-options override, or `undefined` when none was supplied. */
1411
+ readonly format: ContextSectionFormat<T> | undefined;
1412
+ /** Renders one item (already resolved against the manager-options override). */
1413
+ render(item: T): string;
1414
+ }
1415
+
1416
+ /**
1417
+ * Represents a conversation — a live uncompacted tail of messages it OWNS DIRECTLY ABOVE a
1418
+ * flat message store, plus compacted, summarized {@link Section}s and a regenerated rollup
1225
1419
  * `summary`, with on-demand `rehydrate` and substring `search`, driven by a provider-agnostic
1226
- * {@link ConversationSummarizer} seam (so `core` never imports a provider).
1420
+ * {@link ConversationSummaryHandler} seam (so `core` never imports a provider).
1227
1421
  *
1228
1422
  * @remarks
1229
1423
  * - **Live tail + sections.** The conversation OWNS its live tail DIRECTLY — `#messages` is an
1230
- * insertion-ordered `Map` of immutable {@link MessageInterface}s keyed by their minted id
1424
+ * insertion-ordered `Map` of immutable {@link Message}s keyed by their minted id
1231
1425
  * (the SAME store mechanics a flat manager had, folded in: `add` / `message` / `messages` /
1232
1426
  * `remove` / `clear` / `count`), exactly as a `Workspace` owns its files (no separate
1233
1427
  * per-value manager). `#sections` are the compacted history (oldest → newest), each a
@@ -1245,10 +1439,10 @@ export declare interface ContextSectionFormat<T> {
1245
1439
  * THROWS a {@link ConversationError} when no `#summarize` was supplied. Two summarizer calls
1246
1440
  * per compaction.
1247
1441
  * - **`rehydrate(id)` / `search(query)`.** `rehydrate` returns a section's full original
1248
- * messages (`[]` for an unknown id) and emits `rehydrate` — a pure read (v1 never
1249
- * auto-reinserts). `search` is a case-insensitive substring scan of `content` across ALL
1250
- * messages (every section's originals + the live tail).
1251
- * - **Observable (§13).** The owned {@link emitter} ({@link ConversationEventMap}) carries
1442
+ * messages (`[]` for an unknown id) and emits `rehydrate` — a pure read (the caller decides
1443
+ * whether to re-add them; `rehydrate` never reinserts). `search` is a case-insensitive
1444
+ * substring scan of `content` across ALL messages (every section's originals + the live tail).
1445
+ * - **Observable.** The owned {@link emitter} ({@link ConversationEventMap}) carries
1252
1446
  * `compact` / `summary` / `rehydrate`, emitted directly, strictly AFTER the state change;
1253
1447
  * the emitter isolates a listener throw and routes it to its `error` handler (the `error`
1254
1448
  * option), so a buggy observer can never corrupt a compaction.
@@ -1267,30 +1461,30 @@ export declare interface ContextSectionFormat<T> {
1267
1461
  */
1268
1462
  export declare class Conversation implements ConversationInterface {
1269
1463
  #private;
1270
- constructor(options?: ConversationOptions, seed?: ConversationSnapshot);
1464
+ constructor(options?: ConversationOptions);
1271
1465
  get id(): string;
1272
1466
  get emitter(): EmitterInterface<ConversationEventMap>;
1273
1467
  get summary(): string | undefined;
1274
- get sections(): readonly SectionInterface[];
1468
+ get sections(): readonly Section[];
1275
1469
  get summarizable(): boolean;
1276
1470
  get count(): number;
1277
- add(input: MessageInput): MessageInterface;
1278
- add(inputs: readonly MessageInput[]): readonly MessageInterface[];
1279
- message(id: string): MessageInterface | undefined;
1280
- messages(): readonly MessageInterface[];
1471
+ add(input: MessageInput): Message;
1472
+ add(inputs: readonly MessageInput[]): readonly Message[];
1473
+ message(id: string): Message | undefined;
1474
+ messages(): readonly Message[];
1281
1475
  remove(id: string): boolean;
1282
1476
  remove(ids: readonly string[]): boolean;
1283
1477
  clear(): void;
1284
- view(): readonly MessageInterface[];
1285
- compact(options?: CompactOptions): Promise<SectionInterface | undefined>;
1286
- rehydrate(id: string): readonly MessageInterface[];
1287
- search(query: string): readonly MessageInterface[];
1478
+ view(): readonly Message[];
1479
+ compact(options?: CompactOptions): Promise<Section | undefined>;
1480
+ rehydrate(id: string): readonly Message[];
1481
+ search(query: string): readonly Message[];
1288
1482
  reference(options?: ConversationReferenceOptions): string;
1289
1483
  snapshot(): ConversationSnapshot;
1290
1484
  }
1291
1485
 
1292
1486
  /**
1293
- * The framing label a {@link ConversationInterface}'s `view()` prefixes onto each compacted
1487
+ * Names the framing label a {@link ConversationInterface}'s `view()` prefixes onto each compacted
1294
1488
  * section's summary so a small model reads it as a CONDENSED RECAP of earlier turns — not a
1295
1489
  * literal assistant turn to echo or treat as the live answer.
1296
1490
  *
@@ -1306,70 +1500,71 @@ export declare class Conversation implements ConversationInterface {
1306
1500
  export declare const CONVERSATION_RECAP_PREFIX = "[Summary of earlier messages] ";
1307
1501
 
1308
1502
  /**
1309
- * Thrown by a {@link ConversationInterface}'s `compact()` when the conversation has no
1310
- * {@link ConversationSummarizer} to fold its messages with, or when its `sections` cap is
1311
- * structurally invalid — carries a machine-readable `code`.
1503
+ * Reports a conversation with no {@link ConversationSummaryHandler} to fold its messages
1504
+ * with, or with a structurally invalid `sections` cap — thrown by a
1505
+ * {@link ConversationInterface}'s `compact()`, carrying a machine-readable `code`.
1312
1506
  *
1313
1507
  * @remarks
1314
1508
  * Compaction REQUIRES a summarizer (it digests the folded slice into a section summary and
1315
1509
  * regenerates the rollup); a conversation created without one can still store + `view()` its
1316
- * live tail, but a `compact()` is a programmer error (§12) and throws this with `'SUMMARIZER'`.
1317
- * A `sections` cap (§F2, on {@link import('./types.js').ConversationOptions} /
1510
+ * live tail, but a `compact()` is a programmer error and throws this with `'SUMMARIZER'`.
1511
+ * A `sections` cap (on {@link import('./types.js').ConversationOptions} /
1318
1512
  * {@link import('./types.js').ConversationManagerOptions} /
1319
1513
  * {@link import('./types.js').CompactOptions}) must be `>= 1` — a sub-1 cap is a programmer
1320
1514
  * error and throws this with `'SECTIONS'`. Narrow a caught value with
1321
1515
  * {@link isConversationError} and branch on `error.code`.
1322
1516
  */
1323
1517
  export declare class ConversationError extends Error {
1324
- /** The machine-readable condition — `'SUMMARIZER'`: a `compact()` with no summarizer; `'SECTIONS'`: a sub-1 `sections` cap. */
1518
+ /** Names the machine-readable condition — `'SUMMARIZER'`: a `compact()` with no summarizer; `'SECTIONS'`: a sub-1 `sections` cap. */
1325
1519
  readonly code: 'SUMMARIZER' | 'SECTIONS';
1326
1520
  constructor(code: 'SUMMARIZER' | 'SECTIONS', message: string);
1327
1521
  }
1328
1522
 
1329
1523
  /**
1330
- * The push observation surface (§13) of a {@link ConversationInterface} — the compaction
1331
- * moments a fire-and-forget observer subscribes to via `conversation.emitter.on`.
1524
+ * Maps the push observation surface of a {@link ConversationInterface} — the compaction
1525
+ * moments a fire-and-forget observer subscribes to through `conversation.emitter.on`.
1332
1526
  *
1333
1527
  * @remarks
1334
- * `compact` carries the newly-folded {@link SectionInterface}; `collapse` carries a section
1528
+ * `compact` carries the newly-folded {@link Section}; `collapse` carries a section
1335
1529
  * created by folding multiple OLDER sections together (a bounded-`sections` cap enforcement,
1336
1530
  * distinct from `compact`'s fresh live-tail fold); `summary` carries the regenerated
1337
1531
  * conversation rollup (refreshed on each compaction); `rehydrate` carries the `id` of a
1338
- * section whose originals were pulled back. Listener isolation is the emitter's
1339
- * (§13): every event is emitted directly and a listener throw is routed to the emitter's
1532
+ * section whose originals were pulled back. Listener isolation is the emitter's:
1533
+ * every event is emitted directly and a listener throw is routed to the emitter's
1340
1534
  * `error` handler (the `error` option), never onto this map, so a buggy observer can never
1341
- * corrupt a compaction. A `type` alias (not `interface extends EventMap`, §4.5) so the
1535
+ * corrupt a compaction. A `type` alias (not `interface extends EventMap`) so the
1342
1536
  * type-literal satisfies `EventMap` structurally.
1343
1537
  */
1344
1538
  export declare type ConversationEventMap = {
1345
- /** A new section was folded from the live tail — the created section. */
1346
- readonly compact: readonly [section: SectionInterface];
1347
- /** The conversation rollup was regenerated — the new summary text. */
1539
+ /** Reports a new section folded from the live tail — the created section. */
1540
+ readonly compact: readonly [section: Section];
1541
+ /** Reports the conversation rollup regenerated — the new summary text. */
1348
1542
  readonly summary: readonly [summary: string];
1349
- /** A section's original messages were pulled back — the section's `id`. */
1543
+ /** Reports a section's original messages pulled back — the section's `id`. */
1350
1544
  readonly rehydrate: readonly [id: string];
1351
1545
  /**
1352
- * The bounded-`sections` cap folded the oldest sections into ONE merged section — the
1353
- * merged {@link SectionInterface} that replaced them.
1546
+ * Reports the bounded-`sections` cap folding the oldest sections into ONE merged section — the
1547
+ * merged {@link Section} that replaced them.
1354
1548
  */
1355
- readonly collapse: readonly [section: SectionInterface];
1549
+ readonly collapse: readonly [section: Section];
1356
1550
  };
1357
1551
 
1358
1552
  /**
1359
- * The data to author a {@link ConversationInterface} through a
1553
+ * Carries the data to author a {@link ConversationInterface} through a
1360
1554
  * {@link ConversationManagerInterface} — the optional `id`, a `summarize` override, a `keep`
1361
1555
  * override, and the reserved `on` hooks.
1362
1556
  *
1363
1557
  * @remarks
1364
1558
  * `id` is the conversation's identity (minted when omitted). `summarize` OVERRIDES the
1365
- * manager's default {@link ConversationSummarizer} for this conversation (omitted ⇒ the
1559
+ * manager's default {@link ConversationSummaryHandler} for this conversation (omitted ⇒ the
1366
1560
  * manager's default flows in). `keep` overrides the manager's default retained-tail size.
1367
- * `sections` overrides the manager's default `sections` cap. `on` is the §8 reserved key
1561
+ * `sections` overrides the manager's default `sections` cap. `on` is the reserved listener key
1368
1562
  * (initial {@link ConversationEventMap} listeners). `snapshot` is
1369
1563
  * the construction-time hydration seam — a {@link ConversationSnapshot} whose `id` / `summary` /
1370
1564
  * `sections` / live tail are RESTORED into the new conversation (the live `summarize` / `keep` /
1371
1565
  * `on` re-supplied alongside it), the conversation analogue of
1372
- * {@link import('@orkestrel/workspace').WorkspaceOptions}'s `seed` that a
1566
+ * {@link import('@orkestrel/workspace').WorkspaceOptions}'s `seed`, carried onto
1567
+ * {@link ConversationOptions.snapshot}, that a
1373
1568
  * {@link ConversationManagerInterface.open} reads a stored snapshot back through; hydration is
1374
1569
  * silent (no events). When both `snapshot.id` and `id` are given, `snapshot.id` wins (the snapshot
1375
1570
  * IS the conversation's identity).
@@ -1377,21 +1572,21 @@ export declare type ConversationEventMap = {
1377
1572
  export declare interface ConversationInput {
1378
1573
  readonly id?: string;
1379
1574
  /** Overrides the manager's default summarizer for this conversation. */
1380
- readonly summarize?: ConversationSummarizer;
1575
+ readonly summarize?: ConversationSummaryHandler;
1381
1576
  /** Overrides the manager's default retained-tail size for this conversation. */
1382
1577
  readonly keep?: number;
1383
1578
  /** Overrides the manager's default `sections` cap for this conversation. */
1384
1579
  readonly sections?: number;
1385
1580
  readonly on?: EmitterHooks<ConversationEventMap>;
1386
- /** A {@link ConversationSnapshot} to hydrate from, analogous to the workspace package's seed input. */
1581
+ /** Hydrates from a {@link ConversationSnapshot}, passed on as {@link ConversationOptions.snapshot}. */
1387
1582
  readonly snapshot?: ConversationSnapshot;
1388
1583
  }
1389
1584
 
1390
1585
  /**
1391
- * A conversation grouping messages ABOVE the flat {@link MessageManagerInterface} — a live
1392
- * uncompacted tail plus compacted, summarized {@link SectionInterface}s and a conversation
1586
+ * Groups messages ABOVE the flat {@link MessageManagerInterface} — a live
1587
+ * uncompacted tail plus compacted, summarized {@link Section}s and a conversation
1393
1588
  * rollup `summary`, with on-demand `rehydrate` and substring `search`, driven by a
1394
- * provider-agnostic {@link ConversationSummarizer} seam.
1589
+ * provider-agnostic {@link ConversationSummaryHandler} seam.
1395
1590
  *
1396
1591
  * @remarks
1397
1592
  * - **Live tail + sections.** The conversation OWNS its LIVE uncompacted tail DIRECTLY — a
@@ -1401,109 +1596,110 @@ export declare interface ConversationInput {
1401
1596
  * (oldest → newest), each a summarized slice that RETAINS its originals. `summary` is the
1402
1597
  * conversation rollup (a summary-of-summaries over all sections), regenerated on each
1403
1598
  * compaction (`undefined` until the first compaction).
1404
- * - **Message verbs (the inlined store).** `add` takes one {@link MessageInput} or a batch
1405
- * (§9.2), MINTS each message's `id` (a random UUID), stores it, and returns the created
1599
+ * - **Message verbs (the inlined store).** `add` takes one {@link MessageInput} or a batch,
1600
+ * MINTS each message's `id` (a random UUID), stores it, and returns the created
1406
1601
  * message(s); a stored message is immutable. `message(id)` resolves one (`undefined` when
1407
1602
  * absent); `messages()` lists the live tail in insertion order; `remove` drops one by id or
1408
- * a batch (§9.2); `clear` empties the tail; `count` is how many live messages are stored.
1603
+ * a batch (`true` only when EVERY supplied id was removed); `clear` empties the tail;
1604
+ * `count` is how many live messages are stored.
1409
1605
  * - **`view()` — the model input.** Each section folds to ONE synthetic summary message,
1410
1606
  * followed by the live messages verbatim: `[...sections-as-summary-messages, ...live]`. The
1411
1607
  * rollup `summary` is NOT injected (it is a separately pull-able digest for a
1412
1608
  * cross-conversation case); `view()` carries the per-section summaries, which ARE the
1413
1609
  * compaction benefit.
1414
1610
  * - **`compact()` — fold older live → a section.** Folds the oldest `count - keep` live
1415
- * messages into a new {@link SectionInterface} (its `summary` from `summarize`), removes
1611
+ * messages into a new {@link Section} (its `summary` from `summarize`), removes
1416
1612
  * them from the live tail, REGENERATES the rollup (a second `summarize` over all section
1417
1613
  * summaries), and emits `summary` then `compact` — returning the new section (or
1418
1614
  * `undefined` when nothing folds). TWO summarizer calls per compaction (the section digest
1419
1615
  * + the rollup). Throws a {@link import('./errors.js').ConversationError} when no
1420
1616
  * `summarize` was supplied.
1421
1617
  * - **`summarizable` — whether a `compact()` CAN fold.** `true` when a
1422
- * {@link ConversationSummarizer} was supplied, `false` otherwise. The agent loop's AUTOMATIC
1618
+ * {@link ConversationSummaryHandler} was supplied, `false` otherwise. The agent loop's AUTOMATIC
1423
1619
  * compaction (`AgentOptions.window`) gates on it so a conversation that has no summarizer is
1424
1620
  * never auto-compacted (and the loop never throws the `compact()` `SUMMARIZER` error from the
1425
1621
  * auto path). A MANUAL `compact()` still throws without a summarizer — only the auto path is
1426
1622
  * guarded.
1427
1623
  * - **`rehydrate(id)` / `search(query)` — read the retained originals.** `rehydrate` returns
1428
1624
  * a section's full original messages (`[]` for an unknown id) and emits `rehydrate` — a
1429
- * pure READ (the caller decides whether to re-add them; v1 never auto-reinserts).
1625
+ * pure READ (the caller decides whether to re-add them; `rehydrate` never reinserts).
1430
1626
  * `search` is a case-insensitive substring scan of `content` across ALL messages (every
1431
1627
  * section's originals + the live tail).
1432
1628
  * - **`reference(options?)` — pull THIS conversation into ANOTHER with provenance.** A PURE
1433
1629
  * string render (no model call) of a self-labeled, fenced cross-conversation block — the
1434
1630
  * rollup `summary` (when included + present) plus cherry-picked excerpts — framed so a small
1435
- * model reads it as FOREIGN material. Written into the ACTIVE conversation's context via the
1436
- * active workspace (`context.workspaces.active?.write(path, block)`); the cherry-pick comes
1437
- * from this conversation's own `search` / `rehydrate`, never its whole history.
1438
- * - **Observable (§13).** The owned `emitter` ({@link ConversationEventMap}) carries
1631
+ * model reads it as FOREIGN material. Written into the ACTIVE conversation's context through
1632
+ * the active workspace (`context.workspaces.active?.write(path, block)`); the cherry-pick
1633
+ * comes from this conversation's own `search` / `rehydrate`, never its whole history.
1634
+ * - **Observable.** The owned `emitter` ({@link ConversationEventMap}) carries
1439
1635
  * `compact` / `summary` / `rehydrate`; the emitter isolates a listener throw and routes it
1440
- * to its `error` handler (the `error` option, §13).
1636
+ * to its `error` handler (the `error` option).
1441
1637
  */
1442
1638
  export declare interface ConversationInterface {
1443
1639
  readonly id: string;
1444
1640
  readonly emitter: EmitterInterface<ConversationEventMap>;
1445
- /** The conversation rollup (a summary-of-summaries), regenerated on each compaction; `undefined` until the first. */
1641
+ /** Holds the conversation rollup (a summary-of-summaries), regenerated on each compaction; `undefined` until the first. */
1446
1642
  readonly summary: string | undefined;
1447
- /** The compacted history, oldest → newest. */
1448
- readonly sections: readonly SectionInterface[];
1643
+ /** Lists the compacted history, oldest → newest. */
1644
+ readonly sections: readonly Section[];
1449
1645
  /**
1450
- * Whether a `compact()` CAN fold — `true` when a {@link ConversationSummarizer} was supplied.
1646
+ * Reports whether a `compact()` CAN fold — `true` when a {@link ConversationSummaryHandler} was supplied.
1451
1647
  * The agent loop's AUTOMATIC compaction (`AgentOptions.window`) gates on it (a non-summarizable
1452
1648
  * conversation is never auto-compacted, so the auto path never throws the `SUMMARIZER` error);
1453
1649
  * a MANUAL `compact()` still throws without a summarizer.
1454
1650
  */
1455
1651
  readonly summarizable: boolean;
1456
- /** How many LIVE (uncompacted) messages are stored in the tail. */
1652
+ /** Counts the LIVE (uncompacted) messages stored in the tail. */
1457
1653
  readonly count: number;
1458
1654
  /**
1459
- * Append one message to the live tail (or a batch, §9.2) — MINTS each message's `id`
1655
+ * Appends one message to the live tail (or a batch) — MINTS each message's `id`
1460
1656
  * (a random UUID) and returns the created message(s); a stored message is immutable.
1461
1657
  *
1462
1658
  * @param input - One {@link MessageInput}, or a batch
1463
- * @returns The created {@link MessageInterface}(s), with their minted `id`s
1659
+ * @returns The created {@link Message}(s), with their minted `id`s
1464
1660
  */
1465
- add(input: MessageInput): MessageInterface;
1466
- add(inputs: readonly MessageInput[]): readonly MessageInterface[];
1661
+ add(input: MessageInput): Message;
1662
+ add(inputs: readonly MessageInput[]): readonly Message[];
1467
1663
  /**
1468
- * Look up one LIVE message by id.
1664
+ * Looks up one LIVE message by id.
1469
1665
  *
1470
1666
  * @param id - The message id to resolve
1471
- * @returns The {@link MessageInterface}, or `undefined` when absent
1667
+ * @returns The {@link Message}, or `undefined` when absent
1472
1668
  */
1473
- message(id: string): MessageInterface | undefined;
1669
+ message(id: string): Message | undefined;
1474
1670
  /**
1475
- * Every LIVE (uncompacted) message in the tail, in insertion order.
1671
+ * Lists every LIVE (uncompacted) message in the tail, in insertion order.
1476
1672
  *
1477
1673
  * @returns The live tail, in insertion order
1478
1674
  */
1479
- messages(): readonly MessageInterface[];
1675
+ messages(): readonly Message[];
1480
1676
  /**
1481
- * Remove one LIVE message by id (or a batch, §9.2) from the tail.
1677
+ * Removes one LIVE message by id (or a batch) from the tail.
1482
1678
  *
1483
1679
  * @param id - One message id, or a batch
1484
- * @returns `true` when any was removed
1680
+ * @returns True when every supplied id was present and removed; false otherwise
1485
1681
  */
1486
1682
  remove(id: string): boolean;
1487
1683
  remove(ids: readonly string[]): boolean;
1488
- /** Empty the live tail (the compacted `sections` are untouched). */
1684
+ /** Empties the live tail (the compacted `sections` are untouched). */
1489
1685
  clear(): void;
1490
1686
  /**
1491
- * The model input for the next turn — each section as ONE synthetic summary message,
1687
+ * Builds the model input for the next turn — each section as ONE synthetic summary message,
1492
1688
  * then the live messages verbatim (the rollup `summary` is NOT injected).
1493
1689
  *
1494
1690
  * @returns `[...sections-as-summary-messages, ...live messages]`
1495
1691
  */
1496
- view(): readonly MessageInterface[];
1692
+ view(): readonly Message[];
1497
1693
  /**
1498
- * Fold the older live messages into a summarized {@link SectionInterface}, regenerate the
1499
- * rollup, and emit `summary` then `compact`.
1694
+ * Folds the older live messages into a summarized {@link Section}, regenerates the
1695
+ * rollup, and emits `summary` then `compact`.
1500
1696
  *
1501
1697
  * @remarks
1502
1698
  * Folds the oldest `count - keep` live messages (`keep` from `options`, else the
1503
1699
  * conversation's own); when `count <= keep` NOTHING folds and this is a no-op resolving
1504
1700
  * `undefined`. Otherwise it summarizes the slice into the section, removes those messages
1505
1701
  * from the live tail, regenerates the rollup (a second `summarize` over all sections), and
1506
- * resolves the new section. Requires a {@link ConversationSummarizer} — THROWS a
1702
+ * resolves the new section. Requires a {@link ConversationSummaryHandler} — THROWS a
1507
1703
  * {@link import('./errors.js').ConversationError} when none was supplied.
1508
1704
  *
1509
1705
  * @remarks
@@ -1514,26 +1710,26 @@ export declare interface ConversationInterface {
1514
1710
  * propagates; the next successful `compact()` self-heals the section count back to `cap`.
1515
1711
  *
1516
1712
  * @param options - Optional {@link CompactOptions} (`keep` overrides the retained-tail size)
1517
- * @returns The new {@link SectionInterface}, or `undefined` when nothing folded
1713
+ * @returns The new {@link Section}, or `undefined` when nothing folded
1518
1714
  */
1519
- compact(options?: CompactOptions): Promise<SectionInterface | undefined>;
1715
+ compact(options?: CompactOptions): Promise<Section | undefined>;
1520
1716
  /**
1521
- * A section's full original messages — a pure READ that emits `rehydrate`.
1717
+ * Returns a section's full original messages — a pure READ that emits `rehydrate`.
1522
1718
  *
1523
- * @param id - The {@link SectionInterface} `id` to pull back
1719
+ * @param id - The {@link Section} `id` to pull back
1524
1720
  * @returns The section's retained original messages (empty when no such section)
1525
1721
  */
1526
- rehydrate(id: string): readonly MessageInterface[];
1722
+ rehydrate(id: string): readonly Message[];
1527
1723
  /**
1528
- * Case-insensitive substring search over `content` across ALL messages — every section's
1724
+ * Searches `content` for a case-insensitive substring across ALL messages — every section's
1529
1725
  * retained originals plus the live tail.
1530
1726
  *
1531
1727
  * @param query - The substring to match (case-insensitive)
1532
1728
  * @returns The matching messages, sections' originals first then the live tail
1533
1729
  */
1534
- search(query: string): readonly MessageInterface[];
1730
+ search(query: string): readonly Message[];
1535
1731
  /**
1536
- * Render THIS conversation as a self-labeled, fenced PROVENANCE block to pull INTO another
1732
+ * Renders THIS conversation as a self-labeled, fenced PROVENANCE block to pull INTO another
1537
1733
  * conversation — a pure string (NO model call), framed so a small model reads it as FOREIGN
1538
1734
  * material, not as part of the live thread.
1539
1735
  *
@@ -1554,7 +1750,7 @@ export declare interface ConversationInterface {
1554
1750
  */
1555
1751
  reference(options?: ConversationReferenceOptions): string;
1556
1752
  /**
1557
- * Serialize this conversation to a plain, JSON-serializable {@link ConversationSnapshot} — its
1753
+ * Serializes this conversation to a plain, JSON-serializable {@link ConversationSnapshot} — its
1558
1754
  * `id`, the rollup `summary`, the compacted `sections`, and the live tail (its `messages()`).
1559
1755
  *
1560
1756
  * @remarks
@@ -1562,8 +1758,8 @@ export declare interface ConversationInterface {
1562
1758
  * {@link ConversationStoreInterface} persistence seam's payload, the exact analogue of
1563
1759
  * {@link import('@orkestrel/workspace').WorkspaceInterface}'s `snapshot`. The summarizer /
1564
1760
  * `keep` are NOT serialized — they are live
1565
- * CONFIG re-supplied on hydrate (a `ConversationSummarizer` is a function, not data). The snapshot
1566
- * is the durable analogue of the constructor `seed`: a {@link ConversationManagerInterface}
1761
+ * CONFIG re-supplied on hydrate (a `ConversationSummaryHandler` is a function, not data). The snapshot
1762
+ * is the durable analogue of the `snapshot` option: a {@link ConversationManagerInterface}
1567
1763
  * HYDRATES a conversation from it through that seam (see {@link ConversationManagerInterface.open}).
1568
1764
  * Pure — the sections + messages are already plain immutable records (so the snapshot
1569
1765
  * `structuredClone`s / JSON-round-trips losslessly), and snapshotting mutates nothing.
@@ -1574,8 +1770,8 @@ export declare interface ConversationInterface {
1574
1770
  }
1575
1771
 
1576
1772
  /**
1577
- * The registry of {@link Conversation}s keyed by `id`, in insertion order, WITH an active pointer
1578
- * — the §9 store over the conversation layer PLUS the `active` / `switch` seam the
1773
+ * Registers {@link Conversation}s keyed by `id`, in insertion order, WITH an active pointer
1774
+ * — the id-keyed store over the conversation layer PLUS the `active` / `switch` seam the
1579
1775
  * {@link import('../AgentContext.js').AgentContext} renders. Event-free (a registry, like
1580
1776
  * {@link import('@orkestrel/workspace').WorkspaceManager}); the observability lives
1581
1777
  * on each {@link Conversation}.
@@ -1592,8 +1788,8 @@ export declare interface ConversationInterface {
1592
1788
  * `switch(id)` re-points `active` to the conversation with `id` and returns it; an unknown `id`
1593
1789
  * returns `undefined` and leaves `active` unchanged (the lenient lookup style — never throws,
1594
1790
  * no new error code).
1595
- * - **Removal.** `remove` drops one by id, or a batch (§9.2) — `true` when any was removed;
1596
- * removing the ACTIVE conversation sets `active` to `undefined`. `clear` empties the registry
1791
+ * - **Removal.** `remove` drops one by id, or a batch — `true` only when EVERY supplied id was
1792
+ * removed; removing the ACTIVE conversation sets `active` to `undefined`. `clear` empties the registry
1597
1793
  * and sets `active` to `undefined`.
1598
1794
  * - **Event-free.** A purely registry store — no Emitter, no events (each conversation owns
1599
1795
  * its own observable `emitter`).
@@ -1624,8 +1820,8 @@ export declare class ConversationManager implements ConversationManagerInterface
1624
1820
  }
1625
1821
 
1626
1822
  /**
1627
- * A registry of {@link ConversationInterface}s keyed by their `id`, in insertion order, WITH an
1628
- * active pointer — the §9 store over the conversation layer PLUS the `active` / `switch` seam the
1823
+ * Registers {@link ConversationInterface}s keyed by their `id`, in insertion order, WITH an
1824
+ * active pointer — the id-keyed store over the conversation layer PLUS the `active` / `switch` seam the
1629
1825
  * {@link AgentContextInterface} renders. Event-free (a registry, like
1630
1826
  * {@link import('@orkestrel/workspace').WorkspaceManagerInterface}); the observability lives on each
1631
1827
  * {@link ConversationInterface}.
@@ -1642,12 +1838,12 @@ export declare class ConversationManager implements ConversationManagerInterface
1642
1838
  * `switch(id)` re-points `active` to the conversation with `id` and returns it; an unknown
1643
1839
  * `id` returns `undefined` and leaves `active` unchanged (the lenient lookup style — never
1644
1840
  * throws, no new error code).
1645
- * - **Removal.** `remove` drops one by id, or a batch (§9.2, array overload FIRST) — `true`
1646
- * when any was removed; removing the ACTIVE conversation sets `active` to `undefined`. `clear`
1841
+ * - **Removal.** `remove` drops one by id, or a batch (array overload FIRST) — `true`
1842
+ * only when EVERY supplied id was removed; removing the ACTIVE conversation sets `active` to `undefined`. `clear`
1647
1843
  * empties the registry and sets `active` to `undefined`.
1648
1844
  * - **Durable open / save (the optional `store` seam).** When a {@link ConversationStoreInterface}
1649
1845
  * is supplied (the `store` option), `open(id)` HYDRATES a conversation from the store on a registry
1650
- * miss (rebuilding it through the constructor `seed` from the snapshot, flowing the manager's
1846
+ * miss (rebuilding it through the `snapshot` option, flowing the manager's
1651
1847
  * default `summarize` / `keep` in) and `save(id)` PERSISTS a registered conversation's
1652
1848
  * {@link ConversationInterface.snapshot}. Both are LENIENT without a store — `open` resolves only
1653
1849
  * registered ids, `save` is a no-op (`false`) — consistent with the lenient `switch`. It mirrors
@@ -1657,20 +1853,20 @@ export declare class ConversationManager implements ConversationManagerInterface
1657
1853
  */
1658
1854
  export declare interface ConversationManagerInterface {
1659
1855
  readonly count: number;
1660
- /** The active conversation — the agent's message source the context renders; `undefined` until the first `add`. */
1856
+ /** Holds the active conversation — the agent's message source the context renders; `undefined` until the first `add`. */
1661
1857
  readonly active: ConversationInterface | undefined;
1662
1858
  conversation(id: string): ConversationInterface | undefined;
1663
1859
  conversations(): readonly ConversationInterface[];
1664
1860
  add(input?: ConversationInput): ConversationInterface;
1665
1861
  switch(id: string): ConversationInterface | undefined;
1666
1862
  /**
1667
- * Resolve a conversation by id, ACTIVATING it — from the registry if present, else HYDRATED from
1863
+ * Resolves a conversation by id, ACTIVATING it — from the registry if present, else HYDRATED from
1668
1864
  * the optional {@link ConversationStoreInterface} (`store`).
1669
1865
  *
1670
1866
  * @remarks
1671
1867
  * - If `id` is ALREADY registered, it is ACTIVATED (`switch`ed to) and returned — no store hit.
1672
1868
  * - Else if a `store` is set, `store.get(id)` is awaited; on a HIT the snapshot is rehydrated
1673
- * into a fresh {@link ConversationInterface} through the constructor `seed`
1869
+ * into a fresh {@link ConversationInterface} through the `snapshot` option
1674
1870
  * (`add({ snapshot, ... })`, flowing the manager's default `summarize` / `keep` in), which
1675
1871
  * registers AND activates it, and it is returned.
1676
1872
  * - Else (no store, or a store MISS) ⇒ `undefined` (lenient — no throw).
@@ -1680,7 +1876,7 @@ export declare interface ConversationManagerInterface {
1680
1876
  */
1681
1877
  open(id: string): Promise<ConversationInterface | undefined>;
1682
1878
  /**
1683
- * Persist a REGISTERED conversation's {@link ConversationInterface.snapshot} to the optional
1879
+ * Persists a REGISTERED conversation's {@link ConversationInterface.snapshot} to the optional
1684
1880
  * {@link ConversationStoreInterface} (`store`).
1685
1881
  *
1686
1882
  * @remarks
@@ -1689,7 +1885,7 @@ export declare interface ConversationManagerInterface {
1689
1885
  * `false` — never a throw, consistent with the lenient `switch`.
1690
1886
  *
1691
1887
  * @param id - The id of the registered conversation to persist
1692
- * @returns `true` when the snapshot was persisted; `false` when no store / unknown id
1888
+ * @returns True if the snapshot was persisted; false otherwise (no store, or an unknown id)
1693
1889
  */
1694
1890
  save(id: string): Promise<boolean>;
1695
1891
  remove(ids: readonly string[]): boolean;
@@ -1698,7 +1894,7 @@ export declare interface ConversationManagerInterface {
1698
1894
  }
1699
1895
 
1700
1896
  /**
1701
- * Options for `createConversationManager` — the default {@link ConversationSummarizer} and
1897
+ * Configures `createConversationManager` — the default {@link ConversationSummaryHandler} and
1702
1898
  * retained-tail size the conversations it creates inherit.
1703
1899
  *
1704
1900
  * @remarks
@@ -1711,14 +1907,14 @@ export declare interface ConversationManagerInterface {
1711
1907
  * overrides it); omitted ⇒ unlimited.
1712
1908
  */
1713
1909
  export declare interface ConversationManagerOptions {
1714
- /** The default summarizer for conversations this manager creates (a per-`add` override wins). */
1715
- readonly summarize?: ConversationSummarizer;
1716
- /** The default retained-tail size (a per-`add` override wins); defaults to `DEFAULT_CONVERSATION_KEEP`. */
1910
+ /** Supplies the default summarizer for conversations this manager creates (a per-`add` override wins). */
1911
+ readonly summarize?: ConversationSummaryHandler;
1912
+ /** Sets the default retained-tail size (a per-`add` override wins); defaults to `DEFAULT_CONVERSATION_KEEP`. */
1717
1913
  readonly keep?: number;
1718
- /** The default `sections` cap for conversations this manager creates (a per-`add` override wins); omitted ⇒ unlimited. */
1914
+ /** Sets the default `sections` cap for conversations this manager creates (a per-`add` override wins); omitted ⇒ unlimited. */
1719
1915
  readonly sections?: number;
1720
1916
  /**
1721
- * The optional durable {@link ConversationStoreInterface} backing
1917
+ * Holds the optional durable {@link ConversationStoreInterface} backing
1722
1918
  * {@link ConversationManagerInterface.open} / {@link ConversationManagerInterface.save} — a memory
1723
1919
  * / JSON / SQLite / IndexedDB store a conversation is HYDRATED from (`open` a registry-miss) and
1724
1920
  * PERSISTED to (`save`). Omitted ⇒ the manager is registry-only: `open` resolves only what is
@@ -1729,37 +1925,46 @@ export declare interface ConversationManagerOptions {
1729
1925
  }
1730
1926
 
1731
1927
  /**
1732
- * Options for `createConversation` — the optional `id`, the reserved `on` hooks (§8), the
1928
+ * Configures `createConversation` — the optional `id`, the reserved `on` hooks, the
1733
1929
  * provider-agnostic `summarize` seam, and the retained-tail size.
1734
1930
  *
1735
1931
  * @remarks
1736
- * `id` is the conversation's identity (a random UUID when omitted). `on` is the §8 reserved
1737
- * key (initial {@link ConversationEventMap} listeners). `summarize` is the
1738
- * {@link ConversationSummarizer} compaction needs — ABSENT ⇒ `compact()` throws a
1932
+ * `id` is the conversation's identity (a random UUID when omitted). `on` is the reserved
1933
+ * listener key (initial {@link ConversationEventMap} listeners). `summarize` is the
1934
+ * {@link ConversationSummaryHandler} compaction needs — ABSENT ⇒ `compact()` throws a
1739
1935
  * {@link import('./errors.js').ConversationError} (a conversation can still store + view a
1740
- * live tail, it just cannot fold). `keep` is how many recent live messages a `compact()`
1936
+ * live tail; it cannot fold). `keep` is how many recent live messages a `compact()`
1741
1937
  * retains VERBATIM (folding only the older ones); it defaults to
1742
1938
  * {@link import('./constants.js').DEFAULT_CONVERSATION_KEEP} (`0` — a manual `compact()`
1743
1939
  * folds the WHOLE current live tail into one section). `sections` is an optional cap on the
1744
1940
  * compacted `sections` list — when set (`>= 1`), a `compact()` that would leave more than
1745
1941
  * `sections` sections FOLDS the oldest overflow into ONE merged section so the list never
1746
1942
  * exceeds `sections`, emitting `collapse`; omitted ⇒ unlimited (the prior behavior).
1943
+ * `snapshot` is the HYDRATION seam — a {@link ConversationSnapshot} whose `id`, rollup
1944
+ * `summary`, compacted `sections`, and live tail are RESTORED into the new conversation, with
1945
+ * the live `summarize` / `keep` / `on` supplied alongside it (a summarizer is a function, not
1946
+ * serialized data). Restoring is SILENT (no events — nothing was edited), and a `snapshot.id`
1947
+ * WINS over `id` (the snapshot IS the conversation's identity). It is what lets
1948
+ * `createConversation` hydrate, and what a {@link ConversationManagerInterface.open} reads a
1949
+ * stored snapshot back through.
1747
1950
  */
1748
1951
  export declare interface ConversationOptions {
1749
1952
  readonly id?: string;
1750
1953
  readonly on?: EmitterHooks<ConversationEventMap>;
1751
- /** The emitter's listener-error handler (AGENTS §13) — a listener throw routes here, not to a domain event. */
1954
+ /** Holds the emitter's listener-error handler — a listener throw routes here, not to a domain event. */
1752
1955
  readonly error?: EmitterErrorHandler;
1753
- /** The summarizer compaction needs; ABSENT ⇒ `compact()` throws a `ConversationError`. */
1754
- readonly summarize?: ConversationSummarizer;
1755
- /** Recent live messages kept verbatim on `compact`; defaults to `DEFAULT_CONVERSATION_KEEP` (`0`). */
1956
+ /** Supplies the summarizer compaction needs; ABSENT ⇒ `compact()` throws a `ConversationError`. */
1957
+ readonly summarize?: ConversationSummaryHandler;
1958
+ /** Keeps this many recent live messages verbatim on `compact`; defaults to `DEFAULT_CONVERSATION_KEEP` (`0`). */
1756
1959
  readonly keep?: number;
1757
- /** A cap (`>= 1`) on the compacted `sections` list; overflow folds into one merged section. Omitted ⇒ unlimited. */
1960
+ /** Caps the compacted `sections` list (`>= 1`); overflow folds into one merged section. Omitted ⇒ unlimited. */
1758
1961
  readonly sections?: number;
1962
+ /** Hydrates from a {@link ConversationSnapshot} — its `id` wins over `id`; restoring is silent. */
1963
+ readonly snapshot?: ConversationSnapshot;
1759
1964
  }
1760
1965
 
1761
1966
  /**
1762
- * Options for {@link ConversationInterface.reference} — how to render ONE conversation as a
1967
+ * Configures {@link ConversationInterface.reference} — how to render ONE conversation as a
1763
1968
  * self-labeled, fenced PROVENANCE block to pull INTO another conversation (by writing it to
1764
1969
  * the active context's active workspace).
1765
1970
  *
@@ -1767,56 +1972,56 @@ export declare interface ConversationOptions {
1767
1972
  * The rendered block is a cross-conversation reference a SMALL model must read as foreign
1768
1973
  * material, NOT as part of the live thread — so every member keeps it CONCISE and unmistakably
1769
1974
  * attributed:
1770
- * - `label` — the human PROVENANCE name shown in the block's leading marker (e.g. `'planning'`);
1975
+ * - `label` — the human PROVENANCE name shown in the block's leading marker (for example `'planning'`);
1771
1976
  * defaults to the conversation's own `id`. It is what the model attributes the content to.
1772
1977
  * - `summary` — whether to include the conversation's rollup `summary` (its summary-of-summaries)
1773
1978
  * in the block; defaults to `true` (the rollup is included WHEN one exists — `undefined` until
1774
- * the first compaction simply omits the `Summary:` line). Pass `false` to exclude it.
1979
+ * the first compaction omits the `Summary:` line). Pass `false` to exclude it.
1775
1980
  * - `messages` — the CHERRY-PICKED excerpts to include (each rendered `role: content`), default
1776
1981
  * NONE. The intended source is the conversation's OWN `search(query)` / `rehydrate(id)` output
1777
1982
  * (select the few relevant turns), NOT its whole history — dumping every message defeats the
1778
1983
  * point (it re-bloats the destination context a small model then has to wade through).
1779
1984
  */
1780
1985
  export declare interface ConversationReferenceOptions {
1781
- /** The human provenance label in the block's marker; defaults to the conversation's `id`. */
1986
+ /** Names the human provenance label in the block's marker; defaults to the conversation's `id`. */
1782
1987
  readonly label?: string;
1783
- /** Include the conversation's rollup `summary` (when one exists); defaults to `true`. */
1988
+ /** Includes the conversation's rollup `summary` (when one exists); defaults to `true`. */
1784
1989
  readonly summary?: boolean;
1785
- /** The cherry-picked excerpts to include (`role: content`); defaults to none. */
1786
- readonly messages?: readonly MessageInterface[];
1990
+ /** Lists the cherry-picked excerpts to include (`role: content`); defaults to none. */
1991
+ readonly messages?: readonly Message[];
1787
1992
  }
1788
1993
 
1789
1994
  /**
1790
- * A JSON-serializable snapshot of a conversation's state — its `id`, the rollup `summary`, the
1995
+ * Holds a JSON-serializable snapshot of a conversation's state — its `id`, the rollup `summary`, the
1791
1996
  * compacted `sections`, and the live tail `messages` — the durable payload the
1792
1997
  * {@link ConversationStoreInterface} persists. The exact analogue of
1793
1998
  * {@link import('@orkestrel/workspace').WorkspaceSnapshot}.
1794
1999
  *
1795
2000
  * @remarks
1796
- * Pure JSON DATA (no class instances, no functions): each {@link SectionInterface} and
1797
- * {@link MessageInterface} is already a PLAIN record that `structuredClone`s / JSON-round-trips
2001
+ * Pure JSON DATA (no class instances, no functions): each {@link Section} and
2002
+ * {@link Message} is already a PLAIN record that `structuredClone`s / JSON-round-trips
1798
2003
  * losslessly. The snapshot carries the rollup `summary` (a summary-of-summaries; `undefined` until
1799
2004
  * the first compaction), the compacted `sections` (each RETAINING its folded originals), and the
1800
2005
  * live uncompacted tail `messages` — but NOT the `summarize` / `keep`, which are live CONFIG
1801
2006
  * re-supplied on hydrate (a summarizer is a function, not serializable data). The snapshot the
1802
2007
  * container produces from itself ({@link ConversationInterface.snapshot}); the durable analogue of
1803
- * the constructor `seed`. A {@link ConversationManagerInterface} hydrates a conversation from it
1804
- * through the seed seam (see {@link ConversationManagerInterface.open}). It is narrowed back from an
1805
- * untrusted storage read by {@link import('./helpers.js').isConversationSnapshot} (the AGENTS §14
1806
- * boundary narrow).
2008
+ * the {@link ConversationOptions.snapshot} hydration seam. A {@link ConversationManagerInterface}
2009
+ * hydrates a conversation from it through that seam (see {@link ConversationManagerInterface.open}). It is narrowed back from an
2010
+ * untrusted storage read by {@link import('./validators.js').isConversationSnapshot} (the total
2011
+ * boundary guard).
1807
2012
  */
1808
2013
  export declare interface ConversationSnapshot {
1809
2014
  readonly id: string;
1810
- /** The rollup (a summary-of-summaries); `undefined` until the first compaction. */
2015
+ /** Holds the rollup (a summary-of-summaries); `undefined` until the first compaction. */
1811
2016
  readonly summary?: string;
1812
- /** The compacted history, oldest → newest (each section RETAINS its folded originals). */
1813
- readonly sections: readonly SectionInterface[];
1814
- /** The live uncompacted tail, in insertion order. */
1815
- readonly messages: readonly MessageInterface[];
2017
+ /** Lists the compacted history, oldest → newest (each section RETAINS its folded originals). */
2018
+ readonly sections: readonly Section[];
2019
+ /** Lists the live uncompacted tail, in insertion order. */
2020
+ readonly messages: readonly Message[];
1816
2021
  }
1817
2022
 
1818
2023
  /**
1819
- * One row of the table a
2024
+ * Represents one row of the table a
1820
2025
  * {@link import('./conversations/stores/DatabaseConversationStore.js').DatabaseConversationStore}
1821
2026
  * persists — a conversation `id` plus its {@link ConversationSnapshot} held as ONE OPAQUE JSON
1822
2027
  * column. The exact analogue of {@link import('@orkestrel/workspace').WorkspaceSnapshotRow}.
@@ -1828,18 +2033,18 @@ export declare interface ConversationSnapshot {
1828
2033
  * row type stays FLAT and the sections/messages snapshot shape never
1829
2034
  * forces the contract to `Infer` it. The column therefore reads back as the broad `unknown`; the
1830
2035
  * store narrows it to a {@link ConversationSnapshot} on `get`
1831
- * ({@link import('./helpers.js').isConversationSnapshot}, the AGENTS §14 boundary narrow). `id`
2036
+ * ({@link import('./validators.js').isConversationSnapshot}, the total boundary guard). `id`
1832
2037
  * mirrors {@link ConversationSnapshot.id} (the primary key), so a `set` writes
1833
2038
  * `{ id: snapshot.id, snapshot }`.
1834
2039
  */
1835
2040
  export declare interface ConversationSnapshotRow {
1836
2041
  readonly id: string;
1837
- /** The whole {@link ConversationSnapshot} as one opaque JSON blob — read back as `unknown`, narrowed on `get`. */
2042
+ /** Holds the whole {@link ConversationSnapshot} as one opaque JSON blob — read back as `unknown`, narrowed on `get`. */
1838
2043
  readonly snapshot: unknown;
1839
2044
  }
1840
2045
 
1841
2046
  /**
1842
- * The durable persistence seam for a {@link ConversationSnapshot} — three async primitives
2047
+ * Persists a {@link ConversationSnapshot} durably — three async primitives
1843
2048
  * (`get` / `set` / `delete`) keyed by a conversation id, the exact analogue of
1844
2049
  * {@link import('@orkestrel/workspace').WorkspaceStoreInterface}.
1845
2050
  *
@@ -1852,7 +2057,7 @@ export declare interface ConversationSnapshotRow {
1852
2057
  * {@link import('./conversations/stores/DatabaseConversationStore.js').DatabaseConversationStore} (the
1853
2058
  * snapshot as one opaque JSON column) share THIS one interface. Hydration is NOT a store concern
1854
2059
  * — a {@link ConversationManagerInterface} reads a snapshot back and rebuilds the live conversation
1855
- * through the constructor `seed` (re-supplying the live `summarize` / `keep`; see
2060
+ * through the {@link ConversationOptions.snapshot} seam (re-supplying the live `summarize` / `keep`; see
1856
2061
  * {@link ConversationManagerInterface.open} / {@link ConversationManagerInterface.save}).
1857
2062
  *
1858
2063
  * Every primitive is async (a `Promise`), so a durable backend (a database round-trip) fits the
@@ -1861,26 +2066,26 @@ export declare interface ConversationSnapshotRow {
1861
2066
  * {@link import('@orkestrel/workspace').WorkspaceStoreInterface}'s `set`). UNLIKE a session store
1862
2067
  * there is NO idle-TTL
1863
2068
  * / eviction — a persisted conversation lives until an explicit `delete`. It is concrete over
1864
- * {@link ConversationSnapshot} — no generic parameter (AGENTS §21 minimal-interface), since the
2069
+ * {@link ConversationSnapshot} — no generic parameter, because the
1865
2070
  * snapshot is the ONE payload a conversation store persists.
1866
2071
  */
1867
2072
  export declare interface ConversationStoreInterface {
1868
2073
  /**
1869
- * Resolve the persisted snapshot for `id`, or `undefined` if none is stored.
2074
+ * Resolves the persisted snapshot for `id`, or `undefined` if none is stored.
1870
2075
  *
1871
2076
  * @param id - The conversation id to resolve (a {@link ConversationSnapshot.id})
1872
2077
  * @returns The persisted snapshot, or `undefined` if absent
1873
2078
  */
1874
2079
  get(id: string): Promise<ConversationSnapshot | undefined>;
1875
2080
  /**
1876
- * Insert or replace a snapshot under its own `snapshot.id` (no separate id param —
2081
+ * Inserts or replaces a snapshot under its own `snapshot.id` (no separate id param —
1877
2082
  * mirroring {@link import('@orkestrel/workspace').WorkspaceStoreInterface}'s `set`).
1878
2083
  *
1879
2084
  * @param snapshot - The snapshot to store (keyed by its `id`)
1880
2085
  */
1881
2086
  set(snapshot: ConversationSnapshot): Promise<void>;
1882
2087
  /**
1883
- * Drop a snapshot by id; an absent id is a no-op (no throw).
2088
+ * Drops a snapshot by id; an absent id is a no-op (no throw).
1884
2089
  *
1885
2090
  * @param id - The conversation id to drop
1886
2091
  */
@@ -1888,25 +2093,25 @@ export declare interface ConversationStoreInterface {
1888
2093
  }
1889
2094
 
1890
2095
  /**
1891
- * A provider-agnostic conversation summarizer — the seam the agent RUNTIME supplies so
2096
+ * Summarizes a conversation, provider-agnostically — the seam the agent RUNTIME supplies so
1892
2097
  * core never imports a provider. Given the folded messages, it resolves their digest (the
1893
- * model-written summary), used both to summarize a compacted {@link SectionInterface} and
2098
+ * model-written summary), used both to summarize a compacted {@link Section} and
1894
2099
  * to regenerate a {@link ConversationInterface}'s rollup `summary`.
1895
2100
  *
1896
2101
  * @remarks
1897
- * The agent runtime builds one from its `ProviderInterface` (e.g.
2102
+ * The agent runtime builds one from its `ProviderInterface` (for example
1898
2103
  * `async (messages) => (await provider.generate([systemPrompt, ...messages], signal)).content`)
1899
2104
  * and hands it to a {@link ConversationInterface} / {@link ConversationManagerInterface}.
1900
- * The core conversation layer treats it as an opaque async function — it neither knows nor
1901
- * cares which backend produced the digest, keeping `core` free of any provider coupling.
2105
+ * The core conversation layer treats it as an opaque async function — it never reads which
2106
+ * backend produced the digest, keeping `core` free of any provider coupling.
1902
2107
  *
1903
2108
  * @param messages - The folded messages to digest into a summary
1904
2109
  * @returns The summary text (the model-written digest of those messages)
1905
2110
  */
1906
- export declare type ConversationSummarizer = (messages: readonly MessageInterface[]) => Promise<string>;
2111
+ export declare type ConversationSummaryHandler = (messages: readonly Message[]) => Promise<string>;
1907
2112
 
1908
2113
  /**
1909
- * Create an agent loop — an {@link AgentInterface} composing a
2114
+ * Creates an agent loop — an {@link AgentInterface} composing a
1910
2115
  * {@link ProviderInterface}, its {@link AgentContextInterface}, and a tool registry
1911
2116
  * into a bounded context → provider → tools → repeat turn, exposed as a one-shot
1912
2117
  * `generate` and a live `stream`.
@@ -1914,11 +2119,11 @@ export declare type ConversationSummarizer = (messages: readonly MessageInterfac
1914
2119
  * @remarks
1915
2120
  * One private loop drives the turn; `generate` DRAINS the same stream `stream`
1916
2121
  * exposes, so they can never diverge. Each turn is bounded by one cancel folded from
1917
- * `signal` + `timeout` + `budget` (via `AbortSignal.any`) — any trip (or `abort()`)
2122
+ * `signal` + `timeout` + `budget` (through `AbortSignal.any`) — any trip (or `abort()`)
1918
2123
  * commits a PARTIAL result (the stream's `result` RESOLVES on a cancel, rejects only
1919
2124
  * on a genuine provider / tool error). The `scheduler` paces between turns; tool
1920
2125
  * iteration is capped at `limit` (default `DEFAULT_AGENT_LIMIT`). Tools are advertised
1921
- * structurally via `context.tools.definitions()`. Two observation surfaces: the
2126
+ * structurally through `context.tools.definitions()`. Two observation surfaces: the
1922
2127
  * {@link AgentChunk} stream (pull — per-token content) and a typed `emitter` (push —
1923
2128
  * lifecycle + `usage` / `tool` / `deny` for fire-and-forget observers).
1924
2129
  *
@@ -1929,8 +2134,9 @@ export declare type ConversationSummarizer = (messages: readonly MessageInterfac
1929
2134
  *
1930
2135
  * @example
1931
2136
  * ```ts
1932
- * import type { ProviderInterface } from '@src/core'
1933
- * import { createAgent, createTokenBudget } from '@src/core'
2137
+ * import type { ProviderInterface } from '@orkestrel/agent'
2138
+ * import { createAgent } from '@orkestrel/agent'
2139
+ * import { createTokenBudget } from '@orkestrel/budget'
1934
2140
  *
1935
2141
  * declare const provider: ProviderInterface // any concrete implementation supplied by the host app
1936
2142
  * const agent = createAgent(provider, {
@@ -1941,7 +2147,7 @@ export declare type ConversationSummarizer = (messages: readonly MessageInterfac
1941
2147
  *
1942
2148
  * const stream = agent.stream()
1943
2149
  * for await (const chunk of stream.events) {
1944
- * if (chunk.type === 'token') process.stdout.write(chunk.content)
2150
+ * if (chunk.category === 'token') process.stdout.write(chunk.content)
1945
2151
  * }
1946
2152
  * const result = await stream.result // { content, usage?, partial }
1947
2153
  * ```
@@ -1949,7 +2155,7 @@ export declare type ConversationSummarizer = (messages: readonly MessageInterfac
1949
2155
  export declare function createAgent(provider: ProviderInterface, options?: AgentOptions): AgentInterface;
1950
2156
 
1951
2157
  /**
1952
- * Create a richer turn context — an {@link AgentContextInterface} assembling a provider
2158
+ * Creates a richer turn context — an {@link AgentContextInterface} assembling a provider
1953
2159
  * request from the optional system prompt, the instruction registry, the workspace registry,
1954
2160
  * the conversation store, the tool registry, and the active scope.
1955
2161
  *
@@ -1957,11 +2163,11 @@ export declare function createAgent(provider: ProviderInterface, options?: Agent
1957
2163
  * `system` is the optional system prompt; `tools` / `instructions` / `workspaces` are pre-built
1958
2164
  * managers to reuse (empty ones are created when omitted, so `context.workspaces` is ALWAYS
1959
2165
  * present); `scope` is the initial active filter (`undefined` ⇒ no filtering, changeable afterwards
1960
- * via `context.apply(...)`). The `messages` store is always fresh. `build()` folds the scoped
2166
+ * through `context.apply(...)`). The `messages` store is always fresh. `build()` folds the scoped
1961
2167
  * instructions — PLUS the ACTIVE workspace's scope-filtered text files (fenced) — into ONE leading
1962
2168
  * `system` message and appends the scoped conversation (attaching the active workspace's
1963
- * scope-filtered image files' `data` to the last user message), built fresh each call; the active
1964
- * workspace is the SOLE document/image context. Tools are advertised STRUCTURALLY (via
2169
+ * scope-filtered image files' `base64` payload to the last user message), built fresh each call; the active
2170
+ * workspace is the SOLE document/image context. Tools are advertised STRUCTURALLY (through
1965
2171
  * `tools.definitions()`, scope-filtered by the loop), never serialized into the prompt.
1966
2172
  *
1967
2173
  * @param options - Optional `system` / `tools` / `instructions` / `workspaces` / `scope`
@@ -1970,7 +2176,7 @@ export declare function createAgent(provider: ProviderInterface, options?: Agent
1970
2176
  *
1971
2177
  * @example
1972
2178
  * ```ts
1973
- * import { createAgentContext } from '@src/core'
2179
+ * import { createAgentContext } from '@orkestrel/agent'
1974
2180
  *
1975
2181
  * const context = createAgentContext({ system: 'You are concise.' })
1976
2182
  * context.instructions.add({ name: 'tone', content: 'Be terse.' })
@@ -1981,7 +2187,7 @@ export declare function createAgent(provider: ProviderInterface, options?: Agent
1981
2187
  export declare function createAgentContext(options?: AgentContextOptions): AgentContextInterface;
1982
2188
 
1983
2189
  /**
1984
- * Create a durable, bounded-concurrency agent-job queue — a {@link QueueInterface} over
2190
+ * Creates a durable, bounded-concurrency agent-job queue — a {@link QueueInterface} over
1985
2191
  * serializable {@link AgentJobInput}s that COMPOSES `createQueue`: each job is rehydrated
1986
2192
  * through the `registry` into a live {@link AgentInterface}, run to its {@link AgentResult},
1987
2193
  * and subjected to the partial-as-configurable-failure policy.
@@ -1989,30 +2195,31 @@ export declare function createAgentContext(options?: AgentContextOptions): Agent
1989
2195
  * @remarks
1990
2196
  * - **Composes the substrate (no new engine).** The handler is the only new logic;
1991
2197
  * bounded `concurrency`, `retries`, the per-attempt `timeout`, and durable persistence
1992
- * via `store` (+ `restore()` after a crash) are all the backing Queue's. `enqueue`
2198
+ * through `store` (+ `restore()` after a crash) are all the backing Queue's. `enqueue`
1993
2199
  * returns a per-job promise.
1994
2200
  * - **Durable + serializable.** Because `AgentJobInput` is JSON-serializable, a `store`
1995
- * (e.g. `createMemoryQueueStore` / `createDatabaseQueueStore`) persists outstanding
2201
+ * (for example `createMemoryQueueStore` / `createDatabaseQueueStore`) persists outstanding
1996
2202
  * jobs; `restore()` re-enqueues them after a restart and the `registry` rehydrates the
1997
2203
  * live pieces from the names — so a job survives a crash.
1998
2204
  * - **Partial policy.** A partial result THROWS an
1999
2205
  * {@link import('./errors.js').AgentJobError} by default, so a job cancelled by its
2000
- * attempt deadline / a queue abort RETRIES while attempts remain; `allowPartial: true`
2206
+ * attempt deadline / a queue abort RETRIES while attempts remain; `partial: true`
2001
2207
  * resolves the partial as success instead.
2002
- * - **Cancellation threads through.** The handler passes `execution.signal` into
2208
+ * - **Cancellation threads through.** The handler passes `context.signal` into
2003
2209
  * `registry.build`, so a queue `abort()` or a per-attempt timeout cancels the in-flight
2004
2210
  * agent (which commits a partial → throws → retries / fails per policy).
2005
2211
  *
2006
- * @param options - The `registry`, the `allowPartial` policy, and the substrate knobs
2212
+ * @param options - The `registry`, the `partial` policy, and the substrate knobs
2007
2213
  * (`concurrency` / `retries` / `timeout` / `store`) (see {@link AgentQueueOptions})
2008
2214
  * @returns A {@link QueueInterface} of {@link AgentJobInput} → {@link AgentResult}
2009
2215
  *
2010
2216
  * @example
2011
2217
  * ```ts
2012
- * import { createAgentQueue, createAgentRegistry, createMemoryQueueStore } from '@src/core'
2218
+ * import { createAgentQueue, createAgentRegistry } from '@orkestrel/agent'
2219
+ * import { createMemoryQueueStore } from '@orkestrel/queue'
2013
2220
  *
2014
2221
  * const registry = createAgentRegistry({ providers: { main: provider } })
2015
- * const store = createMemoryQueueStore(agentJobShape) // survives a restart via restore()
2222
+ * const store = createMemoryQueueStore(agentJobShape) // survives a restart through restore()
2016
2223
  * const queue = createAgentQueue({ registry, concurrency: 2, retries: 1, store })
2017
2224
  * const result = await queue.enqueue({ provider: 'main', messages: [{ role: 'user', content: 'ok?' }] })
2018
2225
  * ```
@@ -2020,16 +2227,17 @@ export declare function createAgentContext(options?: AgentContextOptions): Agent
2020
2227
  export declare function createAgentQueue(options: AgentQueueOptions): QueueInterface<AgentJobInput, AgentResult>;
2021
2228
 
2022
2229
  /**
2023
- * Create an agent registry — an {@link AgentRegistryInterface} holding the named pools of
2230
+ * Creates an agent registry — an {@link AgentRegistryInterface} holding the named pools of
2024
2231
  * live, non-serializable pieces (providers, tools, authorities, schedulers) that a
2025
2232
  * serializable {@link AgentJobInput}'s names resolve against, and `build`ing a seeded,
2026
2233
  * signal-wired {@link AgentInterface} from a job.
2027
2234
  *
2028
2235
  * @remarks
2029
2236
  * `providers` is required; `tools` / `authorities` / `schedulers` are optional pools.
2030
- * The accessors (`provider` / `tool` / `authority` / `scheduler`) THROW `unknown <category>:
2031
- * <name>` on an unregistered name (§9.1 + §12) — a misconfigured or crash-restored job
2032
- * fails loudly rather than running with a missing dependency. `build(input, signal)`
2237
+ * The accessors (`provider` / `tool` / `authority` / `scheduler`) THROW an
2238
+ * {@link import('./errors.js').AgentError} carrying `code: 'REGISTRY'` and the message
2239
+ * `unknown <category>: <name>` on an unregistered name — a misconfigured or crash-restored
2240
+ * job fails loudly rather than running with a missing dependency. `build(input, signal)`
2033
2241
  * resolves the names, rebuilds the token budget from its ceiling, seeds the agent's
2034
2242
  * context with the job's messages, and threads `signal` so a queue / runner abort
2035
2243
  * propagates. This is the bridge that makes durable, serializable agent jobs runnable.
@@ -2039,8 +2247,8 @@ export declare function createAgentQueue(options: AgentQueueOptions): QueueInter
2039
2247
  *
2040
2248
  * @example
2041
2249
  * ```ts
2042
- * import { createAgentRegistry } from '@src/core'
2043
- * import type { ProviderInterface } from '@src/core'
2250
+ * import { createAgentRegistry } from '@orkestrel/agent'
2251
+ * import type { ProviderInterface } from '@orkestrel/agent'
2044
2252
  * import { createTool } from '@orkestrel/tool'
2045
2253
  *
2046
2254
  * declare const provider: ProviderInterface // any concrete implementation supplied by the host app
@@ -2054,7 +2262,7 @@ export declare function createAgentQueue(options: AgentQueueOptions): QueueInter
2054
2262
  export declare function createAgentRegistry(options: AgentRegistryOptions): AgentRegistryInterface;
2055
2263
 
2056
2264
  /**
2057
- * Create an agent-job runner — a {@link RunnerInterface} over serializable
2265
+ * Creates an agent-job runner — a {@link RunnerInterface} over serializable
2058
2266
  * {@link AgentJobInput}s that COMPOSES `createRunner` (one-shot, ordered, fail-fast), each
2059
2267
  * unit rehydrated through the `registry` and subjected to the partial policy. The runner
2060
2268
  * enables **sub-agent fan-out**: a parent job's handler can `controller.spawn(childJob)`.
@@ -2069,17 +2277,17 @@ export declare function createAgentRegistry(options: AgentRegistryOptions): Agen
2069
2277
  * runner, FAN OUT and return — do NOT inline-`await` a spawn from within the handler (a
2070
2278
  * slot-holding handler awaiting its own spawn can deadlock; see `ControllerInterface`).
2071
2279
  * - **Partial policy + cancellation.** Same as `createAgentQueue`: a partial result
2072
- * THROWS by default (the run's fail-fast engages), `allowPartial: true` resolves it; the
2280
+ * THROWS by default (the run's fail-fast engages), `partial: true` resolves it; the
2073
2281
  * handler threads `controller.signal` into `registry.build`, so a runner abort / a
2074
2282
  * per-attempt timeout cancels the agent.
2075
2283
  *
2076
- * @param options - The `registry`, the `allowPartial` policy, and the substrate knobs
2284
+ * @param options - The `registry`, the `partial` policy, and the substrate knobs
2077
2285
  * (`concurrency` / `retries` / `timeout`) (see {@link AgentRunnerOptions})
2078
2286
  * @returns A {@link RunnerInterface} of {@link AgentJobInput} → {@link AgentResult}
2079
2287
  *
2080
2288
  * @example
2081
2289
  * ```ts
2082
- * import { createAgentRunner, createAgentRegistry } from '@src/core'
2290
+ * import { createAgentRunner, createAgentRegistry } from '@orkestrel/agent'
2083
2291
  *
2084
2292
  * const registry = createAgentRegistry({ providers: { main: provider } })
2085
2293
  * const runner = createAgentRunner({ registry, concurrency: 2 })
@@ -2092,7 +2300,7 @@ export declare function createAgentRegistry(options: AgentRegistryOptions): Agen
2092
2300
  export declare function createAgentRunner(options: AgentRunnerOptions): RunnerInterface<AgentJobInput, AgentResult>;
2093
2301
 
2094
2302
  /**
2095
- * Create a policy gate — an {@link AuthorityInterface} the agent loop consults before
2303
+ * Creates a policy gate — an {@link AuthorityInterface} the agent loop consults before
2096
2304
  * each tool call runs, evaluating the ordered rules first-match-wins and falling back
2097
2305
  * to the configured default when none match.
2098
2306
  *
@@ -2102,16 +2310,16 @@ export declare function createAgentRunner(options: AgentRunnerOptions): RunnerIn
2102
2310
  * `fallback` decides; it defaults to `{ zone: DEFAULT_AUTHORITY_ZONE, allowed: true }`
2103
2311
  * (allow-unmatched — a rules list of denials acts as a DENYLIST). Pass an
2104
2312
  * `allowed: false` `fallback` to flip the gate to deny-by-default (an ALLOWLIST). Wire
2105
- * the result into `createAgent` via `AgentOptions.authority`: a denied call is fed back
2313
+ * the result into `createAgent` through `AgentOptions.authority`: a denied call is fed back
2106
2314
  * to the model as a denial `ToolResult` (not executed, no budget cost), so the model
2107
- * can react. Synchronous now — the async human-approval handshake is deferred.
2315
+ * can react. Synchronous — `evaluate` returns the verdict directly.
2108
2316
  *
2109
2317
  * @param options - Optional `rules` (ordered) and `fallback` (see {@link AuthorityOptions})
2110
2318
  * @returns A working {@link AuthorityInterface}
2111
2319
  *
2112
2320
  * @example
2113
2321
  * ```ts
2114
- * import { createAgent, createAuthority } from '@src/core'
2322
+ * import { createAgent, createAuthority } from '@orkestrel/agent'
2115
2323
  *
2116
2324
  * // Deny the `delete` tool, allow everything else.
2117
2325
  * const authority = createAuthority({
@@ -2123,28 +2331,56 @@ export declare function createAgentRunner(options: AgentRunnerOptions): RunnerIn
2123
2331
  export declare function createAuthority(options?: AuthorityOptions): AuthorityInterface;
2124
2332
 
2125
2333
  /**
2126
- * Create a conversation — a {@link ConversationInterface} grouping messages above a flat
2334
+ * Creates an empty unbounded async channel — a {@link ChannelInterface} a producer writes
2335
+ * values into (`push`) and ends (`close` / `fail`) regardless of consumption, while a
2336
+ * consumer reads them back live through `drain`.
2337
+ *
2338
+ * @remarks
2339
+ * Write and read are decoupled, so the producer never waits for a consumer: an agent's eager
2340
+ * pump writes each chunk into one, which is why a run's `result` settles whether or not the
2341
+ * live events are drained. A value pushed at an already-parked consumer is delivered, buffered
2342
+ * values are yielded before the end is reported, and the FIRST failure wins.
2343
+ *
2344
+ * @typeParam T - The value type the channel carries
2345
+ * @returns A fresh, empty {@link ChannelInterface}
2346
+ *
2347
+ * @example
2348
+ * ```ts
2349
+ * import { createChannel } from '@orkestrel/agent'
2350
+ *
2351
+ * const channel = createChannel<number>()
2352
+ * channel.push(1)
2353
+ * channel.close()
2354
+ * for await (const value of channel.drain()) {
2355
+ * value // 1
2356
+ * }
2357
+ * ```
2358
+ */
2359
+ export declare function createChannel<T>(): ChannelInterface<T>;
2360
+
2361
+ /**
2362
+ * Creates a conversation — a {@link ConversationInterface} grouping messages above a flat
2127
2363
  * message store it OWNS DIRECTLY, with compaction into summarized sections, a regenerated
2128
2364
  * rollup `summary`, on-demand `rehydrate`, and substring `search`, driven by a
2129
- * provider-agnostic {@link ConversationSummarizer} seam.
2365
+ * provider-agnostic {@link ConversationSummaryHandler} seam.
2130
2366
  *
2131
2367
  * @remarks
2132
2368
  * Append turns through the conversation's own `add` (the live tail it owns); `view()` is the model input
2133
2369
  * (each section as a summary message, then the live tail). `compact()` folds the older live
2134
- * messages into a summarized {@link SectionInterface} and regenerates the rollup — it REQUIRES
2370
+ * messages into a summarized {@link Section} and regenerates the rollup — it REQUIRES
2135
2371
  * a `summarize` (omitted ⇒ `compact()` throws a `ConversationError`); `keep` retains a recent
2136
2372
  * tail (default `DEFAULT_CONVERSATION_KEEP` — fold ALL). `rehydrate(id)` / `search(query)` read
2137
2373
  * the retained originals. Observable (`emitter` — `compact` / `summary` / `rehydrate`), wired
2138
- * via the reserved `on` option (§8); the emitter isolates a listener throw and routes it to
2139
- * its `error` handler (the `error` option, §13), so it can never corrupt a compaction.
2374
+ * through the reserved `on` option; the emitter isolates a listener throw and routes it to
2375
+ * its `error` handler (the `error` option), so it can never corrupt a compaction.
2140
2376
  *
2141
2377
  * @param options - Optional `id` / `on` hooks + the `summarize` seam + `keep` (see {@link ConversationOptions})
2142
2378
  * @returns A working {@link ConversationInterface}
2143
2379
  *
2144
2380
  * @example
2145
2381
  * ```ts
2146
- * import type { ProviderInterface } from '@src/core'
2147
- * import { createConversation } from '@src/core'
2382
+ * import type { ProviderInterface } from '@orkestrel/agent'
2383
+ * import { createConversation } from '@orkestrel/agent'
2148
2384
  *
2149
2385
  * declare const provider: ProviderInterface // any concrete implementation supplied by the host app
2150
2386
  * const conversation = createConversation({
@@ -2160,9 +2396,10 @@ export declare function createAuthority(options?: AuthorityOptions): AuthorityIn
2160
2396
  export declare function createConversation(options?: ConversationOptions): ConversationInterface;
2161
2397
 
2162
2398
  /**
2163
- * Create a conversation registry — a {@link ConversationManagerInterface} holding
2399
+ * Creates a conversation registry — a {@link ConversationManagerInterface} holding
2164
2400
  * {@link ConversationInterface}s keyed by their `id` (in insertion order) WITH an active pointer:
2165
- * the §9 store over the conversation layer plus the `active` / `switch` seam the context renders.
2401
+ * the id-keyed store over the conversation layer plus the `active` / `switch` seam the context
2402
+ * renders.
2166
2403
  *
2167
2404
  * @remarks
2168
2405
  * Starts empty; `add(input?)` mints a {@link ConversationInterface} (its `id` from the input
@@ -2171,8 +2408,9 @@ export declare function createConversation(options?: ConversationOptions): Conve
2171
2408
  * AUTO-ACTIVATES the FIRST one (a registry with conversations always has one `active`); a later
2172
2409
  * `add` leaves `active` unchanged. `switch(id)` re-points `active` (an unknown `id` returns
2173
2410
  * `undefined`, leaving `active` unchanged — lenient, never throws); `conversation(id)` /
2174
- * `conversations()` look up; `remove` (one or a batch, §9.2) reports whether any was removed AND
2175
- * clears `active` if it was the removed one; `clear` empties it and clears `active`. Event-free
2411
+ * `conversations()` look up; `remove` (one or a batch) reports `true` only when every supplied id
2412
+ * was removed AND clears `active` if it was a removed one; `clear` empties it and clears `active`.
2413
+ * Event-free
2176
2414
  * (each conversation owns its own observable `emitter`). A conversation created with NEITHER a
2177
2415
  * manager default nor a per-`add` `summarize` cannot `compact` (it throws a `ConversationError`).
2178
2416
  *
@@ -2181,7 +2419,7 @@ export declare function createConversation(options?: ConversationOptions): Conve
2181
2419
  *
2182
2420
  * @example
2183
2421
  * ```ts
2184
- * import { createConversationManager } from '@src/core'
2422
+ * import { createConversationManager } from '@orkestrel/agent'
2185
2423
  *
2186
2424
  * const conversations = createConversationManager({ summarize: async (m) => `recap of ${m.length}` })
2187
2425
  * const chat = conversations.add() // auto-activates — conversations.active === chat
@@ -2191,7 +2429,7 @@ export declare function createConversation(options?: ConversationOptions): Conve
2191
2429
  export declare function createConversationManager(options?: ConversationManagerOptions): ConversationManagerInterface;
2192
2430
 
2193
2431
  /**
2194
- * Create a {@link DatabaseConversationStore} over any {@link DriverInterface} — the durable,
2432
+ * Creates a {@link DatabaseConversationStore} over any {@link DriverInterface} — the durable,
2195
2433
  * driver-pluggable backing for the conversation persistence seam, the opt-in twin of
2196
2434
  * {@link createMemoryConversationStore}. The exact twin of
2197
2435
  * {@link import('@orkestrel/workspace').createDatabaseWorkspaceStore}.
@@ -2203,7 +2441,7 @@ export declare function createConversationManager(options?: ConversationManagerO
2203
2441
  * {@link import('@orkestrel/workspace').createDatabaseWorkspaceStore} stores its snapshot. The
2204
2442
  * snapshot is already a COMPLETE, self-contained, pure-JSON payload, so storing it whole is lossless
2205
2443
  * AND keeps the row type FLAT (the column reads back as `unknown`, narrowed on `get` by
2206
- * {@link import('./helpers.js').isConversationSnapshot}). The `driver` DEFAULTS to
2444
+ * {@link import('./validators.js').isConversationSnapshot}). The `driver` DEFAULTS to
2207
2445
  * {@link createMemoryDriver}, so the store ALSO works in memory out of the box; pass a server
2208
2446
  * `createJSONDriver` / `createSQLiteDriver` (or a browser IndexedDB driver) for a persistent one —
2209
2447
  * the durability is the driver's job, the store engine is shared. It swaps in behind
@@ -2214,7 +2452,8 @@ export declare function createConversationManager(options?: ConversationManagerO
2214
2452
  *
2215
2453
  * @example
2216
2454
  * ```ts
2217
- * import { createConversationManager, createDatabaseConversationStore, createMemoryDriver } from '@src/core'
2455
+ * import { createConversationManager, createDatabaseConversationStore } from '@orkestrel/agent'
2456
+ * import { createMemoryDriver } from '@orkestrel/database'
2218
2457
  *
2219
2458
  * const store = createDatabaseConversationStore(createMemoryDriver()) // a durable driver swaps in here
2220
2459
  * const manager = createConversationManager({ store })
@@ -2226,7 +2465,7 @@ export declare function createConversationManager(options?: ConversationManagerO
2226
2465
  export declare function createDatabaseConversationStore(driver?: DriverInterface): ConversationStoreInterface;
2227
2466
 
2228
2467
  /**
2229
- * Create an instruction — an immutable {@link InstructionInterface} (a named directive)
2468
+ * Creates an instruction — an immutable {@link InstructionInterface} (a named directive)
2230
2469
  * from its `name` / `content` and optional `priority`, the `id` minted at construction.
2231
2470
  *
2232
2471
  * @remarks
@@ -2240,7 +2479,7 @@ export declare function createDatabaseConversationStore(driver?: DriverInterface
2240
2479
  *
2241
2480
  * @example
2242
2481
  * ```ts
2243
- * import { createInstruction } from '@src/core'
2482
+ * import { createInstruction } from '@orkestrel/agent'
2244
2483
  *
2245
2484
  * const instruction = createInstruction({ name: 'tone', content: 'Be concise.', priority: 5 })
2246
2485
  * ```
@@ -2248,28 +2487,28 @@ export declare function createDatabaseConversationStore(driver?: DriverInterface
2248
2487
  export declare function createInstruction(input: InstructionInput): InstructionInterface;
2249
2488
 
2250
2489
  /**
2251
- * Create an instruction registry — an {@link InstructionManagerInterface} holding
2490
+ * Creates an instruction registry — an {@link InstructionManagerInterface} holding
2252
2491
  * immutable instructions keyed by `name`, listed by descending `priority`.
2253
2492
  *
2254
2493
  * @remarks
2255
- * Starts empty; `add` (one or a batch, §9.2) MINTS each `id` and OVERWRITES a same-name
2494
+ * Starts empty; `add` (one or a batch) MINTS each `id` and OVERWRITES a same-name
2256
2495
  * instruction (last write wins); `instructions()` lists them sorted by descending
2257
- * `priority` (stable for ties); `format` / `description` are the build contract a richer
2258
- * context renders an instructions block with; `remove` (one or a batch) reports whether
2259
- * any was removed; `clear` empties it. Carries an observable `emitter`
2260
- * ({@link import('./types.js').InstructionManagerEventMap}) wired via the reserved `on`
2261
- * option (§8); the emitter isolates a listener throw and routes it to its `error` handler
2262
- * (the `error` option, §13), so it can never corrupt a mutation. An optional `format`
2496
+ * `priority` (stable for ties); `open` / `render` are the build contract a richer
2497
+ * context renders an instructions block with; `remove` (one or a batch) reports `true` only
2498
+ * when every supplied name was removed; `clear` empties it. Carries an observable `emitter`
2499
+ * ({@link import('./types.js').InstructionManagerEventMap}) wired through the reserved `on`
2500
+ * option; the emitter isolates a listener throw and routes it to its `error` handler
2501
+ * (the `error` option), so it can never corrupt a mutation. An optional `format`
2263
2502
  * override is the manager-options level of the `AgentContext` build cascade (consulted by
2264
- * `description` / `format`, beating the provider default + built-in; a per-item
2265
- * `InstructionInput.format` still beats it).
2503
+ * `open` / `render`, beating the provider default + built-in; a per-item
2504
+ * `InstructionInput.override` still beats it).
2266
2505
  *
2267
2506
  * @param options - Optional `on` hooks + a `format` override (see {@link InstructionManagerOptions})
2268
2507
  * @returns An empty {@link InstructionManagerInterface}
2269
2508
  *
2270
2509
  * @example
2271
2510
  * ```ts
2272
- * import { createInstructionManager } from '@src/core'
2511
+ * import { createInstructionManager } from '@orkestrel/agent'
2273
2512
  *
2274
2513
  * const instructions = createInstructionManager()
2275
2514
  * instructions.add({ name: 'tone', content: 'Be concise.', priority: 5 })
@@ -2278,7 +2517,7 @@ export declare function createInstruction(input: InstructionInput): InstructionI
2278
2517
  export declare function createInstructionManager(options?: InstructionManagerOptions): InstructionManagerInterface;
2279
2518
 
2280
2519
  /**
2281
- * Create the in-memory conversation store — a {@link ConversationStoreInterface} backed by a
2520
+ * Creates the in-memory conversation store — a {@link ConversationStoreInterface} backed by a
2282
2521
  * process-lifetime `Map` of {@link import('./types.js').ConversationSnapshot}s keyed by conversation
2283
2522
  * id, the DEFAULT backing for the durable {@link ConversationManagerInterface.open} /
2284
2523
  * {@link ConversationManagerInterface.save} seam. The exact twin of
@@ -2293,14 +2532,14 @@ export declare function createInstructionManager(options?: InstructionManagerOpt
2293
2532
  * {@link createDatabaseConversationStore} (the snapshot as one opaque JSON column over a `databases`
2294
2533
  * table) — for a DURABLE store pass it a JSON / SQLite / IndexedDB driver, and it swaps in WITHOUT
2295
2534
  * touching the manager or the conversation. Hydration stays a manager concern: read a snapshot back
2296
- * and rebuild the live conversation through the constructor `seed` (re-supplying the live
2535
+ * and rebuild the live conversation through the `snapshot` option (re-supplying the live
2297
2536
  * `summarize` / `keep`).
2298
2537
  *
2299
2538
  * @returns A memory-backed {@link ConversationStoreInterface}
2300
2539
  *
2301
2540
  * @example
2302
2541
  * ```ts
2303
- * import { createConversationManager, createMemoryConversationStore } from '@src/core'
2542
+ * import { createConversationManager, createMemoryConversationStore } from '@orkestrel/agent'
2304
2543
  *
2305
2544
  * const store = createMemoryConversationStore()
2306
2545
  * const manager = createConversationManager({ store })
@@ -2312,8 +2551,8 @@ export declare function createInstructionManager(options?: InstructionManagerOpt
2312
2551
  export declare function createMemoryConversationStore(): ConversationStoreInterface;
2313
2552
 
2314
2553
  /**
2315
- * Create a named scope — an immutable {@link ScopeInterface} from its `name` and the four
2316
- * optional per-category allow-lists, the `id` minted at construction.
2554
+ * Creates a named scope — an immutable {@link ScopeInterface} from its `name` and its
2555
+ * per-category allow-lists, the `id` minted at construction.
2317
2556
  *
2318
2557
  * @remarks
2319
2558
  * Each list is THREE-WAY: `undefined` ⇒ NO constraint on that category (all pass), `[]` ⇒
@@ -2321,13 +2560,13 @@ export declare function createMemoryConversationStore(): ConversationStoreInterf
2321
2560
  * tighter child by set-INTERSECTION (an `undefined` side imposing no constraint). Stored
2322
2561
  * immutable — never mutated after creation (`narrow` returns a new scope).
2323
2562
  *
2324
- * @param input - `name` (required) and the optional `instructions` / `tools` / `messages` /
2325
- * `files` allow-lists (see {@link ScopeInput})
2563
+ * @param input - `name` (required) and the optional `instructions` / `tools` / `files`
2564
+ * allow-lists (see {@link ScopeInput})
2326
2565
  * @returns A working {@link ScopeInterface}
2327
2566
  *
2328
2567
  * @example
2329
2568
  * ```ts
2330
- * import { createScope } from '@src/core'
2569
+ * import { createScope } from '@orkestrel/agent'
2331
2570
  *
2332
2571
  * const reader = createScope({ name: 'reader', tools: ['search', 'read'] })
2333
2572
  * reader.narrow({ tools: ['read', 'write'] }).tools // ['read'] — intersection tightens
@@ -2336,23 +2575,24 @@ export declare function createMemoryConversationStore(): ConversationStoreInterf
2336
2575
  export declare function createScope(input: ScopeInput): ScopeInterface;
2337
2576
 
2338
2577
  /**
2339
- * Create a scope registry — a {@link ScopeManagerInterface} holding immutable scopes keyed
2578
+ * Creates a scope registry — a {@link ScopeManagerInterface} holding immutable scopes keyed
2340
2579
  * by their minted `id`, in insertion order.
2341
2580
  *
2342
2581
  * @remarks
2343
2582
  * Starts empty; `create` mints each scope's `id` and stores it (keyed by `id`, so it
2344
2583
  * always adds — two scopes may share a `name`); `scopes()` lists them in insertion order;
2345
- * `remove` (one or a batch, §9.2) reports whether any was removed; `clear` empties it.
2346
- * Carries an observable `emitter` ({@link import('./types.js').ScopeManagerEventMap}) wired
2347
- * via the reserved `on` option (§8); the emitter isolates a listener throw and routes it to
2348
- * its `error` handler (the `error` option, §13), so it can never corrupt a mutation.
2584
+ * `remove` (one or a batch) reports `true` only when every supplied id was removed; `clear`
2585
+ * empties it. Carries an observable `emitter`
2586
+ * ({@link import('./types.js').ScopeManagerEventMap}) wired through the reserved `on`
2587
+ * option; the emitter isolates a listener throw and routes it to its `error` handler
2588
+ * (the `error` option), so it can never corrupt a mutation.
2349
2589
  *
2350
2590
  * @param options - Optional `on` hooks (see {@link ScopeManagerOptions})
2351
2591
  * @returns An empty {@link ScopeManagerInterface}
2352
2592
  *
2353
2593
  * @example
2354
2594
  * ```ts
2355
- * import { createScopeManager } from '@src/core'
2595
+ * import { createScopeManager } from '@orkestrel/agent'
2356
2596
  *
2357
2597
  * const scopes = createScopeManager()
2358
2598
  * const reader = scopes.create({ name: 'reader', tools: ['search'] })
@@ -2361,7 +2601,7 @@ export declare function createScope(input: ScopeInput): ScopeInterface;
2361
2601
  export declare function createScopeManager(options?: ScopeManagerOptions): ScopeManagerInterface;
2362
2602
 
2363
2603
  /**
2364
- * Create a stream-stateful `<think>` separator — a {@link ThinkSplitterInterface} that
2604
+ * Creates a stream-stateful `<think>` separator — a {@link ThinkSplitterInterface} that
2365
2605
  * splits a thinking model's in-content `<think>…</think>` reasoning spans away from
2366
2606
  * the answer, delta by delta, so a provider yields ONLY clean content and surfaces the
2367
2607
  * accumulated reasoning as {@link import('./types.js').ProviderResult.thinking}.
@@ -2372,14 +2612,14 @@ export declare function createScopeManager(options?: ScopeManagerOptions): Scope
2372
2612
  * partial open tag that never completed returns as final content; an UNCLOSED think
2373
2613
  * span lands on `thinking`). Tags split ACROSS deltas are held back until
2374
2614
  * disambiguated, multiple spans accumulate in order, and a nested-looking `<think>`
2375
- * inside an open span is just thinking text. One splitter serves ONE stream — create
2615
+ * inside an open span is thinking text. One splitter serves ONE stream — create
2376
2616
  * a fresh one per provider call.
2377
2617
  *
2378
2618
  * @returns A fresh {@link ThinkSplitterInterface} (state empty, outside any span)
2379
2619
  *
2380
2620
  * @example
2381
2621
  * ```ts
2382
- * import { createThinkSplitter } from '@src/core'
2622
+ * import { createThinkSplitter } from '@orkestrel/agent'
2383
2623
  *
2384
2624
  * const splitter = createThinkSplitter()
2385
2625
  * const clean = splitter.split('<think>plan the answer</think>Here it is.')
@@ -2390,7 +2630,7 @@ export declare function createScopeManager(options?: ScopeManagerOptions): Scope
2390
2630
  export declare function createThinkSplitter(): ThinkSplitterInterface;
2391
2631
 
2392
2632
  /**
2393
- * A {@link ConversationStoreInterface} backed by one table of the `databases` layer — a
2633
+ * Backs a {@link ConversationStoreInterface} with one table of the `databases` layer — a
2394
2634
  * conversation's durable state IS a row, so persistence reduces to keyed point-access (`get` / `set`
2395
2635
  * / `delete`) over a {@link TableInterface}, the driver-pluggable twin of the plain-`Map`
2396
2636
  * {@link import('./MemoryConversationStore.js').MemoryConversationStore}. The EXACT twin of
@@ -2416,19 +2656,20 @@ export declare function createThinkSplitter(): ThinkSplitterInterface;
2416
2656
  * - **`set(snapshot)` upserts under the snapshot's OWN `id`** (no separate id param) — it writes
2417
2657
  * the row `{ id: snapshot.id, snapshot }`.
2418
2658
  * - **`get(id)` resolves the stored snapshot for an id**, narrowing the opaque JSON column back to
2419
- * a {@link ConversationSnapshot} ({@link import('../../helpers.js').isConversationSnapshot} — the
2420
- * AGENTS §14 boundary narrow for an untrusted storage read), or `undefined` if none is stored.
2659
+ * a {@link ConversationSnapshot} ({@link import('../../validators.js').isConversationSnapshot} — the
2660
+ * total guard for an untrusted storage read), or `undefined` if none is stored.
2421
2661
  * - **`delete(id)` drops a snapshot by id**; an absent id is a no-op (no throw).
2422
2662
  *
2423
2663
  * UNLIKE a session store there is NO idle-TTL / eviction — a persisted conversation lives until an
2424
2664
  * explicit `delete`. The public surface is EXACTLY `get` / `set` / `delete` — no extra members (the
2425
- * §22 method bijection with {@link ConversationStoreInterface}). Hydration stays a caller concern: a
2665
+ * method bijection with {@link ConversationStoreInterface}). Hydration stays a caller concern: a
2426
2666
  * {@link import('../ConversationManager.js').ConversationManager} reads a snapshot back and rebuilds
2427
- * the live conversation through the constructor `seed` (its `open` / `save`).
2667
+ * the live conversation through the `snapshot` option (its `open` / `save`).
2428
2668
  *
2429
2669
  * @example
2430
2670
  * ```ts
2431
- * import { createConversation, createDatabaseConversationStore, createMemoryDriver } from '@src/core'
2671
+ * import { createConversation, createDatabaseConversationStore } from '@orkestrel/agent'
2672
+ * import { createMemoryDriver } from '@orkestrel/database'
2432
2673
  *
2433
2674
  * const store = createDatabaseConversationStore(createMemoryDriver()) // a durable driver swaps in here
2434
2675
  * const conversation = createConversation()
@@ -2441,30 +2682,30 @@ export declare function createThinkSplitter(): ThinkSplitterInterface;
2441
2682
  export declare class DatabaseConversationStore implements ConversationStoreInterface {
2442
2683
  #private;
2443
2684
  /**
2444
- * Wrap a table as a conversation store.
2685
+ * Wraps a table as a conversation store.
2445
2686
  *
2446
2687
  * @param table - The {@link TableInterface} holding the snapshots — its row is the
2447
2688
  * {@link ConversationSnapshotRow} `{ id; snapshot }` shape (the snapshot one opaque JSON column)
2448
2689
  */
2449
2690
  constructor(table: TableInterface<ConversationSnapshotRow>);
2450
- /** Resolve the persisted snapshot for `id`, narrowing the opaque JSON column back to a `ConversationSnapshot`. */
2691
+ /** Resolves the persisted snapshot for `id`, narrowing the opaque JSON column back to a `ConversationSnapshot`. */
2451
2692
  get(id: string): Promise<ConversationSnapshot | undefined>;
2452
- /** Insert or replace under the snapshot's OWN `id` (no separate id param) — the row is `{ id, snapshot }`. */
2693
+ /** Inserts or replaces under the snapshot's OWN `id` (no separate id param) — the row is `{ id, snapshot }`. */
2453
2694
  set(snapshot: ConversationSnapshot): Promise<void>;
2454
- /** Drop a snapshot by id; an absent id is a no-op (no throw). */
2695
+ /** Drops a snapshot by id; an absent id is a no-op (no throw). */
2455
2696
  delete(id: string): Promise<void>;
2456
2697
  }
2457
2698
 
2458
2699
  /**
2459
- * The default cap on an {@link AgentInterface} turn's tool iterations — the maximum
2700
+ * Caps an {@link AgentInterface} turn's tool iterations by default — the maximum
2460
2701
  * number of context → provider → tools cycles before the loop stops, so a model that
2461
- * keeps requesting tools can never loop forever. Overridable per agent via
2702
+ * keeps requesting tools can never loop forever. Overridable per agent through
2462
2703
  * `AgentOptions.limit`.
2463
2704
  */
2464
2705
  export declare const DEFAULT_AGENT_LIMIT = 10;
2465
2706
 
2466
2707
  /**
2467
- * The zone an {@link AuthorityInterface}'s default fallback {@link AuthorityDecision}
2708
+ * Names the zone an {@link AuthorityInterface}'s default fallback {@link AuthorityDecision}
2468
2709
  * carries — the classification for a tool call that matched no rule. Paired with the
2469
2710
  * default `allowed: true` fallback, an unmatched call is allowed under this zone, so a
2470
2711
  * rules list of denials acts as a denylist; a caller wanting deny-by-default supplies
@@ -2473,17 +2714,38 @@ export declare const DEFAULT_AGENT_LIMIT = 10;
2473
2714
  export declare const DEFAULT_AUTHORITY_ZONE = "default";
2474
2715
 
2475
2716
  /**
2476
- * The default number of recent live messages a {@link ConversationInterface}'s `compact()`
2717
+ * Sets the default number of recent live messages a {@link ConversationInterface}'s `compact()`
2477
2718
  * RETAINS verbatim — `0`, so a manual `compact()` folds ALL of the current live messages
2478
2719
  * into one summarized section (no tail kept). A caller retains a recent tail by passing
2479
2720
  * `keep` (on {@link ConversationOptions}, {@link ConversationManagerOptions}, or per-fold
2480
- * via {@link CompactOptions}), folding only the older `count - keep` messages and leaving
2721
+ * through {@link CompactOptions}), folding only the older `count - keep` messages and leaving
2481
2722
  * the most recent `keep` live for the next turn. Overridable everywhere `keep` is accepted.
2482
2723
  */
2483
2724
  export declare const DEFAULT_CONVERSATION_KEEP = 0;
2484
2725
 
2485
2726
  /**
2486
- * Estimate the context-token footprint of a batch of messages — the default `consume`
2727
+ * Synthesizes the denial {@link ToolResult} an authority-blocked call is fed back with — the
2728
+ * call's `id` / `name` keyed back, carrying a denial `error` instead of a value.
2729
+ *
2730
+ * @remarks
2731
+ * Pure and total. The rule's `reason` is rendered as `denied: <reason>` when one was given,
2732
+ * else the generic `denied by authority`. There is no `value`, so the agent loop feeds it back
2733
+ * exactly like a tool error and the model can react to it.
2734
+ *
2735
+ * @param call - The denied {@link ToolCall}
2736
+ * @param reason - The rule's explanation, or `undefined` for the generic denial
2737
+ * @returns The failure-arm {@link ToolResult}
2738
+ *
2739
+ * @example
2740
+ * ```ts
2741
+ * denyCall({ id: '1', name: 'drop', arguments: {} }, 'read-only mode')
2742
+ * // { success: false, id: '1', name: 'drop', error: 'denied: read-only mode' }
2743
+ * ```
2744
+ */
2745
+ export declare function denyCall(call: ToolCall, reason: string | undefined): ToolResult;
2746
+
2747
+ /**
2748
+ * Estimates the context-token footprint of a batch of messages — the default `consumer`
2487
2749
  * estimator for an agent's context `BudgetInterface` (a budgets surface's tracking contract)
2488
2750
  * (the {@link import('./types.js').AgentOptions} `window`).
2489
2751
  *
@@ -2495,7 +2757,7 @@ export declare const DEFAULT_CONVERSATION_KEEP = 0;
2495
2757
  * deliberately-approximate per-image cost — a base64 length is NOT a token proxy). Deterministic
2496
2758
  * and provider-free — the same messages always yield the same estimate, with an empty batch `0`.
2497
2759
  * It is the fully-swappable default an agent's auto-compaction context budget charges each
2498
- * turn's new messages through; a caller wanting a sharper count supplies its own `consume` to
2760
+ * turn's new messages through; a caller wanting a sharper count supplies its own `consumer` to
2499
2761
  * `createBudget` instead. Total — never throws: a `calls` `JSON.stringify` that throws (a
2500
2762
  * circular `ToolCall.arguments`) is caught and replaced with a conservative fixed contribution of
2501
2763
  * {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD} (the same per-message overhead scale)
@@ -2510,10 +2772,10 @@ export declare const DEFAULT_CONVERSATION_KEEP = 0;
2510
2772
  * estimateMessages([{ id: '1', role: 'user', content: 'hello' }]) // 6 (2 content + 4 overhead)
2511
2773
  * ```
2512
2774
  */
2513
- export declare function estimateMessages(messages: readonly MessageInterface[]): number;
2775
+ export declare function estimateMessages(messages: readonly Message[]): number;
2514
2776
 
2515
2777
  /**
2516
- * Estimate the context-token footprint of a string — the deterministic char-based heuristic
2778
+ * Estimates the context-token footprint of a string — the deterministic char-based heuristic
2517
2779
  * {@link estimateMessages} sums over a conversation's messages (the default context-budget
2518
2780
  * estimator).
2519
2781
  *
@@ -2537,34 +2799,7 @@ export declare function estimateMessages(messages: readonly MessageInterface[]):
2537
2799
  export declare function estimateTokens(text: string): number;
2538
2800
 
2539
2801
  /**
2540
- * Render a path-addressed text body as a fenced reference block — the framing an
2541
- * {@link import('./AgentContext.js').AgentContext}'s ACTIVE-workspace text-file render emits (the
2542
- * active workspace is the SOLE document/image context).
2543
- *
2544
- * @remarks
2545
- * Produces `` File: <path>\n```<language>\n<content>\n``` `` — the `File:` label line, then a
2546
- * fenced code block tagged with `language`, the `content` verbatim inside. Pure string assembly,
2547
- * total — never throws. The one fenced-file format string for the whole module — `AgentContext.build()`
2548
- * frames an active workspace's text files with it (each carries its own `language` on its
2549
- * {@link import('@orkestrel/workspace').FileContent} text arm).
2550
- *
2551
- * @param path - The file path shown on the `File:` label line
2552
- * @param language - The fenced-code language tag (e.g. `'typescript'`)
2553
- * @param content - The file body rendered verbatim inside the fence
2554
- * @returns The fenced reference block
2555
- *
2556
- * @example
2557
- * ```ts
2558
- * import { fencedFile } from '@src/core'
2559
- *
2560
- * fencedFile('src/main.ts', 'typescript', 'const x = 1')
2561
- * // 'File: src/main.ts\n```typescript\nconst x = 1\n```'
2562
- * ```
2563
- */
2564
- export declare function fencedFile(path: string, language: string, content: string): string;
2565
-
2566
- /**
2567
- * Filter a list of items by a {@link import('./types.js').ScopeInterface} allow-list of
2802
+ * Filters a list of items by a {@link import('./types.js').ScopeInterface} allow-list of
2568
2803
  * keys — the pure, total set-membership primitive the context's build step and the agent
2569
2804
  * loop's tool-advertise step apply a scope through.
2570
2805
  *
@@ -2581,7 +2816,7 @@ export declare function fencedFile(path: string, language: string, content: stri
2581
2816
  * @typeParam T - The item type being filtered
2582
2817
  * @param allow - The allow-list of keys (`undefined` ⇒ all, `[]` ⇒ none, else only-listed)
2583
2818
  * @param items - The items to filter (returned unchanged when `allow` is `undefined`)
2584
- * @param key - Extracts the key an item is matched on (e.g. an instruction's `name`)
2819
+ * @param key - Extracts the key an item is matched on (for example an instruction's `name`)
2585
2820
  * @returns The items that pass the allow-list, in their original order
2586
2821
  *
2587
2822
  * @example
@@ -2595,19 +2830,19 @@ export declare function fencedFile(path: string, language: string, content: stri
2595
2830
  export declare function filterAllowList<T>(allow: readonly string[] | undefined, items: readonly T[], key: (item: T) => string): readonly T[];
2596
2831
 
2597
2832
  /**
2598
- * Handle one queued agent job by rehydrating it through a registry with the queue
2833
+ * Handles one queued agent job by rehydrating it through a registry with the queue
2599
2834
  * attempt's signal, then applying the shared partial-result policy.
2600
2835
  *
2601
2836
  * @param registry - The registry that rehydrates the serializable job
2602
- * @param allowPartial - Whether a partial result resolves instead of throwing
2837
+ * @param partial - The partial policy. If `true`, a partial result resolves; if `false`, it throws
2603
2838
  * @param input - The serializable agent job
2604
- * @param execution - The queue attempt whose signal bounds the agent
2839
+ * @param context - The queue attempt whose signal bounds the agent
2605
2840
  * @returns The settled agent result
2606
2841
  */
2607
- export declare function handleAgentQueueJob(registry: AgentRegistryInterface, allowPartial: boolean, input: AgentJobInput, execution: QueueExecution): Promise<AgentResult>;
2842
+ export declare function handleAgentQueueJob(registry: AgentRegistryInterface, partial: boolean, input: AgentJobInput, context: QueueContext): Promise<AgentResult>;
2608
2843
 
2609
2844
  /**
2610
- * Handle one runner agent job by fanning out its declared children, rehydrating the
2845
+ * Handles one runner agent job by fanning out its declared children, rehydrating the
2611
2846
  * parent through a registry with the controller signal, and applying the shared
2612
2847
  * partial-result policy.
2613
2848
  *
@@ -2616,14 +2851,14 @@ export declare function handleAgentQueueJob(registry: AgentRegistryInterface, al
2616
2851
  * inline, preserving bounded-runner progress.
2617
2852
  *
2618
2853
  * @param registry - The registry that rehydrates serializable jobs
2619
- * @param allowPartial - Whether a partial result resolves instead of throwing
2854
+ * @param partial - The partial policy. If `true`, a partial result resolves; if `false`, it throws
2620
2855
  * @param controller - The runner controller for this parent job
2621
2856
  * @returns The settled parent agent result
2622
2857
  */
2623
- export declare function handleAgentRunnerJob(registry: AgentRegistryInterface, allowPartial: boolean, controller: ControllerInterface<AgentJobInput, AgentResult>): Promise<AgentResult>;
2858
+ export declare function handleAgentRunnerJob(registry: AgentRegistryInterface, partial: boolean, controller: ControllerInterface<AgentJobInput, AgentResult>): Promise<AgentResult>;
2624
2859
 
2625
2860
  /**
2626
- * The coarse, deliberately-approximate per-image token cost {@link import('./helpers.js').estimateMessages}
2861
+ * Names the coarse, deliberately-approximate per-image token cost {@link import('./helpers.js').estimateMessages}
2627
2862
  * charges for each attached image.
2628
2863
  *
2629
2864
  * @remarks
@@ -2635,15 +2870,15 @@ export declare function handleAgentRunnerJob(registry: AgentRegistryInterface, a
2635
2870
  export declare const IMAGE_TOKEN_ESTIMATE = 512;
2636
2871
 
2637
2872
  /**
2638
- * An immutable named directive — a {@link InstructionInterface} assembled once from its
2639
- * input (`name` / `content`, an optional `priority` defaulting to `0`), the `id` minted
2640
- * at construction.
2873
+ * Represents an immutable named directive — a {@link InstructionInterface} assembled once
2874
+ * from its input (`name` / `content`, an optional `priority` defaulting to `0`), the `id`
2875
+ * minted at construction.
2641
2876
  *
2642
2877
  * @remarks
2643
2878
  * A thin immutable value object (mirroring {@link import('@orkestrel/tool').Tool}): the
2644
2879
  * constructor mints a fresh `id` (`crypto.randomUUID()`), copies the input's `name` /
2645
2880
  * `content`, resolves `priority` to the input's value or `0`, and carries the input's
2646
- * per-item `format` override ONLY when supplied (assigned just when present, mirroring a
2881
+ * per-item `override` ONLY when supplied (assigned when present, mirroring a
2647
2882
  * message's `images` / `calls` present-when-given convention — kept absent otherwise).
2648
2883
  * Never mutated after construction. An
2649
2884
  * {@link import('./InstructionManager.js').InstructionManager} keys it by `name` and
@@ -2660,77 +2895,77 @@ export declare class Instruction implements InstructionInterface {
2660
2895
  readonly name: string;
2661
2896
  readonly content: string;
2662
2897
  readonly priority: number;
2663
- readonly format?: string;
2898
+ readonly override?: string;
2664
2899
  constructor(input: InstructionInput);
2665
2900
  }
2666
2901
 
2667
2902
  /**
2668
- * The minimal data to author an {@link InstructionInterface} — the `id` is minted by
2903
+ * Carries the minimal data to author an {@link InstructionInterface} — the `id` is minted by
2669
2904
  * the {@link InstructionManagerInterface} that stores it, so a caller supplies only
2670
2905
  * `name` / `content` (and an optional `priority`, defaulting to `0`).
2671
2906
  */
2672
2907
  export declare interface InstructionInput {
2673
2908
  readonly name: string;
2674
2909
  readonly content: string;
2675
- /** Ordering weight (higher renders first); defaults to `0` when omitted. */
2910
+ /** Weights the ordering (higher renders first); defaults to `0` when omitted. */
2676
2911
  readonly priority?: number;
2677
2912
  /**
2678
- * A fully-rendered override of THIS instruction's prompt text — the most-specific
2913
+ * Holds a fully-rendered override of THIS instruction's prompt text — the most-specific
2679
2914
  * level of the {@link import('./AgentContext.js').AgentContext} build cascade (beats a
2680
2915
  * manager-options / provider / built-in format for this item). Round-tripped onto the
2681
2916
  * stored {@link InstructionInterface} when given (present-when-supplied, like `images`).
2682
2917
  */
2683
- readonly format?: string;
2918
+ readonly override?: string;
2684
2919
  }
2685
2920
 
2686
2921
  /**
2687
- * An immutable instruction — a named directive a richer context places between the
2922
+ * Represents an immutable instruction — a named directive a richer context places between the
2688
2923
  * system prompt and the conversation, ordered by descending {@link priority}.
2689
2924
  *
2690
2925
  * @remarks
2691
2926
  * Assembled once from its {@link InstructionInput} (the `id` minted by the storing
2692
2927
  * layer) and never mutated. `name` keys it in an {@link InstructionManagerInterface}
2693
2928
  * (last write wins); `priority` orders the rendered list (higher first), defaulting to
2694
- * `0`. The {@link import('./AgentContext.js').AgentContext} build step renders it via
2695
- * its manager's `format` (`content`) under the manager's `description` header.
2929
+ * `0`. The {@link import('./AgentContext.js').AgentContext} build step renders it through
2930
+ * its manager's `render` (`content`) under the manager's `open` header.
2696
2931
  */
2697
2932
  export declare interface InstructionInterface {
2698
2933
  readonly id: string;
2699
2934
  readonly name: string;
2700
2935
  readonly content: string;
2701
- /** Higher renders first; defaults to `0`. */
2936
+ /** Ranks the instruction — higher renders first; defaults to `0`. */
2702
2937
  readonly priority: number;
2703
2938
  /**
2704
- * A fully-rendered per-item override of this instruction's prompt text — the
2939
+ * Holds a fully-rendered per-item override of this instruction's prompt text — the
2705
2940
  * MOST-SPECIFIC level of the {@link import('./AgentContext.js').AgentContext} build
2706
2941
  * cascade, beating every format level for THIS item. Present only when supplied on the
2707
2942
  * {@link InstructionInput} (round-tripped through the manager, like a message's
2708
2943
  * `images`); absent ⇒ the cascade decides.
2709
2944
  */
2710
- readonly format?: string;
2945
+ readonly override?: string;
2711
2946
  }
2712
2947
 
2713
2948
  /**
2714
- * The instruction registry a richer context assembles a directives block from —
2715
- * immutable {@link Instruction}s keyed by `name`, listed by descending `priority`.
2949
+ * Registers the immutable {@link Instruction}s a richer context assembles a directives
2950
+ * block from — keyed by `name`, listed by descending `priority`.
2716
2951
  *
2717
2952
  * @remarks
2718
2953
  * - **Registry.** Instructions live in an insertion-ordered `Map` keyed by `name`;
2719
- * `add` takes one {@link InstructionInput} or a batch (§9.2), MINTS each instruction's
2954
+ * `add` takes one {@link InstructionInput} or a batch, MINTS each instruction's
2720
2955
  * `id`, and a re-`add` of the same name OVERWRITES it (last write wins). `count` is the
2721
2956
  * map size, `instruction(name)` looks one up, and `instructions()` lists them SORTED by
2722
2957
  * descending `priority` (a stable sort, so equal priorities keep insertion order).
2723
- * - **Build contract (with the manager-options override).** `description` is the section
2724
- * header a context renders the instructions under; `format(instruction)` renders one
2958
+ * - **Build contract (with the manager-options override).** `open` is the section
2959
+ * header a context renders the instructions under; `render(instruction)` renders one
2725
2960
  * instruction (its `content`). Each ENCAPSULATES the cascade's `[options-override →
2726
2961
  * built-in]` half: when `InstructionManagerOptions.format` supplies an `open` /
2727
- * `render`, `description` / `format` return IT, else the built-in — so a richer context
2962
+ * `render`, `open` / `render` return IT, else the built-in — so a richer context
2728
2963
  * reads one consistent pair and layers the provider default + per-item override on top
2729
2964
  * (see {@link import('../AgentContext.js').AgentContext}). The per-item
2730
- * {@link InstructionInput.format} is round-tripped onto the stored instruction.
2731
- * - **Removal.** `remove` drops one by name, or a batch (§9.2) — `true` when any was
2732
- * removed; `clear` empties the registry.
2733
- * - **Observable (§13).** The owned {@link emitter} ({@link InstructionManagerEventMap})
2965
+ * {@link InstructionInput.override} is round-tripped onto the stored instruction.
2966
+ * - **Removal.** `remove` drops one by name, or a batch — `true` only when EVERY supplied
2967
+ * name was removed; `clear` empties the registry.
2968
+ * - **Observable.** The owned {@link emitter} ({@link InstructionManagerEventMap})
2734
2969
  * carries `add` (the created instruction) / `remove` (the name) / `clear` for
2735
2970
  * fire-and-forget observers. Every event is emitted directly, strictly AFTER the map
2736
2971
  * mutation completes; the emitter isolates a listener throw and routes it to its `error`
@@ -2751,105 +2986,129 @@ export declare class InstructionManager implements InstructionManagerInterface {
2751
2986
  constructor(options?: InstructionManagerOptions);
2752
2987
  get emitter(): EmitterInterface<InstructionManagerEventMap>;
2753
2988
  get count(): number;
2754
- get description(): string;
2755
- get framing(): ContextSectionFormat<InstructionInterface> | undefined;
2989
+ get open(): string;
2990
+ get format(): ContextSectionFormat<InstructionInterface> | undefined;
2756
2991
  add(input: InstructionInput): InstructionInterface;
2757
2992
  add(inputs: readonly InstructionInput[]): readonly InstructionInterface[];
2758
2993
  instruction(name: string): InstructionInterface | undefined;
2759
2994
  instructions(): readonly InstructionInterface[];
2760
- format(instruction: InstructionInterface): string;
2995
+ render(instruction: InstructionInterface): string;
2761
2996
  remove(name: string): boolean;
2762
2997
  remove(names: readonly string[]): boolean;
2763
2998
  clear(): void;
2764
2999
  }
2765
3000
 
2766
3001
  /**
2767
- * The push observation surface (§13) of an {@link InstructionManagerInterface} — the
2768
- * mutation moments a fire-and-forget observer subscribes to via `manager.emitter.on`.
3002
+ * Maps the push observation surface of an {@link InstructionManagerInterface} — the
3003
+ * mutation moments a fire-and-forget observer subscribes to through `manager.emitter.on`.
2769
3004
  *
2770
3005
  * @remarks
2771
3006
  * `add` carries the created (or replaced) {@link InstructionInterface}; `remove`
2772
3007
  * carries the removed instruction's `name`; `clear` is a pure signal (no payload).
2773
- * Listener isolation is the emitter's (AGENTS §13): a listener throw is routed to the
3008
+ * Listener isolation is the emitter's: a listener throw is routed to the
2774
3009
  * emitter's `error` handler (the `error` option), never onto this map, so a buggy
2775
3010
  * observer can never corrupt a mutation. Declared as a `type` alias (not `interface
2776
- * extends EventMap`, §4.5) so the type-literal satisfies `EventMap` structurally.
3011
+ * extends EventMap`) so the type-literal satisfies `EventMap` structurally.
2777
3012
  */
2778
3013
  export declare type InstructionManagerEventMap = {
2779
- /** An instruction was added (or a same-name one replaced) — the created instruction. */
3014
+ /** Reports an instruction added (or a same-name one replaced) — the created instruction. */
2780
3015
  readonly add: readonly [instruction: InstructionInterface];
2781
- /** An instruction was removed — its `name`. */
3016
+ /** Reports an instruction removed — its `name`. */
2782
3017
  readonly remove: readonly [name: string];
2783
- /** Every instruction was removed. */
3018
+ /** Reports every instruction removed. */
2784
3019
  readonly clear: readonly [];
2785
3020
  };
2786
3021
 
2787
3022
  /**
2788
- * A registry of {@link InstructionInterface}s keyed by `name` — `add` (one or a batch,
2789
- * §9.2) mints each `id` and OVERWRITES a same-name instruction (last write wins);
3023
+ * Registers {@link InstructionInterface}s keyed by `name` — `add` (one or a batch)
3024
+ * mints each `id` and OVERWRITES a same-name instruction (last write wins);
2790
3025
  * `instructions()` lists them SORTED by descending `priority` (stable for ties).
2791
3026
  *
2792
3027
  * @remarks
2793
- * - **Build contract.** `description` is the section header a richer context renders
2794
- * the instructions under; `format(instruction)` renders one instruction (its
3028
+ * - **Build contract.** `open` is the section header a richer context renders
3029
+ * the instructions under; `render(instruction)` renders one instruction (its
2795
3030
  * `content`). Together they let an {@link import('./AgentContext.js').AgentContext}
2796
3031
  * assemble an instructions block.
2797
- * - **Observable (§13).** The owned `emitter` ({@link InstructionManagerEventMap})
3032
+ * - **Observable.** The owned `emitter` ({@link InstructionManagerEventMap})
2798
3033
  * carries `add` / `remove` / `clear` for fire-and-forget observers; the emitter
2799
- * isolates a listener throw and routes it to its `error` handler (the `error` option, §13).
3034
+ * isolates a listener throw and routes it to its `error` handler (the `error` option).
2800
3035
  */
2801
3036
  export declare interface InstructionManagerInterface {
2802
3037
  readonly emitter: EmitterInterface<InstructionManagerEventMap>;
2803
3038
  readonly count: number;
2804
- /** The section header a context renders the instructions under. */
2805
- readonly description: string;
3039
+ /** Names the section header a context renders the instructions under. */
3040
+ readonly open: string;
2806
3041
  /**
2807
- * The manager-options format override (the {@link InstructionManagerOptions.format}
3042
+ * Holds the manager-options format override (the {@link InstructionManagerOptions.format}
2808
3043
  * supplied at construction), or `undefined` when none — the MANAGER-OPTIONS level of the
2809
3044
  * {@link import('./AgentContext.js').AgentContext} build cascade, exposed so `build()`
2810
- * can interleave the provider default BENEATH it (`description` / `format` already
3045
+ * can interleave the provider default BENEATH it (`open` / `render` already
2811
3046
  * encapsulate the `[override → built-in]` half for standalone use). A `readonly` data
2812
3047
  * member, not a method.
2813
3048
  */
2814
- readonly framing: ContextSectionFormat<InstructionInterface> | undefined;
3049
+ readonly format: ContextSectionFormat<InstructionInterface> | undefined;
2815
3050
  add(input: InstructionInput): InstructionInterface;
2816
3051
  add(inputs: readonly InstructionInput[]): readonly InstructionInterface[];
2817
3052
  instruction(name: string): InstructionInterface | undefined;
2818
- /** Every instruction, sorted by descending `priority` (stable for equal priorities). */
3053
+ /** Lists every instruction, sorted by descending `priority` (stable for equal priorities). */
2819
3054
  instructions(): readonly InstructionInterface[];
2820
- /** Render one instruction for the prompt — its `content`. */
2821
- format(instruction: InstructionInterface): string;
3055
+ /** Renders one instruction for the prompt — its `content`. */
3056
+ render(instruction: InstructionInterface): string;
2822
3057
  remove(name: string): boolean;
2823
3058
  remove(names: readonly string[]): boolean;
2824
3059
  clear(): void;
2825
3060
  }
2826
3061
 
2827
3062
  /**
2828
- * Options for `createInstructionManager` — the reserved `on` hooks (§8) plus an optional
3063
+ * Configures `createInstructionManager` — the reserved `on` hooks plus an optional
2829
3064
  * per-section format override.
2830
3065
  *
2831
3066
  * @remarks
2832
- * `on` is the §8 reserved key: initial listeners for the manager's
3067
+ * `on` is the reserved listener key: initial listeners for the manager's
2833
3068
  * {@link InstructionManagerEventMap}, wired at construction. `format` is the
2834
3069
  * MANAGER-OPTIONS level of the {@link import('./AgentContext.js').AgentContext} build
2835
3070
  * cascade — a {@link ContextSectionFormat} the manager consults FIRST in its own
2836
- * `description` / `format` (falling back to the built-in when a member is omitted), so it
3071
+ * `open` / `render` (falling back to the built-in when a member is omitted), so it
2837
3072
  * BEATS the provider default and the built-in, while a per-item
2838
- * {@link InstructionInput.format} still beats it. Omitted ⇒ the built-in framing applies.
3073
+ * {@link InstructionInput.override} still beats it. Omitted ⇒ the built-in framing applies.
2839
3074
  */
2840
3075
  export declare interface InstructionManagerOptions {
2841
3076
  readonly on?: EmitterHooks<InstructionManagerEventMap>;
2842
- /** The emitter's listener-error handler (AGENTS §13) — a listener throw routes here, not to a domain event. */
3077
+ /** Holds the emitter's listener-error handler — a listener throw routes here, not to a domain event. */
2843
3078
  readonly error?: EmitterErrorHandler;
2844
- /** A manager-level format override (beats the provider default + built-in); see {@link AgentContextInterface.build}. */
3079
+ /** Holds a manager-level format override (beats the provider default + built-in); see {@link AgentContextInterface.build}. */
2845
3080
  readonly format?: ContextSectionFormat<InstructionInterface>;
2846
3081
  }
2847
3082
 
2848
3083
  /**
2849
- * Narrow an unknown caught value to an {@link AgentError}.
3084
+ * Intersects two scope category lists under the "`undefined` is the universal set" rule — the
3085
+ * primitive a scope narrows through.
3086
+ *
3087
+ * @remarks
3088
+ * Pure and total, and it can only TIGHTEN: `undefined` ∩ `undefined` is `undefined` (still no
3089
+ * constraint); `undefined` ∩ a list is a COPY of that list (the `undefined` side imposes
3090
+ * nothing); a list ∩ a list keeps the child keys the parent also allows, so a parent-excluded
3091
+ * key can never be re-admitted. Every returned list is a fresh copy, so a later mutation of
3092
+ * either input cannot leak into the result.
3093
+ *
3094
+ * @param parent - The parent's allow-list (`undefined` ⇒ no constraint)
3095
+ * @param child - The narrowing allow-list (`undefined` ⇒ no constraint)
3096
+ * @returns The intersected allow-list, or `undefined` when neither side constrains
3097
+ *
3098
+ * @example
3099
+ * ```ts
3100
+ * intersectKeys(['read', 'write'], ['write', 'admin']) // ['write']
3101
+ * intersectKeys(undefined, ['read']) // ['read']
3102
+ * intersectKeys(undefined, undefined) // undefined
3103
+ * ```
3104
+ */
3105
+ export declare function intersectKeys(parent: readonly string[] | undefined, child: readonly string[] | undefined): readonly string[] | undefined;
3106
+
3107
+ /**
3108
+ * Narrows an unknown caught value to an {@link AgentError}.
2850
3109
  *
2851
3110
  * @param value - The value to test (typically a `catch` binding)
2852
- * @returns `true` when `value` is an {@link AgentError}
3111
+ * @returns True if `value` is an {@link AgentError}; false otherwise
2853
3112
  *
2854
3113
  * @example
2855
3114
  * ```ts
@@ -2863,10 +3122,10 @@ export declare interface InstructionManagerOptions {
2863
3122
  export declare function isAgentError(value: unknown): value is AgentError;
2864
3123
 
2865
3124
  /**
2866
- * Narrow an unknown caught value to an {@link AgentJobError}.
3125
+ * Narrows an unknown caught value to an {@link AgentJobError}.
2867
3126
  *
2868
3127
  * @param value - The value to test (typically a `catch` binding or a rejected enqueue)
2869
- * @returns `true` when `value` is an {@link AgentJobError}
3128
+ * @returns True if `value` is an {@link AgentJobError}; false otherwise
2870
3129
  *
2871
3130
  * @example
2872
3131
  * ```ts
@@ -2880,10 +3139,10 @@ export declare function isAgentError(value: unknown): value is AgentError;
2880
3139
  export declare function isAgentJobError(value: unknown): value is AgentJobError;
2881
3140
 
2882
3141
  /**
2883
- * Narrow an unknown caught value to a {@link ConversationError}.
3142
+ * Narrows an unknown caught value to a {@link ConversationError}.
2884
3143
  *
2885
3144
  * @param value - The value to test (typically a `catch` binding)
2886
- * @returns `true` when `value` is a {@link ConversationError}
3145
+ * @returns True if `value` is a {@link ConversationError}; false otherwise
2887
3146
  *
2888
3147
  * @example
2889
3148
  * ```ts
@@ -2897,7 +3156,7 @@ export declare function isAgentJobError(value: unknown): value is AgentJobError;
2897
3156
  export declare function isConversationError(value: unknown): value is ConversationError;
2898
3157
 
2899
3158
  /**
2900
- * Narrow an `unknown` to a {@link ConversationSnapshot} — the AGENTS §14 boundary guard for an
3159
+ * Narrows an `unknown` to a {@link ConversationSnapshot} — the total boundary guard for an
2901
3160
  * UNTRUSTED snapshot read (a storage row a
2902
3161
  * {@link import('./conversations/stores/DatabaseConversationStore.js').DatabaseConversationStore}
2903
3162
  * reads back from its opaque JSON column, a snapshot loaded from disk). The EXACT analogue of
@@ -2907,8 +3166,8 @@ export declare function isConversationError(value: unknown): value is Conversati
2907
3166
  * A total guard (it NEVER throws — adversarial input returns `false`). It checks the snapshot's
2908
3167
  * SHAPE: a `string` `id`, an OPTIONAL `string` `summary` (present-or-absent — the rollup is
2909
3168
  * `undefined` until the first compaction), a `sections` array EVERY element of which is a valid
2910
- * {@link SectionInterface} ({@link isSection}), and a `messages` array EVERY element of which is a
2911
- * valid {@link MessageInterface} ({@link isMessage}) — enough to safely impose the
3169
+ * {@link Section} ({@link isSection}), and a `messages` array EVERY element of which is a
3170
+ * valid {@link Message} ({@link isMessage}) — enough to safely impose the
2912
3171
  * {@link ConversationSnapshot} type at a storage boundary WITHOUT a cast. The structural twin of
2913
3172
  * {@link import('@orkestrel/workspace').isWorkspaceSnapshot}. A malformed blob (a non-record, a missing / non-string `id`, a
2914
3173
  * non-string `summary` when present, a non-array `sections` / `messages`, or any malformed
@@ -2917,7 +3176,7 @@ export declare function isConversationError(value: unknown): value is Conversati
2917
3176
  * read yields `undefined` rather than a broken conversation.
2918
3177
  *
2919
3178
  * @param value - The value to test (an opaque storage read)
2920
- * @returns `true` when `value` has the structural shape of a {@link ConversationSnapshot}
3179
+ * @returns True if `value` has the structural shape of a {@link ConversationSnapshot}; false otherwise
2921
3180
  *
2922
3181
  * @example
2923
3182
  * ```ts
@@ -2930,9 +3189,9 @@ export declare function isConversationError(value: unknown): value is Conversati
2930
3189
  export declare function isConversationSnapshot(value: unknown): value is ConversationSnapshot;
2931
3190
 
2932
3191
  /**
2933
- * Whether an `unknown` is structurally a {@link MessageInterface} record — the per-message step of
2934
- * the {@link isConversationSnapshot} read-boundary narrow (AGENTS §14: narrow an untrusted storage
2935
- * read via a guard, never an `as`). The conversation analogue of
3192
+ * Checks whether an `unknown` is structurally a {@link Message} record — the per-message step of
3193
+ * the {@link isConversationSnapshot} read-boundary narrow (a total guard over an untrusted storage
3194
+ * read, never an assertion). The conversation analogue of
2936
3195
  * {@link import('@orkestrel/workspace').isFile}.
2937
3196
  *
2938
3197
  * @remarks
@@ -2940,16 +3199,16 @@ export declare function isConversationSnapshot(value: unknown): value is Convers
2940
3199
  * SHAPE: a record with a `string` `id`, a `string` `role`, a `string` `content`, and — WHEN present
2941
3200
  * — a `calls` array EVERY element of which is a valid
2942
3201
  * {@link import('@orkestrel/tool').ToolCall} ({@link isToolCall} — the
2943
- * ASI06 fail-closed deepening: a tampered `calls` element rejects the message, so the snapshot
3202
+ * fail-closed deepening: a tampered `calls` element rejects the message, so the snapshot
2944
3203
  * reads back as absent rather than replaying a malformed call) and an `images` that is an array
2945
3204
  * (an absent optional passes). The `role` is left as a broad `string` here (an open
2946
3205
  * {@link import('./types.js').MessageRole}, so any storage-read role string is accepted
2947
3206
  * defensively rather than rejected against the current literal set). Enough to safely impose the
2948
- * {@link MessageInterface} type at
3207
+ * {@link Message} type at
2949
3208
  * a storage boundary WITHOUT a cast.
2950
3209
  *
2951
3210
  * @param value - The value to test (one element of a snapshot's `messages` / a section's `messages`)
2952
- * @returns `true` when `value` has the structural shape of a {@link MessageInterface}
3211
+ * @returns True if `value` has the structural shape of a {@link Message}; false otherwise
2953
3212
  *
2954
3213
  * @example
2955
3214
  * ```ts
@@ -2959,13 +3218,13 @@ export declare function isConversationSnapshot(value: unknown): value is Convers
2959
3218
  * isMessage({ id: '1', role: 'assistant', content: '', calls: [null] }) // false (malformed call)
2960
3219
  * ```
2961
3220
  */
2962
- export declare function isMessage(value: unknown): value is MessageInterface;
3221
+ export declare function isMessage(value: unknown): value is Message;
2963
3222
 
2964
3223
  /**
2965
- * Narrow an unknown caught value to a {@link ProviderAbortError}.
3224
+ * Narrows an unknown caught value to a {@link ProviderAbortError}.
2966
3225
  *
2967
3226
  * @param value - The value to test (typically a `catch` binding)
2968
- * @returns `true` when `value` is a {@link ProviderAbortError}
3227
+ * @returns True if `value` is a {@link ProviderAbortError}; false otherwise
2969
3228
  *
2970
3229
  * @example
2971
3230
  * ```ts
@@ -2979,18 +3238,18 @@ export declare function isMessage(value: unknown): value is MessageInterface;
2979
3238
  export declare function isProviderAbortError(value: unknown): value is ProviderAbortError;
2980
3239
 
2981
3240
  /**
2982
- * Whether an `unknown` is structurally a {@link SectionInterface} record — the per-section step of
2983
- * the {@link isConversationSnapshot} read-boundary narrow (AGENTS §14: narrow an untrusted storage
2984
- * read via a guard, never an `as`).
3241
+ * Checks whether an `unknown` is structurally a {@link Section} record — the per-section step of
3242
+ * the {@link isConversationSnapshot} read-boundary narrow (a total guard over an untrusted storage
3243
+ * read, never an assertion).
2985
3244
  *
2986
3245
  * @remarks
2987
3246
  * A total guard (it NEVER throws — adversarial input returns `false`). It checks the section's
2988
3247
  * SHAPE: a record with a `string` `id`, a `string` `summary`, and a `messages` array EVERY element
2989
- * of which is a valid {@link MessageInterface} record ({@link isMessage}). Enough to safely impose
2990
- * the {@link SectionInterface} type at a storage boundary WITHOUT a cast.
3248
+ * of which is a valid {@link Message} record ({@link isMessage}). Enough to safely impose
3249
+ * the {@link Section} type at a storage boundary WITHOUT a cast.
2991
3250
  *
2992
3251
  * @param value - The value to test (one element of a snapshot's `sections` array)
2993
- * @returns `true` when `value` has the structural shape of a {@link SectionInterface}
3252
+ * @returns True if `value` has the structural shape of a {@link Section}; false otherwise
2994
3253
  *
2995
3254
  * @example
2996
3255
  * ```ts
@@ -2999,17 +3258,39 @@ export declare function isProviderAbortError(value: unknown): value is ProviderA
2999
3258
  * isSection({ id: 's', messages: [] }) // false (missing summary)
3000
3259
  * ```
3001
3260
  */
3002
- export declare function isSection(value: unknown): value is SectionInterface;
3261
+ export declare function isSection(value: unknown): value is Section;
3262
+
3263
+ /**
3264
+ * Joins the reasoning a run's provider calls separated from the answer — the first call
3265
+ * seeds the accumulation, a later call appends blank-line separated so each turn's reasoning
3266
+ * stays readable.
3267
+ *
3268
+ * @remarks
3269
+ * Pure and total. `running` is `undefined` until a call surfaces reasoning, so the first join
3270
+ * returns `next` verbatim (no leading separator). The result is display/audit metadata that
3271
+ * never re-enters the conversation.
3272
+ *
3273
+ * @param running - The reasoning accumulated so far (`undefined` before the first)
3274
+ * @param next - This call's separated reasoning
3275
+ * @returns The joined reasoning
3276
+ *
3277
+ * @example
3278
+ * ```ts
3279
+ * joinThinking(undefined, 'first') // 'first'
3280
+ * joinThinking('first', 'second') // 'first\n\nsecond'
3281
+ * ```
3282
+ */
3283
+ export declare function joinThinking(running: string | undefined, next: string): string;
3003
3284
 
3004
3285
  /**
3005
- * The in-memory {@link ConversationStoreInterface} — a process-lifetime `Map` of
3286
+ * Implements the {@link ConversationStoreInterface} in memory — a process-lifetime `Map` of
3006
3287
  * {@link ConversationSnapshot}s keyed by conversation id, the DEFAULT store
3007
3288
  * {@link import('../../factories.js').createMemoryConversationStore} builds. The EXACT twin of
3008
3289
  * {@link import('@orkestrel/workspace').MemoryWorkspaceStore}.
3009
3290
  *
3010
3291
  * @remarks
3011
- * A plain `Map<string, ConversationSnapshot>` (AGENTS §21 — the snapshot is already pure,
3012
- * self-contained JSON, so no encoding is needed for the memory tier). Like the
3292
+ * A plain `Map<string, ConversationSnapshot>` — the snapshot is already pure,
3293
+ * self-contained JSON, so no encoding is needed for the memory tier. Like the
3013
3294
  * {@link import('@orkestrel/workspace').MemoryWorkspaceStore} it twins,
3014
3295
  * there is NO idle-TTL and NO eviction: a persisted conversation lives until an explicit `delete`. A
3015
3296
  * durable backend (JSON / SQLite / IndexedDB) swaps in through the SAME interface without touching
@@ -3022,14 +3303,14 @@ export declare function isSection(value: unknown): value is SectionInterface;
3022
3303
  * - **`set` inserts / replaces under the snapshot's OWN `id`** (no separate id param).
3023
3304
  * - **`delete` drops a snapshot by id**; an absent id is a no-op (no throw).
3024
3305
  *
3025
- * The public surface is EXACTLY `get` / `set` / `delete` — no extra members (the §22 method
3306
+ * The public surface is EXACTLY `get` / `set` / `delete` — no extra members (the method
3026
3307
  * bijection with {@link ConversationStoreInterface}). Hydration is a caller concern: a
3027
3308
  * {@link import('../ConversationManager.js').ConversationManager} reads a snapshot back and rebuilds
3028
- * the live conversation through the constructor `seed` (its `open` / `save`).
3309
+ * the live conversation through the `snapshot` option (its `open` / `save`).
3029
3310
  *
3030
3311
  * @example
3031
3312
  * ```ts
3032
- * import { createConversation, createMemoryConversationStore } from '@src/core'
3313
+ * import { createConversation, createMemoryConversationStore } from '@orkestrel/agent'
3033
3314
  *
3034
3315
  * const store = createMemoryConversationStore()
3035
3316
  * const conversation = createConversation()
@@ -3047,31 +3328,7 @@ export declare class MemoryConversationStore implements ConversationStoreInterfa
3047
3328
  }
3048
3329
 
3049
3330
  /**
3050
- * The estimated per-message role/framing overhead {@link import('./helpers.js').estimateMessages}
3051
- * adds on top of a message's content estimate — accounts for the fixed wire framing every
3052
- * conversation turn carries (its role tag, delimiters) that {@link import('./helpers.js').estimateTokens}'s
3053
- * content-only heuristic does not otherwise capture.
3054
- */
3055
- export declare const MESSAGE_TOKEN_OVERHEAD = 4;
3056
-
3057
- /**
3058
- * The minimal data needed to author a {@link MessageInterface} — the `id` is
3059
- * assigned by the layer that stores it, so a caller supplies only role / content
3060
- * (and, for a replayed assistant turn, its `calls`).
3061
- */
3062
- export declare interface MessageInput {
3063
- readonly role: MessageRole;
3064
- readonly content: string;
3065
- readonly calls?: readonly ToolCall[];
3066
- /**
3067
- * Multimodal image data for this turn — base64-encoded image strings forwarded to a
3068
- * vision-capable provider (carried verbatim onto the stored {@link MessageInterface}).
3069
- */
3070
- readonly images?: readonly string[];
3071
- }
3072
-
3073
- /**
3074
- * One conversation turn fed to a {@link ProviderInterface} — a stored, identified
3331
+ * Represents one conversation turn fed to a {@link ProviderInterface} — a stored, identified
3075
3332
  * message.
3076
3333
  *
3077
3334
  * @remarks
@@ -3080,14 +3337,14 @@ export declare interface MessageInput {
3080
3337
  * the model sees its own decision. A `tool` turn carries the tool's result in
3081
3338
  * `content` (the textual outcome), keyed back to the call by the conversation order.
3082
3339
  */
3083
- export declare interface MessageInterface {
3340
+ export declare interface Message {
3084
3341
  readonly id: string;
3085
3342
  readonly role: MessageRole;
3086
3343
  readonly content: string;
3087
- /** An assistant turn that requested tools — its `tool_calls`, replayed. */
3344
+ /** Holds an assistant turn's requested tools — its `tool_calls`, replayed. */
3088
3345
  readonly calls?: readonly ToolCall[];
3089
3346
  /**
3090
- * Multimodal image data attached to this turn — base64-encoded image strings,
3347
+ * Holds multimodal image data attached to this turn — base64-encoded image strings,
3091
3348
  * forwarded to a vision-capable provider (the provider maps them onto the wire's
3092
3349
  * per-message `images` array). Present only on a multimodal turn; absent otherwise.
3093
3350
  */
@@ -3095,56 +3352,82 @@ export declare interface MessageInterface {
3095
3352
  }
3096
3353
 
3097
3354
  /**
3098
- * The conversation store — immutable {@link MessageInterface}s in insertion order;
3099
- * `add` mints the `id`.
3355
+ * Estimates the per-message role/framing overhead {@link import('./helpers.js').estimateMessages}
3356
+ * adds on top of a message's content estimate — accounts for the fixed wire framing every
3357
+ * conversation turn carries (its role tag, delimiters) that {@link import('./helpers.js').estimateTokens}'s
3358
+ * content-only heuristic does not otherwise capture.
3359
+ */
3360
+ export declare const MESSAGE_TOKEN_OVERHEAD = 4;
3361
+
3362
+ /**
3363
+ * Carries the minimal data needed to author a {@link Message} — the `id` is
3364
+ * assigned by the layer that stores it, so a caller supplies only role / content
3365
+ * (and, for a replayed assistant turn, its `calls`).
3366
+ */
3367
+ export declare interface MessageInput {
3368
+ readonly role: MessageRole;
3369
+ readonly content: string;
3370
+ readonly calls?: readonly ToolCall[];
3371
+ /**
3372
+ * Holds multimodal image data for this turn — base64-encoded image strings forwarded to a
3373
+ * vision-capable provider (carried verbatim onto the stored {@link Message}).
3374
+ */
3375
+ readonly images?: readonly string[];
3376
+ }
3377
+
3378
+ /**
3379
+ * Stores immutable {@link Message}s in insertion order; `add` mints the `id`.
3100
3380
  *
3101
3381
  * @remarks
3102
3382
  * - **Store.** Messages live in insertion order; `count` is how many are stored.
3103
- * `add` takes one {@link MessageInput} or a batch (§9.2) and MINTS each message's
3383
+ * `add` takes one {@link MessageInput} or a batch and MINTS each message's
3104
3384
  * `id` (a random UUID), returning the created message(s). A stored message is
3105
3385
  * immutable — created once from its input, never mutated.
3106
3386
  * - **Lookup.** `message(id)` resolves one by id (`undefined` when absent);
3107
3387
  * `messages()` lists every message in insertion order.
3108
- * - **Removal.** `remove` drops one by id, or a batch (§9.2) — `true` when any was
3109
- * removed; `clear` empties the store.
3388
+ * - **Removal.** `remove` drops one by id, or a batch — `true` only when EVERY supplied id
3389
+ * was removed; `clear` empties the store.
3110
3390
  * - **Event-free.** A purely data store — no Emitter, no events.
3111
3391
  */
3112
3392
  export declare interface MessageManagerInterface {
3113
3393
  readonly count: number;
3114
- add(input: MessageInput): MessageInterface;
3115
- add(inputs: readonly MessageInput[]): readonly MessageInterface[];
3116
- message(id: string): MessageInterface | undefined;
3117
- messages(): readonly MessageInterface[];
3394
+ add(input: MessageInput): Message;
3395
+ add(inputs: readonly MessageInput[]): readonly Message[];
3396
+ message(id: string): Message | undefined;
3397
+ messages(): readonly Message[];
3118
3398
  remove(id: string): boolean;
3119
3399
  remove(ids: readonly string[]): boolean;
3120
3400
  clear(): void;
3121
3401
  }
3122
3402
 
3123
- /** The role a {@link MessageInterface} plays in a conversation turn. */
3403
+ /** Names the role a {@link Message} plays in a conversation turn. */
3124
3404
  export declare type MessageRole = 'system' | 'user' | 'assistant' | 'tool';
3125
3405
 
3126
3406
  /**
3127
- * Thrown by a {@link ProviderInterface}'s `stream` when its bound signal aborts
3128
- * mid-flight — carries the {@link ProviderResult} assembled from whatever streamed
3129
- * before the cancel.
3407
+ * Reports a provider stream cancelled mid-flight by its bound signal — thrown by a
3408
+ * {@link ProviderInterface}'s `stream`, carrying the {@link ProviderResult} assembled
3409
+ * from whatever streamed before the cancel.
3130
3410
  *
3131
3411
  * @remarks
3132
3412
  * Lets a caller recover the partial content (and any tool calls / usage seen so far)
3133
3413
  * on cancellation: `catch` the throw, narrow with {@link isProviderAbortError}, and
3134
- * read `partial`.
3414
+ * read `partial`. `code` is the machine-readable condition (`'ABORT'` — the only one this
3415
+ * error reports), so a `catch` branches on it rather than on the message string.
3135
3416
  */
3136
3417
  export declare class ProviderAbortError extends Error {
3418
+ /** Names the machine-readable condition — `'ABORT'`: a stream cancelled mid-flight. */
3419
+ readonly code: "ABORT";
3137
3420
  readonly partial: ProviderResult;
3138
3421
  constructor(partial: ProviderResult);
3139
3422
  }
3140
3423
 
3141
3424
  /**
3142
- * One streamed delta a {@link ProviderInterface}'s `stream` yields — a TAGGED unit
3425
+ * Represents one streamed delta a {@link ProviderInterface}'s `stream` yields — a TAGGED unit
3143
3426
  * discriminated by the channel it belongs to, so the agent loop can re-surface the two
3144
3427
  * channels separately (answer content vs. live reasoning) as it pumps.
3145
3428
  *
3146
3429
  * @remarks
3147
- * The discriminant `type` names the CHANNEL axis (AGENTS §4.4 — never `kind`): a
3430
+ * The discriminant `channel` names the axis that varies: a
3148
3431
  * `'content'` delta is a chunk of the assistant ANSWER (the deltas that accumulate into
3149
3432
  * {@link ProviderResult.content}); a `'thinking'` delta is a chunk of the model's
3150
3433
  * REASONING the provider separated from the answer (the daemon's native
@@ -3154,15 +3437,15 @@ export declare class ProviderAbortError extends Error {
3154
3437
  * as {@link ProviderResult.thinking} (the authoritative final accumulation) is.
3155
3438
  */
3156
3439
  export declare type ProviderDelta = {
3157
- readonly type: 'content';
3440
+ readonly channel: 'content';
3158
3441
  readonly text: string;
3159
3442
  } | {
3160
- readonly type: 'thinking';
3443
+ readonly channel: 'thinking';
3161
3444
  readonly text: string;
3162
3445
  };
3163
3446
 
3164
3447
  /**
3165
- * The pluggable LLM inference boundary — the one contract every agent chunk depends
3448
+ * Defines the pluggable LLM inference boundary — the one contract every agent chunk depends
3166
3449
  * on. A provider turns a conversation (plus optional tools) into either a single
3167
3450
  * assembled {@link ProviderResult} (`generate`) or a stream of {@link ProviderDelta}s that
3168
3451
  * RETURNS the assembled result (`stream`).
@@ -3171,35 +3454,35 @@ export declare type ProviderDelta = {
3171
3454
  * - `id` is a stable per-instance trace label; `name` identifies the backend
3172
3455
  * (`'ollama'`).
3173
3456
  * - Both calls take an `AbortSignal` so a caller bounds the request (cancel,
3174
- * deadline, or budget folded via `AbortSignal.any`); aborting a `stream` mid-flight
3457
+ * deadline, or budget folded through `AbortSignal.any`); aborting a `stream` mid-flight
3175
3458
  * surfaces a `ProviderAbortError` carrying the partial result.
3176
3459
  * - `tools`, when given non-empty, advertises the callable tools for this turn.
3177
- * - `options` carries the optional per-call {@link ProviderStreamOptions} (e.g. `think`),
3460
+ * - `options` carries the optional per-call {@link ProviderStreamOptions} (for example `think`),
3178
3461
  * overriding the provider's constructed defaults for that one call; omitted ⇒ defaults.
3179
3462
  */
3180
3463
  export declare interface ProviderInterface {
3181
3464
  readonly id: string;
3182
3465
  readonly name: string;
3183
3466
  /**
3184
- * The model's preferred context framing, by section kind — an OPTIONAL
3185
- * {@link ContextFormatInterface} an {@link import('./AgentContext.js').AgentContext}
3467
+ * Holds the model's preferred context framing, by section kind — an OPTIONAL
3468
+ * {@link ContextFormat} an {@link import('./AgentContext.js').AgentContext}
3186
3469
  * applies as the PROVIDER-DEFAULT level of its build cascade (beating the managers'
3187
3470
  * built-in framing, beaten by a manager-options or per-item override). Omitted ⇒ the
3188
3471
  * provider is framing-agnostic and the managers' built-in defaults apply unchanged.
3189
3472
  */
3190
- readonly format?: ContextFormatInterface | undefined;
3473
+ readonly format?: ContextFormat | undefined;
3191
3474
  /**
3192
- * Generate one complete turn — resolves the assembled {@link ProviderResult}.
3475
+ * Generates one complete turn — resolves the assembled {@link ProviderResult}.
3193
3476
  *
3194
3477
  * @param messages - The conversation so far
3195
3478
  * @param signal - Bounds the request; an abort rejects the call
3196
3479
  * @param tools - Optional tools the model may call this turn
3197
- * @param options - Optional per-call {@link ProviderStreamOptions} (e.g. `think`); omitted ⇒ defaults
3480
+ * @param options - Optional per-call {@link ProviderStreamOptions} (for example `think`); omitted ⇒ defaults
3198
3481
  * @returns The assembled result (content + any tool calls + any usage)
3199
3482
  */
3200
- generate(messages: readonly MessageInterface[], signal: AbortSignal, tools?: readonly ToolDefinition[], options?: ProviderStreamOptions): Promise<ProviderResult>;
3483
+ generate(messages: readonly Message[], signal: AbortSignal, tools?: readonly ToolDefinition[], options?: ProviderStreamOptions): Promise<ProviderResult>;
3201
3484
  /**
3202
- * Stream one turn — yields {@link ProviderDelta}s (channel-tagged `content` / `thinking`
3485
+ * Streams one turn — yields {@link ProviderDelta}s (channel-tagged `content` / `thinking`
3203
3486
  * chunks) as they arrive and RETURNS the assembled {@link ProviderResult} (the
3204
3487
  * concatenated content + any separated reasoning + any tool calls + any usage) when the
3205
3488
  * stream completes.
@@ -3211,14 +3494,14 @@ export declare interface ProviderInterface {
3211
3494
  * @param messages - The conversation so far
3212
3495
  * @param signal - Bounds the request; an abort throws `ProviderAbortError`
3213
3496
  * @param tools - Optional tools the model may call this turn
3214
- * @param options - Optional per-call {@link ProviderStreamOptions} (e.g. `think`); omitted ⇒ defaults
3497
+ * @param options - Optional per-call {@link ProviderStreamOptions} (for example `think`); omitted ⇒ defaults
3215
3498
  * @returns A generator of {@link ProviderDelta}s, returning the assembled result
3216
3499
  */
3217
- stream(messages: readonly MessageInterface[], signal: AbortSignal, tools?: readonly ToolDefinition[], options?: ProviderStreamOptions): AsyncGenerator<ProviderDelta, ProviderResult>;
3500
+ stream(messages: readonly Message[], signal: AbortSignal, tools?: readonly ToolDefinition[], options?: ProviderStreamOptions): AsyncGenerator<ProviderDelta, ProviderResult>;
3218
3501
  }
3219
3502
 
3220
3503
  /**
3221
- * A single inference turn's structured outcome — the assembled assistant content,
3504
+ * Holds a single inference turn's structured outcome — the assembled assistant content,
3222
3505
  * any reasoning the provider separated from it, any tool calls the model requested,
3223
3506
  * and the token usage it reported.
3224
3507
  *
@@ -3234,16 +3517,16 @@ export declare interface ProviderInterface {
3234
3517
  */
3235
3518
  export declare interface ProviderResult {
3236
3519
  readonly content: string;
3237
- /** Present ⇒ reasoning the provider separated from the answer — never re-enters the conversation. */
3520
+ /** Carries reasoning the provider separated from the answer when present — never re-enters the conversation. */
3238
3521
  readonly thinking?: string;
3239
- /** Present ⇒ the model wants these tool calls. */
3522
+ /** Carries the tool calls the model wants when present. */
3240
3523
  readonly tools?: readonly ToolCall[];
3241
- /** Present ⇒ token consumption for this turn (from the wire's `done` line / body). */
3524
+ /** Carries token consumption for this turn when present (from the wire's `done` line / body). */
3242
3525
  readonly usage?: TokenUsage;
3243
3526
  }
3244
3527
 
3245
3528
  /**
3246
- * Per-call options threaded into a {@link ProviderInterface}'s `generate` / `stream` —
3529
+ * Carries the per-call options threaded into a {@link ProviderInterface}'s `generate` / `stream` —
3247
3530
  * the bag a caller passes to influence ONE inference call without reconfiguring the
3248
3531
  * provider instance.
3249
3532
  *
@@ -3259,28 +3542,151 @@ export declare interface ProviderResult {
3259
3542
  * that passes no options behaves exactly as before.
3260
3543
  */
3261
3544
  export declare interface ProviderStreamOptions {
3262
- /** Override the provider's reasoning preference for this call; omitted ⇒ the provider default. */
3545
+ /** Overrides the provider's reasoning preference for this call; omitted ⇒ the provider default. */
3263
3546
  readonly think?: boolean;
3264
- /** Constrain the response to this JSON-Schema shape (the same open record {@link ToolDefinition.parameters} uses); omitted ⇒ no constraint. */
3547
+ /** Constrains the response to this JSON-Schema shape (the same open record {@link ToolDefinition.parameters} uses); omitted ⇒ no constraint. */
3265
3548
  readonly schema?: Readonly<Record<string, unknown>>;
3266
3549
  }
3267
3550
 
3268
3551
  /**
3269
- * The immutable per-run outcome value an {@link AgentInterface}'s loop replaces as it runs — the
3270
- * assembled value its `stream`'s `result` promise resolves into a settled
3271
- * {@link AgentResult} once the run completes.
3552
+ * Renders a path-addressed text body as a fenced reference block — the framing an
3553
+ * {@link import('./AgentContext.js').AgentContext}'s ACTIVE-workspace text-file render emits (the
3554
+ * active workspace is the SOLE document/image context).
3272
3555
  *
3273
3556
  * @remarks
3274
- * Created fresh per run (so concurrent runs never share state) and replaced through
3275
- * the loop: `content` accumulates the streamed assistant text, `thinking` the
3276
- * reasoning the provider calls separated from it ({@link ProviderResult.thinking},
3277
- * joined across calls — `undefined` until one surfaces it), `usage` the summed
3278
- * {@link TokenUsage} (present only when a provider call reported it), `partial`
3279
- * flips `true` when a cancel commits the run early OR when the loop exhausts its
3280
- * `limit` with unresolved tool intent, and `exhausted` flips `true` in that second
3281
- * case specifically (a distinct, non-cancel cause the {@link AgentEventMap} `exhaust`
3282
- * event observes). It is the INTERNAL precursor to the settled `AgentResult` — the
3283
- * loop reads it back to assemble the public result — not a caller-facing shape.
3557
+ * Produces `` File: <path>\n```<language>\n<content>\n``` `` — the `File:` label line, then a
3558
+ * fenced code block tagged with `language`, the `content` verbatim inside. Pure string assembly,
3559
+ * total — never throws. The one fenced-file format string for the whole module — `AgentContext.build()`
3560
+ * frames an active workspace's text files with it (each carries its own `language` on its
3561
+ * {@link import('@orkestrel/workspace').FileContent} text arm).
3562
+ *
3563
+ * @param path - The file path shown on the `File:` label line
3564
+ * @param language - The fenced-code language tag (for example `'typescript'`)
3565
+ * @param content - The file body rendered verbatim inside the fence
3566
+ * @returns The fenced reference block
3567
+ *
3568
+ * @example
3569
+ * ```ts
3570
+ * import { renderFencedFile } from '@orkestrel/agent'
3571
+ *
3572
+ * renderFencedFile('src/main.ts', 'typescript', 'const x = 1')
3573
+ * // 'File: src/main.ts\n```typescript\nconst x = 1\n```'
3574
+ * ```
3575
+ */
3576
+ export declare function renderFencedFile(path: string, language: string, content: string): string;
3577
+
3578
+ /**
3579
+ * Renders one context section — the resolved `open`, each item's rendering, and the resolved
3580
+ * `close` when one exists, blank-line joined.
3581
+ *
3582
+ * @remarks
3583
+ * Pure and total. A section with NO items renders nothing (`undefined`), so an empty or fully
3584
+ * scoped-out manager stays silent — its `open` / `close` never appear without items. `close`
3585
+ * is the only optional slot: an unset one (there is no built-in close) drops the
3586
+ * trailing line.
3587
+ *
3588
+ * @typeParam T - The section item being rendered
3589
+ * @param open - The section's resolved leading text
3590
+ * @param items - The already scope-filtered items
3591
+ * @param render - Renders one item to its prompt text
3592
+ * @param close - The section's resolved trailing text, or `undefined` for none
3593
+ * @returns The rendered section, or `undefined` when there are no items
3594
+ *
3595
+ * @example
3596
+ * ```ts
3597
+ * renderSection('## Instructions', [{ content: 'Be terse.' }], (one) => one.content, undefined)
3598
+ * // '## Instructions\n\nBe terse.'
3599
+ * renderSection('<rules>', [], (one) => one.content, '</rules>') // undefined (no items)
3600
+ * ```
3601
+ */
3602
+ export declare function renderSection<T>(open: string, items: readonly T[], render: (item: T) => string, close: string | undefined): string | undefined;
3603
+
3604
+ /**
3605
+ * Resolves one section's CLOSE text through the format cascade — manager-options override >
3606
+ * provider default.
3607
+ *
3608
+ * @remarks
3609
+ * Pure and total. There is NO built-in close, so a section with neither level set returns
3610
+ * `undefined` and {@link renderSection} appends no closing line. Paired with
3611
+ * {@link resolveOpen}, one level can WRAP the whole group.
3612
+ *
3613
+ * @typeParam T - The section item the manager renders
3614
+ * @param manager - The section source (its `format` override)
3615
+ * @param provider - The provider-default framing for this section, or `undefined`
3616
+ * @returns The section's trailing text, or `undefined` when no level sets one
3617
+ *
3618
+ * @example
3619
+ * ```ts
3620
+ * resolveClose(instructions, undefined) // undefined (no built-in close)
3621
+ * resolveClose(instructions, { close: '</rules>' }) // '</rules>'
3622
+ * ```
3623
+ */
3624
+ export declare function resolveClose<T>(manager: ContextSectionSourceInterface<T>, provider: ContextSectionFormat<T> | undefined): string | undefined;
3625
+
3626
+ /**
3627
+ * Resolves ONE item's rendering through the format cascade — item override >
3628
+ * manager-options override > provider default > built-in rendering.
3629
+ *
3630
+ * @remarks
3631
+ * Pure and total. The item's own `override` is the most-specific level (a fully-rendered
3632
+ * string for that item alone). A manager's `render(item)` already encapsulates
3633
+ * `[options-override → built-in]`, so it is reached only when no higher level applies — and
3634
+ * there it IS the built-in rendering.
3635
+ *
3636
+ * @typeParam T - The section item being rendered (it may carry its own `override`)
3637
+ * @param manager - The section source (its `format` override + its built-in `render`)
3638
+ * @param provider - The provider-default framing for this section, or `undefined`
3639
+ * @param item - The item to render
3640
+ * @returns The item's prompt text
3641
+ *
3642
+ * @example
3643
+ * ```ts
3644
+ * resolveItem(instructions, undefined, terse) // 'Be terse.' (the built-in rendering)
3645
+ * resolveItem(instructions, { render: (one) => `<rule>${one.content}</rule>` }, terse)
3646
+ * // '<rule>Be terse.</rule>'
3647
+ * ```
3648
+ */
3649
+ export declare function resolveItem<T extends {
3650
+ readonly override?: string;
3651
+ }>(manager: ContextSectionSourceInterface<T>, provider: ContextSectionFormat<T> | undefined, item: T): string;
3652
+
3653
+ /**
3654
+ * Resolves one section's OPEN text through the format cascade — manager-options override >
3655
+ * provider default > built-in header.
3656
+ *
3657
+ * @remarks
3658
+ * Pure and total. The leading text has NO per-item level. A manager's `open` already
3659
+ * encapsulates `[options-override → built-in]`, so it is reached only when neither the
3660
+ * override's `open` nor the provider's `open` applies — and there it IS the built-in header.
3661
+ *
3662
+ * @typeParam T - The section item the manager renders
3663
+ * @param manager - The section source (its `format` override + its built-in `open`)
3664
+ * @param provider - The provider-default framing for this section, or `undefined`
3665
+ * @returns The section's leading text
3666
+ *
3667
+ * @example
3668
+ * ```ts
3669
+ * resolveOpen(instructions, undefined) // '## Instructions' (the built-in header)
3670
+ * resolveOpen(instructions, { open: '<rules>' }) // '<rules>' (the provider default)
3671
+ * ```
3672
+ */
3673
+ export declare function resolveOpen<T>(manager: ContextSectionSourceInterface<T>, provider: ContextSectionFormat<T> | undefined): string;
3674
+
3675
+ /**
3676
+ * Holds the immutable per-run outcome an {@link AgentInterface}'s loop settles on — the value its
3677
+ * run RETURNS, assembled from there into the {@link AgentResult} its `stream`'s `result`
3678
+ * promise resolves.
3679
+ *
3680
+ * @remarks
3681
+ * Computed inside one run (so concurrent runs never share state) and returned once, when the
3682
+ * loop settles: `content` is the streamed assistant text, `thinking` the reasoning the
3683
+ * provider calls separated from it ({@link ProviderResult.thinking}, joined across calls —
3684
+ * `undefined` when none surfaced), `usage` the summed {@link TokenUsage} (present only when
3685
+ * a provider call reported it), `partial` is `true` when a cancel committed the run early OR
3686
+ * when the loop exhausted its `limit` with unresolved tool intent, and `exhausted` is `true`
3687
+ * in that second case specifically (a distinct, non-cancel cause the {@link AgentEventMap}
3688
+ * `exhaust` event observes). It is the settled outcome one run returns, before the agent folds
3689
+ * it into the {@link AgentResult} its `stream`'s `result` promise resolves.
3284
3690
  */
3285
3691
  export declare interface RunOutcome {
3286
3692
  readonly content: string;
@@ -3291,7 +3697,7 @@ export declare interface RunOutcome {
3291
3697
  }
3292
3698
 
3293
3699
  /**
3294
- * Sanitize one reported token count into a safe non-negative integer.
3700
+ * Sanitizes one reported token count into a safe non-negative integer.
3295
3701
  *
3296
3702
  * @param value - The token count to sanitize
3297
3703
  * @returns The floored count, or `0` when the value is non-finite or non-positive
@@ -3299,7 +3705,7 @@ export declare interface RunOutcome {
3299
3705
  export declare function sanitizeToken(value: number): number;
3300
3706
 
3301
3707
  /**
3302
- * Sanitize a {@link TokenUsage} into safe, non-negative integers — the guard an agent's
3708
+ * Sanitizes a {@link TokenUsage} into safe, non-negative integers — the guard an agent's
3303
3709
  * abort-usage path applies to a provider's partial usage before it is charged against a
3304
3710
  * budget or folded into the run total.
3305
3711
  *
@@ -3308,7 +3714,7 @@ export declare function sanitizeToken(value: number): number;
3308
3714
  * `-Infinity`) or a negative value floors to `0`; a fractional value floors to its
3309
3715
  * non-negative integer part. No upper cap is applied. Total — never throws.
3310
3716
  *
3311
- * @param usage - The token usage to sanitize (e.g. a provider's abort-partial usage)
3717
+ * @param usage - The token usage to sanitize (for example a provider's abort-partial usage)
3312
3718
  * @returns A new {@link TokenUsage} with every field a safe non-negative integer
3313
3719
  *
3314
3720
  * @example
@@ -3319,14 +3725,14 @@ export declare function sanitizeToken(value: number): number;
3319
3725
  export declare function sanitizeUsage(usage: TokenUsage): TokenUsage;
3320
3726
 
3321
3727
  /**
3322
- * A named, immutable filter over a richer context's items — three optional allow-lists,
3323
- * one per category (`instructions` / `tools` / `files`), each keyed by that category's
3324
- * identity (an instruction's `name`, a tool's `name`, a workspace file's `path`).
3728
+ * Represents a named, immutable filter over a richer context's items — an optional
3729
+ * allow-list per category (`instructions` / `tools` / `files`), each keyed by that
3730
+ * category's identity (an instruction's `name`, a tool's `name`, a workspace file's `path`).
3325
3731
  *
3326
3732
  * @remarks
3327
3733
  * - **A category list is three-way.** `undefined` ⇒ NO constraint on that category (all
3328
3734
  * pass); `[]` ⇒ NONE pass; a non-empty list ⇒ only the listed keys pass. The build
3329
- * step / loop apply this via `filterAllowList`.
3735
+ * step / loop apply this through `filterAllowList`.
3330
3736
  * - **Immutable.** The `id` is minted at construction; every supplied list is COPIED in
3331
3737
  * (so a later mutation of the caller's array can't leak in), and the lists are
3332
3738
  * `readonly`. A `Scope` is never mutated after construction — `narrow` returns a NEW
@@ -3349,19 +3755,18 @@ export declare function sanitizeUsage(usage: TokenUsage): TokenUsage;
3349
3755
  * ```
3350
3756
  */
3351
3757
  export declare class Scope implements ScopeInterface {
3352
- #private;
3353
3758
  readonly id: string;
3354
3759
  readonly name: string;
3355
3760
  readonly instructions?: readonly string[];
3356
3761
  readonly tools?: readonly string[];
3357
3762
  readonly files?: readonly string[];
3358
3763
  constructor(input: ScopeInput);
3359
- narrow(config: ScopeConfiguration): ScopeInterface;
3764
+ narrow(config: ScopeFilter): ScopeInterface;
3360
3765
  }
3361
3766
 
3362
3767
  /**
3363
- * The per-category allow-lists a {@link ScopeInterface} carries — three optional
3364
- * `readonly string[]`s, one per filterable context category, each keyed by that
3768
+ * Lists the per-category allow-lists a {@link ScopeInterface} carries — an optional
3769
+ * `readonly string[]` for `instructions`, for `tools`, and for `files`, each keyed by that
3365
3770
  * category's identity (an instruction's `name`, a tool's `name`, a workspace file's
3366
3771
  * `path`).
3367
3772
  *
@@ -3373,13 +3778,13 @@ export declare class Scope implements ScopeInterface {
3373
3778
  * files (by `path`) in {@link AgentContextInterface.build} — both the text files folded into
3374
3779
  * the system block and the image files attached to the last user message.
3375
3780
  */
3376
- export declare interface ScopeConfiguration {
3377
- /** Allowed instruction `name`s (`undefined` ⇒ all, `[]` ⇒ none, else only-listed). */
3781
+ export declare interface ScopeFilter {
3782
+ /** Lists the allowed instruction `name`s (`undefined` ⇒ all, `[]` ⇒ none, else only-listed). */
3378
3783
  readonly instructions?: readonly string[];
3379
- /** Allowed tool `name`s (`undefined` ⇒ all, `[]` ⇒ none, else only-listed). */
3784
+ /** Lists the allowed tool `name`s (`undefined` ⇒ all, `[]` ⇒ none, else only-listed). */
3380
3785
  readonly tools?: readonly string[];
3381
3786
  /**
3382
- * Allowed ACTIVE-workspace file `path`s (`undefined` ⇒ all, `[]` ⇒ none, else only-listed) —
3787
+ * Lists the allowed ACTIVE-workspace file `path`s (`undefined` ⇒ all, `[]` ⇒ none, else only-listed) —
3383
3788
  * the filter {@link AgentContextInterface.build} applies to the active workspace's
3384
3789
  * {@link import('@orkestrel/workspace').WorkspaceInterface.files} before rendering them (text → the system block, image →
3385
3790
  * the last user message).
@@ -3388,16 +3793,16 @@ export declare interface ScopeConfiguration {
3388
3793
  }
3389
3794
 
3390
3795
  /**
3391
- * The data to author a {@link ScopeInterface} — a {@link ScopeConfiguration} plus the
3796
+ * Carries the data to author a {@link ScopeInterface} — a {@link ScopeFilter} plus the
3392
3797
  * required `name` (a human label; the `id` is minted by the layer that stores it).
3393
3798
  */
3394
- export declare interface ScopeInput extends ScopeConfiguration {
3799
+ export declare interface ScopeInput extends ScopeFilter {
3395
3800
  readonly name: string;
3396
3801
  }
3397
3802
 
3398
3803
  /**
3399
- * A named, immutable filter over a richer context's items — the three per-category
3400
- * allow-lists ({@link ScopeConfiguration}) plus an `id` / `name`, and a `narrow` that
3804
+ * Represents a named, immutable filter over a richer context's items — the per-category
3805
+ * allow-lists ({@link ScopeFilter}) plus an `id` / `name`, and a `narrow` that
3401
3806
  * composes a tighter child by set-INTERSECTION.
3402
3807
  *
3403
3808
  * @remarks
@@ -3407,22 +3812,22 @@ export declare interface ScopeInput extends ScopeConfiguration {
3407
3812
  * so `undefined ∩ list = list` and `undefined ∩ undefined = undefined`. Narrowing can
3408
3813
  * only TIGHTEN (a parent-excluded key never returns); the scope itself is never mutated.
3409
3814
  */
3410
- export declare interface ScopeInterface extends ScopeConfiguration {
3815
+ export declare interface ScopeInterface extends ScopeFilter {
3411
3816
  readonly id: string;
3412
3817
  readonly name: string;
3413
3818
  /**
3414
- * Compose a tighter child scope — its per-category set is the intersection of this
3819
+ * Composes a tighter child scope — its per-category set is the intersection of this
3415
3820
  * scope's list and `config`'s (an `undefined` side imposing no constraint).
3416
3821
  *
3417
- * @param config - The narrowing allow-lists (a `name`-less {@link ScopeConfiguration})
3822
+ * @param config - The narrowing allow-lists (a `name`-less {@link ScopeFilter})
3418
3823
  * @returns A NEW, tighter {@link ScopeInterface} (this one is left unchanged)
3419
3824
  */
3420
- narrow(config: ScopeConfiguration): ScopeInterface;
3825
+ narrow(config: ScopeFilter): ScopeInterface;
3421
3826
  }
3422
3827
 
3423
3828
  /**
3424
- * The scope registry a richer context reuses named filters from — immutable {@link Scope}s
3425
- * keyed by their minted `id`, in insertion order.
3829
+ * Registers the named filters a richer context reuses — immutable {@link Scope}s keyed by
3830
+ * their minted `id`, in insertion order.
3426
3831
  *
3427
3832
  * @remarks
3428
3833
  * - **Registry.** Scopes live in an insertion-ordered `Map` keyed by their minted `id`;
@@ -3431,9 +3836,9 @@ export declare interface ScopeInterface extends ScopeConfiguration {
3431
3836
  * one up, and `scopes()` lists them in insertion order. (Unlike the name-keyed
3432
3837
  * instruction registry, a scope's key is its minted `id`, so two scopes may share a
3433
3838
  * `name`; `create` therefore always adds — it never overwrites.)
3434
- * - **Removal.** `remove` drops one by id, or a batch (§9.2) — `true` when any was
3435
- * removed; `clear` empties the registry.
3436
- * - **Observable (§13).** The owned {@link emitter} ({@link ScopeManagerEventMap}) carries
3839
+ * - **Removal.** `remove` drops one by id, or a batch — `true` only when EVERY supplied id
3840
+ * was removed; `clear` empties the registry.
3841
+ * - **Observable.** The owned {@link emitter} ({@link ScopeManagerEventMap}) carries
3437
3842
  * `create` (the created scope) / `remove` (the id) / `clear`. Every event is emitted
3438
3843
  * directly, strictly AFTER the map mutation completes; the emitter isolates a listener
3439
3844
  * throw and routes it to its `error` handler (the `error` option), so a buggy observer can
@@ -3449,7 +3854,7 @@ export declare interface ScopeInterface extends ScopeConfiguration {
3449
3854
  */
3450
3855
  export declare class ScopeManager implements ScopeManagerInterface {
3451
3856
  #private;
3452
- constructor(on?: EmitterHooks<ScopeManagerEventMap>, error?: EmitterErrorHandler);
3857
+ constructor(options?: ScopeManagerOptions);
3453
3858
  get emitter(): EmitterInterface<ScopeManagerEventMap>;
3454
3859
  get count(): number;
3455
3860
  create(input: ScopeInput): ScopeInterface;
@@ -3461,43 +3866,43 @@ export declare class ScopeManager implements ScopeManagerInterface {
3461
3866
  }
3462
3867
 
3463
3868
  /**
3464
- * The push observation surface (§13) of a {@link ScopeManagerInterface} — analogous to
3869
+ * Maps the push observation surface of a {@link ScopeManagerInterface} — analogous to
3465
3870
  * {@link InstructionManagerEventMap}, but keyed by the minted `id` and carrying `create`
3466
3871
  * (a scope always mints, never overwrites) rather than `add`.
3467
3872
  *
3468
3873
  * @remarks
3469
3874
  * `create` carries the created {@link ScopeInterface}; `remove` carries the removed
3470
3875
  * scope's `id`; `clear` is a pure signal. The emitter isolates a listener throw and routes
3471
- * it to its `error` handler (§13). A `type` alias (§4.5) so it satisfies `EventMap` structurally.
3876
+ * it to its `error` handler. A `type` alias so it satisfies `EventMap` structurally.
3472
3877
  */
3473
3878
  export declare type ScopeManagerEventMap = {
3474
- /** A scope was created — the created scope. */
3879
+ /** Reports a scope created — the created scope. */
3475
3880
  readonly create: readonly [scope: ScopeInterface];
3476
- /** A scope was removed — its `id`. */
3881
+ /** Reports a scope removed — its `id`. */
3477
3882
  readonly remove: readonly [id: string];
3478
- /** Every scope was removed. */
3883
+ /** Reports every scope removed. */
3479
3884
  readonly clear: readonly [];
3480
3885
  };
3481
3886
 
3482
3887
  /**
3483
- * A registry of reusable {@link ScopeInterface}s keyed by their minted `id` — `create`
3888
+ * Registers reusable {@link ScopeInterface}s keyed by their minted `id` — `create`
3484
3889
  * mints + stores one (never overwrites), `scopes()` lists them in insertion order.
3485
3890
  *
3486
3891
  * @remarks
3487
- * - **Registry.** `create(input)` mints a scope (an `id` + the three allow-lists) and
3892
+ * - **Registry.** `create(input)` mints a scope (an `id` + the per-category allow-lists) and
3488
3893
  * stores it; `count` is how many are stored. `scope(id)` looks one up; `scopes()` lists
3489
3894
  * them in insertion order. (Keyed by minted `id`, not `name`, so two scopes may share a
3490
3895
  * `name` and `create` always adds.)
3491
- * - **Observable (§13).** The owned `emitter` ({@link ScopeManagerEventMap}) carries
3896
+ * - **Observable.** The owned `emitter` ({@link ScopeManagerEventMap}) carries
3492
3897
  * `create` / `remove` / `clear` for fire-and-forget observers; the emitter isolates a
3493
- * listener throw and routes it to its `error` handler (the `error` option, §13).
3898
+ * listener throw and routes it to its `error` handler (the `error` option).
3494
3899
  */
3495
3900
  export declare interface ScopeManagerInterface {
3496
3901
  readonly emitter: EmitterInterface<ScopeManagerEventMap>;
3497
3902
  readonly count: number;
3498
3903
  create(input: ScopeInput): ScopeInterface;
3499
3904
  scope(id: string): ScopeInterface | undefined;
3500
- /** Every scope, in insertion order. */
3905
+ /** Lists every scope, in insertion order. */
3501
3906
  scopes(): readonly ScopeInterface[];
3502
3907
  remove(id: string): boolean;
3503
3908
  remove(ids: readonly string[]): boolean;
@@ -3505,59 +3910,60 @@ export declare interface ScopeManagerInterface {
3505
3910
  }
3506
3911
 
3507
3912
  /**
3508
- * Options for `createScopeManager` — the reserved `on` hooks (§8): initial listeners for
3913
+ * Configures `createScopeManager` — the reserved `on` hooks: initial listeners for
3509
3914
  * the manager's {@link ScopeManagerEventMap}, wired at construction.
3510
3915
  */
3511
3916
  export declare interface ScopeManagerOptions {
3512
3917
  readonly on?: EmitterHooks<ScopeManagerEventMap>;
3513
- /** The emitter's listener-error handler (AGENTS §13) — a listener throw routes here, not to a domain event. */
3918
+ /** Holds the emitter's listener-error handler — a listener throw routes here, not to a domain event. */
3514
3919
  readonly error?: EmitterErrorHandler;
3515
3920
  }
3516
3921
 
3517
3922
  /**
3518
- * A slice of folded messages digested into a summary — the unit of compaction a
3923
+ * Holds a slice of folded messages digested into a summary — the unit of compaction a
3519
3924
  * {@link ConversationInterface} produces when it `compact`s its live tail.
3520
3925
  *
3521
3926
  * @remarks
3522
- * `summary` is the model-written digest of this slice (via the
3523
- * {@link ConversationSummarizer}); `messages` are the folded ORIGINALS, RETAINED in full so
3927
+ * `summary` is the model-written digest of this slice (through the
3928
+ * {@link ConversationSummaryHandler}); `messages` are the folded ORIGINALS, RETAINED in full so
3524
3929
  * `rehydrate` can pull them back and `search` can scan them (compaction shrinks the model
3525
3930
  * INPUT, never discards history).
3526
3931
  */
3527
- export declare interface SectionInterface {
3932
+ export declare interface Section {
3528
3933
  readonly id: string;
3529
- /** The model-written digest of this slice (its {@link ConversationSummarizer} output). */
3934
+ /** Holds the model-written digest of this slice (its {@link ConversationSummaryHandler} output). */
3530
3935
  readonly summary: string;
3531
- /** The folded original messages, RETAINED in full for `rehydrate` / `search`. */
3532
- readonly messages: readonly MessageInterface[];
3936
+ /** Retains the folded original messages in full for `rehydrate` / `search`. */
3937
+ readonly messages: readonly Message[];
3533
3938
  }
3534
3939
 
3535
3940
  /**
3536
- * Run one rehydrated agent and apply the partial-as-configurable-failure policy — the
3941
+ * Runs one rehydrated agent and applies the partial-as-configurable-failure policy — the
3537
3942
  * shared job-handler step BOTH `createAgentQueue` and `createAgentRunner` settle each job
3538
3943
  * through, so the policy can never diverge between them.
3539
3944
  *
3540
3945
  * @remarks
3541
3946
  * A turn that committed PARTIAL (a cancel — abort / budget / timeout) is by default a
3542
3947
  * FAILURE, so it THROWS an {@link import('./errors.js').AgentJobError} carrying the partial
3543
- * (the Queue's retries + a Runner's fail-fast then engage); with `allowPartial` it RESOLVES
3544
- * the partial as success instead. A natural finish ALWAYS resolves with its result.
3948
+ * (the Queue's retries + a Runner's fail-fast then engage); the `partial` policy RESOLVES
3949
+ * it as success instead. A natural finish ALWAYS resolves with its result.
3545
3950
  *
3546
3951
  * @param agent - The rehydrated {@link AgentInterface} to run to its {@link AgentResult}
3547
- * @param allowPartial - When `true`, a partial result resolves as success; when `false`
3548
- * (the default policy), a partial result throws an {@link AgentJobError}
3549
- * @returns The agent's {@link AgentResult} (a natural finish, or a partial when `allowPartial`)
3550
- * @throws {AgentJobError} When the run ended `partial` and `allowPartial` is `false`
3952
+ * @param partial - The partial policy. If `true`, a partial result resolves as success; if
3953
+ * `false` (the default policy), a partial result throws an {@link AgentJobError}
3954
+ * @returns The agent's {@link AgentResult} (a natural finish, or a partial one under the
3955
+ * `partial` policy)
3956
+ * @throws {AgentJobError} Thrown when the run ended partial and the `partial` policy is `false`
3551
3957
  *
3552
3958
  * @example
3553
3959
  * ```ts
3554
3960
  * const result = await settleAgentJob(registry.build(input, signal), false)
3555
3961
  * ```
3556
3962
  */
3557
- export declare function settleAgentJob(agent: AgentInterface, allowPartial: boolean): Promise<AgentResult>;
3963
+ export declare function settleAgentJob(agent: AgentInterface, partial: boolean): Promise<AgentResult>;
3558
3964
 
3559
3965
  /**
3560
- * A live event stream paired with the eventual settled result and a cancel — the
3966
+ * Pairs a live event stream with the eventual settled result and a cancel — the
3561
3967
  * generic pull/streaming handle a long-running operation hands back.
3562
3968
  *
3563
3969
  * @remarks
@@ -3573,7 +3979,7 @@ export declare interface StreamInterface<T, R> {
3573
3979
  readonly events: AsyncIterable<T>;
3574
3980
  readonly result: Promise<R>;
3575
3981
  /**
3576
- * Cancel the in-flight operation — fires its bound signal.
3982
+ * Cancels the in-flight operation — fires its bound signal.
3577
3983
  *
3578
3984
  * @param reason - An optional cancellation reason propagated to the signal
3579
3985
  */
@@ -3581,14 +3987,36 @@ export declare interface StreamInterface<T, R> {
3581
3987
  }
3582
3988
 
3583
3989
  /**
3584
- * The closing tag that ends a {@link THINK_OPEN} reasoning span. A span the stream never closes
3990
+ * Adds two {@link TokenUsage} values field by field — the running total an agent run keeps
3991
+ * across its provider calls.
3992
+ *
3993
+ * @remarks
3994
+ * Pure and total: the first call seeds the total (`running` `undefined` returns `next`
3995
+ * unchanged), later calls accumulate. No sanitization happens here — charge a provider's
3996
+ * reported usage through {@link sanitizeUsage} first.
3997
+ *
3998
+ * @param running - The total so far (`undefined` before the first usage-bearing call)
3999
+ * @param next - This call's reported usage
4000
+ * @returns The summed usage
4001
+ *
4002
+ * @example
4003
+ * ```ts
4004
+ * sumUsage(undefined, { prompt: 2, completion: 1, total: 3 }) // { prompt: 2, completion: 1, total: 3 }
4005
+ * sumUsage({ prompt: 2, completion: 1, total: 3 }, { prompt: 1, completion: 1, total: 2 })
4006
+ * // { prompt: 3, completion: 2, total: 5 }
4007
+ * ```
4008
+ */
4009
+ export declare function sumUsage(running: TokenUsage | undefined, next: TokenUsage): TokenUsage;
4010
+
4011
+ /**
4012
+ * Names the closing tag that ends a {@link THINK_OPEN} reasoning span. A span the stream never closes
3585
4013
  * (the model was cut off mid-reasoning) is treated as thinking to its end —
3586
4014
  * {@link import('./types.js').ThinkSplitterInterface.flush} settles it.
3587
4015
  */
3588
4016
  export declare const THINK_CLOSE = "</think>";
3589
4017
 
3590
4018
  /**
3591
- * The opening tag a {@link import('./ThinkSplitter.js').ThinkSplitter} recognizes as the start of
4019
+ * Names the opening tag a {@link import('./ThinkSplitter.js').ThinkSplitter} recognizes as the start of
3592
4020
  * an in-content reasoning span — the de-facto wire convention thinking models (qwen3, DeepSeek-R1
3593
4021
  * family) emit their chain-of-thought under when a daemon renders it inline instead of on a
3594
4022
  * separate wire field. Paired with {@link THINK_CLOSE}.
@@ -3596,10 +4024,10 @@ export declare const THINK_CLOSE = "</think>";
3596
4024
  export declare const THINK_OPEN = "<think>";
3597
4025
 
3598
4026
  /**
3599
- * The stream-stateful `<think>` separator — feeds raw content deltas through a tiny
3600
- * state machine that routes everything inside a `<think>…</think>` span to `thinking`
3601
- * and returns everything outside it as clean content, so a provider yields ONLY the
3602
- * answer and surfaces the reasoning as {@link import('./types.js').ProviderResult.thinking}.
4027
+ * Feeds raw content deltas through a tiny stream-stateful state machine that routes
4028
+ * everything inside a `<think>…</think>` span to `thinking` and returns everything outside
4029
+ * it as clean content, so a provider yields ONLY the answer and surfaces the reasoning as
4030
+ * {@link import('./types.js').ProviderResult.thinking}.
3603
4031
  *
3604
4032
  * @remarks
3605
4033
  * - **Cross-chunk tags.** A tag may arrive split across wire deltas (`'<thi'` then
@@ -3615,7 +4043,7 @@ export declare const THINK_OPEN = "<think>";
3615
4043
  * prefix cannot be recalled, so `content` is the authoritative accumulation). The
3616
4044
  * rule is ONE-SHOT: after any tag event a bare `</think>` is plain text.
3617
4045
  * - **Multiple spans** accumulate onto `thinking` in stream order. A nested-looking
3618
- * `<think>` inside an open span is just thinking text (no nesting is tracked — the
4046
+ * `<think>` inside an open span is thinking text (no nesting is tracked — the
3619
4047
  * first `</think>` closes the span), matching how the models emit it.
3620
4048
  * - **Unclosed span at stream end.** `flush()` routes the open span's tail (including
3621
4049
  * any held partial close tag) to `thinking` — a cut-off model was still reasoning.
@@ -3641,10 +4069,9 @@ export declare class ThinkSplitter implements ThinkSplitterInterface {
3641
4069
  }
3642
4070
 
3643
4071
  /**
3644
- * The stream-stateful `<think>` separator — splits a thinking model's in-content
3645
- * `<think>…</think>` reasoning spans away from the answer, delta by delta, so a
3646
- * provider yields ONLY clean content and surfaces the reasoning as
3647
- * {@link ProviderResult.thinking}.
4072
+ * Splits a thinking model's in-content `<think>…</think>` reasoning spans away from the
4073
+ * answer, delta by delta with per-stream state, so a provider yields ONLY clean content
4074
+ * and surfaces the reasoning as {@link ProviderResult.thinking}.
3648
4075
  *
3649
4076
  * @remarks
3650
4077
  * - **Stateful across deltas.** A tag may arrive SPLIT across wire chunks (`'<thi'`
@@ -3652,9 +4079,9 @@ export declare class ThinkSplitter implements ThinkSplitterInterface {
3652
4079
  * back until the next delta (or `flush`) disambiguates it, so a partial tag is
3653
4080
  * never leaked as content and never mis-eaten as thinking.
3654
4081
  * - **`split(delta)`** feeds one raw content delta and returns the CLEAN content to
3655
- * surface for it (possibly `''` — e.g. mid-think). Text inside a
4082
+ * surface for it (possibly `''` — for example mid-think). Text inside a
3656
4083
  * `<think>…</think>` span accumulates on `thinking`; multiple spans accumulate in
3657
- * order; a nested-looking `<think>` inside an open span is just thinking text (no
4084
+ * order; a nested-looking `<think>` inside an open span is thinking text (no
3658
4085
  * nesting — the first `</think>` closes).
3659
4086
  * - **The IMPLICIT leading open (the qwen3-template shape).** Some chat templates
3660
4087
  * PRE-SEED `<think>` into the prompt scaffold, so the wire stream begins
@@ -3675,27 +4102,27 @@ export declare class ThinkSplitter implements ThinkSplitterInterface {
3675
4102
  * one per call ({@link import('./factories.js').createThinkSplitter}).
3676
4103
  */
3677
4104
  export declare interface ThinkSplitterInterface {
3678
- /** The AUTHORITATIVE clean content accumulated so far (corrected across an implicit-open reclassification). */
4105
+ /** Holds the AUTHORITATIVE clean content accumulated so far (corrected across an implicit-open reclassification). */
3679
4106
  readonly content: string;
3680
- /** The reasoning text accumulated from every `<think>…</think>` span so far. */
4107
+ /** Holds the reasoning text accumulated from every `<think>…</think>` span so far. */
3681
4108
  readonly thinking: string;
3682
- /** Feed one raw delta; returns the clean (non-think) content to surface for it. */
4109
+ /** Feeds one raw delta; returns the clean (non-think) content to surface for it. */
3683
4110
  split(delta: string): string;
3684
- /** Settle the stream end — returns any held clean tail; an unclosed think span lands on `thinking`. */
4111
+ /** Settles the stream end — returns any held clean tail; an unclosed think span lands on `thinking`. */
3685
4112
  flush(): string;
3686
4113
  }
3687
4114
 
3688
4115
  /**
3689
- * The section header {@link import('./AgentContext.js').AgentContext}'s `build()` renders the
4116
+ * Names the section header {@link import('./AgentContext.js').AgentContext}'s `build()` renders the
3690
4117
  * ACTIVE workspace's TEXT files under — the leading line of the dedicated workspace block in the
3691
4118
  * system message, the carrier-split counterpart to the documents / images section headers.
3692
4119
  *
3693
4120
  * @remarks
3694
4121
  * `build()` OWNS the workspace render (a `Workspace` / `WorkspaceManager` stays file-focused — no
3695
- * `description` / `framing` getters), so this header lives here as the agents module's one
4122
+ * `open` / `format` getters), so this header lives here as the agents module's one
3696
4123
  * workspace-section framing constant rather than on a manager. Each workspace text file renders
3697
4124
  * beneath it as a fenced `` File: <path>\n```<language>\n<text>\n``` `` block — the SAME framing
3698
- * the documents section uses — placed just after the documents section in the system block.
4125
+ * the documents section uses — placed immediately after the documents section in the system block.
3699
4126
  */
3700
4127
  export declare const WORKSPACE_SECTION_HEADER = "## Workspace";
3701
4128