@orkestrel/agent 0.0.41 → 0.0.43

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.
@@ -25,18 +25,22 @@ import type { QueueContext } from '@orkestrel/queue';
25
25
  import type { QueueInterface } from '@orkestrel/queue';
26
26
  import type { QueueOptions } from '@orkestrel/queue';
27
27
  import type { QueueStoreInterface } from '@orkestrel/queue';
28
+ import { RawShape } from '@orkestrel/contract';
28
29
  import type { Result } from '@orkestrel/contract';
29
30
  import type { RunnerInterface } from '@orkestrel/workflow';
30
31
  import type { SchedulerInterface } from '@orkestrel/workflow';
31
32
  import { StringShape } from '@orkestrel/contract';
32
33
  import type { TableInterface } from '@orkestrel/database';
33
34
  import type { TokenUsage } from '@orkestrel/budget';
35
+ import type { ToolAnnotations } from '@orkestrel/tool';
34
36
  import type { ToolCall } from '@orkestrel/tool';
35
37
  import type { ToolDefinition } from '@orkestrel/tool';
36
38
  import type { ToolInterface } from '@orkestrel/tool';
37
39
  import type { ToolManagerInterface } from '@orkestrel/tool';
40
+ import type { ToolOptions } from '@orkestrel/tool';
38
41
  import type { ToolResult } from '@orkestrel/tool';
39
42
  import { UnionShape } from '@orkestrel/contract';
43
+ import type { WorkspaceInterface } from '@orkestrel/workspace';
40
44
  import type { WorkspaceManagerInterface } from '@orkestrel/workspace';
41
45
 
42
46
  /**
@@ -99,6 +103,25 @@ export declare class Agent implements AgentInterface {
99
103
  abort(reason?: unknown): void;
100
104
  }
101
105
 
106
+ /**
107
+ * Lists the members `AgentOptions` declares, frozen — the keys the `Agent` constructor admits.
108
+ *
109
+ * @remarks
110
+ * The constructor passes the list to `refuseOptionKeys` of `@orkestrel/contract`, so an own
111
+ * enumerable member outside it refuses with a `ContractError` coded `'structure'`.
112
+ */
113
+ export declare const AGENT_OPTION_KEYS: readonly ["on", "error", "system", "tools", "instructions", "skills", "memos", "workspaces", "scope", "limit", "timeout", "budget", "allowance", "scheduler", "signal", "authority", "conversations", "window", "strict", "select", "builtins", "workspace"];
114
+
115
+ /**
116
+ * Lists the members `AgentRunOptions` declares, frozen — the keys the `stream` and `generate`
117
+ * methods admit.
118
+ *
119
+ * @remarks
120
+ * The `stream` method passes the list to `refuseOptionKeys` of `@orkestrel/contract`, so an own
121
+ * enumerable member outside it refuses with a `ContractError` coded `'structure'`.
122
+ */
123
+ export declare const AGENT_RUN_KEYS: readonly ["think", "schema", "limit", "timeout", "budget", "allowance", "signal", "conversation", "prompt", "scope", "workspace"];
124
+
102
125
  /** Carries a page's answer to one `ask` frame; only `approved: true` approves. */
103
126
  export declare interface AgentAnswer {
104
127
  readonly id: string;
@@ -107,8 +130,8 @@ export declare interface AgentAnswer {
107
130
 
108
131
  /** Validates and projects a page's answers to `ask` frames at a JSON wire boundary. */
109
132
  export declare const agentAnswerContract: ContractInterface<Readonly<{
110
- id: string;
111
- approved: boolean;
133
+ id: string;
134
+ approved: boolean;
112
135
  } & {}>>;
113
136
 
114
137
  /**
@@ -123,6 +146,35 @@ id: StringShape;
123
146
  approved: BooleanShape;
124
147
  }, boolean | ContractShape>;
125
148
 
149
+ /**
150
+ * Names a tool the agent serves itself: `load` and `unload` show and hide a skill, `memo` reads a
151
+ * memo, `remember` writes one, and `switch` selects a workspace.
152
+ *
153
+ * @remarks
154
+ * Each is enabled through {@link AgentOptions.builtins}, and each passes the turn's ceiling and the
155
+ * agent's authority as any tool does.
156
+ */
157
+ export declare type AgentBuiltin = 'load' | 'unload' | 'memo' | 'remember' | 'switch';
158
+
159
+ /**
160
+ * Carries what an agent run hands each tool call as `ToolContext.caller`: the workspace the run acts
161
+ * on and the paths it reaches there.
162
+ *
163
+ * @remarks
164
+ * The agent builds one for each call as the call starts, from the view of the request the model
165
+ * answered and the ceiling at that moment, the context scope intersected with the run scope. Both
166
+ * keys are always present, so a run that shows no workspace or states no `files` list says so with
167
+ * `undefined` rather than an omitted member. `ToolContext.caller` is unverified by contract and can
168
+ * reach a handler from a wire, so read it through {@link isAgentCaller} and accept its `workspace`
169
+ * only as the very instance your own registry holds under that id.
170
+ */
171
+ export declare interface AgentCaller {
172
+ /** Holds the workspace the run acts on: the one the turn's request rendered, while the ceiling admits it at the call. */
173
+ readonly workspace: WorkspaceInterface | undefined;
174
+ /** Lists the paths the run reaches in that workspace: the live ceiling's `files` list at the call (`undefined` ⇒ every path, `[]` ⇒ none). */
175
+ readonly files: readonly string[] | undefined;
176
+ }
177
+
126
178
  /**
127
179
  * Represents a streamed step of an agent turn — the union the loop yields as it runs, discriminated
128
180
  * by the `category` of step it carries, and the pull surface beside the push {@link AgentEventMap}.
@@ -191,8 +243,9 @@ export declare function agentChunkToFrame(chunk: AgentChunk): AgentFrame | undef
191
243
  * {@link ConversationManagerInterface} message source whose active conversation is `messages`, the
192
244
  * {@link ToolManagerInterface} registry, and an active {@link ScopeInterface} changed through
193
245
  * {@link AgentContextInterface.apply}. `build()` folds the system prompt, the scoped instructions,
194
- * and the skills index into one system message, the memos index and the active workspace's text into
195
- * one `user` context message after it, then the conversation, and never reads `tools`.
246
+ * the skills index, and the shown skills' bodies into one system message, the memos index and the
247
+ * rendered workspace's text into one `user` context message after it, then the conversation, and
248
+ * never reads `tools`.
196
249
  *
197
250
  * @remarks
198
251
  * - **Composition.** `system` is the optional system prompt; `instructions` / `skills` / `memos` /
@@ -211,40 +264,43 @@ export declare function agentChunkToFrame(chunk: AgentChunk): AgentFrame | undef
211
264
  * reference, no duplication), and `build()` with no selection folds that conversation's `view()`
212
265
  * (its per-section summaries + live tail) as the authoritative message inclusion — the scope does
213
266
  * not filter the conversation (it owns inclusion through compaction; scope filters only
214
- * instructions / skills / memos / tools / workspace files). An agent run binds a conversation at
267
+ * instructions / skills / memos / tools / workspace files / workspaces). An agent run binds a conversation at
215
268
  * its call, the active one unless the run names another, and builds through a selection over that
216
269
  * conversation, so `conversations.switch(id)` sets the next run's default at any moment and never
217
270
  * moves a live run; `select(conversation, request, signal)` checks the conversation it is given.
218
271
  * - **`build()` — the scoped assembly + the format cascade.** It folds, in order,
219
272
  * the system prompt, the scope-filtered instructions (a block: the section's `open` text,
220
273
  * each item's rendering, then any `close` text), then the scope-filtered skills index (a block
221
- * whose entries join with a single newline) into one leading `system` message (prepended only
222
- * when at least one part exists), then the scope-filtered memos index (the same block) and the
223
- * active workspace's text files into one `user` context message (present only when the memos or
224
- * workspace section renders), then
274
+ * whose entries join with a single newline), then the shown skills' bodies, into one leading
275
+ * `system` message (prepended only when at least one part exists), then the scope-filtered memos
276
+ * index (the same block), the listed workspace ids, and the rendered workspace's text files into
277
+ * one `user` context message (present only when one of those sections renders), then
225
278
  * appends the active conversation's `view()` (the conversation owns message inclusion through
226
279
  * compaction — the scope does not filter the conversation). The instruction manager resolves
227
280
  * each `open` / item / `close` most-specific-first: `open` = manager-options-override >
228
281
  * built-in; per item = item-override > manager-options-override > built-in; `close` =
229
282
  * manager-options-override (no built-in ⇒ no closing line when unset) (see
230
283
  * {@link AgentContextInterface.build}). With no override set, each section is its built-in
231
- * header + items, no closing line. The active workspace's scoped-in image files' `base64` payload is attached to
284
+ * header + items, no closing line. The rendered workspace's scoped-in image files' `base64` payload is attached to
232
285
  * the last user message (a vision provider reads images off a user turn); when no user message
233
286
  * exists the attachment is skipped. Built fresh each call (recomputed, never cached), so it
234
- * always reflects the current managers / messages / scope / active workspace; it never mutates a
287
+ * always reflects the current managers / messages / scope / workspaces; it never mutates a
235
288
  * manager or the stored messages. `build(selection)` adds at most one `system` message of its own
236
289
  * and reads the selection's messages as conversation parts without a role check; the select path
237
290
  * refuses a selected `system` role as a `'ROLE'` fault over `view()`; a host's direct
238
291
  * `build(selection)` is host-trusted, and a conversation a host implements itself whose `view()`
239
292
  * holds a `system` message is read as host-trusted too.
240
- * - **The active workspace, rendered by carrier — the sole document/image context.**
241
- * `workspaces.active` (when set) has its {@link import('@orkestrel/workspace').FileInterface} values scope-filtered by `scope.files`,
293
+ * - **The rendered workspace, by carrier — the sole document/image context.**
294
+ * The rendered workspace has its {@link import('@orkestrel/workspace').FileInterface} values scope-filtered by `scope.files`,
242
295
  * then split: text files fold into a dedicated `## Workspace` section (fenced reference blocks)
243
296
  * in the context message — a `user` message with a minted id, never stored — and image files'
244
297
  * `base64` payload attaches to the last user message of the conversation, never to the context
245
298
  * message. The `system` message holds host-authored text alone: the system prompt, the
246
- * instructions, and the skills index. Active-only — never the other registered workspaces; with no
247
- * active workspace nothing renders for workspaces. `build()` owns this render (a `Workspace` /
299
+ * instructions, the skills index, and last the bodies of the skills `options.disclosure` shows.
300
+ * One workspace renders: the one `options.disclosure` selects, else the active one, and only
301
+ * while the scope's `workspaces` list admits it; with neither, nothing renders for workspaces.
302
+ * `options.switchable` adds the admitted workspace ids to the context message, after the memos
303
+ * index. `build()` never moves the active workspace, and it owns this render (a `Workspace` /
248
304
  * `WorkspaceManager` stays file-focused).
249
305
  * - **Tools are structural, not in the prompt.** The registry is advertised to the provider
250
306
  * through `tools.definitions()` (scope-filtered by the loop), never serialized into the
@@ -273,8 +329,8 @@ export declare class AgentContext implements AgentContextInterface {
273
329
  get tools(): ToolManagerInterface;
274
330
  get scope(): ScopeInterface | undefined;
275
331
  apply(scope: ScopeInterface | undefined): void;
276
- select(conversation: ConversationInterface, request: Message, signal: AbortSignal): Promise<Selection> | undefined;
277
- build(selection?: Selection): readonly Message[];
332
+ select(conversation: ConversationInterface, request: Message, signal: AbortSignal, scope?: ScopeInterface): Promise<Selection> | undefined;
333
+ build(options?: ContextBuildOptions): readonly Message[];
278
334
  }
279
335
 
280
336
  /**
@@ -286,12 +342,14 @@ export declare class AgentContext implements AgentContextInterface {
286
342
  * (`instructions` / `skills` / `memos` / `workspaces` / `conversations`), `messages` (the active
287
343
  * conversation's live tail, satisfying {@link import('../conversations/index.js').MessageManagerInterface}), and the current `scope`
288
344
  * (the active {@link ScopeInterface} filter, or `undefined` for no filtering). `build()` folds the
289
- * system prompt, the scoped instructions, and the scoped skills index into one leading `system`
290
- * message (under each manager's `open`, each item through its `render`), renders the scoped memos
291
- * index and the active workspace's scope-filtered text files (fenced reference blocks) into one
292
- * `user` context message after it, and appends the active conversation's `view()`, attaching the active workspace's scope-filtered image files'
293
- * `base64` payload to the last user message. The
294
- * active workspace is the sole document/image context. Tools are advertised to the provider
345
+ * system prompt, the scoped instructions, the scoped skills index, and the bodies of the skills
346
+ * its `disclosure` option shows into one leading `system` message (under each manager's `open`,
347
+ * each item through its `render`, the bodies last), renders the scoped memos index, the admitted
348
+ * workspace ids when `switchable` is `true`, and the rendered workspace's scope-filtered text files
349
+ * (fenced reference blocks) into one `user` context message after it, and appends the active
350
+ * conversation's `view()`, attaching the rendered workspace's scope-filtered image files' `base64`
351
+ * payload to the last user message. The rendered workspace is the one `disclosure` names, else
352
+ * the active one, and it is the sole document/image context. Tools are advertised to the provider
295
353
  * structurally (through `tools.definitions()`, scope-filtered by the loop), not serialized into
296
354
  * the prompt, so they never appear in the output of the `build()` method. The context managers are observable
297
355
  * (each through its own `emitter` property); the context itself is event-free.
@@ -304,13 +362,14 @@ export declare interface AgentContextInterface {
304
362
  /** Holds the always-present memo set whose index `build()` renders in the `user` context message. */
305
363
  readonly memos: MemoManagerInterface;
306
364
  /**
307
- * Holds the {@link WorkspaceManagerInterface} whose active workspace `build()` renders by carrier —
308
- * its text files folded into the `user` context message (fenced reference blocks) and its image files'
309
- * `base64` payload attached to the last user message. The active workspace is the sole
310
- * document/image context. Always present (a fresh empty manager when none was supplied).
311
- * `build()` reads its `active` (and the active workspace's `files()`) fresh each call. With no
312
- * active workspace, nothing is rendered for workspaces. Active-only — never the other registered
313
- * workspaces.
365
+ * Holds the {@link WorkspaceManagerInterface} one of whose workspaces `build()` renders by
366
+ * carrier — its text files folded into the `user` context message (fenced reference blocks) and
367
+ * its image files' `base64` payload attached to the last user message. That workspace is the one
368
+ * the `disclosure` build option names, else the active one, and it renders only while the
369
+ * scope's `workspaces` list admits it; it is the sole document/image context. Always present (a
370
+ * fresh empty manager when none was supplied). `build()` reads the registry and the workspace's
371
+ * `files()` fresh each call, and never moves `active`. With no workspace to render, nothing is
372
+ * rendered for workspaces.
314
373
  */
315
374
  readonly workspaces: WorkspaceManagerInterface;
316
375
  /**
@@ -355,8 +414,8 @@ export declare interface AgentContextInterface {
355
414
  */
356
415
  apply(scope: ScopeInterface | undefined): void;
357
416
  /**
358
- * Runs the selection handler for one request — the active scope's `select`, else the agent
359
- * default — and checks that the conversation did not change under it.
417
+ * Runs the selection handler for one request — the run scope's `select`, else the active
418
+ * scope's, else the agent default — and checks that the conversation did not change under it.
360
419
  *
361
420
  * @remarks
362
421
  * Resolves the handler once per call. With no handler in either home it returns `undefined`
@@ -374,35 +433,44 @@ export declare interface AgentContextInterface {
374
433
  * @param conversation - The conversation the handler selects over and the check compares
375
434
  * @param request - The user message the run serves
376
435
  * @param signal - The run's abort signal, passed to the handler
436
+ * @param scope - The run's scope, whose `select` runs in place of the active scope's; omitted ⇒ none
377
437
  * @returns The pending {@link Selection}, or `undefined` when no handler is set
378
438
  *
379
439
  * @example
380
440
  * ```ts
381
441
  * const request = context.messages.add({ role: 'user', content: 'Summarize the ticket.' })
382
442
  * const selection = await context.select(context.messages, request, new AbortController().signal)
383
- * context.build(selection)
443
+ * context.build({ selection })
384
444
  * ```
385
445
  */
386
- select(conversation: ConversationInterface, request: Message, signal: AbortSignal): Promise<Selection> | undefined;
446
+ select(conversation: ConversationInterface, request: Message, signal: AbortSignal, scope?: ScopeInterface): Promise<Selection> | undefined;
387
447
  /**
388
448
  * Builds the provider input for the next turn: a leading `system` message folding the
389
- * prompt, the scope-filtered instructions, and the scope-filtered skills index (each section's
390
- * header and each item's rendering resolved through the format cascade), then one `user` context
391
- * message holding the scope-filtered memos index before the active workspace's scope-filtered
392
- * (`scope.files`) text files as fenced reference blocks in a
393
- * `## Workspace` section, then the active conversation's `view()`, or the selection's
394
- * `messages` when a selection is passed, with the active workspace's image files' `base64`
395
- * payload attached to the last user message. With no override set, each section renders on its
396
- * manager's built-in framing. The `system` message is prepended only when some part of it
397
- * exists, the context message only when the memos or workspace section renders, the workspace render
398
- * covers the active workspace alone, tools are advertised structurally rather than in the
399
- * prompt, and the input is built fresh on each call.
449
+ * prompt, the scope-filtered instructions, the scope-filtered skills index (each section's
450
+ * header and each item's rendering resolved through the format cascade), and last the bodies of
451
+ * the skills `disclosure` shows under `## Loaded skills`, then one `user` context message holding
452
+ * the scope-filtered memos index, the admitted workspace ids under `## Workspaces` when
453
+ * `switchable` is `true`, and the rendered workspace's scope-filtered (`scope.files`) text files
454
+ * as fenced reference blocks in a `## Workspace` section, then the active conversation's
455
+ * `view()`, or the selection's `messages` when a selection is passed, with the rendered
456
+ * workspace's image files' `base64` payload attached to the last user message. With no override
457
+ * set, each section renders on its manager's built-in framing. The `system` message is prepended
458
+ * only when some part of it exists, the context message only when one of its sections renders,
459
+ * one workspace renders, tools are advertised structurally rather than in the prompt, and the
460
+ * input is built fresh on each call.
400
461
  *
401
462
  * @remarks
402
- * **The active workspace (rendered by carrier) — the sole document/image context.** When
403
- * `workspaces.active` is set, its
463
+ * **The shown bodies.** Each name `disclosure.skills` lists renders once, in the given order,
464
+ * as `### name` and the skill's `content`, when the skill registry holds it and the scope's
465
+ * `skills` list admits it; a blank body renders nothing, and an unregistered or excluded name
466
+ * renders nothing.
467
+ *
468
+ * **The rendered workspace (by carrier) — the sole document/image context.** It is the one
469
+ * `disclosure.workspace` names, else `workspaces.active`, and it renders only while the scope's
470
+ * `workspaces` list admits it; an unregistered `disclosure.workspace` renders none, and the build
471
+ * never moves `workspaces.active`. Its
404
472
  * {@link import('@orkestrel/workspace').WorkspaceInterface.files} are filtered by
405
- * `scope.files` (a three-way allow-list; `undefined` ⇒ all active files), then split by
473
+ * `scope.files` (a three-way allow-list; `undefined` ⇒ all its files), then split by
406
474
  * carrier: text files ({@link import('@orkestrel/workspace').isTextContent}) render into a dedicated
407
475
  * `## Workspace` section in the context message — a `user` message with a minted id that
408
476
  * follows the system message and is never stored — each a fenced
@@ -410,8 +478,7 @@ export declare interface AgentContextInterface {
410
478
  * the longest backtick run in the text, and never shorter than three; binary files whose MIME
411
479
  * starts with `image/` have their `base64` payload
412
480
  * attached to the last user message (a vision provider reads images off a user turn).
413
- * Active-only — never the other registered workspaces; with no active workspace nothing is
414
- * rendered for workspaces.
481
+ * One workspace renders at most; with none to render, nothing is rendered for workspaces.
415
482
  *
416
483
  * **The format cascade.** Each manager section frames as `[open, ...items.map(render), close]`
417
484
  * (empty / absent slots dropped, the survivors `\n\n`-joined), reading the manager's `open`,
@@ -437,12 +504,15 @@ export declare interface AgentContextInterface {
437
504
  * handler that adds text for the model, such as a ledger's records, writes it into a message of
438
505
  * `selection.messages`.
439
506
  *
440
- * @param selection - The selection whose `messages` replace `view()`; omitted ⇒ `view()`
441
- * @returns The scoped conversation, prefixed by the context message when the scoped memos or the
442
- * active workspace's scoped text files are non-empty, and before it by the assembled `system`
443
- * message when the prompt, the scoped instructions, or the scoped skills are non-empty
507
+ * @param options - The selection whose `messages` replace `view()`, a run's scope intersected
508
+ * with the active one, what the build shows, and whether it lists the workspace ids; omitted ⇒
509
+ * `view()` under the active scope, with no body and the active workspace
510
+ * @returns The scoped conversation, prefixed by the context message when the scoped memos, the
511
+ * listed workspace ids, or the rendered workspace's scoped text files are non-empty, and before
512
+ * it by the assembled `system` message when the prompt, the scoped instructions, the scoped
513
+ * skills, or the shown bodies are non-empty
444
514
  */
445
- build(selection?: Selection): readonly Message[];
515
+ build(options?: ContextBuildOptions): readonly Message[];
446
516
  }
447
517
 
448
518
  /**
@@ -464,8 +534,8 @@ export declare interface AgentContextInterface {
464
534
  * {@link ConversationManagerInterface} is created and a default conversation is added (so
465
535
  * `messages` is always defined). All default to a context with no system prompt, empty registries,
466
536
  * no scope, and a fresh conversation registry holding one default conversation. `select` is the
467
- * agent's default {@link SelectionHandler}, which the active scope's `select` overrides; omitted,
468
- * `select()` returns `undefined` while the active scope holds no handler.
537
+ * agent's default {@link SelectionHandler}, which the active scope's `select` and a run scope's
538
+ * `select` override; omitted, `select()` returns `undefined` while neither scope holds a handler.
469
539
  */
470
540
  export declare interface AgentContextOptions {
471
541
  readonly system?: string;
@@ -482,11 +552,11 @@ export declare interface AgentContextOptions {
482
552
  readonly memos?: MemoManagerInterface;
483
553
  /**
484
554
  * Reuses a pre-built {@link WorkspaceManagerInterface}; a fresh empty one is created when
485
- * omitted (so `context.workspaces` is always present). `build()` renders the active workspace's
486
- * files by carrier — text files into the `user` context message after the system message
487
- * (fenced), image files attached to the last user message. The registry is structural; change
488
- * its active workspace through
489
- * `workspaces.switch(id)`. The active workspace is the sole document/image context.
555
+ * omitted (so `context.workspaces` is always present). `build()` renders one workspace's files
556
+ * by carrier — the one its `disclosure` option names, else the active one — text files into the
557
+ * `user` context message after the system message (fenced), image files attached to the last user
558
+ * message. That one workspace is the sole document/image context. The registry is structural;
559
+ * change its active workspace through `workspaces.switch(id)`.
490
560
  */
491
561
  readonly workspaces?: WorkspaceManagerInterface;
492
562
  /** Sets the initial active scope (the build-time filter); `undefined` ⇒ no filtering. */
@@ -498,20 +568,43 @@ export declare interface AgentContextOptions {
498
568
  * names no conversation — is always defined. `build()` folds the active conversation's
499
569
  * `view()` (the per-section summaries + the live tail), or a passed selection's `messages`.
500
570
  * The scope's filters never touch messages; message inclusion is the conversation's through
501
- * compaction and, when a handler is set, the selection's. A scope change reaches the prompt at
502
- * the next build or select site (run entry, the pre-first-turn compaction fold, or a compaction
503
- * rebuild) and the tools at the next turn's snapshot. The registry is structural; change its
571
+ * compaction and, when a handler is set, the selection's. In an agent run, a scope change reaches
572
+ * the tools and the head at the next turn's snapshot, where a changed list rebuilds the head, and
573
+ * a `select` change waits for the next build or select site (run entry, the pre-first-turn
574
+ * compaction fold, or a compaction rebuild). The registry is structural; change its
504
575
  * active conversation through the manager's `switch(id)`, which sets the next run's default and
505
576
  * never moves a live run.
506
577
  */
507
578
  readonly conversations?: ConversationManagerInterface;
508
579
  /**
509
- * Holds the agent's default selection handler; the active scope's `select` overrides it.
510
- * Omitted ⇒ with no scope handler either, `build()` folds the active conversation's `view()`.
580
+ * Holds the agent's default selection handler; the active scope's `select` overrides it, and a
581
+ * run scope's `select` overrides both. Omitted ⇒ with no scope handler either, `build()` folds the
582
+ * active conversation's `view()`.
511
583
  */
512
584
  readonly select?: SelectionHandler;
513
585
  }
514
586
 
587
+ /**
588
+ * Holds what one run shows within its ceiling: the loaded skills and the selected workspace.
589
+ *
590
+ * @remarks
591
+ * The agent loop derives one for each turn and passes it to `build`: the skills from the
592
+ * conversation's stored calls of the built-ins a run enables, and the workspace from the thread's
593
+ * last `switch`, else the `workspace` option of the run or the agent. Every read of it passes the
594
+ * ceiling and the registries, so a name that is not registered or not admitted shows nothing.
595
+ *
596
+ * @example
597
+ * ```ts
598
+ * const disclosure: AgentDisclosure = { skills: ['refunds'], workspace: 'orders' }
599
+ * ```
600
+ */
601
+ export declare interface AgentDisclosure {
602
+ /** Names the loaded skills, in load order. */
603
+ readonly skills: readonly string[];
604
+ /** Names the selected workspace; omitted ⇒ the registry's active workspace. */
605
+ readonly workspace?: string;
606
+ }
607
+
515
608
  /**
516
609
  * Reports an `ask` on an authority that has no approver or that its approver refuses, an authority missing its fallback or a rule's verdict, tools set with no authority, a run sharing accounting or a conversation with a live run, a `limit` that is not a positive safe integer, a name absent from a registry pool, a strict run's answer that fails its schema, or a strict run whose request exceeds its window. Agent construction, the `stream` and `generate` methods, and registry accessors throw synchronously, before returning a handle or promise; a `'WINDOW'` refusal rejects the run's `result` instead, and an `'APPROVER'` refusal rejects the promise the `ask` method of an `Authority` or the `ask` handler of an `Approver` returns. Await the call inside `try`/`catch` to catch it.
517
610
  *
@@ -523,6 +616,9 @@ export declare interface AgentContextOptions {
523
616
  * `'AUTHORITY'` reports an `Authority` built with no valid `fallback`, a rule with no valid `verdict`
524
617
  * (its `context` names the `rule` index), and an agent built with `tools` and no `authority`. Each
525
618
  * throws at construction, with the options a host passes to correct it in the message.
619
+ * `'BUILTIN'` reports a `builtins` entry that is not a built-in or repeats one, `unload` enabled
620
+ * without `load`, and a tool manager holding a tool under an enabled built-in's name, each thrown
621
+ * at construction.
526
622
  * `'CONCURRENCY'` reports a run started while another run on the same agent is live, when the
527
623
  * agent carries a `window` (a shared context budget) or when the run's effective `budget` or
528
624
  * `allowance` is an instance a live run holds — the second run's `start()` would replace that
@@ -531,18 +627,18 @@ export declare interface AgentContextOptions {
531
627
  * `agent` id, and the `conversation` id for a shared conversation. For concurrent runs, use
532
628
  * separate agents, or one agent with no `window`, distinct budget and allowance instances per
533
629
  * run, and a distinct conversation per run.
534
- * `'LIMIT'` reports a construction or per-run `limit` that is not a positive safe integer,
535
- * including one a rehydrated job carries into `build`. `'REGISTRY'` reports a rehydration name
536
- * absent from its registry pool, on `provider` / `tool` / `authority` / `scheduler` / `build`,
537
- * whose `context` names the `category` and the `name`, and a job that names `tools` and no
538
- * `authority` at `build`, whose `context` names the `tools`. `'WINDOW'` reports a `strict` run whose
630
+ * `'LIMIT'` reports a construction or per-run `limit` that is not a positive safe integer.
631
+ * `'REGISTRY'` reports a rehydration name absent from its registry pool, on `provider` / `tool` /
632
+ * `authority` / `scheduler` / `build`, whose `context` names the `category` and the `name`, and a
633
+ * job `build` refuses as a record, whose `context` holds the contract's `faults` or the
634
+ * `refusals` lines `collectJobRefusals` returns. `'WINDOW'` reports a `strict` run whose
539
635
  * complete provider request is still over the `window` budget, equal to its `max` included, after
540
636
  * the one permitted fold or with no fold possible; it settles the run `error` before the provider
541
637
  * is called, and its `context` holds the `agent` id, the measured `consumed`, and the window `max`.
542
638
  * Narrow a caught value with {@link isAgentError} and branch on `error.code`.
543
639
  */
544
640
  export declare class AgentError extends Error {
545
- /** Names the machine-readable condition — `'APPROVER'`: an `ask` on an authority that has no approver, or one its approver refuses; `'AUTHORITY'`: an authority missing its fallback or a rule's verdict, or tools set with no authority; `'CONCURRENCY'`: a run sharing accounting or a conversation with a live run; `'LIMIT'`: a `limit` that is not a positive safe integer; `'REGISTRY'`: a rehydration name absent from its registry pool; `'WINDOW'`: a strict run whose complete request is still over its window budget. */
641
+ /** Names the machine-readable condition — `'APPROVER'`: an `ask` on an authority that has no approver, or one its approver refuses; `'AUTHORITY'`: an authority missing its fallback or a rule's verdict, or tools set with no authority; `'BUILTIN'`: a built-in list the agent cannot serve; `'CONCURRENCY'`: a run sharing accounting or a conversation with a live run; `'LIMIT'`: a `limit` that is not a positive safe integer; `'REGISTRY'`: a rehydration name absent from its registry pool; `'WINDOW'`: a strict run whose complete request is still over its window budget. */
546
642
  readonly code: AgentErrorCode;
547
643
  /** Holds the values that locate the failure, such as the `agent` id of a refused run, or `undefined` when none were supplied. */
548
644
  readonly context: Readonly<Record<string, unknown>> | undefined;
@@ -556,8 +652,8 @@ export declare class AgentError extends Error {
556
652
  constructor(code: AgentErrorCode, message: string, options?: CodedErrorOptions);
557
653
  }
558
654
 
559
- /** Names the machine-readable agent approver, authority, concurrency, limit, registry, schema, and window failures. */
560
- export declare type AgentErrorCode = 'APPROVER' | 'AUTHORITY' | 'CONCURRENCY' | 'LIMIT' | 'REGISTRY' | 'SCHEMA' | 'WINDOW';
655
+ /** Names the machine-readable agent approver, authority, built-in, concurrency, limit, registry, schema, and window failures. */
656
+ export declare type AgentErrorCode = 'APPROVER' | 'AUTHORITY' | 'BUILTIN' | 'CONCURRENCY' | 'LIMIT' | 'REGISTRY' | 'SCHEMA' | 'WINDOW';
561
657
 
562
658
  /**
563
659
  * Maps the push observation surface of an {@link AgentInterface} — the lifecycle, usage, and tool
@@ -663,6 +759,21 @@ export declare type AgentEventMap = {
663
759
  * fire none.
664
760
  */
665
761
  readonly select: readonly [selection: Selection];
762
+ /**
763
+ * Reports the exact request a turn dispatches, with the turn's `index` and the conversation its
764
+ * run is bound to, once a turn after the loop admits the request and before the provider receives
765
+ * it, so after a compaction fold it carries the rebuilt request. The request object and its
766
+ * `messages` and `tools` arrays are frozen; each message, `options`, and each definition is a
767
+ * shared object, so a listener is host code that reads the request and never writes to it. A
768
+ * request whose turn advertises no tool carries no `tools` member, and a turn cancelled before
769
+ * its request is composed emits none. A run aborted while a turn's `request` listeners run sends
770
+ * nothing for that turn: the provider receives no call for it, and the turn ends as a cancel.
771
+ */
772
+ readonly request: readonly [
773
+ index: number,
774
+ request: ProviderRequest,
775
+ conversation: ConversationInterface
776
+ ];
666
777
  };
667
778
 
668
779
  /**
@@ -677,6 +788,17 @@ export declare type AgentEventMap = {
677
788
  * awaited inline, so a bounded runner frees the parent's slot for them. `createAgentRunner`
678
789
  * creates one instance per runner and binds its `execute` method as the runner's handler.
679
790
  *
791
+ * A child job runs within its parent. Before a unit spawns or runs, on every attempt, the
792
+ * `execute` method walks the whole tree under it through the `scanJobTree` helper and refuses the
793
+ * unit when any job exceeds its own parent on `tools`, `builtins`, `scope`, `authority`,
794
+ * `provider`, `scheduler`, `limit`, `timeout`, or `budget`, or when a job is malformed or its build
795
+ * would refuse it (the lines `collectJobRefusals` returns), so nothing in a refused tree spawns, builds,
796
+ * or runs. A child's `workspace` is free, because it renders nothing its own `scope`
797
+ * omits. Each child is held within its parent alone, so the children of one parent can together
798
+ * spend more than it. A job that needs another provider, another authority, a skill, memo,
799
+ * workspace, or built-in its parent lacks, or more room than its parent is a root job the host
800
+ * enqueues.
801
+ *
680
802
  * @example
681
803
  * ```ts
682
804
  * import type { AgentJobInput, ProviderInterface } from '@orkestrel/agent'
@@ -701,11 +823,20 @@ export declare class AgentFanout {
701
823
  */
702
824
  constructor(registry: AgentRegistryInterface, partial: boolean);
703
825
  /**
704
- * Executes one unit: spawns its declared children unless an earlier attempt of the unit already
705
- * did, then runs the rehydrated agent and settles it under the partial policy.
826
+ * Executes one unit: refuses its tree when a job in it is malformed or exceeds its parent, spawns
827
+ * its declared children unless an earlier attempt of the unit already did, then runs the
828
+ * rehydrated agent and settles it under the partial policy.
829
+ *
830
+ * @remarks
831
+ * The check runs on every attempt, before the unit spawns or runs, and throws synchronously. The
832
+ * error's message opens with the rule each kind of finding breaks, a refused job's rule when a
833
+ * finding opens with `JOB_REFUSAL_PREFIX` and the within-parent rule when a finding names an
834
+ * exceeded member, then lists every finding, one a line. Its `context.findings` holds the same
835
+ * findings in walk order.
706
836
  *
707
837
  * @param controller - The runner controller for this unit's attempt
708
838
  * @returns The settled agent result of the unit
839
+ * @throws {AgentError} Thrown with code `'REGISTRY'` when a job in the unit's tree is malformed or exceeds its parent, or when the registry cannot rehydrate the unit
709
840
  * @throws {AgentJobError} Thrown when the run ended partial and the partial policy is `false`
710
841
  */
711
842
  execute(controller: ControllerInterface<AgentJobInput, AgentResult>): Promise<AgentResult>;
@@ -761,45 +892,45 @@ export declare type AgentFrame = {
761
892
 
762
893
  /** Validates and projects agent frames at a JSON wire boundary. */
763
894
  export declare const agentFrameContract: ContractInterface<Readonly<{
764
- category: "token";
765
- content: string;
895
+ category: "token";
896
+ content: string;
766
897
  } & {}> | Readonly<{
767
- category: "think";
768
- content: string;
898
+ category: "think";
899
+ content: string;
769
900
  } & {}> | Readonly<{
770
- category: "tool";
771
- success: true;
772
- name: string;
901
+ category: "tool";
902
+ success: true;
903
+ name: string;
773
904
  } & {}> | Readonly<{
774
- category: "tool";
775
- success: false;
905
+ category: "tool";
906
+ success: false;
776
907
  } & {}> | Readonly<{
777
- category: "usage";
778
- usage: Readonly<{
779
- prompt: number;
780
- completion: number;
781
- total: number;
782
- } & {}>;
783
- estimate: number;
908
+ category: "usage";
909
+ usage: Readonly<{
910
+ prompt: number;
911
+ completion: number;
912
+ total: number;
913
+ } & {}>;
914
+ estimate: number;
784
915
  } & {}> | Readonly<{
785
- category: "ask";
786
- id: string;
787
- name: string;
788
- zone: string;
789
- arguments: string;
916
+ category: "ask";
917
+ id: string;
918
+ name: string;
919
+ zone: string;
920
+ arguments: string;
790
921
  } & {}> | Readonly<{
791
- category: "finish";
792
- content: string;
793
- partial: boolean;
922
+ category: "finish";
923
+ content: string;
924
+ partial: boolean;
794
925
  } & {
795
- usage?: Readonly<{
796
- prompt: number;
797
- completion: number;
798
- total: number;
799
- } & {}>;
800
- layer?: "budget" | "meter" | "model";
926
+ usage?: Readonly<{
927
+ prompt: number;
928
+ completion: number;
929
+ total: number;
930
+ } & {}>;
931
+ layer?: "budget" | "meter" | "model";
801
932
  }> | Readonly<{
802
- category: "error";
933
+ category: "error";
803
934
  } & {}>>;
804
935
 
805
936
  /**
@@ -877,7 +1008,7 @@ category: LiteralShape<readonly ["error"]>;
877
1008
  * judge, a tool handler, and a selection handler are awaited until they settle, because each can
878
1009
  * carry usage or finished work, so one that ignores its signal holds the run past a cancel or a
879
1010
  * timeout, and on a ledger its held scan, until it returns.
880
- * The agent supplies no caller identity.
1011
+ * Each call's `ToolContext.caller` is an {@link AgentCaller}.
881
1012
  * - **Paced + capped.** The `scheduler` (when given) yields between turns; tool
882
1013
  * iteration is capped at `limit` so the loop always terminates.
883
1014
  * - **Two observation surfaces.** Pull: the {@link AgentChunk} stream (`stream().events`)
@@ -906,9 +1037,10 @@ export declare interface AgentInterface {
906
1037
  * `budget` or `allowance` is an instance a live run holds, or when a live run is bound to the
907
1038
  * run's conversation; a run whose `limit` is not a positive safe
908
1039
  * integer throws one with `code: 'LIMIT'`. A `prompt` that `agentPromptContract` refuses, a
909
- * `budget` or `allowance` that does not implement `BudgetInterface`, or a `conversation` that
910
- * does not implement `ConversationInterface`, throws a `ContractError` with code `'placement'`
911
- * before either bound starts. Each throws synchronously, before any `Promise` is returned, and
1040
+ * `budget` or `allowance` that does not implement `BudgetInterface`, a `conversation` that does
1041
+ * not implement `ConversationInterface`, a `scope` that does not implement `ScopeInterface`, or a
1042
+ * `workspace` that is not a string throws a `ContractError` with code
1043
+ * `'placement'` before either bound starts. Each throws synchronously, before any `Promise` is returned, and
912
1044
  * leaves the run's conversation unchanged. A fire-and-forget `agent.generate().catch(...)`
913
1045
  * therefore will not catch them (the throw happens on the call itself, ahead of the `.catch` ever
914
1046
  * attaching) — await the call (inside a `try`/`catch`) or wrap the call expression itself in
@@ -917,7 +1049,7 @@ export declare interface AgentInterface {
917
1049
  * @param options - Optional per-run {@link AgentRunOptions} (for example `think`); omitted ⇒ defaults
918
1050
  * @returns The settled {@link AgentResult} (`partial: true` when cancelled)
919
1051
  * @throws {AgentError} Thrown when a live run shares the `window`, a budget or allowance instance, or the run's conversation (`code: 'CONCURRENCY'`) or the `limit` is not a positive safe integer (`code: 'LIMIT'`), synchronously before a handle returns.
920
- * @throws {ContractError} Thrown when the `prompt` is not an exact `AgentPrompt`, the `budget` or `allowance` does not implement `BudgetInterface`, or the `conversation` does not implement `ConversationInterface` (`code: 'placement'`), synchronously before a handle returns.
1052
+ * @throws {ContractError} Thrown when the `prompt` is not an exact `AgentPrompt`, the `budget` or `allowance` does not implement `BudgetInterface`, the `conversation` does not implement `ConversationInterface`, the `scope` does not implement `ScopeInterface`, or the `workspace` is not a string (`code: 'placement'`), synchronously before a handle returns.
921
1053
  */
922
1054
  generate(options?: AgentRunOptions): Promise<AgentResult>;
923
1055
  /**
@@ -930,7 +1062,8 @@ export declare interface AgentInterface {
930
1062
  * instance, or a live run's conversation throws an {@link import('./errors.js').AgentError} with
931
1063
  * `code: 'CONCURRENCY'`, a `limit` that is not a positive safe integer throws one with `code: 'LIMIT'`, and a `prompt` that
932
1064
  * `agentPromptContract` refuses, a `budget` or `allowance` that does not implement
933
- * `BudgetInterface`, or a `conversation` that does not implement `ConversationInterface` throws a
1065
+ * `BudgetInterface`, a `conversation` that does not implement `ConversationInterface`, a `scope`
1066
+ * that does not implement `ScopeInterface`, or a `workspace` that is not a string throws a
934
1067
  * `ContractError` with code `'placement'`, synchronously — before the
935
1068
  * {@link AgentStreamInterface} handle is even returned, so it cannot be caught by chaining
936
1069
  * off the (never-produced) handle; wrap the call itself in `try`/`catch`. Each of those leaves
@@ -944,7 +1077,7 @@ export declare interface AgentInterface {
944
1077
  * @param options - Optional per-run {@link AgentRunOptions} (for example `think`); omitted ⇒ defaults
945
1078
  * @returns A live {@link AgentStreamInterface} handle (events + result + abort)
946
1079
  * @throws {AgentError} Thrown when a live run shares the `window`, a budget or allowance instance, or the run's conversation (`code: 'CONCURRENCY'`) or the `limit` is not a positive safe integer (`code: 'LIMIT'`), synchronously before a handle returns.
947
- * @throws {ContractError} Thrown when the `prompt` is not an exact `AgentPrompt`, the `budget` or `allowance` does not implement `BudgetInterface`, or the `conversation` does not implement `ConversationInterface` (`code: 'placement'`), synchronously before a handle returns.
1080
+ * @throws {ContractError} Thrown when the `prompt` is not an exact `AgentPrompt`, the `budget` or `allowance` does not implement `BudgetInterface`, the `conversation` does not implement `ConversationInterface`, the `scope` does not implement `ScopeInterface`, or the `workspace` is not a string (`code: 'placement'`), synchronously before a handle returns.
948
1081
  */
949
1082
  stream(options?: AgentRunOptions): AgentStreamInterface;
950
1083
  /**
@@ -958,33 +1091,40 @@ export declare interface AgentInterface {
958
1091
 
959
1092
  /** Checks a durable agent job exactly at `AgentRegistry.build`. */
960
1093
  export declare const agentJobContract: ContractInterface<Readonly<{
961
- provider: string;
962
- } & {
963
- messages?: readonly Readonly<{
964
- role: "assistant" | "system" | "tool" | "user";
965
- content: string;
1094
+ provider: string;
966
1095
  } & {
967
- calls?: readonly Readonly<{
968
- id: string;
969
- name: string;
970
- arguments: {
971
- readonly [k: string]: JSONValue;
972
- };
973
- } & {}>[];
974
- call?: string;
975
- images?: readonly string[];
976
- thinking?: string;
977
- }>[];
978
- system?: string;
979
- tools?: readonly string[];
980
- authority?: string;
981
- scheduler?: string;
982
- limit?: number;
983
- timeout?: number;
984
- budget?: number;
985
- children?: readonly {
986
- readonly [k: string]: JSONValue;
987
- }[];
1096
+ messages?: readonly Readonly<{
1097
+ content: string;
1098
+ role: "assistant" | "tool" | "user";
1099
+ } & {
1100
+ calls?: readonly Readonly<{
1101
+ id: string;
1102
+ name: string;
1103
+ arguments: {
1104
+ readonly [k: string]: JSONValue;
1105
+ };
1106
+ } & {}>[];
1107
+ call?: string;
1108
+ images?: readonly string[];
1109
+ thinking?: string;
1110
+ }>[];
1111
+ system?: string;
1112
+ tools?: readonly string[];
1113
+ authority?: string;
1114
+ scheduler?: string;
1115
+ limit?: number;
1116
+ timeout?: number;
1117
+ budget?: number;
1118
+ scope?: Readonly<{
1119
+ skills: readonly string[];
1120
+ memos: readonly string[];
1121
+ workspaces: readonly string[];
1122
+ } & {}>;
1123
+ workspace?: string;
1124
+ builtins?: readonly ("load" | "memo" | "remember" | "switch" | "unload")[];
1125
+ children?: readonly {
1126
+ readonly [k: string]: JSONValue;
1127
+ }[];
988
1128
  }>>;
989
1129
 
990
1130
  /**
@@ -1027,7 +1167,11 @@ export declare class AgentJobError extends Error {
1027
1167
  * to run); `messages` defaults to an empty seed. `tools` lists registry keys whose
1028
1168
  * resolved tools are loaded into the agent's manager; `authority` / `scheduler` are
1029
1169
  * single registry keys (their live objects carry functions, so they can't serialize).
1030
- * `budget` is a token ceiling rebuilt into a `createTokenBudget({ max })`.
1170
+ * `budget` is a token ceiling rebuilt into a `createTokenBudget({ max })`. A job holds what it
1171
+ * names: `scope` lists the skills, memos, and workspaces it holds of the registry's managers, so a
1172
+ * job with no `scope` holds none, as a job with no `tools` holds no tool; `workspace` renders within
1173
+ * that scope; and `builtins` names the built-in tools it serves itself, which pass the authority
1174
+ * `authority` names as its tools do.
1031
1175
  */
1032
1176
  export declare interface AgentJobInput {
1033
1177
  /** Names the registry key of the {@link ProviderInterface} the job runs against. */
@@ -1038,7 +1182,7 @@ export declare interface AgentJobInput {
1038
1182
  readonly system?: string;
1039
1183
  /** Names the registry keys of the values of {@link ToolInterface} loaded into the agent's tool manager; a non-empty list requires `authority`. */
1040
1184
  readonly tools?: readonly string[];
1041
- /** Names the registry key of the {@link AuthorityInterface} policy gate; required when `tools` names any. */
1185
+ /** Names the registry key of the {@link AuthorityInterface} policy gate; required when `tools` or `builtins` names any. */
1042
1186
  readonly authority?: string;
1043
1187
  /** Names the registry key of an optional {@link SchedulerInterface} pacing the loop. */
1044
1188
  readonly scheduler?: string;
@@ -1048,6 +1192,15 @@ export declare interface AgentJobInput {
1048
1192
  readonly timeout?: number;
1049
1193
  /** Sets a token ceiling rebuilt into a `createTokenBudget({ max })` cost bound. */
1050
1194
  readonly budget?: number;
1195
+ /**
1196
+ * Holds the job's ceiling over the `skills`, `memos`, and `workspaces` managers of the registry,
1197
+ * each list required, `[]` for none. Omitted ⇒ the job holds no skill, memo, or workspace.
1198
+ */
1199
+ readonly scope?: Required<Pick<ScopeFilter, 'skills' | 'memos' | 'workspaces'>>;
1200
+ /** Names the workspace the job renders in place of the active one, within its `scope` (see {@link AgentOptions.workspace}). */
1201
+ readonly workspace?: string;
1202
+ /** Lists the built-in tools the job serves itself (see {@link AgentOptions.builtins}); a non-empty list requires `authority`. */
1203
+ readonly builtins?: readonly AgentBuiltin[];
1051
1204
  /**
1052
1205
  * Lists the sub-agent jobs this job fans out — each a nested {@link AgentJobInput} (so the whole
1053
1206
  * tree stays serializable). On a `createAgentRunner`, the handler calls `controller.spawn` for
@@ -1063,14 +1216,16 @@ export declare interface AgentJobInput {
1063
1216
  * refuses instead of running an agent without it.
1064
1217
  *
1065
1218
  * @remarks
1066
- * `children` holds JSON records, because each child crosses this shape at its own `build`. `limit`
1067
- * reads as a number here and as a positive safe integer at the agent's construction, which owns that
1068
- * refusal.
1219
+ * `children` holds JSON records, because each child crosses this shape at its own `build`. Each
1220
+ * bound states what the build reads: `limit` an integer from 1 through `Number.MAX_SAFE_INTEGER`,
1221
+ * `timeout` an integer from 0 through `MAX_TIMEOUT_MS`, and `budget` a number of at least 0. A seed
1222
+ * message plays a `ConversationRole`, so a `system` message refuses here. A `scope` holds the
1223
+ * `skills`, `memos`, and `workspaces` lists, each required, and no other member; `builtins` admits
1224
+ * only the names of `AgentBuiltin`, and `collectJobRefusals` reads what a list of them cannot state.
1069
1225
  */
1070
1226
  export declare const agentJobShape: ObjectShape< {
1071
1227
  provider: StringShape;
1072
1228
  messages: OptionalShape<ArrayShape<ObjectShape< {
1073
- role: LiteralShape<readonly ["system", "user", "assistant", "tool"]>;
1074
1229
  content: StringShape;
1075
1230
  calls: OptionalShape<ArrayShape<ObjectShape< {
1076
1231
  id: StringShape;
@@ -1080,6 +1235,7 @@ arguments: ObjectShape<Record<never, never>, JSONShape>;
1080
1235
  call: OptionalShape<StringShape>;
1081
1236
  images: OptionalShape<ArrayShape<StringShape>>;
1082
1237
  thinking: OptionalShape<StringShape>;
1238
+ role: LiteralShape<readonly ["user", "assistant", "tool"]>;
1083
1239
  }, boolean | ContractShape>>>;
1084
1240
  system: OptionalShape<StringShape>;
1085
1241
  tools: OptionalShape<ArrayShape<StringShape>>;
@@ -1088,6 +1244,13 @@ scheduler: OptionalShape<StringShape>;
1088
1244
  limit: OptionalShape<NumberShape>;
1089
1245
  timeout: OptionalShape<NumberShape>;
1090
1246
  budget: OptionalShape<NumberShape>;
1247
+ scope: OptionalShape<ObjectShape< {
1248
+ skills: ArrayShape<StringShape>;
1249
+ memos: ArrayShape<StringShape>;
1250
+ workspaces: ArrayShape<StringShape>;
1251
+ }, boolean | ContractShape>>;
1252
+ workspace: OptionalShape<StringShape>;
1253
+ builtins: OptionalShape<ArrayShape<LiteralShape<readonly ["load", "unload", "memo", "remember", "switch"]>>>;
1091
1254
  children: OptionalShape<ArrayShape<ObjectShape<Record<never, never>, JSONShape>>>;
1092
1255
  }, boolean | ContractShape>;
1093
1256
 
@@ -1190,10 +1353,14 @@ export declare interface AgentJudgeInterface extends JudgeInterface {
1190
1353
  * Configures `createAgent` — the loop's bounds and pacing, the reserved `on` hooks, the
1191
1354
  * construction-time context wiring (`instructions` / `skills` / `memos` / `workspaces` / `scope`), the `conversations`
1192
1355
  * registry holding every run's default, the context `window` budget that opts into automatic
1193
- * compaction of the run's conversation, and the `strict` switch that aborts the run on an
1194
- * automatic-compaction summarizer failure instead of the lenient default.
1356
+ * compaction of the run's conversation, the `builtins` each run serves and the `workspace` it
1357
+ * renders, and the `strict` switch that settles the run `error` on
1358
+ * an automatic-compaction summarizer failure, a selection fault, or a request still over the
1359
+ * window, or continues past them when `false`.
1195
1360
  *
1196
1361
  * @remarks
1362
+ * An own enumerable member this type does not declare refuses at construction with a
1363
+ * `ContractError` coded `'structure'`, and a declared member holding `undefined` reads as omitted.
1197
1364
  * - `system` — an optional system prompt prepended to the turn (seeds the context).
1198
1365
  * - `tools` — an optional pre-built {@link ToolManagerInterface} the loop dispatches
1199
1366
  * the model's calls through; an empty one is created when omitted.
@@ -1213,9 +1380,10 @@ export declare interface AgentJudgeInterface extends JudgeInterface {
1213
1380
  * The loop races that yield against the run signal, so a scheduler that ignores its signal still ends on a cancel.
1214
1381
  * - `signal` — an optional external `AbortSignal` whose abort cancels the turn (a
1215
1382
  * partial result).
1216
- * - `authority` — an optional {@link AuthorityInterface} that decides each scope-admitted call;
1217
- * omitted ⇒ a default `Authority` that allows an unannotated call and asks for a
1218
- * `consequential` one, which no approver answers, so it is denied.
1383
+ * - `authority` — an {@link AuthorityInterface} that decides each scope-admitted call; required
1384
+ * when `tools` is set or `builtins` lists a name, and construction throws an `AgentError` with
1385
+ * code `'AUTHORITY'` without it. Omitted with no `tools` ⇒ the agent holds no authority, and the
1386
+ * loop denies a call to a tool added later through `context.tools`.
1219
1387
  * - `conversations` — an optional {@link ConversationManagerInterface} forwarded to the agent's
1220
1388
  * context (so `context.messages` is its active conversation's live tail); a run binds that
1221
1389
  * active conversation when it names no `conversation` of its own. Omitted ⇒ a fresh registry
@@ -1234,11 +1402,11 @@ export declare interface AgentJudgeInterface extends JudgeInterface {
1234
1402
  * thrown handler, a returned `fault`, a conversation changed under the handler, a selected
1235
1403
  * message whose role is not a `ConversationRole`) settle the same way, and a request still over
1236
1404
  * the `window` after the permitted fold, or one that cannot fold, settles `error` with an
1237
- * `AgentError` coded `'WINDOW'` before the provider is called.
1238
- * Default: `false`. The run continues over-window, or on `view()` after a selection fault.
1405
+ * `AgentError` coded `'WINDOW'` before the provider is called. When `false`, the run continues
1406
+ * over-window, or on `view()` after a selection fault. Default: `true`.
1239
1407
  * - `select` — an optional default {@link SelectionHandler} forwarded to the agent's context; the
1240
- * active scope's `select` overrides it. The loop runs it at run entry and after each automatic
1241
- * compaction rebuild, emits each {@link Selection} it builds from on `select`, and charges the
1408
+ * active scope's `select` overrides it, and a run scope's `select` overrides both for its run.
1409
+ * The loop runs it at run entry and after each automatic compaction rebuild, emits each {@link Selection} it builds from on `select`, and charges the
1242
1410
  * selection's usage to `budget` and the result's `usage`.
1243
1411
  * - `instructions` — an optional pre-built {@link InstructionManagerInterface} forwarded to the
1244
1412
  * agent's context; an empty one is created when omitted (mirrors {@link AgentContextOptions.instructions}).
@@ -1250,6 +1418,18 @@ export declare interface AgentJudgeInterface extends JudgeInterface {
1250
1418
  * agent's context; a fresh empty one is created when omitted (mirrors {@link AgentContextOptions.workspaces}).
1251
1419
  * - `scope` — an optional initial active {@link ScopeInterface} forwarded to the agent's context
1252
1420
  * (the context and tool-dispatch filter); `undefined` ⇒ every registered tool is admitted.
1421
+ * - `builtins` — the {@link AgentBuiltin} tools each run serves itself, each advertised only where
1422
+ * the turn's ceiling admits its name and each call passing the authority. `remember` and `switch`
1423
+ * are advertised only while the ceiling's `memos` or `workspaces` list names a key, and `load` and
1424
+ * `unload` are not advertised under an empty `skills` list; construction throws an
1425
+ * `AgentError` with code `'BUILTIN'` for a name that is no built-in, a repeated name, `unload`
1426
+ * without `load`, or a name the tool manager already holds. Omitted ⇒ none.
1427
+ * - `workspace` — the id of the workspace every run renders in place of the active one, from its
1428
+ * first request, until the thread's own `switch`, and only where the registry holds it and the
1429
+ * ceiling admits it; a run's own `workspace` replaces it. It selects for the run and never moves
1430
+ * the `workspaces` manager's active pointer, which every conversation of the agent reads.
1431
+ * Construction throws a `ContractError` with code `'placement'` for a value that is not a string.
1432
+ * Omitted ⇒ the active workspace.
1253
1433
  * - `on` — the reserved {@link EmitterHooks} key: initial listeners for the agent's
1254
1434
  * {@link AgentEventMap}, wired at construction (for example `{ finish: (r) => log(r) }`).
1255
1435
  */
@@ -1275,10 +1455,12 @@ export declare interface AgentOptions {
1275
1455
  * denied the same way, whatever the authority would decide.
1276
1456
  * Every scoped-out call, one in a turn advertising no tools included, produces a denial tool
1277
1457
  * result and message and a `deny` event, and the loop continues.
1278
- * A scope change through the context's `apply` method applies the tool allow-list at the next
1279
- * turn's snapshot, which a `turn` listener reaches for the same turn, and the instructions,
1280
- * skills, memos, files, and `select` at the next build or select site: run entry, the pre-first-turn
1281
- * compaction fold, or a compaction rebuild.
1458
+ * A scope change through the context's `apply` method applies at the next turn's snapshot, which
1459
+ * a `turn` listener reaches for the same turn: the snapshot decides the advertised tools, and a
1460
+ * changed `instructions`, `skills`, `memos`, `files`, or `workspaces` list rebuilds the head for
1461
+ * that turn over the same messages. A `select` change, and an instruction text edit with no list
1462
+ * change, wait for the next build or select site: run entry, the pre-first-turn compaction fold,
1463
+ * or a compaction rebuild.
1282
1464
  */
1283
1465
  readonly scope?: ScopeInterface;
1284
1466
  /**
@@ -1374,12 +1556,17 @@ export declare interface AgentOptions {
1374
1556
  readonly strict?: boolean;
1375
1557
  /**
1376
1558
  * Holds the default selection handler forwarded to the agent's context; the active scope's
1377
- * `select` overrides it while that scope is active. The loop runs it at run entry and after
1559
+ * `select` overrides it while that scope is active, and a run scope's `select` overrides both for
1560
+ * its run. The loop runs it at run entry and after
1378
1561
  * each automatic compaction rebuild, for the user message that ends the run's conversation, and
1379
1562
  * charges its usage to the cost `budget`. Omitted ⇒ with no scope handler either, the loop
1380
1563
  * builds from the run's conversation's `view()` and awaits nothing.
1381
1564
  */
1382
1565
  readonly select?: SelectionHandler;
1566
+ /** Lists the built-in tools each run serves itself, each subject to the ceiling and the authority. Default: none. */
1567
+ readonly builtins?: readonly AgentBuiltin[];
1568
+ /** Names the workspace every run renders in place of the active one, until the thread's own `switch`. Default: the active workspace. */
1569
+ readonly workspace?: string;
1383
1570
  }
1384
1571
 
1385
1572
  /**
@@ -1393,9 +1580,9 @@ export declare interface AgentPrompt {
1393
1580
 
1394
1581
  /** Validates and projects agent prompts at the run's `prompt` option and a page's request body. */
1395
1582
  export declare const agentPromptContract: ContractInterface<Readonly<{
1396
- content: string;
1583
+ content: string;
1397
1584
  } & {
1398
- images?: readonly string[];
1585
+ images?: readonly string[];
1399
1586
  }>>;
1400
1587
 
1401
1588
  /**
@@ -1584,16 +1771,22 @@ export declare interface AgentQueueOptions {
1584
1771
  * the message `unknown <category>: <name>` when it is absent — an unknown name in a
1585
1772
  * rehydrated job is a programmer / config error that must fail loudly at build time, never
1586
1773
  * silently resolve to `undefined` and run an agent missing a dependency.
1587
- * - **`build` rehydrates.** Resolve the job's `provider`; assemble a fresh
1588
- * {@link ToolManager} from the `tools` names, which refuses with `code: 'REGISTRY'` when the job
1589
- * names no `authority`; rebuild the token `budget` from its
1590
- * ceiling (`createTokenBudget({ max })`); resolve the optional `authority` /
1774
+ * - **`build` rehydrates.** Refuse with `code: 'REGISTRY'` a job `agentJobContract` refuses,
1775
+ * its faults under `context.faults`, and a job `collectJobRefusals` refuses, its lines under
1776
+ * `context.refusals`: tools or built-ins with no `authority`, a `builtins` list an agent
1777
+ * refuses, and a built-in the job's `tools` also name. Then resolve the job's `provider`;
1778
+ * assemble a fresh {@link ToolManager} from the `tools` names; rebuild the token `budget` from
1779
+ * its ceiling (`createTokenBudget({ max })`); resolve the optional `authority` /
1591
1780
  * `scheduler` names; construct the {@link Agent} with `system` / `limit` / `timeout` /
1592
1781
  * the threaded `signal`; seed its context with the job's `messages`; return it. The
1593
1782
  * `signal` is the queue attempt's / runner unit's cancel, so a bounded abort propagates
1594
1783
  * into the agent (which commits a partial — the job's `partial` policy then
1595
- * decides success vs. retry). A job `limit` that is not a positive safe integer throws an
1596
- * {@link AgentError} carrying `code: 'LIMIT'` from the agent's construction.
1784
+ * decides success vs. retry). A job is a record, so a malformed `limit`, `timeout`, `budget`,
1785
+ * seed role, or `builtins` list refuses as one, with `code: 'REGISTRY'`.
1786
+ * - **A job holds what it names.** A job with a `scope` gets the registry's `skills`, `memos`, and
1787
+ * `workspaces` managers, which every scoped job shares, and a scope named `job` built from its
1788
+ * three lists; a job with no `scope` gets none of them. Its `workspace` and `builtins` pass to
1789
+ * the agent.
1597
1790
  * - **Event-free.** A pure resolver — no Emitter, no events.
1598
1791
  *
1599
1792
  * @example
@@ -1675,8 +1868,7 @@ export declare interface AgentRegistryInterface {
1675
1868
  * @param input - The serializable {@link AgentJobInput} to rehydrate
1676
1869
  * @param signal - An optional cancel threaded into the agent (a queue / runner abort)
1677
1870
  * @returns The ready agent, its context seeded with the job's messages
1678
- * @throws {AgentError} Thrown when a referenced provider, tool, authority, or scheduler name is unregistered, or the job names `tools` and no `authority` (`code: 'REGISTRY'`), or when the job's `limit` is not a nonnegative safe integer (`code: 'LIMIT'`)
1679
- * @throws {ConversationError} Thrown when a seed message's role is not a `ConversationRole` (`code: 'ROLE'`), before the agent is returned
1871
+ * @throws {AgentError} Thrown when the job holds a member `AgentJobInput` does not declare or a member of the wrong shape, a bound out of range or a seed role that is not a `ConversationRole` included, when the job names `tools` or `builtins` and no `authority`, when its `builtins` repeats a name, lists `unload` without `load`, or names a tool its `tools` hold, or when a referenced provider, tool, authority, or scheduler name is unregistered (`code: 'REGISTRY'`)
1680
1872
  */
1681
1873
  build(input: AgentJobInput, signal?: AbortSignal): AgentInterface;
1682
1874
  }
@@ -1694,7 +1886,10 @@ export declare interface AgentRegistryInterface {
1694
1886
  * build (minted by the seeded `add`), so concurrent builds never collide, and the store
1695
1887
  * accumulates one snapshot per built agent that later calls `save`. Persistence
1696
1888
  * stays caller-triggered (`open` / `save`) — `build` never hydrates, so `build` stays
1697
- * synchronous. Omitted ⇒ every built agent gets a registry-only manager.
1889
+ * synchronous. Omitted ⇒ every built agent gets a registry-only manager. `skills`, `memos`, and
1890
+ * `workspaces` are pre-built managers every job with a `scope` shares, each read through that
1891
+ * job's lists; a job with no `scope` is passed none of them. Omitted ⇒ a scoped job's agent
1892
+ * creates an empty one.
1698
1893
  */
1699
1894
  export declare interface AgentRegistryOptions {
1700
1895
  readonly providers: Readonly<Record<string, ProviderInterface>>;
@@ -1702,6 +1897,12 @@ export declare interface AgentRegistryOptions {
1702
1897
  readonly authorities?: Readonly<Record<string, AuthorityInterface>>;
1703
1898
  readonly schedulers?: Readonly<Record<string, SchedulerInterface>>;
1704
1899
  readonly store?: ConversationStoreInterface;
1900
+ /** Holds the skill registry every job with a `scope` shares, read through its `skills` list. */
1901
+ readonly skills?: SkillManagerInterface;
1902
+ /** Holds the memo set every job with a `scope` shares, read and written through its `memos` list. */
1903
+ readonly memos?: MemoManagerInterface;
1904
+ /** Holds the workspace registry every job with a `scope` shares, read through its `workspaces` list. */
1905
+ readonly workspaces?: WorkspaceManagerInterface;
1705
1906
  }
1706
1907
 
1707
1908
  /**
@@ -1830,17 +2031,22 @@ export declare interface AgentRunnerOptions {
1830
2031
  }
1831
2032
 
1832
2033
  /**
1833
- * Carries overrides for one call to the `generate` or `stream` method of an {@link AgentInterface}. Each member overrides the matching {@link AgentOptions} value, while `signal` composes with the construction signal, `conversation` binds the run to one conversation, and `prompt` adds the run's user turn to it.
2034
+ * Carries overrides for one call to the `generate` or `stream` method of an {@link AgentInterface}. Each member overrides the matching {@link AgentOptions} value, while `signal` composes with the construction signal, `conversation` binds the run to one conversation, `prompt` adds the run's user turn to it, and `scope` narrows the context scope for the run.
1834
2035
  *
1835
2036
  * @remarks
2037
+ * An own enumerable member this type does not declare refuses the call synchronously with a
2038
+ * `ContractError` coded `'structure'`, before the run changes anything, and a declared member
2039
+ * holding `undefined` reads as omitted.
1836
2040
  * Every member is optional and resolved independently, so an omitted member leaves the
1837
2041
  * agent's constructed value in force and a caller that passes no options runs exactly the
1838
2042
  * agent it configured. `think` / `schema` ride through to the provider as
1839
2043
  * {@link ProviderStreamOptions}; `limit` / `timeout` / `budget` / `allowance` replace their construction
1840
2044
  * defaults for this run only; `signal` composes with the constructed `signal` (both fold into
1841
- * the run's bound abort) rather than replacing it. `conversation` and `prompt` have no construction
1842
- * counterpart: `conversation` names the conversation the run binds in place of the one active at
1843
- * the call, and `prompt` is the user turn the run appends to that conversation before it starts.
2045
+ * the run's bound abort) rather than replacing it. `conversation`, `prompt`, and `scope` have no
2046
+ * construction default: `conversation` names the conversation the run binds in place of the one
2047
+ * active at the call, `prompt` is the user turn the run appends to that conversation before it
2048
+ * starts, and the run `scope` narrows the construction `scope`, the context scope, at each turn of
2049
+ * the run and never replaces it.
1844
2050
  * Nothing here mutates the agent — the next run reads the construction defaults again.
1845
2051
  */
1846
2052
  export declare interface AgentRunOptions {
@@ -1910,6 +2116,25 @@ export declare interface AgentRunOptions {
1910
2116
  * run reads its request from the conversation's tail.
1911
2117
  */
1912
2118
  readonly prompt?: AgentPrompt;
2119
+ /**
2120
+ * Narrows this run's ceiling: each turn reads the context scope intersected with it, list by
2121
+ * list, one time, and each build site of the run filters instructions, skills, memos, files, and
2122
+ * workspaces by the same intersection. Its `select` runs in place of the context scope's. A later
2123
+ * `context.apply` still reaches the run at its next turn, and never past this scope, so a run
2124
+ * that needs a wider scope than the context scope needs another agent. The `stream` or
2125
+ * `generate` call throws a `ContractError` coded `'placement'` synchronously when the value does
2126
+ * not implement {@link ScopeInterface}, before the run appends its prompt or starts. Omitted ⇒ the
2127
+ * context scope alone.
2128
+ */
2129
+ readonly scope?: ScopeInterface;
2130
+ /**
2131
+ * Replaces {@link AgentOptions.workspace} for this run: the id of the workspace the run renders in
2132
+ * place of the active one, from its first request, until the thread's own `switch`, within the
2133
+ * ceiling. The `stream` or `generate` call throws a `ContractError` coded `'placement'`
2134
+ * synchronously when the value is not a string, before the run appends its prompt or starts.
2135
+ * Omitted ⇒ the agent's value.
2136
+ */
2137
+ readonly workspace?: string;
1913
2138
  }
1914
2139
 
1915
2140
  /**
@@ -2133,6 +2358,22 @@ export declare interface ApproverInterface {
2133
2358
  answer(answer: AgentAnswer): boolean;
2134
2359
  }
2135
2360
 
2361
+ /**
2362
+ * Matches a text that is blank: empty after white space and default-ignorable code points, such
2363
+ * as U+3164, are removed, frozen.
2364
+ */
2365
+ export declare const ARGUMENT_BLANK_PATTERN: Readonly<RegExp>;
2366
+
2367
+ /**
2368
+ * Matches one control, format, line-separator, or paragraph-separator code point — the class
2369
+ * `renderArguments` encodes and a memo's one-line name and description may not hold, frozen.
2370
+ *
2371
+ * @remarks
2372
+ * Not global, so a `test` call keeps no state between calls; a global replace builds its own
2373
+ * global copy from `source`.
2374
+ */
2375
+ export declare const ARGUMENT_CONTROL_PATTERN: Readonly<RegExp>;
2376
+
2136
2377
  /**
2137
2378
  * Arms signal propagation to a byte reader and returns the controller that removes the listener.
2138
2379
  *
@@ -2272,6 +2513,9 @@ export declare class Authority implements AuthorityInterface {
2272
2513
  */
2273
2514
  export declare const AUTHORITY_NOTES: AuthorityNote;
2274
2515
 
2516
+ /** Lists the members `AuthorityOptions` declares, frozen — the keys the `Authority` constructor admits. */
2517
+ export declare const AUTHORITY_OPTION_KEYS: readonly ["rules", "fallback", "ask"];
2518
+
2275
2519
  /**
2276
2520
  * Carries what an {@link AuthorityInterface} evaluates for one tool call — the call under
2277
2521
  * consideration.
@@ -2377,6 +2621,9 @@ export declare interface AuthorityRule {
2377
2621
  /** Names an authority's verdict on one tool call. */
2378
2622
  export declare type AuthorityVerdict = 'allow' | 'ask' | 'deny';
2379
2623
 
2624
+ /** Lists the members `ContextBuildOptions` declares, frozen — the keys the `build` method of an `AgentContext` admits. */
2625
+ export declare const BUILD_OPTION_KEYS: readonly ["selection", "scope", "disclosure", "switchable"];
2626
+
2380
2627
  /**
2381
2628
  * Merges the results of a judge request's calls into one result.
2382
2629
  *
@@ -2690,6 +2937,68 @@ export declare function buildRequestMessage(request: Message, records: string):
2690
2937
  */
2691
2938
  export declare function buildSummaryMessage(section: Section): Message;
2692
2939
 
2940
+ /**
2941
+ * Caps each built-in argument in code points, as the built-in argument shapes count them — a `name`
2942
+ * (a skill name, a memo name, or a workspace id), a memo `description`, and a memo `content` — and
2943
+ * the `candidates` one refusal lists, frozen.
2944
+ */
2945
+ export declare const BUILTIN_LIMITS: Readonly<{
2946
+ name: number;
2947
+ description: number;
2948
+ content: number;
2949
+ candidates: number;
2950
+ }>;
2951
+
2952
+ /**
2953
+ * Holds the texts the built-ins return on success — `loaded`, `unloaded`, `remembered`, and
2954
+ * `switched` — frozen.
2955
+ *
2956
+ * @remarks
2957
+ * `loaded`, `unloaded`, and `switched` are the texts the conversation's stored tool messages are
2958
+ * matched against to derive what a run shows, so each is one fixed constant. A stored message
2959
+ * counts only under a call to a built-in the run enables.
2960
+ */
2961
+ export declare const BUILTIN_NOTES: BuiltinNote;
2962
+
2963
+ /**
2964
+ * Declares each built-in tool's model-facing description and annotations, keyed by its
2965
+ * {@link AgentBuiltin} name, frozen.
2966
+ *
2967
+ * @remarks
2968
+ * `memo` is `pure` and `untrusted`, because it returns memo text a model can have written;
2969
+ * `remember` is `consequential`, so an `allow` verdict becomes an `ask`. A run's own tools and the
2970
+ * definitions `collectBuiltinDefinitions` returns both read their text and annotations here.
2971
+ */
2972
+ export declare const BUILTIN_TOOLS: Readonly<Record<AgentBuiltin, Readonly<{
2973
+ description: string;
2974
+ annotations?: ToolAnnotations;
2975
+ }>>>;
2976
+
2977
+ /** Holds the model-facing texts the built-ins return on success. */
2978
+ export declare interface BuiltinNote {
2979
+ readonly loaded: string;
2980
+ readonly unloaded: string;
2981
+ readonly remembered: string;
2982
+ readonly switched: string;
2983
+ }
2984
+
2985
+ /**
2986
+ * Pairs each built-in's argument shape, which its tool's door compiles, with its compiled contract,
2987
+ * keyed by its {@link AgentBuiltin} name, frozen.
2988
+ *
2989
+ * @remarks
2990
+ * The one map from a built-in to its arguments: `createBuiltinTool` builds the door from `shape`,
2991
+ * and `collectBuiltinDefinitions` and `collectDisclosure` read `contract`, so the advertised
2992
+ * parameters, the door, and the derivation admit by one rule. The record declares no shape: each
2993
+ * `shape` is a reference to the one `shapers.ts` declares, held beside the contract compiled from
2994
+ * it, because the tool door takes a shape and the derivation takes a compiled contract. The record
2995
+ * is data, as the rest of this file is.
2996
+ */
2997
+ export declare const builtinToolContracts: Readonly<Record<AgentBuiltin, Readonly<{
2998
+ shape: ContractShape;
2999
+ contract: ContractInterface<Readonly<Record<string, unknown>>>;
3000
+ }>>>;
3001
+
2693
3002
  /**
2694
3003
  * Buffers chunks in a minimal unbounded async channel — the eager pump writes them in (`push`)
2695
3004
  * and ends it (`close` / `fail`) regardless of consumption, while a consumer reads them back live
@@ -2875,6 +3184,9 @@ export declare class Classifier implements ClassifierInterface {
2875
3184
  classification(): LedgerClassification;
2876
3185
  }
2877
3186
 
3187
+ /** Lists the members `ClassifierOptions` declares, frozen — the keys the `Classifier` constructor admits. */
3188
+ export declare const CLASSIFIER_OPTION_KEYS: readonly ["strict", "conversation", "judge", "questions", "topics", "thresholds", "assign", "entities", "correction", "scheduler"];
3189
+
2878
3190
  /**
2879
3191
  * Carries what became of one filing question: its judgment key, its phase, its outcome, and the time spent resolving it.
2880
3192
  *
@@ -3040,6 +3352,61 @@ export declare interface CodedErrorOptions {
3040
3352
  */
3041
3353
  export declare function collectAmendments(input: LedgerProjectionInput, byId: ReadonlyMap<string, Message>, live: readonly string[]): readonly LedgerAmendment[];
3042
3354
 
3355
+ /**
3356
+ * Collects the definitions of the tools an agent serves itself, as a run advertises them.
3357
+ *
3358
+ * @remarks
3359
+ * Each definition carries the name, description, and annotations `BUILTIN_TOOLS` declares and the
3360
+ * parameters of the built-in's compiled contract in `builtinToolContracts`, in the order `builtins` lists them, so
3361
+ * it equals the definition of the tool `createBuiltinTool` creates. A relay server lists these
3362
+ * among its declared definitions to forward a page's built-ins. A name that is no built-in
3363
+ * contributes nothing.
3364
+ *
3365
+ * @param options - The agent options whose `builtins` to project
3366
+ * @returns The definitions, empty when `builtins` is absent
3367
+ *
3368
+ * @example
3369
+ * ```ts
3370
+ * collectBuiltinDefinitions({ builtins: ['load', 'unload'] }).map((definition) => definition.name) // ['load', 'unload']
3371
+ * ```
3372
+ */
3373
+ export declare function collectBuiltinDefinitions(options: Pick<AgentOptions, 'builtins'>): readonly ToolDefinition[];
3374
+
3375
+ /**
3376
+ * Collects the loaded skills and the selected workspace a conversation's stored built-in calls
3377
+ * record, counting only the built-ins a run enables.
3378
+ *
3379
+ * @remarks
3380
+ * Pure. It reads each section's retained originals, oldest first, then the live tail, and pairs
3381
+ * each tool message with the call that owns it through {@link collectToolGroups} and
3382
+ * {@link findToolCall}. It then folds the pairs in message order: a `load` whose message content
3383
+ * equals `BUILTIN_NOTES.loaded` adds its `skill`, an `unload` with `BUILTIN_NOTES.unloaded` removes
3384
+ * it, and a `switch` with `BUILTIN_NOTES.switched` selects its `workspace`. Each call's arguments
3385
+ * are admitted through the built-in's contract in `builtinToolContracts`, lossless repairs
3386
+ * included, as its tool's door admits them, so a `{ skill: 1 }` the door repaired to `'1'` counts
3387
+ * as `'1'`; arguments the contract refuses change nothing. A skill loaded again while shown keeps
3388
+ * its place, and one loaded again after its unload goes last. Any other message and a denied or
3389
+ * refused call change nothing. The result holds `workspace` only when a switch succeeded.
3390
+ *
3391
+ * A record counts only while its built-in is in `builtins`, so a host tool that holds a built-in's
3392
+ * name on a run that does not enable it shows nothing; with none of `load`, `unload`, and `switch`
3393
+ * enabled, nothing is read. A stored record cannot tell its writer, so one a host tool wrote under a
3394
+ * built-in's name while that built-in was off counts after a run enables it, bounded by the registry
3395
+ * and the ceiling as every record is.
3396
+ *
3397
+ * @param conversation - The conversation whose stored messages record the calls
3398
+ * @param builtins - The built-ins the run enables
3399
+ * @returns The skills in load order and the last selected workspace
3400
+ *
3401
+ * @example
3402
+ * ```ts
3403
+ * import { collectDisclosure, createConversation } from '@orkestrel/agent'
3404
+ *
3405
+ * collectDisclosure(createConversation(), ['load', 'unload']) // { skills: [] }
3406
+ * ```
3407
+ */
3408
+ export declare function collectDisclosure(conversation: Pick<ConversationInterface, 'sections' | 'messages'>, builtins: readonly AgentBuiltin[]): AgentDisclosure;
3409
+
3043
3410
  /**
3044
3411
  * Collects whole exchanges, joining every exchange spanned by a tool group.
3045
3412
  *
@@ -3079,6 +3446,28 @@ export declare function collectExchanges(messages: readonly Message[]): Readonly
3079
3446
  */
3080
3447
  export declare function collectImageData(files: readonly FileInterface[]): readonly string[];
3081
3448
 
3449
+ /**
3450
+ * Collects the refusals a job the contract admitted would meet at its build: tools or built-ins with
3451
+ * no authority, a `builtins` list `requireBuiltins` refuses, and a built-in its own `tools` name.
3452
+ *
3453
+ * @remarks
3454
+ * Each line names the member first, then the refusal and its remedy. The `builtins` line of a list
3455
+ * `requireBuiltins` refuses carries that error's message; a job's tool manager holds exactly its
3456
+ * `tools`, so a built-in its `tools` list also names is the name a manager would already hold.
3457
+ * `AgentRegistry.build` refuses a job with any line, and `scanJobTree` refuses each such job of a
3458
+ * tree before anything spawns.
3459
+ *
3460
+ * @param job - The `tools`, `builtins`, and `authority` of a job `agentJobContract` admitted
3461
+ * @returns One line a refusal, in member order; empty when the job builds
3462
+ *
3463
+ * @example
3464
+ * ```ts
3465
+ * collectJobRefusals({ provider: 'main', tools: ['search'] })
3466
+ * // ["authority: a job that names tools or builtins and no authority cannot run them; add authority: 'NAME' to the job and register that NAME under authorities"]
3467
+ * ```
3468
+ */
3469
+ export declare function collectJobRefusals(job: Pick<AgentJobInput, 'tools' | 'builtins' | 'authority'>): readonly string[];
3470
+
3082
3471
  /**
3083
3472
  * Captures source bytes and direct amendment edges for a held window.
3084
3473
  * @param messages - Current stored messages
@@ -3271,6 +3660,9 @@ export declare function collectToolGroups(messages: readonly Message[]): Readonl
3271
3660
  */
3272
3661
  export declare function collectWriteSupersessions(messages: readonly Message[], findings: readonly LedgerLookupFinding[]): ReadonlyMap<string, readonly string[]>;
3273
3662
 
3663
+ /** Lists the members `CompactOptions` declares, frozen — the keys the `compact` method of a `Conversation` admits. */
3664
+ export declare const COMPACT_OPTION_KEYS: readonly ["keep", "sections", "signal"];
3665
+
3274
3666
  /**
3275
3667
  * Configures one {@link ConversationInterface.compact} call — the retained-tail size, the
3276
3668
  * `sections` cap, or both, overridden for one fold.
@@ -3316,6 +3708,26 @@ export declare interface CompactOptions {
3316
3708
  */
3317
3709
  export declare function computeLedgerChecksum(text: string): string;
3318
3710
 
3711
+ /**
3712
+ * Computes the tokens loading a skill adds: its body, and the definitions it names beyond an advertised set.
3713
+ *
3714
+ * @remarks
3715
+ * The body is the text `renderSkillBody` renders, priced at `scale`, and a blank `content` renders
3716
+ * no body. The caller passes the definitions the skill names that the turn does not advertise,
3717
+ * priced as {@link computeToolPrice} prices an addition.
3718
+ *
3719
+ * @param skill - The skill to load
3720
+ * @param added - The definitions the skill names that the advertised set leaves out
3721
+ * @param calibrated - The definitions the gauge's overhead priced
3722
+ * @param gauge - The gauge's scale and overhead
3723
+ * @returns The tokens the load adds
3724
+ * @example
3725
+ * ```ts
3726
+ * computeSkillPrice({ name: 'refunds', content: 'Check the order first.' }, [], [], { scale: 1, overhead: 0 }) // 9
3727
+ * ```
3728
+ */
3729
+ export declare function computeSkillPrice(skill: Pick<Skill, 'name' | 'content'>, added: readonly ToolDefinition[], calibrated: readonly ToolDefinition[], gauge: LedgerGauge): number;
3730
+
3319
3731
  /**
3320
3732
  * Computes the completion tokens attributable to a message's thinking.
3321
3733
  *
@@ -3336,6 +3748,78 @@ export declare function computeLedgerChecksum(text: string): string;
3336
3748
  */
3337
3749
  export declare function computeThinking(message: Pick<Message, 'thinking' | 'content' | 'calls'>, completion: number): number;
3338
3750
 
3751
+ /**
3752
+ * Computes the tokens one estimate unit of a definition costs beyond the calibrated set.
3753
+ *
3754
+ * @remarks
3755
+ * The larger of `scale` and the calibrated set's overhead per estimate unit, or `scale` for an
3756
+ * empty set or one that estimates 0. A set's estimate is `estimateTokens` over its JSON text.
3757
+ *
3758
+ * @param calibrated - The definitions the gauge's overhead priced
3759
+ * @param gauge - The gauge's scale and overhead
3760
+ * @returns The tokens one estimate unit of a definition costs
3761
+ * @example
3762
+ * ```ts
3763
+ * computeToolDensity([], { scale: 1.1, overhead: 400 }) // 1.1
3764
+ * ```
3765
+ */
3766
+ export declare function computeToolDensity(calibrated: readonly ToolDefinition[], gauge: LedgerGauge): number;
3767
+
3768
+ /**
3769
+ * Computes what a call's advertised set spares of the calibrated overhead and adds beyond it.
3770
+ *
3771
+ * @remarks
3772
+ * Definitions compare by their JSON text, so a definition replaced under its name by another text
3773
+ * is both left out and added. An empty advertised set spares the whole overhead. Otherwise the
3774
+ * calibrated definitions the call leaves out spare the lower of `scale` and the calibrated set's
3775
+ * overhead per estimate unit, times their estimate, so a credit never exceeds their proportional
3776
+ * share of the overhead; the definitions it advertises beyond the calibrated set add
3777
+ * {@link computeToolDensity}, the higher of the two, times theirs. A set's estimate is
3778
+ * `estimateTokens` over its JSON text, 0 for an empty set. The call's price is
3779
+ * `overhead - spared + added`.
3780
+ *
3781
+ * @param calibrated - The definitions the gauge's overhead priced
3782
+ * @param advertised - The definitions the call advertises
3783
+ * @param gauge - The gauge's scale and overhead
3784
+ * @returns The tokens the call spares and adds
3785
+ * @example
3786
+ * ```ts
3787
+ * computeToolPrice([], [], { scale: 1.1, overhead: 400 }) // { spared: 400, added: 0 }
3788
+ * ```
3789
+ */
3790
+ export declare function computeToolPrice(calibrated: readonly ToolDefinition[], advertised: readonly ToolDefinition[], gauge: LedgerGauge): Required<Pick<GaugeCall, 'spared' | 'added'>>;
3791
+
3792
+ /** Lists the members `AgentContextOptions` declares, frozen — the keys the `AgentContext` constructor admits. */
3793
+ export declare const CONTEXT_OPTION_KEYS: readonly ["system", "tools", "instructions", "skills", "memos", "workspaces", "scope", "conversations", "select"];
3794
+
3795
+ /**
3796
+ * Selects what one `build` call renders.
3797
+ *
3798
+ * @remarks
3799
+ * `selection` holds the conversation part in place of the active conversation's `view()`. `scope`
3800
+ * holds a run's scope: the build filters by the context scope intersected with it, list by list,
3801
+ * so a run scope narrows the context scope and never widens it. `disclosure` names the skills
3802
+ * whose bodies close the `system` message and the workspace to render in place of the active one,
3803
+ * each kept only where its registry holds it and that intersection admits it. `switchable` lists
3804
+ * the admitted workspace ids in the context message, as an agent run does while it advertises
3805
+ * `switch`.
3806
+ *
3807
+ * @example
3808
+ * ```ts
3809
+ * context.build({ selection: { messages: conversation.view(), judgments: [] }, scope })
3810
+ * ```
3811
+ */
3812
+ export declare interface ContextBuildOptions {
3813
+ /** Holds the messages that replace `view()`; omitted ⇒ the active conversation's `view()`. */
3814
+ readonly selection?: Selection;
3815
+ /** Holds a run's scope; the build filters by the context scope intersected with it. */
3816
+ readonly scope?: ScopeInterface;
3817
+ /** Holds the skills whose bodies close the system message and the workspace to render. Default: no body, the active workspace. */
3818
+ readonly disclosure?: AgentDisclosure;
3819
+ /** If `true`, the context message lists the admitted workspace ids; if `false`, it lists none. Default: `false`. */
3820
+ readonly switchable?: boolean;
3821
+ }
3822
+
3339
3823
  /**
3340
3824
  * Reports a context snapshot that `isMemoSnapshot` refuses, thrown by the construction of a
3341
3825
  * {@link import('./memos/MemoManager.js').MemoManager} before it seats any state or by a memo store,
@@ -3505,6 +3989,15 @@ export declare class Conversation implements ConversationInterface {
3505
3989
  snapshot(): ConversationSnapshot;
3506
3990
  }
3507
3991
 
3992
+ /** Lists the members `ConversationInput` declares, frozen — the keys the `add` method of a `ConversationManager` admits. */
3993
+ export declare const CONVERSATION_INPUT_KEYS: readonly ["id", "summarize", "keep", "sections", "cumulative", "on", "error", "snapshot"];
3994
+
3995
+ /** Lists the members `ConversationManagerOptions` declares, frozen — the keys the `ConversationManager` constructor admits. */
3996
+ export declare const CONVERSATION_MANAGER_KEYS: readonly ["summarize", "keep", "sections", "store"];
3997
+
3998
+ /** Lists the members `ConversationOptions` declares, frozen — the keys the `Conversation` constructor admits. */
3999
+ export declare const CONVERSATION_OPTION_KEYS: readonly ["id", "on", "error", "summarize", "keep", "sections", "cumulative", "snapshot"];
4000
+
3508
4001
  /**
3509
4002
  * Names the framing label the `view()` method of a {@link ConversationInterface} prefixes onto the
3510
4003
  * summary of each compacted section so a small model reads it as a condensed recap of earlier turns — the lean
@@ -3553,7 +4046,8 @@ export declare const CONVERSATION_ROLES: readonly ["user", "assistant", "tool"];
3553
4046
  * `'SUMMARY'`. A stored message plays a `ConversationRole`: `add` refuses any other role with
3554
4047
  * `'ROLE'` before it stores any message of the batch, a hydrating snapshot that holds one throws
3555
4048
  * `'ROLE'`, and an agent's selection that holds one becomes a `'ROLE'` fault. `add` refuses an input
3556
- * whose other members fail `isMessageInput` with `'MESSAGE'`, its `context` holding the `faults`,
4049
+ * that is not a plain record, before its role is read, or whose other members fail `isMessageInput`
4050
+ * with `'MESSAGE'`, its `context` holding the `faults`,
3557
4051
  * before it stores any message of the batch. A hydrating snapshot that fails
3558
4052
  * `isConversationSnapshot` or repeats an id, and a store row or written snapshot that does, throw
3559
4053
  * `'SNAPSHOT'`; a judgment the guard admits but JSON cannot carry still throws `'JUDGMENT'`. A
@@ -3561,7 +4055,7 @@ export declare const CONVERSATION_ROLES: readonly ["user", "assistant", "tool"];
3561
4055
  * {@link isConversationError} and branch on `error.code`.
3562
4056
  */
3563
4057
  export declare class ConversationError extends Error {
3564
- /** Names the machine-readable condition — `'SUMMARIZER'`: a `compact()` with no summarizer; `'SECTIONS'`: a `sections` cap that is not a positive safe integer, or a cap combined with `cumulative`; `'JUDGMENT'`: a judgment or judge request that is not JSON; `'KEEP'`: a `keep` that is not a nonnegative safe integer; `'SUMMARY'`: a summarizer digest whose trimmed text is empty; `'ROLE'`: a stored or selected message whose role is not a `ConversationRole`; `'MESSAGE'`: a message input whose other members fail `isMessageInput`; `'SNAPSHOT'`: a snapshot that fails `isConversationSnapshot` or repeats an id; `'ID'`: a manager's `add` of an id it already holds. */
4058
+ /** Names the machine-readable condition — `'SUMMARIZER'`: a `compact()` with no summarizer; `'SECTIONS'`: a `sections` cap that is not a positive safe integer, or a cap combined with `cumulative`; `'JUDGMENT'`: a judgment or judge request that is not JSON; `'KEEP'`: a `keep` that is not a nonnegative safe integer; `'SUMMARY'`: a summarizer digest whose trimmed text is empty; `'ROLE'`: a stored or selected message whose role is not a `ConversationRole`; `'MESSAGE'`: a message input that is not a plain record or whose other members fail `isMessageInput`; `'SNAPSHOT'`: a snapshot that fails `isConversationSnapshot` or repeats an id; `'ID'`: a manager's `add` of an id it already holds. */
3565
4059
  readonly code: ConversationErrorCode;
3566
4060
  /** Holds the values that locate the failure, such as the `question` id of a malformed question, or `undefined` when none were supplied. */
3567
4061
  readonly context: Readonly<Record<string, unknown>> | undefined;
@@ -4870,6 +5364,30 @@ export declare function createApprover(): ApproverInterface;
4870
5364
  */
4871
5365
  export declare function createAuthority(options: AuthorityOptions): AuthorityInterface;
4872
5366
 
5367
+ /**
5368
+ * Creates the tool a run serves for one built-in: its description and annotations from
5369
+ * `BUILTIN_TOOLS`, its argument shape from `builtinToolContracts`, and the given handler.
5370
+ *
5371
+ * @remarks
5372
+ * The tool's door refuses a missing, empty, over-long, or extra argument before the handler runs,
5373
+ * and repairs a value that converts to a string without loss, such as a number, so the handler
5374
+ * reads only arguments the shape admits. Its definition equals the one `collectBuiltinDefinitions`
5375
+ * returns for the same name.
5376
+ *
5377
+ * @param name - The built-in to create
5378
+ * @param execute - The handler the door hands admitted arguments to
5379
+ * @returns The tool
5380
+ *
5381
+ * @example
5382
+ * ```ts
5383
+ * import { createBuiltinTool } from '@orkestrel/agent'
5384
+ *
5385
+ * const memo = createBuiltinTool('memo', (args) => `read ${String(args.name)}`)
5386
+ * memo.annotations // { pure: true, untrusted: true }
5387
+ * ```
5388
+ */
5389
+ export declare function createBuiltinTool(name: AgentBuiltin, execute: ToolOptions['execute']): ToolInterface;
5390
+
4873
5391
  /**
4874
5392
  * Creates an empty unbounded async channel — a {@link ChannelInterface} a producer writes
4875
5393
  * values into (`push`) and ends (`close` / `fail`) regardless of consumption, while a
@@ -5433,6 +5951,34 @@ export declare function createThinkSplitter(): ThinkSplitterInterface;
5433
5951
  */
5434
5952
  export declare function cutListing(entries: readonly string[], room: number, kind?: 'older' | 'more', first?: boolean): string;
5435
5953
 
5954
+ /**
5955
+ * Cuts the workspace text a calibration sample adds over its head to a number of characters, or
5956
+ * returns `undefined` when the sample adds anything else.
5957
+ *
5958
+ * @remarks
5959
+ * The head and the shown sample are what a context's `build` returns for an empty turn without and
5960
+ * with the workspace: the shown sample holds the head's messages with the workspace section appended
5961
+ * to the context message, or one context message added where the head holds none. The cut keeps the
5962
+ * first `limit` characters of that added text and every other message as the sample holds it. A
5963
+ * sample whose messages differ from the head's in any other way, or that adds no text, returns
5964
+ * `undefined`.
5965
+ *
5966
+ * @param head - The head built with no workspace
5967
+ * @param shown - The head built with the workspace a request renders
5968
+ * @param limit - The characters of added text to keep
5969
+ * @returns The cut sample, or `undefined` when the sample adds no trailing text to one message
5970
+ *
5971
+ * @example
5972
+ * ```ts
5973
+ * import { cutWorkspaceSample } from '@orkestrel/agent'
5974
+ *
5975
+ * const head = [{ id: 's', role: 'system', content: 'Serve the desk.' }] as const
5976
+ * const shown = [...head, { id: 'c', role: 'user', content: '## Workspace\n\nFile: a.md' }] as const
5977
+ * cutWorkspaceSample(head, shown, 12)?.[1]?.content // '## Workspace'
5978
+ * ```
5979
+ */
5980
+ export declare function cutWorkspaceSample(head: readonly Message[], shown: readonly Message[], limit: number): readonly Message[] | undefined;
5981
+
5436
5982
  /**
5437
5983
  * Backs a {@link ConversationStoreInterface} with one table of the `databases` layer — a
5438
5984
  * conversation's durable state is a row holding the snapshot as one opaque JSON column, narrowed
@@ -5636,7 +6182,7 @@ export declare const DEFAULT_CONVERSATION_KEEP = 0;
5636
6182
  export declare const DEFAULT_LEDGER_LIMIT = 8;
5637
6183
 
5638
6184
  /**
5639
- * Supplies the default prompt and tail shares.
6185
+ * Supplies the default prompt, tail, and skills shares.
5640
6186
  */
5641
6187
  export declare const DEFAULT_LEDGER_SHARE: LedgerShare;
5642
6188
 
@@ -5681,6 +6227,28 @@ export declare const DEFAULT_RELAY_LIMIT = 1048576;
5681
6227
  */
5682
6228
  export declare function denyCall(call: ToolCall, reason: string | undefined): ToolResult;
5683
6229
 
6230
+ /**
6231
+ * Returns the refusal that names a subject and at most `BUILTIN_LIMITS.candidates` of the names a
6232
+ * caller can use.
6233
+ *
6234
+ * @remarks
6235
+ * The subject reads after "No", so it names what the caller may use, such as `'skill you can load'`.
6236
+ * The text echoes no argument, so an absent name and a name outside the ceiling read byte for byte
6237
+ * the same. Each name is JSON-encoded and capped by `preview`, in the order given. Past the cap one
6238
+ * fixed sentence sends the reader to the index in its prompt.
6239
+ *
6240
+ * @param subject - What the caller may name, such as `'skill you can load'`
6241
+ * @param names - The names the caller can use, in registry order
6242
+ * @returns The refusal text
6243
+ *
6244
+ * @example
6245
+ * ```ts
6246
+ * describeCandidates('skill you can load', ['refunds', 'billing'])
6247
+ * // 'No skill you can load has that name. Use one of: "refunds", "billing".'
6248
+ * ```
6249
+ */
6250
+ export declare function describeCandidates(subject: string, names: readonly string[]): string;
6251
+
5684
6252
  /**
5685
6253
  * Describes why a judge question refuses, in the text both of its doors throw.
5686
6254
  *
@@ -5748,9 +6316,10 @@ export declare const DETERMINISTIC_JUDGE_ERROR: RegExp;
5748
6316
  * Digests tool definitions as the JSON a provider request carries them, in order.
5749
6317
  *
5750
6318
  * @remarks
5751
- * A ledger stores this digest with its gauge, so a hydrate reuses the gauge only for the same
5752
- * definitions: an added, removed, reordered, or edited definition changes the digest. The digest is
5753
- * a {@link computeLedgerChecksum} checksum and makes no security claim.
6319
+ * A ledger stores this digest with its gauge and compares it at a hydrate and at each `respond`
6320
+ * call, so it reuses the gauge only for the same definitions: an added, removed, reordered, or
6321
+ * edited definition changes the digest. The digest is a {@link computeLedgerChecksum} checksum and
6322
+ * makes no security claim.
5754
6323
  *
5755
6324
  * @param definitions - The tool definitions, as a tool manager's `definitions` method returns them
5756
6325
  * @returns The 16-digit hexadecimal digest, or undefined when JSON cannot render the definitions
@@ -5939,6 +6508,34 @@ export declare interface FailureRead {
5939
6508
  readonly cause?: unknown;
5940
6509
  }
5941
6510
 
6511
+ /**
6512
+ * Returns the definitions a turn advertises from the allow-list, the registered skills, and the
6513
+ * shown skills.
6514
+ *
6515
+ * @remarks
6516
+ * The allow-list admits first, as `filterAllowList` does. When no skill is passed, or an allow-list
6517
+ * admits no `load` definition, the admitted list returns as it is. Otherwise a tool any registered
6518
+ * skill names is held back unless a shown skill names it too; `load` and `unload` are never held
6519
+ * back. A caller passes the registered skills only while `load` is enabled, so with no allow-list a
6520
+ * ceiling whose empty `skills` list withholds `load` from the candidates still holds the skills'
6521
+ * tools back. Holding a tool back is presentation, never authority: a call to it is denied as
6522
+ * outside the turn's scope.
6523
+ *
6524
+ * @param definitions - The candidate definitions, in advertisement order
6525
+ * @param names - The turn's `tools` allow-list (`undefined` ⇒ all, `[]` ⇒ none)
6526
+ * @param skills - The registered skills whose `tools` gate, or none while `load` is not enabled
6527
+ * @param shown - The names of the skills the turn shows
6528
+ * @returns The advertised definitions, in candidate order
6529
+ *
6530
+ * @example
6531
+ * ```ts
6532
+ * const skills = [{ id: '1', name: 'refunds', description: 'Refunds', content: '', tools: ['refund'], files: [] }]
6533
+ * filterAdvertisedTools([{ name: 'load' }, { name: 'refund' }], undefined, skills, []) // [{ name: 'load' }]
6534
+ * filterAdvertisedTools([{ name: 'load' }, { name: 'refund' }], undefined, skills, ['refunds']).length // 2
6535
+ * ```
6536
+ */
6537
+ export declare function filterAdvertisedTools(definitions: readonly ToolDefinition[], names: readonly string[] | undefined, skills: readonly Skill[], shown: readonly string[]): readonly ToolDefinition[];
6538
+
5942
6539
  /**
5943
6540
  * Filters a list of members by a {@link import('./contexts/index.js').ScopeInterface} allow-list of keys —
5944
6541
  * `undefined` passes everything, `[]` passes nothing, and a non-empty list passes the listed keys
@@ -5971,16 +6568,27 @@ export declare interface FailureRead {
5971
6568
  export declare function filterAllowList<T>(allow: readonly string[] | undefined, members: readonly T[], key: (member: T) => string): readonly T[];
5972
6569
 
5973
6570
  /**
5974
- * Finds the call that owns a tool message within a collected tool group.
5975
- * @param group - The assistant leader followed by its tool results
5976
- * @param message - The tool result to pair; distinct leader ids pair by result id when any result has one
5977
- * @returns The call matching the result's call id, or its position when the leader repeats an id or every result lacks an id; undefined when unpaired
6571
+ * Returns the definitions a run offers before the allow-list, without `remember` unless the
6572
+ * ceiling's `memos` list names a memo, without `switch` unless its `workspaces` list names a
6573
+ * workspace, and without `load` and `unload` while its `skills` list is empty.
6574
+ *
6575
+ * @remarks
6576
+ * `remember` writes and `switch` selects only a name its list holds, so an absent list and an empty
6577
+ * list each leave the built-in nothing to act on, and it is not advertised. An absent `skills` list
6578
+ * admits every registered skill, so `load` and `unload` are withheld only when the list is empty.
6579
+ * Every other definition keeps its place.
6580
+ *
6581
+ * @param definitions - The candidate definitions, in advertisement order
6582
+ * @param ceiling - The turn's ceiling
6583
+ * @returns The definitions, in candidate order
6584
+ *
5978
6585
  * @example
5979
6586
  * ```ts
5980
- * findLedgerCall(group, result)?.arguments
6587
+ * filterBuiltinCandidates([{ name: 'memo' }, { name: 'remember' }], { memos: [] }) // [{ name: 'memo' }]
6588
+ * filterBuiltinCandidates([{ name: 'memo' }, { name: 'remember' }], { memos: ['tone'] }).length // 2
5981
6589
  * ```
5982
6590
  */
5983
- export declare function findLedgerCall(group: readonly Message[], message: Message): ToolCall | undefined;
6591
+ export declare function filterBuiltinCandidates(definitions: readonly ToolDefinition[], ceiling: ScopeFilter): readonly ToolDefinition[];
5984
6592
 
5985
6593
  /**
5986
6594
  * Finds the first cut in a range whose probe returns a value, by bisection.
@@ -6000,6 +6608,18 @@ export declare function findLedgerCall(group: readonly Message[], message: Messa
6000
6608
  */
6001
6609
  export declare function findLedgerCut<T>(low: number, high: number, probe: (cut: number) => T | undefined, found?: T): T | undefined;
6002
6610
 
6611
+ /**
6612
+ * Finds the call that owns a tool message within a collected tool group.
6613
+ * @param group - The assistant leader followed by its tool results, as {@link collectToolGroups} returns it
6614
+ * @param message - The tool result to pair; distinct leader ids pair by result id when any result has one
6615
+ * @returns The call matching the result's call id, or its position when the leader repeats an id or every result lacks an id; undefined when unpaired
6616
+ * @example
6617
+ * ```ts
6618
+ * findToolCall(group, result)?.arguments
6619
+ * ```
6620
+ */
6621
+ export declare function findToolCall(group: readonly Message[], message: Message): ToolCall | undefined;
6622
+
6003
6623
  /**
6004
6624
  * Fits the marginal tokens one estimate unit adds within a request.
6005
6625
  *
@@ -6082,6 +6702,9 @@ export declare class Gauge implements GaugeInterface {
6082
6702
  observe(calls: readonly GaugeCall[], reply?: GaugeCall): void;
6083
6703
  }
6084
6704
 
6705
+ /** Lists the members `GaugeOptions` declares, frozen — the keys the `Gauge` constructor admits. */
6706
+ export declare const GAUGE_OPTION_KEYS: readonly ["scale", "overhead", "capacity", "predict", "replay"];
6707
+
6085
6708
  /**
6086
6709
  * Carries one agent call as the gauge reads it.
6087
6710
  *
@@ -6089,9 +6712,11 @@ export declare class Gauge implements GaugeInterface {
6089
6712
  * `estimate` is the `estimateMessages` estimate of the call's messages. `prompt` and `completion`
6090
6713
  * are the tokens the provider reported, absent when it reported none. `tools` is the count of tool
6091
6714
  * definitions the call advertised. `spared` is the tokens of definitions it did not advertise;
6092
- * estimated use subtracts it from overhead, floored at 0. Omission means 0. Observation rescales
6093
- * only with exact overhead: `spared` absent or zero retains all overhead, and `spared` at or above
6094
- * overhead retains none. A partially spared first call keeps the prior scale.
6715
+ * estimated use subtracts it from overhead, floored at 0. `added` is the tokens of definitions it
6716
+ * advertised beyond the calibrated set; estimated use adds it. Omission means 0 for both.
6717
+ * Observation rescales only with exact overhead: `spared` absent or zero retains all overhead, and
6718
+ * `spared` at or above overhead retains none. A partially spared first call, and a first call with
6719
+ * `added` above 0, keep the prior scale.
6095
6720
  * `thinking` estimates the completion tokens spent on thinking from its share of the generated
6096
6721
  * characters, rounded to the nearest integer and capped at `completion`. With replay `'none'`,
6097
6722
  * the measured call uses `prompt + completion - thinking`; other policies retain the whole
@@ -6101,6 +6726,8 @@ export declare interface GaugeCall {
6101
6726
  readonly estimate: number;
6102
6727
  /** Tokens spared by tool definitions this call did not advertise. Default: 0. */
6103
6728
  readonly spared?: number;
6729
+ /** Tokens of definitions this call advertised beyond the calibrated set. Default: 0. */
6730
+ readonly added?: number;
6104
6731
  readonly prompt?: number;
6105
6732
  readonly completion?: number;
6106
6733
  readonly thinking?: number;
@@ -6172,7 +6799,7 @@ export declare interface GaugeInterface extends LedgerGauge {
6172
6799
  * `'CAPACITY'` otherwise. `replay` names the thinking the next request carries. Default: `'none'`.
6173
6800
  * Measured use is `prompt + completion - (thinking ?? 0)` for `'none'`, and `prompt + completion`
6174
6801
  * otherwise; absent completion counts as 0. Without prompt usage, use is
6175
- * `max(0, overhead - (spared ?? 0)) + scale * estimate`.
6802
+ * `max(0, overhead - (spared ?? 0)) + (added ?? 0) + scale * estimate`.
6176
6803
  * Capacity left is `max(0, capacity - used)`. The reply reserve adds recall uniform at the marginal
6177
6804
  * rate to the largest observed reply's `completion - (thinking ?? 0)` for every policy.
6178
6805
  * Without a positive reply observation, it prices the longest reply text at that rate. The room formula
@@ -6321,8 +6948,10 @@ export declare function inferStop(reason: unknown, allowance: BudgetInterface<To
6321
6948
  * A thin immutable value object (mirroring {@link import('@orkestrel/tool').Tool}): the
6322
6949
  * constructor mints a fresh `id` (`crypto.randomUUID()`), copies the input's `name` /
6323
6950
  * `content`, resolves `priority` to the input's value or `0`, and carries the input's
6324
- * per-item `override` value when supplied; otherwise that property is `undefined`.
6325
- * Never mutated after construction. An
6951
+ * per-item `override` value when supplied; otherwise the instance owns no `override` member, so
6952
+ * its own keys and a JSON copy carry no member holding `undefined`. The input meets its exact
6953
+ * contract first, so a missing required member, an undeclared member, and a declared member holding
6954
+ * `undefined` refuse with a `ContractError` coded `'structure'`. Never mutated after construction. An
6326
6955
  * {@link import('./InstructionManager.js').InstructionManager} keys it by `name` and
6327
6956
  * renders it (highest `priority` first) under its section header.
6328
6957
  *
@@ -6341,6 +6970,9 @@ export declare class Instruction implements InstructionInterface {
6341
6970
  constructor(input: InstructionInput);
6342
6971
  }
6343
6972
 
6973
+ /** Lists the members `InstructionManagerOptions` declares, frozen — the keys the `InstructionManager` constructor admits. */
6974
+ export declare const INSTRUCTION_MANAGER_KEYS: readonly ["on", "error", "format"];
6975
+
6344
6976
  /**
6345
6977
  * Carries the minimal data to author an {@link InstructionInterface} — the `id` is minted by
6346
6978
  * the {@link InstructionManagerInterface} that stores it, so a caller supplies only
@@ -6360,6 +6992,29 @@ export declare interface InstructionInput {
6360
6992
  readonly override?: string;
6361
6993
  }
6362
6994
 
6995
+ /** Admits an instruction input exactly, and reads the faults of a refused one. */
6996
+ export declare const instructionInputContract: ContractInterface<Readonly<{
6997
+ name: string;
6998
+ content: string;
6999
+ } & {
7000
+ priority?: number;
7001
+ override?: string;
7002
+ }>>;
7003
+
7004
+ /**
7005
+ * Describes an instruction input exactly: a string `name` and `content`, and an optional finite
7006
+ * `priority` and string `override`.
7007
+ *
7008
+ * @remarks
7009
+ * An unknown member, a missing required member, and a declared member holding `undefined` refuse.
7010
+ */
7011
+ export declare const instructionInputShape: ObjectShape< {
7012
+ name: StringShape;
7013
+ content: StringShape;
7014
+ priority: OptionalShape<NumberShape>;
7015
+ override: OptionalShape<StringShape>;
7016
+ }, boolean | ContractShape>;
7017
+
6363
7018
  /**
6364
7019
  * Represents an immutable instruction — a named directive a richer context places between the
6365
7020
  * system prompt and the conversation, ordered by descending {@link priority}.
@@ -6496,6 +7151,7 @@ export declare interface InstructionManagerInterface {
6496
7151
  *
6497
7152
  * @param input - One {@link InstructionInput}, or a batch
6498
7153
  * @returns The stored instruction, or the stored batch in input order
7154
+ * @throws {ContractError} Thrown when an input fails `instructionInputContract`: a missing required member, an undeclared member, or a declared member holding `undefined` (`code: 'structure'`); a refused batch stores nothing
6499
7155
  */
6500
7156
  add(input: InstructionInput): InstructionInterface;
6501
7157
  add(inputs: readonly InstructionInput[]): readonly InstructionInterface[];
@@ -6554,6 +7210,30 @@ export declare interface InstructionManagerOptions {
6554
7210
  readonly format?: ContextSectionFormat<InstructionInterface>;
6555
7211
  }
6556
7212
 
7213
+ /**
7214
+ * Intersects two scope filters list by list; an absent side constrains nothing.
7215
+ *
7216
+ * @remarks
7217
+ * Pure, and it can only tighten. Each list of the result is {@link intersectKeys} over the two
7218
+ * sides' lists, each read one time, in the order `instructions`, `skills`, `memos`, `tools`,
7219
+ * `files`, and `workspaces`. A list neither side constrains is omitted, and every returned list is
7220
+ * a fresh copy.
7221
+ * `Scope.narrow`, a run's build, and a ledger's answer-pass scope compose their layers through it.
7222
+ *
7223
+ * @param parent - The outer filter, such as the context scope (`undefined` ⇒ no constraint)
7224
+ * @param child - The inner filter, such as a run scope (`undefined` ⇒ no constraint)
7225
+ * @returns The intersected filter
7226
+ *
7227
+ * @example
7228
+ * ```ts
7229
+ * import { intersectFilters } from '@orkestrel/agent'
7230
+ *
7231
+ * intersectFilters({ tools: ['read', 'write'] }, { tools: ['write', 'admin'], files: [] })
7232
+ * // { tools: ['write'], files: [] }
7233
+ * ```
7234
+ */
7235
+ export declare function intersectFilters(parent: ScopeFilter | undefined, child: ScopeFilter | undefined): ScopeFilter;
7236
+
6557
7237
  /**
6558
7238
  * Intersects two scope category lists under the "`undefined` is the universal set" rule — a
6559
7239
  * fresh copy that can only tighten, and the primitive a scope narrows through.
@@ -6585,6 +7265,43 @@ export declare function intersectKeys(parent: readonly string[] | undefined, chi
6585
7265
  */
6586
7266
  export declare const INVALID_RELAY_STATUS = 400;
6587
7267
 
7268
+ /**
7269
+ * Checks whether a value names a built-in: `load`, `unload`, `memo`, `remember`, or `switch`.
7270
+ *
7271
+ * @param value - The unknown name candidate
7272
+ * @returns True if the value names a built-in; false otherwise
7273
+ *
7274
+ * @example
7275
+ * ```ts
7276
+ * isAgentBuiltin('load') // true
7277
+ * isAgentBuiltin('open') // false
7278
+ * ```
7279
+ */
7280
+ export declare function isAgentBuiltin(value: unknown): value is AgentBuiltin;
7281
+
7282
+ /**
7283
+ * Checks whether a value is an agent caller: a plain record whose own keys are exactly `workspace`
7284
+ * and `files`, whose `workspace` is `undefined` or an object, and whose `files` is `undefined` or an
7285
+ * array of strings.
7286
+ *
7287
+ * @remarks
7288
+ * Total: each member is read once, and an omitted, inherited, or undeclared member, a throwing
7289
+ * accessor, and a revoked `Proxy` return false rather than throw. It checks the shape a caller
7290
+ * carries, never that `workspace` is a live workspace: a value that crossed a wire passes when it
7291
+ * holds that shape, so accept its `workspace` only as the very instance your own registry holds
7292
+ * under that id.
7293
+ *
7294
+ * @param value - The unknown caller candidate, such as `ToolContext.caller`
7295
+ * @returns True if the value satisfies the caller contract; false otherwise
7296
+ *
7297
+ * @example
7298
+ * ```ts
7299
+ * isAgentCaller({ workspace: undefined, files: undefined }) // true
7300
+ * isAgentCaller({ workspace: 'returns' }) // false
7301
+ * ```
7302
+ */
7303
+ export declare function isAgentCaller(value: unknown): value is AgentCaller;
7304
+
6588
7305
  /**
6589
7306
  * Narrows an unknown caught value to an {@link AgentError} through its identity brand and declared members, so a `catch`
6590
7307
  * can branch on its `code`.
@@ -7027,13 +7744,17 @@ export declare function isMemoSnapshot(value: unknown): value is MemoSnapshot;
7027
7744
  export declare function isMessage(value: unknown): value is Message;
7028
7745
 
7029
7746
  /**
7030
- * Checks whether a value is a message input a conversation can store: a string `content`, and `calls`,
7031
- * `call`, `images`, and `thinking` absent or of their declared types.
7747
+ * Checks whether a value is a message input a conversation can store: a `ConversationRole`, a string
7748
+ * `content`, and `calls`, `call`, `images`, and `thinking` absent or of their declared types.
7032
7749
  *
7033
7750
  * @remarks
7034
- * A hand guard, because `add` checks every message: it reads the members once and composes no record
7035
- * guard. The role is `requireRole`'s to refuse, so its text can name the role received. Unknown members
7036
- * are left behind by the store. An unreadable member returns false.
7751
+ * An exact record, because a stored message is one: a value that is not a plain record, such as a
7752
+ * class instance or an object that inherits its `role`, returns false through `recordOf`'s own plain
7753
+ * record check, as does a member `MessageInput` does not declare or a declared optional member holding
7754
+ * `undefined`. Each tool call crosses `isToolCall` of
7755
+ * `@orkestrel/tool`, whose interface admits more members, so the store keeps `id`, `name`, and
7756
+ * `arguments` and leaves the rest. `add` reads the role through `requireRole` first, so its text can
7757
+ * name the role received. An unreadable member returns false.
7037
7758
  *
7038
7759
  * @param value - The unknown input candidate
7039
7760
  * @returns True if the input's members are valid; false otherwise
@@ -7043,7 +7764,7 @@ export declare function isMessage(value: unknown): value is Message;
7043
7764
  * isMessageInput({ role: 'user' }) // false
7044
7765
  * ```
7045
7766
  */
7046
- export declare function isMessageInput(value: unknown): value is MessageInput;
7767
+ export declare const isMessageInput: Guard<MessageInput>;
7047
7768
 
7048
7769
  /**
7049
7770
  * Checks whether a value is a non-negative safe integer, `-0` included.
@@ -7130,6 +7851,30 @@ export declare function isProviderError(value: unknown): value is ProviderError;
7130
7851
  */
7131
7852
  export declare const isProviderResult: Guard<ProviderResult>;
7132
7853
 
7854
+ /**
7855
+ * Checks whether a value implements `ScopeInterface`; total, each member read one time, any
7856
+ * implementation admitted.
7857
+ *
7858
+ * @remarks
7859
+ * A scope is a string `id` and `name`, each of `instructions`, `skills`, `memos`, `tools`, `files`,
7860
+ * and `workspaces` absent or a dense array of strings, `select` absent or a function, and a `narrow`
7861
+ * function. The guard reads each of those members one time and never calls a method. It admits
7862
+ * unknown members, a class instance, and a transparent proxy, and returns false for a throwing
7863
+ * getter, a revoked proxy, and any other malformed input.
7864
+ *
7865
+ * @param value - The value to test
7866
+ * @returns True if `value` carries the members of a {@link ScopeInterface}; false otherwise
7867
+ *
7868
+ * @example
7869
+ * ```ts
7870
+ * import { createScope, isScope } from '@orkestrel/agent'
7871
+ *
7872
+ * isScope(createScope({ name: 'reader', tools: ['search'] })) // true
7873
+ * isScope({ id: 's1', name: 'reader' }) // false
7874
+ * ```
7875
+ */
7876
+ export declare function isScope(value: unknown): value is ScopeInterface;
7877
+
7133
7878
  /**
7134
7879
  * Checks whether an `unknown` is structurally a {@link Section} record — a `string` `id` and
7135
7880
  * `summary` beside a `messages` array of valid {@link Message} records, the per-section step of
@@ -7193,6 +7938,18 @@ export declare function isSystemOneAnswer(value: unknown): value is SystemOneAns
7193
7938
  */
7194
7939
  export declare function isSystemOneResponse(value: unknown): value is SystemOneResponse;
7195
7940
 
7941
+ /**
7942
+ * Opens a job tree finding that refuses a whole job, which sets it apart from a finding that names an exceeded member.
7943
+ *
7944
+ * @remarks
7945
+ * The `scanJobTree` helper writes it before the path of a job the contract refuses or a member read
7946
+ * makes unreadable, and the `AgentFanout` class reads it to open its refusal with the rule that
7947
+ * finding breaks. An
7948
+ * exceeded member's finding opens with `job`, so text later in a finding cannot pass for this
7949
+ * prefix.
7950
+ */
7951
+ export declare const JOB_REFUSAL_PREFIX = "refused ";
7952
+
7196
7953
  /**
7197
7954
  * Joins the reasoning a run's provider calls separated from the answer — the first call
7198
7955
  * seeds the accumulation, a later call appends blank-line separated so each turn's reasoning
@@ -7218,6 +7975,9 @@ export declare function isSystemOneResponse(value: unknown): value is SystemOneR
7218
7975
  */
7219
7976
  export declare function joinThinking(prior: string | undefined, next: string): string;
7220
7977
 
7978
+ /** Lists the members `AgentJudgeInput` declares, frozen — the keys the `AgentJudge` constructor admits. */
7979
+ export declare const JUDGE_INPUT_KEYS: readonly ["url", "path", "model", "batch", "timeout", "fetch", "headers"];
7980
+
7221
7981
  /**
7222
7982
  * Reports a judge call cancelled by the caller's signal or its deadline, carrying the
7223
7983
  * {@link JudgeResult} merged from the calls that completed before the cancel and the
@@ -7728,10 +8488,10 @@ export declare class Ledger implements LedgerInterface {
7728
8488
  */
7729
8489
  constructor(provider: ProviderInterface, options: LedgerOptions);
7730
8490
  /**
7731
- * Returns the owned request engine.
7732
- * @returns The engine serving this conversation
8491
+ * Returns the record of the owned request engine, which starts no run.
8492
+ * @returns The frozen record of the agent serving this conversation
7733
8493
  */
7734
- get agent(): AgentInterface;
8494
+ get agent(): LedgerAgentInterface;
7735
8495
  /**
7736
8496
  * Returns the owned message history.
7737
8497
  * @returns The history filed and served by this ledger
@@ -7744,9 +8504,10 @@ export declare class Ledger implements LedgerInterface {
7744
8504
  get gauge(): LedgerGauge | undefined;
7745
8505
  /**
7746
8506
  * Measures message scale and tool overhead from provider prompt usage.
7747
- * @param signal - The signal bounding both calibration calls; an abort rejects with its reason
8507
+ * @param signal - The signal bounding every calibration call; an abort rejects with its reason
7748
8508
  * @returns The stored scale and overhead cost
7749
- * @throws {LedgerError} Thrown when either call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)
8509
+ * @throws {LedgerError} Thrown when a calibration call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)
8510
+ * @throws {LedgerError} Thrown when a calibration call, with the tool definitions, without them, or with the workspace text, reports a prompt over `capacity`, the head included (code `'GAUGE'`)
7750
8511
  * @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)
7751
8512
  */
7752
8513
  calibrate(signal: AbortSignal): Promise<LedgerGauge>;
@@ -7759,18 +8520,31 @@ export declare class Ledger implements LedgerInterface {
7759
8520
  /**
7760
8521
  * Appends a request and serves it, recovering an unfinished or rejected first pass with one answer pass.
7761
8522
  * In either pass, a call the model makes in a turn that advertises no tools runs nothing and ends the pass after that generation, whatever the agent's `limit`, and when every call of that turn failed, the ledger stores the reply without its calls: a reply with text ends the pass complete, and one without text ends it partial with empty content.
7762
- * A calibration call that reports no prompt usage, or a prompt usage of 0 or less, rejects with `LedgerError` code `'GAUGE'`; a provider error during calibration rejects with that error.
8523
+ * A calibration call that reports no prompt usage, or a prompt usage of 0 or less, rejects with `LedgerError` code `'GAUGE'`; a provider error during calibration rejects with that error. A calibration call, with the tool definitions, without them, or with the workspace text, that reports a prompt over `capacity`, the head included, rejects with the same code and stores no request.
7763
8524
  * When the answer pass rejects, `respond` rejects with that error, and under the default `strict` a judge failure or another selection failure rejects it too. A rejection belongs to its own call: the ledger stays free, and the next call asks the judge again about whatever is still unanswered.
7764
8525
  * @param content - The request text
7765
8526
  * @param signal - The caller's cancellation signal; an abort during calibration rejects with its reason
7766
8527
  * @returns The final pass, the usage of every pass, and the filing attempts of this request alone
7767
8528
  * @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)
7768
8529
  * @throws {LedgerError} Thrown when a calibration call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)
8530
+ * @throws {LedgerError} Thrown when a calibration call, with the tool definitions, without them, or with the workspace text, reports a prompt over `capacity`, the head included (code `'GAUGE'`)
8531
+ * @throws {LedgerError} Thrown when the answer pass prices over `capacity - predict` with its note left out, or a host act after the note grows its request past that limit (code `'OVERFLOW'`)
7769
8532
  * @throws {ContractError} Thrown when `signal` is defined and is not a native `AbortSignal`
7770
8533
  */
7771
8534
  respond(content: string, signal?: AbortSignal): Promise<LedgerResult>;
7772
8535
  }
7773
8536
 
8537
+ /**
8538
+ * Lists the members the `LedgerAgentOptions` pick declares, frozen — the keys a ledger's `agent`
8539
+ * option admits.
8540
+ *
8541
+ * @remarks
8542
+ * The `Ledger` constructor passes the list to `refuseOptionKeys` of `@orkestrel/contract`, so an
8543
+ * own enumerable member outside it, an `AgentOptions` member the pick leaves out included, refuses
8544
+ * with a `ContractError` coded `'structure'`.
8545
+ */
8546
+ export declare const LEDGER_AGENT_KEYS: readonly ["limit", "timeout", "on", "scheduler", "instructions", "skills", "memos", "workspaces", "strict", "authority", "builtins", "workspace"];
8547
+
7774
8548
  /**
7775
8549
  * Lists the categories the ledger files a message under, in the order the category question
7776
8550
  * names them — the one list the {@link LedgerCategory} union derives from.
@@ -7780,9 +8554,22 @@ export declare const LEDGER_CATEGORIES: readonly ["fact", "rule", "correction",
7780
8554
  /**
7781
8555
  * Supplies the text of each ledger note, worded for a model that answers in its final
7782
8556
  * message.
8557
+ *
8558
+ * @remarks
8559
+ * `overflow` names `unload` because a skill the thread shows is the room a model can give back: a
8560
+ * successful `unload` reopens every call the room denied in that request.
7783
8561
  */
7784
8562
  export declare const LEDGER_NOTES: LedgerNote;
7785
8563
 
8564
+ /**
8565
+ * Lists the members `LedgerOptions` declares, frozen — the keys the `Ledger` constructor admits.
8566
+ *
8567
+ * @remarks
8568
+ * The constructor passes the list to `refuseOptionKeys` of `@orkestrel/contract`, so an own
8569
+ * enumerable member outside it refuses with a `ContractError` coded `'structure'`.
8570
+ */
8571
+ export declare const LEDGER_OPTION_KEYS: readonly ["judge", "system", "topics", "questions", "thresholds", "capacity", "predict", "think", "gauge", "lookups", "writes", "share", "recall", "correction", "agent", "snapshot"];
8572
+
7786
8573
  /** Prefixes the key of an owner's record, which the owner's id follows. */
7787
8574
  export declare const LEDGER_OWNER_PREFIX = "owner:";
7788
8575
 
@@ -7803,6 +8590,17 @@ export declare const LEDGER_RECALL_LABELS: Readonly<{
7803
8590
  /** Names the key of the record that holds the rules no owner claims. */
7804
8591
  export declare const LEDGER_RULES_KEY = "rules";
7805
8592
 
8593
+ /**
8594
+ * Sets the 3 UTF-8 bytes one UTF-16 code unit encodes to at most, the divisor that sizes the
8595
+ * workspace text a calibration's third call carries.
8596
+ *
8597
+ * @remarks
8598
+ * A tokenizer that falls back to bytes charges at most one token a byte, so workspace text cut to the
8599
+ * capacity the call without definitions left, divided by this figure, in characters, reports at most
8600
+ * `capacity` apart from a template's few tokens for an added message.
8601
+ */
8602
+ export declare const LEDGER_SAMPLE_BYTES = 3;
8603
+
7806
8604
  /**
7807
8605
  * Holds back the share of the prompt budget the scale can rise by between calibration and a
7808
8606
  * request's first call.
@@ -7831,6 +8629,30 @@ export declare const LEDGER_SLICE = 5;
7831
8629
  */
7832
8630
  export declare const LEDGER_WORD: RegExp;
7833
8631
 
8632
+ /**
8633
+ * Holds the members of a ledger's agent a host reads: its emitter, id, status, context, and abort.
8634
+ *
8635
+ * @remarks
8636
+ * It is one frozen record the ledger builds at construction, and it holds no `generate` or `stream`
8637
+ * member, own or inherited, so the ledger's `respond` method is the only caller that starts a run on
8638
+ * the agent: every run is a pass of the active `respond` call, on the ledger's `conversation`. The
8639
+ * `emitter`, `id`, and `context` members are the agent's own. The `status` member reads the agent's
8640
+ * live status, and `abort` ends the active pass partial with the reason it takes; because the caller
8641
+ * did not abort, the ledger then runs the answer pass. To serve another conversation, build another
8642
+ * ledger or another agent for it.
8643
+ *
8644
+ * @example
8645
+ * ```ts
8646
+ * import { createLedger } from '@orkestrel/agent'
8647
+ *
8648
+ * const ledger = createLedger(provider, options) // `provider` and `options` come from the host
8649
+ * ledger.agent.emitter.on('request', (_index, request) => log(request.tools?.length))
8650
+ * ledger.agent.status // 'idle'
8651
+ * 'generate' in ledger.agent // false
8652
+ * ```
8653
+ */
8654
+ export declare type LedgerAgentInterface = Pick<AgentInterface, 'emitter' | 'id' | 'status' | 'context' | 'abort'>;
8655
+
7834
8656
  /**
7835
8657
  * Selects the agent bounds, hooks, scheduler, and context libraries a ledger passes through to the agent it builds.
7836
8658
  *
@@ -7854,9 +8676,14 @@ export declare const LEDGER_WORD: RegExp;
7854
8676
  * unanswered as a repeat, before its `evaluate` method and with no ask, and its `ask` refuses the
7855
8677
  * identical twin in the same batch of a declined or unanswered ask without calling this authority's
7856
8678
  * `ask`, so a person is asked about such a call once per request. The agent still reports that
7857
- * twin's `ask` event.
8679
+ * twin's `ask` event. `builtins` enables the built-in tools and `workspace` names the workspace
8680
+ * every request renders, as `AgentOptions` describes them. A ledger with `builtins` requires `authority`:
8681
+ * construction throws `AgentError` with code `'AUTHORITY'` without it. The ledger tests each
8682
+ * built-in call for a repeat and for room before this authority reads it, and every call it admits
8683
+ * reaches this authority's `evaluate` and, when asked, its `ask`. While `builtins` enables `load`,
8684
+ * calibration measures every definition but the tools a registered skill holds back.
7858
8685
  */
7859
- export declare type LedgerAgentOptions = Pick<AgentOptions, 'limit' | 'timeout' | 'on' | 'scheduler' | 'instructions' | 'skills' | 'memos' | 'workspaces' | 'strict' | 'authority'>;
8686
+ export declare type LedgerAgentOptions = Pick<AgentOptions, 'limit' | 'timeout' | 'on' | 'scheduler' | 'instructions' | 'skills' | 'memos' | 'workspaces' | 'strict' | 'authority' | 'builtins' | 'workspace'>;
7860
8687
 
7861
8688
  /** Identifies an accepted direct message amendment whose sentence scope remains unresolved. */
7862
8689
  export declare interface LedgerAmendment {
@@ -7891,6 +8718,13 @@ export declare interface LedgerClassification {
7891
8718
  readonly supersessions: ReadonlyMap<string, readonly string[]>;
7892
8719
  }
7893
8720
 
8721
+ /** Carries one price a request committed: the tokens, the count of calls observed when it was committed, and the skill a `load` names. */
8722
+ export declare interface LedgerCommit {
8723
+ readonly price: number;
8724
+ readonly turn: number;
8725
+ readonly skill?: string;
8726
+ }
8727
+
7894
8728
  /**
7895
8729
  * Narrows the pair questions the ledger asks about each correction.
7896
8730
  *
@@ -7928,7 +8762,9 @@ export declare type LedgerEntityHandler = (text: string, partial: boolean) => Re
7928
8762
  * @remarks
7929
8763
  * A threshold, share, capacity, limit, topic, lookup, write, question, or gauge outside its bounds is a
7930
8764
  * programmer error and throws this with the matching {@link LedgerErrorCode}. A calibration call that reports
7931
- * no prompt usage throws this with `'GAUGE'`. A snapshot option that `isLedgerSnapshot` refuses
8765
+ * no prompt usage, or a calibration call, with the tool definitions, without them, or with the workspace text, that reports a prompt
8766
+ * over `capacity`, the head included, throws this with `'GAUGE'`; the second holds `capacity` and
8767
+ * `prompt` in its `context`. A snapshot option that `isLedgerSnapshot` refuses
7932
8768
  * throws this with `'SNAPSHOT'`, its `context` holding the `faults`. Narrow a caught value with {@link isLedgerError} and
7933
8769
  * branch on `error.code`. A selection without an active `respond` call, for a conversation other
7934
8770
  * than the ledger's, or for a request other than that call's request or a ledger note, reports
@@ -7965,7 +8801,7 @@ export declare type LedgerErrorCode =
7965
8801
  | 'TOPIC'
7966
8802
  /** Reports a lookup tool named `recall` or a name another lookup tool carries. */
7967
8803
  | 'LOOKUP'
7968
- /** Reports a supplied gauge outside its bounds, or a calibration call that reports no prompt usage, or a prompt usage of 0 or less. */
8804
+ /** Reports a supplied gauge outside its bounds, a calibration call that reports no prompt usage or a prompt usage of 0 or less, or a calibration call, with the tool definitions, without them, or with the workspace text, that prices a prompt over `capacity`, the head included. */
7969
8805
  | 'GAUGE'
7970
8806
  /** Reports a render context that holds no reference for a source it annotates. */
7971
8807
  | 'REFERENCE'
@@ -7974,7 +8810,9 @@ export declare type LedgerErrorCode =
7974
8810
  /** Reports filing wording that `isLedgerQuestion` refuses. */
7975
8811
  | 'QUESTION'
7976
8812
  /** Reports a write without the `consequential` annotation, writes without `agent.authority`, or a write named `recall` or with a name a lookup or another write carries. */
7977
- | 'WRITE';
8813
+ | 'WRITE'
8814
+ /** Reports a request no pass can carry, because the context the thread shows and the request price over `capacity - predict` with every cut made, or a host act after the answer pass's note grew its request past that limit. */
8815
+ | 'OVERFLOW';
7978
8816
 
7979
8817
  /** Captures held message identities and the accepted edges used to validate their copies. */
7980
8818
  export declare interface LedgerEvidence {
@@ -8014,9 +8852,13 @@ export declare interface LedgerGauge {
8014
8852
  * Carries a stored gauge: its price and the digest of the tool definitions that price measured.
8015
8853
  *
8016
8854
  * @remarks
8017
- * `digest` is what the `digestLedgerTools` helper returns for the definitions the calibration request
8018
- * carried, or for the ledger's definitions at construction when the options supplied the gauge. A
8019
- * hydrate reuses the price only when the hydrated ledger's definitions have the same digest.
8855
+ * `digest` is what the `digestLedgerTools` helper returns for the calibrated definitions: those the
8856
+ * calibration request carried, or, when the options supplied the gauge, the ledger's calibrated
8857
+ * definitions at construction. The calibrated set is every definition a turn can advertise but the
8858
+ * tools a registered skill holds back while `agent.builtins` enables `load`. A hydrate reuses the
8859
+ * price only when the hydrated ledger's calibrated definitions have the same digest, and each
8860
+ * `respond` call compares the digest again, so a calibrated definition added or removed since drops
8861
+ * the gauge.
8020
8862
  */
8021
8863
  export declare interface LedgerGaugeSnapshot extends LedgerGauge {
8022
8864
  readonly digest: string;
@@ -8063,8 +8905,11 @@ export declare interface LedgerIndex {
8063
8905
  * selection handler.
8064
8906
  */
8065
8907
  export declare interface LedgerInterface {
8066
- /** Holds the agent the ledger drives, with the ledger's tools and selection handler. */
8067
- readonly agent: AgentInterface;
8908
+ /**
8909
+ * Holds the record of the agent the ledger drives, with the ledger's tools and selection handler;
8910
+ * it starts no run, so the `respond` method runs every pass.
8911
+ */
8912
+ readonly agent: LedgerAgentInterface;
8068
8913
  /** Holds the one conversation the ledger files and serves. */
8069
8914
  readonly conversation: ConversationInterface;
8070
8915
  /** Holds the measured price of a prompt, or undefined until the ledger calibrates when neither the options nor a snapshot priced on the same tool definitions supplied one. */
@@ -8073,7 +8918,9 @@ export declare interface LedgerInterface {
8073
8918
  * Appends `content` as a user message and serves it through to its reply.
8074
8919
  *
8075
8920
  * @remarks
8076
- * The ledger calibrates first while `gauge` is undefined. When the first pass ends without final
8921
+ * The ledger calibrates first while `gauge` is undefined, and again when the digest of its tool
8922
+ * definitions at this call differs from the one its gauge priced. When the first pass ends
8923
+ * without final
8077
8924
  * text and the caller did not abort, the ledger adds the results and cue notes and makes one
8078
8925
  * answer pass that advertises no tools. In either pass, a call the model makes in a turn that
8079
8926
  * advertises no tools runs nothing and ends the pass after that turn, so such a pass makes one
@@ -8082,23 +8929,25 @@ export declare interface LedgerInterface {
8082
8929
  * reply's text and `partial: false`, or partial with empty content when the reply carries no text. A rejected first pass counts as unfinished; when the
8083
8930
  * answer pass rejects as well, `respond` rejects with that pass's error. A `respond` or `calibrate` call while either is in flight
8084
8931
  * rejects with an `AgentError` whose `code` is `'CONCURRENCY'`. A calibration call that reports no prompt usage, or a prompt usage of 0 or less, rejects with
8085
- * `LedgerError` code `'GAUGE'`; a provider error during calibration rejects with that error.
8086
- * A direct agent run on `conversation` while a `respond` call's pass runs is refused with an
8087
- * `AgentError` whose `code` is `'CONCURRENCY'`. Under the default `strict`, any other run no active
8088
- * `respond` call owns rejects with a `LedgerError` whose `code` is `'REQUEST'`: a direct run between
8089
- * requests, one during calibration, and a run on another conversation during a call. Under
8090
- * `strict: false` that run goes on over the whole view with no ledger selection; a run on another
8091
- * conversation then adds its turns and usage to that call's gauge readings and shares its repeat
8092
- * stop, and it can still reach the `recall` and lookup tools, which read `conversation`. The
8093
- * ledger's own guard refuses only `respond`, `calibrate`, and `snapshot` calls.
8094
- * Under `strict: false`, a run no `respond` call owns, including a run during calibration, reads no
8095
- * request's state: its lookup and `recall` calls run with no repeat stop, recall limit, or close rule.
8096
- * Every rejection leaves the ledger free for a later call.
8932
+ * `LedgerError` code `'GAUGE'`; a provider error during calibration rejects with that error. A calibration call, with the
8933
+ * tool definitions, without them, or with the workspace text, that reports a prompt over `capacity`, the head included,
8934
+ * rejects with the same code and stores no request.
8935
+ * Every run on the ledger's agent is a pass of this method, because `agent` holds no `generate` or
8936
+ * `stream` member. A direct call to `agent.context.select` for a message no active `respond` call
8937
+ * owns returns a selection whose `fault` is a `LedgerError` with code `'REQUEST'`, on
8938
+ * `conversation` or another one, and asks the judge nothing; over another conversation, that
8939
+ * selection carries that conversation's view alone. Calibration owns no message, so a direct
8940
+ * selection during it faults the same way. Host code that calls a ledger tool by hand through
8941
+ * `agent.context.tools` while a request runs reaches that request's state: a lookup or a write
8942
+ * meets its repeat stop, and a `recall` call spends its recall limit. Between requests, and during
8943
+ * calibration, such a call reads no request's state and runs with no repeat stop, recall limit, or
8944
+ * close rule. Every rejection leaves the ledger free for a later call.
8097
8945
  *
8098
8946
  * @param content - The request text
8099
8947
  * @param signal - An optional caller signal; an abort during calibration rejects with its reason; afterward it ends the request partial and skips the answer pass
8100
8948
  * @returns The reply, the passes the request took, and the filing attempts of this request alone
8101
8949
  * @throws {LedgerError} Thrown when a calibration call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)
8950
+ * @throws {LedgerError} Thrown when a calibration call, with the tool definitions, without them, or with the workspace text, reports a prompt over `capacity`, the head included (code `'GAUGE'`)
8102
8951
  * @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)
8103
8952
  * @throws {ContractError} Thrown when `signal` is defined and is not a native `AbortSignal`
8104
8953
  */
@@ -8107,16 +8956,25 @@ export declare interface LedgerInterface {
8107
8956
  * Measures the gauge, holds it as `gauge`, and returns it.
8108
8957
  *
8109
8958
  * @remarks
8110
- * The ledger sends the head its agent's context builds and its conversation's view to the provider twice, with
8111
- * and without the tool definitions. The call without tools prices the messages and the
8112
- * difference between the calls is the overhead cost. The ledger records the digest of the
8959
+ * The ledger sends the head its agent's context builds for an empty turn, with no workspace text and
8960
+ * no conversation message, to the provider with the calibrated tool definitions and then without
8961
+ * them, and the difference between the calls is the overhead cost. When the workspace the next
8962
+ * request renders adds text, a third call carries the head and that text with no definitions, cut
8963
+ * to the capacity the second call left over `LEDGER_SAMPLE_BYTES`, in characters. The scale is the
8964
+ * reported prompt of the head with the workspace over its estimate, a cut text's tokens scaled to the
8965
+ * whole text's estimate, and never under the head's own rate; with no workspace text it is the
8966
+ * second call's prompt over the head's estimate. When the call with the definitions reports a
8967
+ * prompt over `capacity`, the head included, the ledger sends no second call, stores no gauge, and
8968
+ * rejects with `LedgerError` code `'GAUGE'`, whose `context` holds `capacity` and `prompt`; the
8969
+ * call without them and the call with the workspace text refuse the same way. The ledger records the digest of the
8113
8970
  * definitions the call with tools carried, and its snapshot stores that digest with the gauge.
8114
8971
  * An abort during calibration rejects with the abort reason. A call during `respond` or `calibrate` rejects
8115
8972
  * with `AgentError` code `'CONCURRENCY'`.
8116
8973
  *
8117
- * @param signal - The signal that aborts both calls
8974
+ * @param signal - The signal that aborts every calibration call
8118
8975
  * @returns The measured gauge
8119
8976
  * @throws {LedgerError} Thrown when a call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)
8977
+ * @throws {LedgerError} Thrown when a calibration call, with the tool definitions, without them, or with the workspace text, reports a prompt over `capacity`, the head included (code `'GAUGE'`)
8120
8978
  * @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)
8121
8979
  */
8122
8980
  calibrate(signal: AbortSignal): Promise<LedgerGauge>;
@@ -8124,10 +8982,9 @@ export declare interface LedgerInterface {
8124
8982
  * Serializes the conversation, the marked ids, and the gauge into a snapshot a later ledger hydrates from.
8125
8983
  *
8126
8984
  * @remarks
8127
- * The ledger first files every tool result whose message is appended, so a failure a direct
8128
- * agent run left is marked; a result whose tool message is not yet appended is not captured. A
8129
- * call while a `respond` or `calibrate` call is in flight throws, because an entered, unanswered
8130
- * request would hydrate as a dangling request; a direct agent run is not refused. The `gauge`
8985
+ * The ledger first files every tool result whose message is appended; a result whose tool message
8986
+ * is not yet appended is not captured. A call while a `respond` or `calibrate` call is in flight
8987
+ * throws, because an entered, unanswered request would hydrate as a dangling request. The `gauge`
8131
8988
  * member carries the digest of the tool definitions the gauge priced.
8132
8989
  *
8133
8990
  * @returns The snapshot, each id list in conversation order and `gauge` present after the ledger holds one whose definitions JSON renders
@@ -8248,12 +9105,17 @@ export declare type LedgerLookupState = 'failed' | 'empty' | 'shown' | 'hidden';
8248
9105
  * and the reason of the denial the ledger gives the identical retry of a call the authority denied;
8249
9106
  * the ledger reads a failure with exactly this text, or that denial, as a repeat. `closure` is the
8250
9107
  * failure a `recall` call returns after the request's recalls are spent, repeated, or out of room.
9108
+ * `overflow` is the reason of the denial the ledger gives a `load`, a `remember`, or a `switch` the
9109
+ * request or the thread has no room for. That denial stays out of the repeat stop, and a successful
9110
+ * `unload` in the same request reopens the call.
8251
9111
  */
8252
9112
  export declare interface LedgerNote {
8253
9113
  readonly cue: string;
8254
9114
  readonly results: string;
8255
9115
  readonly repeat: string;
8256
9116
  readonly closure: string;
9117
+ /** Holds the reason the ledger denies a `load`, a `remember`, or a `switch` the request or the thread has no room for. */
9118
+ readonly overflow: string;
8257
9119
  }
8258
9120
 
8259
9121
  /** Carries a rendered sentence with its record placement. */
@@ -8270,11 +9132,20 @@ export declare interface LedgerOccurrence extends LedgerLine, LedgerReceipt {
8270
9132
  * sentence included; it opens the system message, which also holds the instructions and the skills index the `agent` option supplies. The memos index and the workspace text go into the context message after it, and the records go into a copy of each request turn. `topics` lists the desk
8271
9133
  * topics. `questions` and `thresholds` are required with no default; pass the `LEDGER_QUESTIONS`
8272
9134
  * constant for the measured wording, and fit `thresholds` on the wording and the judge you pass. `capacity` is the model's context window in tokens and must be a positive safe
8273
- * integer. Without `gauge`, or a `snapshot` gauge priced on the same tool definitions, the ledger calibrates before its first pass. `share` defaults leaf by leaf to `DEFAULT_LEDGER_SHARE`. The ledger writes the `LEDGER_NOTES` text.
9135
+ * integer. Without `gauge`, or a `snapshot` gauge priced on the same calibrated definitions, the ledger calibrates before its first pass. The ledger prices with a supplied `gauge` as stated and compares it with no reported usage. `share` defaults leaf by leaf to `DEFAULT_LEDGER_SHARE`. The ledger writes the `LEDGER_NOTES` text.
8274
9136
  * `predict` is the generation cap in tokens, including thinking. Default: 0. It must be a
8275
9137
  * nonnegative safe integer less than `capacity`; construction throws `LedgerError` with code
8276
9138
  * `'CAPACITY'` otherwise. The plan budgets
8277
- * `max(0, (capacity - predict) * share.prompt - overhead) / (1 + LEDGER_SCALE_DRIFT)`.
9139
+ * `max(0, (capacity - predict) * share.prompt - (overhead - spared + added) - holdback) / (1 + LEDGER_SCALE_DRIFT)`.
9140
+ * `spared` and `added` are what `computeToolPrice` returns for the definitions the first pass
9141
+ * advertises with the thread's shown skills, against the calibrated set. While that pass advertises
9142
+ * `load`, `holdback` is the `computeSkillPrice` of the largest skill the ceiling admits and the
9143
+ * thread does not show, plus the price of one result: the longer of the longest stored tool result
9144
+ * and the gauge's reply reserve. Otherwise it is 0.
9145
+ * The ledger sends no request it prices over `capacity - predict`. A first pass or a later turn that
9146
+ * does not fit ends with the agent's `abort` reason `overflow`, and the answer pass answers; an
9147
+ * answer pass that does not fit with its note left out rejects `respond` with `LedgerError` code
9148
+ * `'OVERFLOW'`.
8278
9149
  * The plan retains its `remainder - predict < 2 * reserve` admission rule. Runtime recall fits whole
8279
9150
  * results to measured remaining capacity at the larger of the gauge rate and the request's measured
8280
9151
  * rate, allowing `LEDGER_SCALE_DRIFT` for new text. Lack of room omits results without closing recall.
@@ -8283,6 +9154,9 @@ export declare interface LedgerOccurrence extends LedgerLine, LedgerReceipt {
8283
9154
  * the marked ids a ledger's `snapshot()` returned; construction throws `LedgerError` with code
8284
9155
  * `'SNAPSHOT'` when `isLedgerSnapshot` refuses it, and `ConversationError` with code `'ROLE'` or
8285
9156
  * `'SNAPSHOT'` when its conversation holds a `system` message or repeats an id.
9157
+ * An own enumerable member this type or the `agent` pick does not declare refuses at construction
9158
+ * with a `ContractError` coded `'structure'`, an `AgentOptions` member the pick leaves out included,
9159
+ * and a declared member holding `undefined` reads as omitted.
8286
9160
  */
8287
9161
  export declare interface LedgerOptions {
8288
9162
  readonly judge: JudgeInterface;
@@ -8569,6 +9443,9 @@ export declare class LedgerRequest implements LedgerRequestInterface {
8569
9443
  /** Returns recall results with their accepted whole groups and provider-turn positions. */
8570
9444
  get listings(): readonly LedgerListing[];
8571
9445
  lines(result: string): ReadonlyMap<string, string> | undefined;
9446
+ commit(price: number, skill?: string): void;
9447
+ get committed(): number;
9448
+ get loads(): readonly string[];
8572
9449
  }
8573
9450
 
8574
9451
  /**
@@ -8578,7 +9455,7 @@ export declare class LedgerRequest implements LedgerRequestInterface {
8578
9455
  *
8579
9456
  * @remarks
8580
9457
  * A ledger creates one request per `respond` call and drops it when the call settles, so no request
8581
- * state reaches a later call or a run no call owns. Each agent run the call makes is a pass: `open`
9458
+ * state reaches a later call or a ledger tool a host calls by hand between requests. Each agent run the call makes is a pass: `open`
8582
9459
  * starts one, and `selection`, `boundary`, `usage`, `signal`, and `aborted` read the current pass,
8583
9460
  * the last one opened.
8584
9461
  * `calls` lists the gauge calls of every pass in order. A call stays in flight, taking its usage and
@@ -8743,6 +9620,17 @@ export declare interface LedgerRequestInterface {
8743
9620
  * @returns Each listed lookup line mapped to its stored first line, or undefined when no recall returned `result`
8744
9621
  */
8745
9622
  lines(result: string): ReadonlyMap<string, string> | undefined;
9623
+ /**
9624
+ * Records the tokens one cleared call commits to the next prompt.
9625
+ *
9626
+ * @param price - The tokens the call commits
9627
+ * @param skill - The skill the call loads, for a `load`
9628
+ */
9629
+ commit(price: number, skill?: string): void;
9630
+ /** Holds the tokens committed after the call in flight started. */
9631
+ readonly committed: number;
9632
+ /** Holds the skills the loads committed after the call in flight started name, in commit order. */
9633
+ readonly loads: readonly string[];
8746
9634
  }
8747
9635
 
8748
9636
  /**
@@ -8773,11 +9661,17 @@ export declare interface LedgerResult extends AgentResult {
8773
9661
  * with a delta copy, then its newest plain exchange with a full copy, then no exchange are priced
8774
9662
  * in that order. Admission cannot close an otherwise open recall or displace a selected record
8775
9663
  * line or seed message. A seed stub reads visibility across the window and the copy together.
9664
+ * `skills` is the share of the prompt budget, `(capacity - predict) * prompt`, that a thread's shown
9665
+ * skills can take: their bodies and the definitions they add beyond the calibrated set. A `load`
9666
+ * that would take the shown skills, the loads its batch already admitted, and its own skill past it
9667
+ * is denied with the {@link LedgerNote} `overflow` text.
8776
9668
  * Each share must be finite, greater than 0, and at most 1.
8777
9669
  */
8778
9670
  export declare interface LedgerShare {
8779
9671
  readonly prompt: number;
8780
9672
  readonly tail: number;
9673
+ /** Holds the share of the prompt budget a thread's shown skills can take, bodies and tools together. */
9674
+ readonly skills: number;
8781
9675
  }
8782
9676
 
8783
9677
  /**
@@ -9314,6 +10208,30 @@ export declare interface LiteralSet {
9314
10208
  readonly numbers: ReadonlySet<number>;
9315
10209
  }
9316
10210
 
10211
+ /**
10212
+ * Names the section header the loaded skills' bodies render under at the end of the system
10213
+ * message — `'## Loaded skills'`.
10214
+ */
10215
+ export declare const LOADED_SECTION_HEADER = "## Loaded skills";
10216
+
10217
+ /** Checks the arguments of the `load` and `unload` built-ins; its schema is the parameters they advertise. */
10218
+ export declare const loadToolContract: ContractInterface<Readonly<{
10219
+ skill: string;
10220
+ } & {}>>;
10221
+
10222
+ /**
10223
+ * Describes the arguments of the `load` and `unload` built-ins — one `skill` name, non-empty and
10224
+ * at most `BUILTIN_LIMITS.name` code points.
10225
+ *
10226
+ * @remarks
10227
+ * The tool's door refuses a missing, empty, over-long, or extra member before the handler runs,
10228
+ * and repairs a value that converts to a string without loss, such as a number. A value of white
10229
+ * space alone passes the door; the handler refuses it as it refuses any name it cannot use.
10230
+ */
10231
+ export declare const loadToolShape: ObjectShape< {
10232
+ skill: StringShape;
10233
+ }, boolean | ContractShape>;
10234
+
9317
10235
  /**
9318
10236
  * Matches the registry ids and owners a text names.
9319
10237
  *
@@ -9358,6 +10276,27 @@ export declare function matchEntities(index: LedgerIndex, text: string, partial:
9358
10276
  */
9359
10277
  export declare function matchesCutLine(line: string): boolean;
9360
10278
 
10279
+ /**
10280
+ * Checks whether two ceilings carry the same lists of what a head renders: `instructions`,
10281
+ * `skills`, `memos`, `files`, and `workspaces`.
10282
+ *
10283
+ * @remarks
10284
+ * Each list compares by its members in order, and an absent list equals only an absent list,
10285
+ * because `undefined` admits everything and `[]` admits nothing. The `tools` list is not compared:
10286
+ * it reaches the tools block, never the head.
10287
+ *
10288
+ * @param left - One ceiling's lists
10289
+ * @param right - The other ceiling's lists
10290
+ * @returns True if every compared list matches; false otherwise
10291
+ *
10292
+ * @example
10293
+ * ```ts
10294
+ * matchesHeadLists({ skills: ['refunds'] }, { skills: ['refunds'], tools: [] }) // true
10295
+ * matchesHeadLists({ skills: [] }, {}) // false
10296
+ * ```
10297
+ */
10298
+ export declare function matchesHeadLists(left: ScopeFilter, right: ScopeFilter): boolean;
10299
+
9361
10300
  /**
9362
10301
  * Matches two values of JSON data by JSON value, whatever their key order, and reads a value with no JSON text as no match.
9363
10302
  *
@@ -9411,6 +10350,27 @@ export declare function matchesJudgment(judgment: Judgment, question: JudgeQuest
9411
10350
  */
9412
10351
  export declare function matchesLookup(left: LedgerLookupFinding, right: LedgerLookupFinding): boolean;
9413
10352
 
10353
+ /**
10354
+ * Checks whether a text is one nonblank line: it holds a code point other than white space and
10355
+ * default-ignorable code points (`ARGUMENT_BLANK_PATTERN`), and no control, format, line-separator, or
10356
+ * paragraph-separator code point (`ARGUMENT_CONTROL_PATTERN`).
10357
+ *
10358
+ * @remarks
10359
+ * The class is the one `renderArguments` encodes. A memo's name and description render in the memos
10360
+ * index one line each, so `remember` refuses a value outside this check.
10361
+ *
10362
+ * @param text - The text to check
10363
+ * @returns True if the text is one nonblank line; false otherwise
10364
+ *
10365
+ * @example
10366
+ * ```ts
10367
+ * matchesPlainLine('Reply tone') // true
10368
+ * matchesPlainLine('Reply\ntone') // false
10369
+ * matchesPlainLine(' ') // false
10370
+ * ```
10371
+ */
10372
+ export declare function matchesPlainLine(text: string): boolean;
10373
+
9414
10374
  /**
9415
10375
  * Bounds the decoded error excerpt's input in bytes — `2048`, the leading bytes of a non-OK
9416
10376
  * response body handed to the decoder before the read cancels the remainder, so a `ProviderError`
@@ -9520,6 +10480,9 @@ export declare interface Memo {
9520
10480
  readonly origin?: MemoOrigin;
9521
10481
  }
9522
10482
 
10483
+ /** Lists the members `MemoManagerOptions` declares, frozen — the keys the `MemoManager` constructor admits. */
10484
+ export declare const MEMO_MANAGER_KEYS: readonly ["id", "on", "error", "format", "snapshot"];
10485
+
9523
10486
  /**
9524
10487
  * Names the built-in section header a {@link import('./types.js').MemoManagerInterface} renders
9525
10488
  * its index under — `'## Memos'`, the `open` value when no `format.open` overrides it.
@@ -9557,6 +10520,37 @@ export declare interface MemoInput {
9557
10520
  readonly origin?: MemoOrigin;
9558
10521
  }
9559
10522
 
10523
+ /** Admits a memo input exactly, and reads the faults of a refused one. */
10524
+ export declare const memoInputContract: ContractInterface<Readonly<{
10525
+ name: string;
10526
+ description: string;
10527
+ content: string;
10528
+ } & {
10529
+ origin?: Readonly<{
10530
+ conversation: string;
10531
+ } & {
10532
+ message?: string;
10533
+ }>;
10534
+ }>>;
10535
+
10536
+ /**
10537
+ * Describes a memo input exactly: the members of a stored revision less the `id` and `time` the
10538
+ * manager mints, each taken from {@link memoShape}.
10539
+ *
10540
+ * @remarks
10541
+ * An unknown member, a missing required member, and a declared member holding `undefined` refuse, so
10542
+ * a revision `add` stores is one its own snapshot hydrates.
10543
+ */
10544
+ export declare const memoInputShape: ObjectShape< {
10545
+ name: StringShape;
10546
+ description: StringShape;
10547
+ content: StringShape;
10548
+ origin: OptionalShape<ObjectShape< {
10549
+ conversation: StringShape;
10550
+ message: OptionalShape<StringShape>;
10551
+ }, boolean | ContractShape>>;
10552
+ }, boolean | ContractShape>;
10553
+
9560
10554
  /**
9561
10555
  * Registers the revisions of a memo set — durable facts keyed by `name`, where a same-name `add`
9562
10556
  * with changed text appends a revision and the earlier ones stay readable — carrying the `open` /
@@ -9672,6 +10666,7 @@ export declare interface MemoManagerInterface {
9672
10666
  *
9673
10667
  * @param input - One {@link MemoInput}, or a batch
9674
10668
  * @returns The appended or unchanged current revision, or the batch's results in input order
10669
+ * @throws {ContractError} Thrown when an input fails `memoInputContract`: a missing required member, an undeclared member, or a declared member holding `undefined` (`code: 'structure'`); a refused batch stores nothing
9675
10670
  */
9676
10671
  add(input: MemoInput): Memo;
9677
10672
  add(inputs: readonly MemoInput[]): readonly Memo[];
@@ -10003,6 +10998,24 @@ export declare interface MemoStoreInterface {
10003
10998
  delete(id: string): Promise<void>;
10004
10999
  }
10005
11000
 
11001
+ /** Checks the arguments of the `memo` built-in; its schema is the parameters it advertises. */
11002
+ export declare const memoToolContract: ContractInterface<Readonly<{
11003
+ name: string;
11004
+ } & {}>>;
11005
+
11006
+ /**
11007
+ * Describes the arguments of the `memo` built-in — one memo `name`, non-empty and at most
11008
+ * `BUILTIN_LIMITS.name` code points.
11009
+ *
11010
+ * @remarks
11011
+ * The tool's door refuses a missing, empty, over-long, or extra member before the handler runs,
11012
+ * and repairs a value that converts to a string without loss, such as a number. A value of white
11013
+ * space alone passes the door; the handler refuses it as it refuses any name it cannot use.
11014
+ */
11015
+ export declare const memoToolShape: ObjectShape< {
11016
+ name: StringShape;
11017
+ }, boolean | ContractShape>;
11018
+
10006
11019
  /**
10007
11020
  * Merges supersession edges into a classification, adding each edge to both its supersessions and its amendments.
10008
11021
  *
@@ -10364,6 +11377,9 @@ export declare const PLACED_CATEGORIES: readonly LedgerCategory[];
10364
11377
  */
10365
11378
  export declare function placeMember(input: LedgerProjectionInput, links: ReadonlyMap<string, string>, amended: ReadonlyMap<string, readonly string[]>, id: string, seen: ReadonlySet<string>, settled?: Map<string, ReadonlySet<string>>): ReadonlySet<string>;
10366
11379
 
11380
+ /** Lists the members `AgentProviderInput` declares, frozen — the keys the `AgentProvider` constructor admits. */
11381
+ export declare const PROVIDER_INPUT_KEYS: readonly ["url", "path", "split", "strict", "timeout", "replay", "fetch", "headers"];
11382
+
10367
11383
  /**
10368
11384
  * Reports a provider stream cancelled mid-flight by its bound signal — thrown by the
10369
11385
  * `stream` method of a {@link ProviderInterface}, carrying the {@link ProviderResult} assembled from
@@ -10728,6 +11744,9 @@ export declare interface ProviderStreamOptions {
10728
11744
  */
10729
11745
  export declare function questionToSystemOne(question: JudgeQuestion): SystemOneQuestion;
10730
11746
 
11747
+ /** Lists the members `AgentQueueOptions` declares, frozen — the keys `createAgentQueue` admits. */
11748
+ export declare const QUEUE_OPTION_KEYS: readonly ["registry", "partial", "concurrency", "retries", "timeout", "store"];
11749
+
10731
11750
  /** Lists the categories whose messages the projection leaves out as quiet. */
10732
11751
  export declare const QUIET_CATEGORIES: readonly LedgerCategory[];
10733
11752
 
@@ -10866,6 +11885,9 @@ export declare function readJudgeOutcome(result: JudgeResult, id: string): {
10866
11885
  */
10867
11886
  export declare function readProviderDelta(value: unknown): ProviderDelta | undefined;
10868
11887
 
11888
+ /** Lists the members `ConversationReferenceOptions` declares, frozen — the keys the `reference` method of a `Conversation` admits. */
11889
+ export declare const REFERENCE_OPTION_KEYS: readonly ["label", "messages"];
11890
+
10869
11891
  /** Reports a question a wire could not read a candidate for; it lists the caller's keys and invents no probability. */
10870
11892
  export declare interface Refusal {
10871
11893
  readonly missing: readonly string[];
@@ -10884,12 +11906,21 @@ export declare const REFUSED_RELAY_CONTENT_TYPE = "text/plain; charset=utf-8";
10884
11906
  */
10885
11907
  export declare const REFUSED_RELAY_STATUS = 422;
10886
11908
 
11909
+ /** Lists the members `AgentRegistryOptions` declares, frozen — the keys the `AgentRegistry` constructor admits. */
11910
+ export declare const REGISTRY_OPTION_KEYS: readonly ["providers", "tools", "authorities", "schedulers", "store", "skills", "memos", "workspaces"];
11911
+
10887
11912
  /**
10888
11913
  * Names the relay's newline-delimited JSON content type — `'application/x-ndjson; charset=utf-8'`,
10889
11914
  * the header a relay response carries beside `cache-control: no-store`.
10890
11915
  */
10891
11916
  export declare const RELAY_CONTENT_TYPE = "application/x-ndjson; charset=utf-8";
10892
11917
 
11918
+ /** Lists the members `RelayOptions` declares, frozen — the keys `createRelay` admits. */
11919
+ export declare const RELAY_OPTION_KEYS: readonly ["provider", "authorize", "limit", "system", "tools"];
11920
+
11921
+ /** Lists the members `RelayProviderOptions` declares, frozen — the keys the `RelayProvider` constructor admits. */
11922
+ export declare const RELAY_PROVIDER_KEYS: readonly ["url", "parser", "timeout", "replay", "fetch", "headers"];
11923
+
10893
11924
  /**
10894
11925
  * Names the public message for an unexpected upstream relay failure — `'relay provider failed'`,
10895
11926
  * the fixed text every `error` frame carries, so an upstream failure's own message never reaches
@@ -10897,6 +11928,9 @@ export declare const RELAY_CONTENT_TYPE = "application/x-ndjson; charset=utf-8";
10897
11928
  */
10898
11929
  export declare const RELAY_PROVIDER_MESSAGE = "relay provider failed";
10899
11930
 
11931
+ /** Lists the members `RelayStreamOptions` declares, frozen — the keys the `RelayStream` constructor admits. */
11932
+ export declare const RELAY_STREAM_KEYS: readonly ["provider", "request", "signal"];
11933
+
10900
11934
  /** Carries a relay delta, settled result, remote abort, or remote failure. */
10901
11935
  export declare type RelayFrame = ProviderDelta | {
10902
11936
  readonly channel: 'result';
@@ -11221,6 +12255,28 @@ export declare interface RelayToolOptions {
11221
12255
  */
11222
12256
  export declare function releaseReader(reader: ReadableStreamDefaultReader<Uint8Array>): Promise<void>;
11223
12257
 
12258
+ /** Checks the arguments of the `remember` built-in; its schema is the parameters it advertises. */
12259
+ export declare const rememberToolContract: ContractInterface<Readonly<{
12260
+ name: string;
12261
+ description: string;
12262
+ content: string;
12263
+ } & {}>>;
12264
+
12265
+ /**
12266
+ * Describes the arguments of the `remember` built-in — a memo `name`, the one-line `description`
12267
+ * the memos index shows, and the `content`, each non-empty and within its `BUILTIN_LIMITS` cap.
12268
+ *
12269
+ * @remarks
12270
+ * The tool's door refuses a missing, empty, over-long, or extra member before the handler runs,
12271
+ * and repairs a value that converts to a string without loss, such as a number. A value of white
12272
+ * space alone passes the door; the handler refuses it as it refuses any name it cannot use.
12273
+ */
12274
+ export declare const rememberToolShape: ObjectShape< {
12275
+ name: StringShape;
12276
+ description: StringShape;
12277
+ content: StringShape;
12278
+ }, boolean | ContractShape>;
12279
+
11224
12280
  /**
11225
12281
  * Removes each key through a single-key remover and folds the outcomes, so a batch `remove`
11226
12282
  * reports whether the whole batch applied.
@@ -11328,6 +12384,26 @@ export declare function renderFencedFile(path: string, language: string, content
11328
12384
  */
11329
12385
  export declare function renderIndexEntry(entry: Pick<Memo, 'name' | 'description'>): string;
11330
12386
 
12387
+ /**
12388
+ * Renders one index line from its text as `- text`, with each run of line-break code points as one
12389
+ * space.
12390
+ *
12391
+ * @remarks
12392
+ * Pure and total. The memo and skill index lines and the workspace index lines render through it,
12393
+ * so text in an index never opens another line or heading.
12394
+ *
12395
+ * @param text - The line's text
12396
+ * @returns The index line
12397
+ *
12398
+ * @example
12399
+ * ```ts
12400
+ * import { renderIndexLine } from '@orkestrel/agent'
12401
+ *
12402
+ * renderIndexLine('orders') // '- orders'
12403
+ * ```
12404
+ */
12405
+ export declare function renderIndexLine(text: string): string;
12406
+
11331
12407
  /**
11332
12408
  * Renders a value as the JSON text `JSON.stringify` produces, or `undefined` when JSON cannot
11333
12409
  * carry the value.
@@ -11441,22 +12517,52 @@ export declare function renderLookupCall(name: string, args: Readonly<Record<str
11441
12517
  */
11442
12518
  export declare function renderSection<T>(open: string, members: readonly T[], render: (member: T) => string, close: string | undefined): string | undefined;
11443
12519
 
12520
+ /**
12521
+ * Renders one loaded skill's body: `### name`, a blank line, then its content.
12522
+ *
12523
+ * @remarks
12524
+ * Pure and total. The context build renders each shown skill through it under the loaded skills
12525
+ * header, last in the system message.
12526
+ *
12527
+ * @param skill - The skill whose name and content the body shows
12528
+ * @returns The body
12529
+ *
12530
+ * @example
12531
+ * ```ts
12532
+ * import { renderSkillBody } from '@orkestrel/agent'
12533
+ *
12534
+ * renderSkillBody({ name: 'refunds', content: 'Check the order first.' })
12535
+ * // '### refunds\n\nCheck the order first.'
12536
+ * ```
12537
+ */
12538
+ export declare function renderSkillBody(skill: Pick<Skill, 'name' | 'content'>): string;
12539
+
11444
12540
  /**
11445
12541
  * Renders the tail stub of a lookup result from an earlier request.
11446
12542
  *
12543
+ * @remarks
12544
+ * A `hidden` stub names the `recall` call that finds its result, with the first string argument,
12545
+ * trimmed, or `its id` when no argument is a string or that one is blank, only while `offered` is `true`. The ledger plans the
12546
+ * tail with every stub naming `recall`, then renders the tail's stubs again after it admits a window
12547
+ * rung, with `offered` set to whether that rung offers `recall` and the scope admits it, so the
12548
+ * second render can only shorten a stub and raises no price. `offered` changes no other state.
12549
+ *
11447
12550
  * @param name - The lookup tool name
11448
12551
  * @param args - The arguments the call carried; arguments JSON cannot carry leave the call as its bare tool name, per {@link renderLookupCall}
11449
12552
  * @param state - What became of the result: `failed`, `empty`, `shown` in the records, or `hidden` from them
11450
12553
  * @param write - If `true`, the call is a write's, whose `empty` state reads `changed nothing`; if `false`, a lookup's, whose `empty` state reads `no record`. Default: `false`
12554
+ * @param offered - If `true`, a `hidden` result names the `recall` route; if `false`, because the admitted rung offers no `recall` or the scope excludes it, it reads `result not shown`. Default: `true`
11451
12555
  * @returns The stub text, which carries the call and its state
11452
12556
  *
11453
12557
  * @example
11454
12558
  * ```ts
11455
12559
  * renderStub('lookup_order', { id: 'BW-5512' }, 'hidden')
11456
12560
  * // 'lookup_order {"id":"BW-5512"}: result not shown; call recall with BW-5512'
12561
+ * renderStub('lookup_order', { id: 'BW-5512' }, 'hidden', false, false)
12562
+ * // 'lookup_order {"id":"BW-5512"}: result not shown'
11457
12563
  * ```
11458
12564
  */
11459
- export declare function renderStub(name: string, args: Readonly<Record<string, unknown>>, state: LedgerLookupState, write?: boolean): string;
12565
+ export declare function renderStub(name: string, args: Readonly<Record<string, unknown>>, state: LedgerLookupState, write?: boolean, offered?: boolean): string;
11460
12566
 
11461
12567
  /**
11462
12568
  * Renders a tool's output as the string content of its tool message, or returns `undefined` when JSON
@@ -11575,6 +12681,28 @@ export declare function requireAnswer(content: string, schema: Readonly<Record<s
11575
12681
  */
11576
12682
  export declare function requireBudget(value: BudgetInterface<TokenUsage> | undefined, key: 'budget' | 'allowance'): BudgetInterface<TokenUsage> | undefined;
11577
12683
 
12684
+ /**
12685
+ * Returns an agent's `builtins` option as an owned, frozen list, or throws a coded error before the
12686
+ * agent is built.
12687
+ *
12688
+ * @remarks
12689
+ * `undefined` returns an empty list. The option must be an array of distinct {@link AgentBuiltin}
12690
+ * names; `unload` needs `load`, because only a loaded skill can be unloaded; and the host's tool
12691
+ * manager may hold no tool under an enabled name, because the run serves that name itself.
12692
+ *
12693
+ * @param value - The `builtins` option
12694
+ * @param tools - The host's tool manager
12695
+ * @returns The enabled names, in the order given
12696
+ * @throws {AgentError} Thrown when the option is not an array, names something that is no built-in, repeats a name, lists `unload` without `load`, or names a tool the manager holds (code `'BUILTIN'`)
12697
+ *
12698
+ * @example
12699
+ * ```ts
12700
+ * requireBuiltins(['load', 'unload'], createToolManager()) // ['load', 'unload']
12701
+ * requireBuiltins(['unload'], createToolManager()) // throws AgentError ('BUILTIN')
12702
+ * ```
12703
+ */
12704
+ export declare function requireBuiltins(value: unknown, tools: Pick<ToolManagerInterface, 'tool'>): readonly AgentBuiltin[];
12705
+
11578
12706
  /**
11579
12707
  * Returns a run's `conversation` option after checking it implements `ConversationInterface`, or
11580
12708
  * throws a coded error before the run starts.
@@ -11767,14 +12895,17 @@ export declare function requireLimit(limit: number): number;
11767
12895
  * Returns a message input after checking its role and its members, or throws a coded error.
11768
12896
  *
11769
12897
  * @remarks
11770
- * The role goes first, through {@link requireRole}, so its refusal names what it received. The members
11771
- * cross {@link isMessageInput}, and `audit` runs only after it refused, so a stored message costs one
11772
- * guard read. Tool-call arguments must also be JSON values before a message is stored.
12898
+ * A value that is not a plain record, such as a class instance or an object that inherits its
12899
+ * `role`, refuses first, through `isRecord` of `@orkestrel/contract`, with a text saying so. The role
12900
+ * goes next, through {@link requireRole}, so its refusal names what it received. The members
12901
+ * cross {@link isMessageInput}, an exact record guard, so a member `MessageInput` does not declare or a
12902
+ * declared member holding `undefined` refuses, and `audit` runs only after a refusal. Tool-call
12903
+ * arguments must also be JSON values before a message is stored.
11773
12904
  *
11774
12905
  * @param input - The message input to check
11775
12906
  * @param contract - The message input contract, whose `audit` is read only on a refusal
11776
12907
  * @returns The input, narrowed
11777
- * @throws ConversationError Thrown when the role is not a `ConversationRole` (code `'ROLE'`) or a member fails `isMessageInput` (code `'MESSAGE'`), with the faults under `context.faults`
12908
+ * @throws ConversationError Thrown when the input is not a plain record (code `'MESSAGE'`), when the role is not a `ConversationRole` (code `'ROLE'`), or when a member fails `isMessageInput`, an undeclared member included (code `'MESSAGE'`), with the faults under `context.faults`
11778
12909
  *
11779
12910
  * @example
11780
12911
  * ```ts
@@ -11805,6 +12936,34 @@ export declare function requireMessageInput(input: unknown, contract: Pick<Contr
11805
12936
  */
11806
12937
  export declare function requireProviderResult(value: unknown): ProviderResult;
11807
12938
 
12939
+ /**
12940
+ * Checks a stored record's input against its exact contract, and throws a `ContractError` coded
12941
+ * `'structure'` when it fails.
12942
+ *
12943
+ * @remarks
12944
+ * The input must pass the contract's `is` guard: a missing required member, a member the input type
12945
+ * does not declare, a declared member holding `undefined`, and a member of another type each refuse,
12946
+ * so nothing a refused input carries is stored. A class instance refuses, and the contract reads own
12947
+ * enumerable string keys alone, as every option door does. The contract's `audit` runs only after a refusal, and
12948
+ * the message names the owner, the input type, and every fault with the members to send. The
12949
+ * `context` holds the first fault's `path` and the input type as its `shape`.
12950
+ *
12951
+ * @param input - The input to check
12952
+ * @param contract - The input's compiled contract
12953
+ * @param owner - The entity named at the head of the refusal
12954
+ * @param shape - The input type named in the refusal and its `context`
12955
+ * @throws ContractError Thrown when the input fails the contract (code `'structure'`)
12956
+ *
12957
+ * @example
12958
+ * ```ts
12959
+ * import { memoInputContract, requireRecordInput } from '@orkestrel/agent'
12960
+ *
12961
+ * requireRecordInput({ name: 'tone', description: 'Prefers short replies.', content: 'Answer briefly.' }, memoInputContract, 'MemoManager', 'MemoInput') // returns
12962
+ * requireRecordInput({ name: 'tone', description: undefined, content: 'Answer briefly.' }, memoInputContract, 'MemoManager', 'MemoInput') // throws ContractError ('structure')
12963
+ * ```
12964
+ */
12965
+ export declare function requireRecordInput(input: unknown, contract: Pick<ContractInterface<unknown>, 'is' | 'audit' | 'schema'>, owner: string, shape: string): void;
12966
+
11808
12967
  /**
11809
12968
  * Returns a stored message role after checking it is a conversation role, or throws a coded error.
11810
12969
  *
@@ -11845,6 +13004,28 @@ export declare function requireRole(role: unknown): ConversationRole;
11845
13004
  */
11846
13005
  export declare function requireRules(rules: readonly AuthorityRule[] | undefined): readonly AuthorityRule[];
11847
13006
 
13007
+ /**
13008
+ * Returns a scope a run can bind, or throws a `ContractError` coded `'placement'`; `undefined`
13009
+ * passes through.
13010
+ *
13011
+ * @remarks
13012
+ * The check is {@link isScope}, a total guard that reads each member one time and admits any
13013
+ * implementation of `ScopeInterface`. `undefined` passes, because an absent option leaves the
13014
+ * context scope alone as the run's ceiling. The error's `context` carries the option path, the
13015
+ * limit `'ScopeInterface'`, and a preview of the refused value.
13016
+ *
13017
+ * @param value - The run's `scope` option, or `undefined`
13018
+ * @returns The value unchanged
13019
+ * @throws {ContractError} Thrown when `value` is defined and does not implement `ScopeInterface` (code `'placement'`)
13020
+ *
13021
+ * @example
13022
+ * ```ts
13023
+ * requireScope(createScope({ name: 'reader', tools: ['search'] })) // the scope
13024
+ * requireScope({ id: 's1', name: 'reader' }) // throws ContractError ('placement')
13025
+ * ```
13026
+ */
13027
+ export declare function requireScope(value: unknown): ScopeInterface | undefined;
13028
+
11848
13029
  /**
11849
13030
  * Returns a `sections` cap after checking it is a positive safe integer, or throws a coded error.
11850
13031
  *
@@ -11885,6 +13066,27 @@ export declare function requireSectionsCap(cap: number | undefined): number | un
11885
13066
  */
11886
13067
  export declare function requireSummary(summary: string): string;
11887
13068
 
13069
+ /**
13070
+ * Returns a `workspace` option unchanged, or throws a `ContractError` coded `'placement'`;
13071
+ * `undefined` passes through.
13072
+ *
13073
+ * @remarks
13074
+ * The check is `isString`. An id the workspace registry does not hold, or the ceiling does not
13075
+ * admit, passes here and renders nothing. The error's `context` carries the option path, the limit
13076
+ * `'string'`, and a preview of the refused value.
13077
+ *
13078
+ * @param value - The `workspace` option of an agent, a run, or a ledger's agent, or `undefined`
13079
+ * @returns The value unchanged
13080
+ * @throws {ContractError} Thrown when `value` is defined and is not a string (code `'placement'`)
13081
+ *
13082
+ * @example
13083
+ * ```ts
13084
+ * requireWorkspace('orders') // 'orders'
13085
+ * requireWorkspace(7) // throws ContractError ('placement')
13086
+ * ```
13087
+ */
13088
+ export declare function requireWorkspace(value: unknown): string | undefined;
13089
+
11888
13090
  /**
11889
13091
  * Applies the `consequential` floor to one {@link AuthorityDecision} — an `allow` for a tool
11890
13092
  * whose advertised definition is annotated `consequential` becomes an `ask`.
@@ -11906,6 +13108,32 @@ export declare function requireSummary(summary: string): string;
11906
13108
  */
11907
13109
  export declare function resolveDecision(decision: AuthorityDecision, definition: ToolDefinition | undefined): AuthorityDecision;
11908
13110
 
13111
+ /**
13112
+ * Resolves what a turn shows: the conversation's record, and the given workspace, within the
13113
+ * ceiling and the registries.
13114
+ *
13115
+ * @remarks
13116
+ * The caller reads the ceiling, so a turn reads each scope list one time. The skills are those
13117
+ * {@link collectDisclosure} reads from the conversation, in load order, keeping each that the skill
13118
+ * registry holds and the ceiling's `skills` list admits; an unregistered or excluded name shows
13119
+ * nothing. The workspace is the conversation's last switch, else the given one, kept only when the
13120
+ * workspace registry holds it and the ceiling's `workspaces` list admits it. The record counts only
13121
+ * the built-ins in `builtins`, as {@link collectDisclosure} states.
13122
+ *
13123
+ * @param context - The agent's context, whose scope, skills, and workspaces it reads
13124
+ * @param conversation - The conversation whose record to read
13125
+ * @param workspace - The `workspace` option of the run or the agent, or `undefined`
13126
+ * @param ceiling - The ceiling the turn read: the context scope intersected with the run scope
13127
+ * @param builtins - The built-ins the run enables
13128
+ * @returns The shown skills, in order, and the shown workspace when one is
13129
+ *
13130
+ * @example
13131
+ * ```ts
13132
+ * resolveDisclosure(agent.context, agent.context.messages, 'orders', {}, []) // { skills: [], workspace: 'orders' } when orders is registered
13133
+ * ```
13134
+ */
13135
+ export declare function resolveDisclosure(context: AgentContextInterface, conversation: Pick<ConversationInterface, 'sections' | 'messages'>, workspace: string | undefined, ceiling: ScopeFilter, builtins: readonly AgentBuiltin[]): AgentDisclosure;
13136
+
11909
13137
  /**
11910
13138
  * Resolves the generation cap and checks it against the context capacity.
11911
13139
  *
@@ -11920,6 +13148,33 @@ export declare function resolveDecision(decision: AuthorityDecision, definition:
11920
13148
  */
11921
13149
  export declare function resolvePredict(predict: number | undefined, capacity: number): number;
11922
13150
 
13151
+ /**
13152
+ * Resolves the workspace a run renders and acts on: the one `selected` names, else the registry's
13153
+ * active one, kept only while `allowed` admits its id.
13154
+ *
13155
+ * @remarks
13156
+ * A selection the registry does not hold resolves to `undefined` and never falls back to the active
13157
+ * workspace. `allowed` is three-way, as {@link import('../helpers.js').filterAllowList} reads it.
13158
+ * `AgentContext.build`, the caller an agent run hands each tool call, and a ledger's calibration
13159
+ * resolve through it, so what a request renders and what a call receives come from one rule.
13160
+ *
13161
+ * @param workspaces - The workspace registry to read
13162
+ * @param selected - The id a `switch` call or the `workspace` option selected, or `undefined`
13163
+ * @param allowed - The ceiling's `workspaces` list (`undefined` ⇒ every id, `[]` ⇒ none)
13164
+ * @returns The workspace, or `undefined` when none resolves
13165
+ *
13166
+ * @example
13167
+ * ```ts
13168
+ * import { resolveWorkspace } from '@orkestrel/agent'
13169
+ *
13170
+ * resolveWorkspace(agent.context.workspaces, 'returns', ['returns']) // the registered returns workspace
13171
+ * ```
13172
+ */
13173
+ export declare function resolveWorkspace(workspaces: WorkspaceManagerInterface, selected: string | undefined, allowed: readonly string[] | undefined): WorkspaceInterface | undefined;
13174
+
13175
+ /** Lists the members `AgentRunnerOptions` declares, frozen — the keys `createAgentRunner` admits. */
13176
+ export declare const RUNNER_OPTION_KEYS: readonly ["registry", "partial", "concurrency", "retries", "timeout"];
13177
+
11923
13178
  /**
11924
13179
  * Sanitizes one reported token count into a non-negative integer — a non-finite or
11925
13180
  * non-positive value becomes `0`, and a positive fractional value floors down.
@@ -11969,6 +13224,39 @@ export declare function sanitizeUsage(usage: TokenUsage): TokenUsage;
11969
13224
  */
11970
13225
  export declare function scanAmendments(amendments: ReadonlyMap<string, readonly string[]>, start: string, admit: (id: string) => boolean): readonly string[];
11971
13226
 
13227
+ /**
13228
+ * Scans every job under a root for a member that exceeds its own parent's; an empty result clears the tree.
13229
+ *
13230
+ * @remarks
13231
+ * The walk audits each job, the root included, through `agentJobContract` before it reads a member,
13232
+ * because a job's `children` cross that contract as JSON records, and then reads each job the
13233
+ * contract admits through `collectJobRefusals`. A job the contract refuses yields one finding with its
13234
+ * faults, or with an unreadable note when a member read throws; a job its build would refuse yields
13235
+ * one finding a refusal, its path, a dot, and the line; and the walk reads nothing under either. A
13236
+ * child is within its parent when each of
13237
+ * its `tools` is one its parent names (a parent with no `tools` names none), each of its `builtins`
13238
+ * is one its parent names (a parent with no `builtins` names none), each name in each list of its
13239
+ * `scope` is in its parent's same list (a job with no `scope` holds the three lists empty), its
13240
+ * `authority` and `scheduler` are absent or its parent's, its `provider` is its parent's, its `limit`
13241
+ * is at most its parent's (an absent `limit` reads `DEFAULT_AGENT_LIMIT`), and, where its parent
13242
+ * holds a `timeout` or a `budget`, it holds one no larger. `system`, `messages`, and `workspace` are
13243
+ * free: a `workspace` renders nothing its own `scope` omits. A refused job's finding
13244
+ * opens with `JOB_REFUSAL_PREFIX` and then the job's path from `job`; an exceeded member's opens
13245
+ * with that path, a dot, and the member. The walk is total: an unreadable job yields a finding,
13246
+ * never a throw. The `AgentFanout` class runs it on every attempt of a unit, before the unit spawns
13247
+ * or runs.
13248
+ *
13249
+ * @param root - The root job of the tree
13250
+ * @returns One finding per refused job and per exceeded member, in walk order
13251
+ *
13252
+ * @example
13253
+ * ```ts
13254
+ * scanJobTree({ provider: 'main', children: [{ provider: 'other' }] })
13255
+ * // ['job.children[0].provider: "other" differs from its parent\'s, which is "main"']
13256
+ * ```
13257
+ */
13258
+ export declare function scanJobTree(root: AgentJobInput): readonly string[];
13259
+
11972
13260
  /**
11973
13261
  * Scans what a judge's answer must hold to its question: the same form, every probability in
11974
13262
  * `[0, 1]`, a choice's keys equal to the criteria keys, and a score as long as its levels.
@@ -12004,9 +13292,9 @@ export declare function scanProbability(value: number | undefined, path: readonl
12004
13292
 
12005
13293
  /**
12006
13294
  * Represents a named, immutable filter over a richer context's items — an optional allow-list per
12007
- * category (`instructions` / `skills` / `memos` / `tools` / `files`), each keyed by that category's
12008
- * identity (an instruction's, a skill's, a memo's, or a tool's `name`, a workspace file's `path`)
12009
- * and read as an allow-list:
13295
+ * category (`instructions` / `skills` / `memos` / `tools` / `files` / `workspaces`), each keyed by
13296
+ * that category's identity (an instruction's, a skill's, a memo's, or a tool's `name`, a workspace
13297
+ * file's `path`, a workspace's `id`) and read as an allow-list:
12010
13298
  * `undefined` lets everything pass, `[]` lets nothing pass, and a non-empty list passes the listed
12011
13299
  * keys alone. `narrow` composes a tighter child by set intersection.
12012
13300
  *
@@ -12024,6 +13312,10 @@ export declare function scanProbability(value: number | undefined, path: readonl
12024
13312
  * `undefined` with a list yields the list, and `undefined` with `undefined` stays
12025
13313
  * `undefined`. Narrowing can only tighten, never widen — a key excluded by a parent
12026
13314
  * can never be re-admitted by a child. The child keeps this scope's `name` and `select` handler.
13315
+ * - **Exact.** The constructor refuses an own enumerable member of its input outside
13316
+ * `SCOPE_KEYS`, and `narrow` one of its filter outside `SCOPE_FILTER_KEYS`, with a
13317
+ * `ContractError` coded `'structure'`, so a misspelled list never builds an open scope. A
13318
+ * declared member holding `undefined` reads as omitted.
12027
13319
  *
12028
13320
  * @example
12029
13321
  * ```ts
@@ -12043,38 +13335,72 @@ export declare class Scope implements ScopeInterface {
12043
13335
  readonly memos?: readonly string[];
12044
13336
  readonly tools?: readonly string[];
12045
13337
  readonly files?: readonly string[];
13338
+ readonly workspaces?: readonly string[];
12046
13339
  readonly select?: SelectionHandler;
12047
13340
  constructor(input: ScopeInput);
12048
13341
  narrow(config: ScopeFilter): ScopeInterface;
12049
13342
  }
12050
13343
 
13344
+ /**
13345
+ * Lists the members `ScopeFilter` declares, frozen — the keys the `narrow` method of a scope admits.
13346
+ *
13347
+ * @remarks
13348
+ * The `narrow` method passes the list to `refuseOptionKeys` of `@orkestrel/contract`, so an own
13349
+ * enumerable member outside it refuses with a `ContractError` coded `'structure'`.
13350
+ */
13351
+ export declare const SCOPE_FILTER_KEYS: readonly ["instructions", "skills", "memos", "tools", "files", "workspaces"];
13352
+
13353
+ /**
13354
+ * Lists the members `ScopeInput` declares, frozen — the keys a `Scope` is built from.
13355
+ *
13356
+ * @remarks
13357
+ * The `Scope` constructor passes the list to `refuseOptionKeys` of `@orkestrel/contract`, so an
13358
+ * own enumerable member outside it, a misspelled list included, refuses with a `ContractError`
13359
+ * coded `'structure'` instead of building a scope with no constraint.
13360
+ */
13361
+ export declare const SCOPE_KEYS: readonly ["name", "select", "instructions", "skills", "memos", "tools", "files", "workspaces"];
13362
+
13363
+ /** Lists the members `ScopeManagerOptions` declares, frozen — the keys the `ScopeManager` constructor admits. */
13364
+ export declare const SCOPE_MANAGER_KEYS: readonly ["on", "error"];
13365
+
12051
13366
  /**
12052
13367
  * Holds the model-facing text the loop writes after a tool name in the denial result of a call
12053
- * outside the active scope's tool allow-list or whose name no definition advertises this turn.
13368
+ * outside the turn's tool ceiling, the context scope's tool allow-list intersected with the run
13369
+ * scope's, or whose name no definition advertises this turn.
12054
13370
  */
12055
13371
  export declare const SCOPE_NOTE = "it is not one of the listed tools. Use a listed tool or answer with what you have.";
12056
13372
 
12057
13373
  /**
12058
13374
  * Lists the per-category allow-lists a {@link ScopeInterface} carries — an optional `readonly
12059
- * string[]` for `instructions`, for `skills`, for `memos`, for `tools`, and for `files`, each keyed
12060
- * by that category's identity (an instruction's, a skill's, a memo's, or a tool's `name`, a workspace
12061
- * file's `path`) and read as an allow-list: `undefined` lets everything pass, `[]` lets nothing pass,
12062
- * and a non-empty list passes the listed keys alone.
13375
+ * string[]` for `instructions`, for `skills`, for `memos`, for `tools`, for `files`, and for
13376
+ * `workspaces`, each keyed by that category's identity (an instruction's, a skill's, a memo's, or a
13377
+ * tool's `name`, a workspace file's `path`, a workspace's `id`) and read as an allow-list:
13378
+ * `undefined` lets everything pass, `[]` lets nothing pass, and a non-empty list passes the listed
13379
+ * keys alone.
12063
13380
  *
12064
13381
  * @remarks
12065
13382
  * Each list is three-way (see {@link import('../helpers.js').filterAllowList}): `undefined`
12066
13383
  * ⇒ no constraint on that category (all pass); `[]` ⇒ none pass; a non-empty list ⇒ only
12067
13384
  * the listed keys pass. It is the shape both a {@link ScopeInput} and `Scope.narrow`
12068
- * accept (a `name`-less narrowing config). `files` filters the active workspace's rendered
12069
- * files (by `path`) in {@link AgentContextInterface.build} — both the text files folded into
12070
- * the context message and the image files attached to the last user message.
13385
+ * accept (a `name`-less narrowing config). `files` filters the rendered workspace's files (by
13386
+ * `path`) in {@link AgentContextInterface.build} — both the text files folded into the context
13387
+ * message and the image files attached to the last user message — and `workspaces` decides
13388
+ * whether that workspace renders at all. Two lists bound a write as well as a read: the
13389
+ * `remember` built-in writes only a name a defined `memos` list holds, and the `switch` built-in
13390
+ * selects only an id a defined `workspaces` list holds. The `files` list also bounds the workspace
13391
+ * tool of `@orkestrel/toolbox`, which receives it as `caller.files`, an
13392
+ * {@link import('../agents/types.js').AgentCaller} member.
12071
13393
  */
12072
13394
  export declare interface ScopeFilter {
12073
13395
  /** Lists the allowed instruction names matched against the `name` property (`undefined` ⇒ all, `[]` ⇒ none, else only-listed). */
12074
13396
  readonly instructions?: readonly string[];
12075
13397
  /** Lists the allowed skill names matched against the `name` property (`undefined` ⇒ all, `[]` ⇒ none, else only-listed). */
12076
13398
  readonly skills?: readonly string[];
12077
- /** Lists the allowed memo names matched against the `name` property (`undefined` ⇒ all, `[]` ⇒ none, else only-listed). */
13399
+ /**
13400
+ * Lists the allowed memo names matched against the `name` property (`undefined` ⇒ all, `[]` ⇒ none, else only-listed).
13401
+ * A write is the exception: the `remember` built-in writes only a name a defined list holds, so
13402
+ * `undefined` lets it write none.
13403
+ */
12078
13404
  readonly memos?: readonly string[];
12079
13405
  /**
12080
13406
  * Lists the allowed tool names matched against the `name` property (`undefined` ⇒ all, `[]` ⇒ none, else only-listed).
@@ -12084,11 +13410,18 @@ export declare interface ScopeFilter {
12084
13410
  readonly tools?: readonly string[];
12085
13411
  /**
12086
13412
  * Lists the allowed active-workspace file paths matched against the `path` property (`undefined` ⇒ all, `[]` ⇒ none, else only-listed) —
12087
- * the filter {@link AgentContextInterface.build} applies to the active workspace's
13413
+ * the filter {@link AgentContextInterface.build} applies to the rendered workspace's
12088
13414
  * {@link import('@orkestrel/workspace').WorkspaceInterface.files} before rendering them (text → the context message, image →
12089
- * the last user message).
13415
+ * the last user message). Each tool call receives the list as `caller.files`, and the workspace
13416
+ * tool of `@orkestrel/toolbox` reaches the listed paths alone.
12090
13417
  */
12091
13418
  readonly files?: readonly string[];
13419
+ /**
13420
+ * Lists the allowed workspace ids matched against the `id` property (`undefined` ⇒ all, `[]` ⇒ none, else only-listed).
13421
+ * A selection is the exception: the `switch` built-in selects only an id a defined list holds, so
13422
+ * `undefined` lets it select none.
13423
+ */
13424
+ readonly workspaces?: readonly string[];
12092
13425
  }
12093
13426
 
12094
13427
  /**
@@ -12097,7 +13430,10 @@ export declare interface ScopeFilter {
12097
13430
  */
12098
13431
  export declare interface ScopeInput extends ScopeFilter {
12099
13432
  readonly name: string;
12100
- /** Holds the selection handler that overrides the agent default while this scope is active. */
13433
+ /**
13434
+ * Holds the selection handler that overrides the agent default while this scope is active, and
13435
+ * overrides the active scope's too while this scope is a run's.
13436
+ */
12101
13437
  readonly select?: SelectionHandler;
12102
13438
  }
12103
13439
 
@@ -12116,7 +13452,10 @@ export declare interface ScopeInput extends ScopeFilter {
12116
13452
  export declare interface ScopeInterface extends ScopeFilter {
12117
13453
  readonly id: string;
12118
13454
  readonly name: string;
12119
- /** Holds the selection handler that overrides the agent default while this scope is active. */
13455
+ /**
13456
+ * Holds the selection handler that overrides the agent default while this scope is active, and
13457
+ * overrides the active scope's too while this scope is a run's.
13458
+ */
12120
13459
  readonly select?: SelectionHandler;
12121
13460
  /**
12122
13461
  * Composes a tighter child scope — each category is the set intersection of this scope's
@@ -12454,8 +13793,8 @@ export declare function settleToolResult(result: ToolResult): {
12454
13793
  };
12455
13794
 
12456
13795
  /**
12457
- * Holds one skill: a name and a description the index shows, the instructions loading adds, and
12458
- * bundled files.
13796
+ * Holds one skill: a name and a description the index shows, the body a run shows, the tools it
13797
+ * holds back, and bundled files.
12459
13798
  *
12460
13799
  * @remarks
12461
13800
  * A {@link SkillManagerInterface} mints it from a {@link SkillInput} and never mutates it. Its
@@ -12468,12 +13807,23 @@ export declare interface Skill {
12468
13807
  readonly name: string;
12469
13808
  /** Holds the one-line entry the skill index shows. */
12470
13809
  readonly description: string;
12471
- /** Holds the instructions loading the skill adds. */
13810
+ /**
13811
+ * Holds the body a run renders while it shows the skill: last in the `system` message, under
13812
+ * `## Loaded skills`, for the run's conversation alone. A blank body renders nothing.
13813
+ */
12472
13814
  readonly content: string;
13815
+ /**
13816
+ * Names the tools the skill holds back: while a turn advertises `load`, each is advertised only
13817
+ * while a shown skill names it, within the turn's ceiling.
13818
+ */
13819
+ readonly tools: readonly string[];
12473
13820
  /** Lists the bundled files. */
12474
13821
  readonly files: readonly FileInterface[];
12475
13822
  }
12476
13823
 
13824
+ /** Lists the members `SkillManagerOptions` declares, frozen — the keys the `SkillManager` constructor admits. */
13825
+ export declare const SKILL_MANAGER_KEYS: readonly ["on", "error", "format"];
13826
+
12477
13827
  /**
12478
13828
  * Names the built-in section header a {@link import('./types.js').SkillManagerInterface} renders
12479
13829
  * its index under — `'## Skills'`, the `open` value when no `format.open` overrides it.
@@ -12492,10 +13842,43 @@ export declare interface SkillInput {
12492
13842
  readonly name: string;
12493
13843
  readonly description: string;
12494
13844
  readonly content: string;
13845
+ /**
13846
+ * Names the tools the skill holds back until it is shown. The manager copies the list, and
13847
+ * refuses a value that is neither absent nor an array of strings with a `ContractError` coded
13848
+ * `'placement'`. Default: none.
13849
+ */
13850
+ readonly tools?: readonly string[];
12495
13851
  /** Lists the bundled files to mint with `createFile`. Default: none. */
12496
13852
  readonly files?: readonly FileInput[];
12497
13853
  }
12498
13854
 
13855
+ /** Admits a skill input exactly, and reads the faults of a refused one. */
13856
+ export declare const skillInputContract: ContractInterface<Readonly<{
13857
+ name: string;
13858
+ description: string;
13859
+ content: string;
13860
+ } & {
13861
+ tools?: readonly string[];
13862
+ files?: readonly unknown[];
13863
+ }>>;
13864
+
13865
+ /**
13866
+ * Describes a skill input exactly: a string `name`, `description`, and `content`, optional `tools`
13867
+ * names, and optional `files`.
13868
+ *
13869
+ * @remarks
13870
+ * An unknown member, a missing required member, and a declared member holding `undefined` refuse.
13871
+ * Each file is the `FileInput` interface of `@orkestrel/workspace`, which publishes no guard for it,
13872
+ * so the shape admits any defined element and `createFile`, that package's own door, reads it.
13873
+ */
13874
+ export declare const skillInputShape: ObjectShape< {
13875
+ name: StringShape;
13876
+ description: StringShape;
13877
+ content: StringShape;
13878
+ tools: OptionalShape<ArrayShape<StringShape>>;
13879
+ files: OptionalShape<ArrayShape<RawShape>>;
13880
+ }, boolean | ContractShape>;
13881
+
12499
13882
  /**
12500
13883
  * Registers the skills a host supplies — instruction bundles keyed by `name`, listed in insertion
12501
13884
  * order, where adding a skill whose name is already stored overwrites it, last write wins —
@@ -12586,11 +13969,17 @@ export declare interface SkillManagerInterface {
12586
13969
  /** Holds the line after the skills: the manager-options `close`, or `undefined` when none. */
12587
13970
  readonly close: string | undefined;
12588
13971
  /**
12589
- * Adds one {@link SkillInput}, or a batch: mints each `id` and file, and overwrites a
12590
- * same-name skill, last write wins.
13972
+ * Adds one {@link SkillInput}, or a batch: mints each `id` and file, copies each `tools` list,
13973
+ * and overwrites a same-name skill, last write wins.
13974
+ *
13975
+ * @remarks
13976
+ * Each input is checked and minted before any skill is stored or emitted, so a refused batch
13977
+ * stores nothing. A `tools` member is read first, then the input meets `skillInputContract`.
12591
13978
  *
12592
13979
  * @param input - One {@link SkillInput}, or a batch
12593
13980
  * @returns The stored skill, or the stored batch in input order
13981
+ * @throws {ContractError} Thrown when a `tools` member is neither absent nor an array of strings (`code: 'placement'`)
13982
+ * @throws {ContractError} Thrown when an input fails `skillInputContract`: a missing required member, an undeclared member, or a declared member holding `undefined` (`code: 'structure'`)
12594
13983
  */
12595
13984
  add(input: SkillInput): Skill;
12596
13985
  add(inputs: readonly SkillInput[]): readonly Skill[];
@@ -12699,6 +14088,9 @@ export declare function splitTopic(topic: string): readonly string[];
12699
14088
  */
12700
14089
  export declare function splitWords(part: string): readonly string[];
12701
14090
 
14091
+ /** Lists the members `ProviderStreamOptions` declares, frozen — the keys the `generate` and `stream` methods of an `AgentProvider` admits. */
14092
+ export declare const STREAM_OPTION_KEYS: readonly ["think", "schema"];
14093
+
12702
14094
  /**
12703
14095
  * Pairs a live event stream with the eventual settled result and a cancel — the
12704
14096
  * generic pull/streaming handle a long-running operation hands back.
@@ -12772,6 +14164,27 @@ export declare function stripThinking(messages: readonly Message[], replay: Thin
12772
14164
  */
12773
14165
  export declare function sumUsage(prior: TokenUsage | undefined, next: TokenUsage): TokenUsage;
12774
14166
 
14167
+ /** Checks the arguments of the `switch` built-in; its schema is the parameters it advertises. */
14168
+ export declare const switchToolContract: ContractInterface<Readonly<{
14169
+ workspace: string;
14170
+ } & {}>>;
14171
+
14172
+ /**
14173
+ * Describes the arguments of the `switch` built-in — one `workspace` id, non-empty and at most
14174
+ * `BUILTIN_LIMITS.name` code points.
14175
+ *
14176
+ * @remarks
14177
+ * The tool's door refuses a missing, empty, over-long, or extra member before the handler runs,
14178
+ * and repairs a value that converts to a string without loss, such as a number. A value of white
14179
+ * space alone passes the door; the handler refuses it as it refuses any name it cannot use.
14180
+ */
14181
+ export declare const switchToolShape: ObjectShape< {
14182
+ workspace: StringShape;
14183
+ }, boolean | ContractShape>;
14184
+
14185
+ /** Lists the members `SystemOneJudgeOptions` declares, frozen — the keys the `SystemOneJudge` constructor admits. */
14186
+ export declare const SYSTEM_ONE_OPTION_KEYS: readonly ["url", "model", "timeout", "fetch", "headers"];
14187
+
12775
14188
  /** Names the System One decision endpoint shared by compatible servers. */
12776
14189
  export declare const SYSTEM_ONE_PATH = "/v1/systemone";
12777
14190
 
@@ -13108,6 +14521,12 @@ export declare const UNAUTHORIZED_RELAY_STATUS = 401;
13108
14521
  */
13109
14522
  export declare const UPSTREAM_RELAY_STATUS = 502;
13110
14523
 
14524
+ /**
14525
+ * Names the section header the admitted workspace ids render under in the user context message —
14526
+ * `'## Workspaces'`, rendered only while a run can select a workspace.
14527
+ */
14528
+ export declare const WORKSPACE_INDEX_HEADER = "## Workspaces";
14529
+
13111
14530
  /**
13112
14531
  * Names the section header the `build()` method of {@link import('./AgentContext.js').AgentContext}
13113
14532
  * renders the active workspace's text files under — `'## Workspace'`, the line that opens the