@orkestrel/agent 0.0.41 → 0.0.42

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,16 +25,19 @@ 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';
40
43
  import type { WorkspaceManagerInterface } from '@orkestrel/workspace';
@@ -99,6 +102,25 @@ export declare class Agent implements AgentInterface {
99
102
  abort(reason?: unknown): void;
100
103
  }
101
104
 
105
+ /**
106
+ * Lists the members `AgentOptions` declares, frozen — the keys the `Agent` constructor admits.
107
+ *
108
+ * @remarks
109
+ * The constructor passes the list to `refuseOptionKeys` of `@orkestrel/contract`, so an own
110
+ * enumerable member outside it refuses with a `ContractError` coded `'structure'`.
111
+ */
112
+ 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"];
113
+
114
+ /**
115
+ * Lists the members `AgentRunOptions` declares, frozen — the keys the `stream` and `generate`
116
+ * methods admit.
117
+ *
118
+ * @remarks
119
+ * The `stream` method passes the list to `refuseOptionKeys` of `@orkestrel/contract`, so an own
120
+ * enumerable member outside it refuses with a `ContractError` coded `'structure'`.
121
+ */
122
+ export declare const AGENT_RUN_KEYS: readonly ["think", "schema", "limit", "timeout", "budget", "allowance", "signal", "conversation", "prompt", "scope", "workspace"];
123
+
102
124
  /** Carries a page's answer to one `ask` frame; only `approved: true` approves. */
103
125
  export declare interface AgentAnswer {
104
126
  readonly id: string;
@@ -107,8 +129,8 @@ export declare interface AgentAnswer {
107
129
 
108
130
  /** Validates and projects a page's answers to `ask` frames at a JSON wire boundary. */
109
131
  export declare const agentAnswerContract: ContractInterface<Readonly<{
110
- id: string;
111
- approved: boolean;
132
+ id: string;
133
+ approved: boolean;
112
134
  } & {}>>;
113
135
 
114
136
  /**
@@ -123,6 +145,16 @@ id: StringShape;
123
145
  approved: BooleanShape;
124
146
  }, boolean | ContractShape>;
125
147
 
148
+ /**
149
+ * Names a tool the agent serves itself: `load` and `unload` show and hide a skill, `memo` reads a
150
+ * memo, `remember` writes one, and `switch` selects a workspace.
151
+ *
152
+ * @remarks
153
+ * Each is enabled through {@link AgentOptions.builtins}, and each passes the turn's ceiling and the
154
+ * agent's authority as any tool does.
155
+ */
156
+ export declare type AgentBuiltin = 'load' | 'unload' | 'memo' | 'remember' | 'switch';
157
+
126
158
  /**
127
159
  * Represents a streamed step of an agent turn — the union the loop yields as it runs, discriminated
128
160
  * by the `category` of step it carries, and the pull surface beside the push {@link AgentEventMap}.
@@ -191,8 +223,9 @@ export declare function agentChunkToFrame(chunk: AgentChunk): AgentFrame | undef
191
223
  * {@link ConversationManagerInterface} message source whose active conversation is `messages`, the
192
224
  * {@link ToolManagerInterface} registry, and an active {@link ScopeInterface} changed through
193
225
  * {@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`.
226
+ * the skills index, and the shown skills' bodies into one system message, the memos index and the
227
+ * rendered workspace's text into one `user` context message after it, then the conversation, and
228
+ * never reads `tools`.
196
229
  *
197
230
  * @remarks
198
231
  * - **Composition.** `system` is the optional system prompt; `instructions` / `skills` / `memos` /
@@ -211,40 +244,43 @@ export declare function agentChunkToFrame(chunk: AgentChunk): AgentFrame | undef
211
244
  * reference, no duplication), and `build()` with no selection folds that conversation's `view()`
212
245
  * (its per-section summaries + live tail) as the authoritative message inclusion — the scope does
213
246
  * 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
247
+ * instructions / skills / memos / tools / workspace files / workspaces). An agent run binds a conversation at
215
248
  * its call, the active one unless the run names another, and builds through a selection over that
216
249
  * conversation, so `conversations.switch(id)` sets the next run's default at any moment and never
217
250
  * moves a live run; `select(conversation, request, signal)` checks the conversation it is given.
218
251
  * - **`build()` — the scoped assembly + the format cascade.** It folds, in order,
219
252
  * the system prompt, the scope-filtered instructions (a block: the section's `open` text,
220
253
  * 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
254
+ * whose entries join with a single newline), then the shown skills' bodies, into one leading
255
+ * `system` message (prepended only when at least one part exists), then the scope-filtered memos
256
+ * index (the same block), the listed workspace ids, and the rendered workspace's text files into
257
+ * one `user` context message (present only when one of those sections renders), then
225
258
  * appends the active conversation's `view()` (the conversation owns message inclusion through
226
259
  * compaction — the scope does not filter the conversation). The instruction manager resolves
227
260
  * each `open` / item / `close` most-specific-first: `open` = manager-options-override >
228
261
  * built-in; per item = item-override > manager-options-override > built-in; `close` =
229
262
  * manager-options-override (no built-in ⇒ no closing line when unset) (see
230
263
  * {@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
264
+ * header + items, no closing line. The rendered workspace's scoped-in image files' `base64` payload is attached to
232
265
  * the last user message (a vision provider reads images off a user turn); when no user message
233
266
  * 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
267
+ * always reflects the current managers / messages / scope / workspaces; it never mutates a
235
268
  * manager or the stored messages. `build(selection)` adds at most one `system` message of its own
236
269
  * and reads the selection's messages as conversation parts without a role check; the select path
237
270
  * refuses a selected `system` role as a `'ROLE'` fault over `view()`; a host's direct
238
271
  * `build(selection)` is host-trusted, and a conversation a host implements itself whose `view()`
239
272
  * 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`,
273
+ * - **The rendered workspace, by carrier — the sole document/image context.**
274
+ * The rendered workspace has its {@link import('@orkestrel/workspace').FileInterface} values scope-filtered by `scope.files`,
242
275
  * then split: text files fold into a dedicated `## Workspace` section (fenced reference blocks)
243
276
  * in the context message — a `user` message with a minted id, never stored — and image files'
244
277
  * `base64` payload attaches to the last user message of the conversation, never to the context
245
278
  * 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` /
279
+ * instructions, the skills index, and last the bodies of the skills `options.disclosure` shows.
280
+ * One workspace renders: the one `options.disclosure` selects, else the active one, and only
281
+ * while the scope's `workspaces` list admits it; with neither, nothing renders for workspaces.
282
+ * `options.switchable` adds the admitted workspace ids to the context message, after the memos
283
+ * index. `build()` never moves the active workspace, and it owns this render (a `Workspace` /
248
284
  * `WorkspaceManager` stays file-focused).
249
285
  * - **Tools are structural, not in the prompt.** The registry is advertised to the provider
250
286
  * through `tools.definitions()` (scope-filtered by the loop), never serialized into the
@@ -273,8 +309,8 @@ export declare class AgentContext implements AgentContextInterface {
273
309
  get tools(): ToolManagerInterface;
274
310
  get scope(): ScopeInterface | undefined;
275
311
  apply(scope: ScopeInterface | undefined): void;
276
- select(conversation: ConversationInterface, request: Message, signal: AbortSignal): Promise<Selection> | undefined;
277
- build(selection?: Selection): readonly Message[];
312
+ select(conversation: ConversationInterface, request: Message, signal: AbortSignal, scope?: ScopeInterface): Promise<Selection> | undefined;
313
+ build(options?: ContextBuildOptions): readonly Message[];
278
314
  }
279
315
 
280
316
  /**
@@ -286,12 +322,14 @@ export declare class AgentContext implements AgentContextInterface {
286
322
  * (`instructions` / `skills` / `memos` / `workspaces` / `conversations`), `messages` (the active
287
323
  * conversation's live tail, satisfying {@link import('../conversations/index.js').MessageManagerInterface}), and the current `scope`
288
324
  * (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
325
+ * system prompt, the scoped instructions, the scoped skills index, and the bodies of the skills
326
+ * its `disclosure` option shows into one leading `system` message (under each manager's `open`,
327
+ * each item through its `render`, the bodies last), renders the scoped memos index, the admitted
328
+ * workspace ids when `switchable` is `true`, and the rendered workspace's scope-filtered text files
329
+ * (fenced reference blocks) into one `user` context message after it, and appends the active
330
+ * conversation's `view()`, attaching the rendered workspace's scope-filtered image files' `base64`
331
+ * payload to the last user message. The rendered workspace is the one `disclosure` names, else
332
+ * the active one, and it is the sole document/image context. Tools are advertised to the provider
295
333
  * structurally (through `tools.definitions()`, scope-filtered by the loop), not serialized into
296
334
  * the prompt, so they never appear in the output of the `build()` method. The context managers are observable
297
335
  * (each through its own `emitter` property); the context itself is event-free.
@@ -304,13 +342,14 @@ export declare interface AgentContextInterface {
304
342
  /** Holds the always-present memo set whose index `build()` renders in the `user` context message. */
305
343
  readonly memos: MemoManagerInterface;
306
344
  /**
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.
345
+ * Holds the {@link WorkspaceManagerInterface} one of whose workspaces `build()` renders by
346
+ * carrier — its text files folded into the `user` context message (fenced reference blocks) and
347
+ * its image files' `base64` payload attached to the last user message. That workspace is the one
348
+ * the `disclosure` build option names, else the active one, and it renders only while the
349
+ * scope's `workspaces` list admits it; it is the sole document/image context. Always present (a
350
+ * fresh empty manager when none was supplied). `build()` reads the registry and the workspace's
351
+ * `files()` fresh each call, and never moves `active`. With no workspace to render, nothing is
352
+ * rendered for workspaces.
314
353
  */
315
354
  readonly workspaces: WorkspaceManagerInterface;
316
355
  /**
@@ -355,8 +394,8 @@ export declare interface AgentContextInterface {
355
394
  */
356
395
  apply(scope: ScopeInterface | undefined): void;
357
396
  /**
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.
397
+ * Runs the selection handler for one request — the run scope's `select`, else the active
398
+ * scope's, else the agent default — and checks that the conversation did not change under it.
360
399
  *
361
400
  * @remarks
362
401
  * Resolves the handler once per call. With no handler in either home it returns `undefined`
@@ -374,35 +413,44 @@ export declare interface AgentContextInterface {
374
413
  * @param conversation - The conversation the handler selects over and the check compares
375
414
  * @param request - The user message the run serves
376
415
  * @param signal - The run's abort signal, passed to the handler
416
+ * @param scope - The run's scope, whose `select` runs in place of the active scope's; omitted ⇒ none
377
417
  * @returns The pending {@link Selection}, or `undefined` when no handler is set
378
418
  *
379
419
  * @example
380
420
  * ```ts
381
421
  * const request = context.messages.add({ role: 'user', content: 'Summarize the ticket.' })
382
422
  * const selection = await context.select(context.messages, request, new AbortController().signal)
383
- * context.build(selection)
423
+ * context.build({ selection })
384
424
  * ```
385
425
  */
386
- select(conversation: ConversationInterface, request: Message, signal: AbortSignal): Promise<Selection> | undefined;
426
+ select(conversation: ConversationInterface, request: Message, signal: AbortSignal, scope?: ScopeInterface): Promise<Selection> | undefined;
387
427
  /**
388
428
  * 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.
429
+ * prompt, the scope-filtered instructions, the scope-filtered skills index (each section's
430
+ * header and each item's rendering resolved through the format cascade), and last the bodies of
431
+ * the skills `disclosure` shows under `## Loaded skills`, then one `user` context message holding
432
+ * the scope-filtered memos index, the admitted workspace ids under `## Workspaces` when
433
+ * `switchable` is `true`, and the rendered workspace's scope-filtered (`scope.files`) text files
434
+ * as fenced reference blocks in a `## Workspace` section, then the active conversation's
435
+ * `view()`, or the selection's `messages` when a selection is passed, with the rendered
436
+ * workspace's image files' `base64` payload attached to the last user message. With no override
437
+ * set, each section renders on its manager's built-in framing. The `system` message is prepended
438
+ * only when some part of it exists, the context message only when one of its sections renders,
439
+ * one workspace renders, tools are advertised structurally rather than in the prompt, and the
440
+ * input is built fresh on each call.
400
441
  *
401
442
  * @remarks
402
- * **The active workspace (rendered by carrier) — the sole document/image context.** When
403
- * `workspaces.active` is set, its
443
+ * **The shown bodies.** Each name `disclosure.skills` lists renders once, in the given order,
444
+ * as `### name` and the skill's `content`, when the skill registry holds it and the scope's
445
+ * `skills` list admits it; a blank body renders nothing, and an unregistered or excluded name
446
+ * renders nothing.
447
+ *
448
+ * **The rendered workspace (by carrier) — the sole document/image context.** It is the one
449
+ * `disclosure.workspace` names, else `workspaces.active`, and it renders only while the scope's
450
+ * `workspaces` list admits it; an unregistered `disclosure.workspace` renders none, and the build
451
+ * never moves `workspaces.active`. Its
404
452
  * {@link import('@orkestrel/workspace').WorkspaceInterface.files} are filtered by
405
- * `scope.files` (a three-way allow-list; `undefined` ⇒ all active files), then split by
453
+ * `scope.files` (a three-way allow-list; `undefined` ⇒ all its files), then split by
406
454
  * carrier: text files ({@link import('@orkestrel/workspace').isTextContent}) render into a dedicated
407
455
  * `## Workspace` section in the context message — a `user` message with a minted id that
408
456
  * follows the system message and is never stored — each a fenced
@@ -410,8 +458,7 @@ export declare interface AgentContextInterface {
410
458
  * the longest backtick run in the text, and never shorter than three; binary files whose MIME
411
459
  * starts with `image/` have their `base64` payload
412
460
  * 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.
461
+ * One workspace renders at most; with none to render, nothing is rendered for workspaces.
415
462
  *
416
463
  * **The format cascade.** Each manager section frames as `[open, ...items.map(render), close]`
417
464
  * (empty / absent slots dropped, the survivors `\n\n`-joined), reading the manager's `open`,
@@ -437,12 +484,15 @@ export declare interface AgentContextInterface {
437
484
  * handler that adds text for the model, such as a ledger's records, writes it into a message of
438
485
  * `selection.messages`.
439
486
  *
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
487
+ * @param options - The selection whose `messages` replace `view()`, a run's scope intersected
488
+ * with the active one, what the build shows, and whether it lists the workspace ids; omitted ⇒
489
+ * `view()` under the active scope, with no body and the active workspace
490
+ * @returns The scoped conversation, prefixed by the context message when the scoped memos, the
491
+ * listed workspace ids, or the rendered workspace's scoped text files are non-empty, and before
492
+ * it by the assembled `system` message when the prompt, the scoped instructions, the scoped
493
+ * skills, or the shown bodies are non-empty
444
494
  */
445
- build(selection?: Selection): readonly Message[];
495
+ build(options?: ContextBuildOptions): readonly Message[];
446
496
  }
447
497
 
448
498
  /**
@@ -464,8 +514,8 @@ export declare interface AgentContextInterface {
464
514
  * {@link ConversationManagerInterface} is created and a default conversation is added (so
465
515
  * `messages` is always defined). All default to a context with no system prompt, empty registries,
466
516
  * 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.
517
+ * agent's default {@link SelectionHandler}, which the active scope's `select` and a run scope's
518
+ * `select` override; omitted, `select()` returns `undefined` while neither scope holds a handler.
469
519
  */
470
520
  export declare interface AgentContextOptions {
471
521
  readonly system?: string;
@@ -482,11 +532,11 @@ export declare interface AgentContextOptions {
482
532
  readonly memos?: MemoManagerInterface;
483
533
  /**
484
534
  * 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.
535
+ * omitted (so `context.workspaces` is always present). `build()` renders one workspace's files
536
+ * by carrier — the one its `disclosure` option names, else the active one — text files into the
537
+ * `user` context message after the system message (fenced), image files attached to the last user
538
+ * message. That one workspace is the sole document/image context. The registry is structural;
539
+ * change its active workspace through `workspaces.switch(id)`.
490
540
  */
491
541
  readonly workspaces?: WorkspaceManagerInterface;
492
542
  /** Sets the initial active scope (the build-time filter); `undefined` ⇒ no filtering. */
@@ -498,20 +548,43 @@ export declare interface AgentContextOptions {
498
548
  * names no conversation — is always defined. `build()` folds the active conversation's
499
549
  * `view()` (the per-section summaries + the live tail), or a passed selection's `messages`.
500
550
  * 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
551
+ * compaction and, when a handler is set, the selection's. In an agent run, a scope change reaches
552
+ * the tools and the head at the next turn's snapshot, where a changed list rebuilds the head, and
553
+ * a `select` change waits for the next build or select site (run entry, the pre-first-turn
554
+ * compaction fold, or a compaction rebuild). The registry is structural; change its
504
555
  * active conversation through the manager's `switch(id)`, which sets the next run's default and
505
556
  * never moves a live run.
506
557
  */
507
558
  readonly conversations?: ConversationManagerInterface;
508
559
  /**
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()`.
560
+ * Holds the agent's default selection handler; the active scope's `select` overrides it, and a
561
+ * run scope's `select` overrides both. Omitted ⇒ with no scope handler either, `build()` folds the
562
+ * active conversation's `view()`.
511
563
  */
512
564
  readonly select?: SelectionHandler;
513
565
  }
514
566
 
567
+ /**
568
+ * Holds what one run shows within its ceiling: the loaded skills and the selected workspace.
569
+ *
570
+ * @remarks
571
+ * The agent loop derives one for each turn and passes it to `build`: the skills from the
572
+ * conversation's stored calls of the built-ins a run enables, and the workspace from the thread's
573
+ * last `switch`, else the `workspace` option of the run or the agent. Every read of it passes the
574
+ * ceiling and the registries, so a name that is not registered or not admitted shows nothing.
575
+ *
576
+ * @example
577
+ * ```ts
578
+ * const disclosure: AgentDisclosure = { skills: ['refunds'], workspace: 'orders' }
579
+ * ```
580
+ */
581
+ export declare interface AgentDisclosure {
582
+ /** Names the loaded skills, in load order. */
583
+ readonly skills: readonly string[];
584
+ /** Names the selected workspace; omitted ⇒ the registry's active workspace. */
585
+ readonly workspace?: string;
586
+ }
587
+
515
588
  /**
516
589
  * 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
590
  *
@@ -523,6 +596,9 @@ export declare interface AgentContextOptions {
523
596
  * `'AUTHORITY'` reports an `Authority` built with no valid `fallback`, a rule with no valid `verdict`
524
597
  * (its `context` names the `rule` index), and an agent built with `tools` and no `authority`. Each
525
598
  * throws at construction, with the options a host passes to correct it in the message.
599
+ * `'BUILTIN'` reports a `builtins` entry that is not a built-in or repeats one, `unload` enabled
600
+ * without `load`, and a tool manager holding a tool under an enabled built-in's name, each thrown
601
+ * at construction.
526
602
  * `'CONCURRENCY'` reports a run started while another run on the same agent is live, when the
527
603
  * agent carries a `window` (a shared context budget) or when the run's effective `budget` or
528
604
  * `allowance` is an instance a live run holds — the second run's `start()` would replace that
@@ -531,18 +607,18 @@ export declare interface AgentContextOptions {
531
607
  * `agent` id, and the `conversation` id for a shared conversation. For concurrent runs, use
532
608
  * separate agents, or one agent with no `window`, distinct budget and allowance instances per
533
609
  * 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
610
+ * `'LIMIT'` reports a construction or per-run `limit` that is not a positive safe integer.
611
+ * `'REGISTRY'` reports a rehydration name absent from its registry pool, on `provider` / `tool` /
612
+ * `authority` / `scheduler` / `build`, whose `context` names the `category` and the `name`, and a
613
+ * job `build` refuses as a record, whose `context` holds the contract's `faults` or the
614
+ * `refusals` lines `collectJobRefusals` returns. `'WINDOW'` reports a `strict` run whose
539
615
  * complete provider request is still over the `window` budget, equal to its `max` included, after
540
616
  * the one permitted fold or with no fold possible; it settles the run `error` before the provider
541
617
  * is called, and its `context` holds the `agent` id, the measured `consumed`, and the window `max`.
542
618
  * Narrow a caught value with {@link isAgentError} and branch on `error.code`.
543
619
  */
544
620
  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. */
621
+ /** 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
622
  readonly code: AgentErrorCode;
547
623
  /** Holds the values that locate the failure, such as the `agent` id of a refused run, or `undefined` when none were supplied. */
548
624
  readonly context: Readonly<Record<string, unknown>> | undefined;
@@ -556,8 +632,8 @@ export declare class AgentError extends Error {
556
632
  constructor(code: AgentErrorCode, message: string, options?: CodedErrorOptions);
557
633
  }
558
634
 
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';
635
+ /** Names the machine-readable agent approver, authority, built-in, concurrency, limit, registry, schema, and window failures. */
636
+ export declare type AgentErrorCode = 'APPROVER' | 'AUTHORITY' | 'BUILTIN' | 'CONCURRENCY' | 'LIMIT' | 'REGISTRY' | 'SCHEMA' | 'WINDOW';
561
637
 
562
638
  /**
563
639
  * Maps the push observation surface of an {@link AgentInterface} — the lifecycle, usage, and tool
@@ -663,6 +739,21 @@ export declare type AgentEventMap = {
663
739
  * fire none.
664
740
  */
665
741
  readonly select: readonly [selection: Selection];
742
+ /**
743
+ * Reports the exact request a turn dispatches, with the turn's `index` and the conversation its
744
+ * run is bound to, once a turn after the loop admits the request and before the provider receives
745
+ * it, so after a compaction fold it carries the rebuilt request. The request object and its
746
+ * `messages` and `tools` arrays are frozen; each message, `options`, and each definition is a
747
+ * shared object, so a listener is host code that reads the request and never writes to it. A
748
+ * request whose turn advertises no tool carries no `tools` member, and a turn cancelled before
749
+ * its request is composed emits none. A run aborted while a turn's `request` listeners run sends
750
+ * nothing for that turn: the provider receives no call for it, and the turn ends as a cancel.
751
+ */
752
+ readonly request: readonly [
753
+ index: number,
754
+ request: ProviderRequest,
755
+ conversation: ConversationInterface
756
+ ];
666
757
  };
667
758
 
668
759
  /**
@@ -677,6 +768,17 @@ export declare type AgentEventMap = {
677
768
  * awaited inline, so a bounded runner frees the parent's slot for them. `createAgentRunner`
678
769
  * creates one instance per runner and binds its `execute` method as the runner's handler.
679
770
  *
771
+ * A child job runs within its parent. Before a unit spawns or runs, on every attempt, the
772
+ * `execute` method walks the whole tree under it through the `scanJobTree` helper and refuses the
773
+ * unit when any job exceeds its own parent on `tools`, `builtins`, `scope`, `authority`,
774
+ * `provider`, `scheduler`, `limit`, `timeout`, or `budget`, or when a job is malformed or its build
775
+ * would refuse it (the lines `collectJobRefusals` returns), so nothing in a refused tree spawns, builds,
776
+ * or runs. A child's `workspace` is free, because it renders nothing its own `scope`
777
+ * omits. Each child is held within its parent alone, so the children of one parent can together
778
+ * spend more than it. A job that needs another provider, another authority, a skill, memo,
779
+ * workspace, or built-in its parent lacks, or more room than its parent is a root job the host
780
+ * enqueues.
781
+ *
680
782
  * @example
681
783
  * ```ts
682
784
  * import type { AgentJobInput, ProviderInterface } from '@orkestrel/agent'
@@ -701,11 +803,20 @@ export declare class AgentFanout {
701
803
  */
702
804
  constructor(registry: AgentRegistryInterface, partial: boolean);
703
805
  /**
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.
806
+ * Executes one unit: refuses its tree when a job in it is malformed or exceeds its parent, spawns
807
+ * its declared children unless an earlier attempt of the unit already did, then runs the
808
+ * rehydrated agent and settles it under the partial policy.
809
+ *
810
+ * @remarks
811
+ * The check runs on every attempt, before the unit spawns or runs, and throws synchronously. The
812
+ * error's message opens with the rule each kind of finding breaks, a refused job's rule when a
813
+ * finding opens with `JOB_REFUSAL_PREFIX` and the within-parent rule when a finding names an
814
+ * exceeded member, then lists every finding, one a line. Its `context.findings` holds the same
815
+ * findings in walk order.
706
816
  *
707
817
  * @param controller - The runner controller for this unit's attempt
708
818
  * @returns The settled agent result of the unit
819
+ * @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
820
  * @throws {AgentJobError} Thrown when the run ended partial and the partial policy is `false`
710
821
  */
711
822
  execute(controller: ControllerInterface<AgentJobInput, AgentResult>): Promise<AgentResult>;
@@ -761,45 +872,45 @@ export declare type AgentFrame = {
761
872
 
762
873
  /** Validates and projects agent frames at a JSON wire boundary. */
763
874
  export declare const agentFrameContract: ContractInterface<Readonly<{
764
- category: "token";
765
- content: string;
875
+ category: "token";
876
+ content: string;
766
877
  } & {}> | Readonly<{
767
- category: "think";
768
- content: string;
878
+ category: "think";
879
+ content: string;
769
880
  } & {}> | Readonly<{
770
- category: "tool";
771
- success: true;
772
- name: string;
881
+ category: "tool";
882
+ success: true;
883
+ name: string;
773
884
  } & {}> | Readonly<{
774
- category: "tool";
775
- success: false;
885
+ category: "tool";
886
+ success: false;
776
887
  } & {}> | Readonly<{
777
- category: "usage";
778
- usage: Readonly<{
779
- prompt: number;
780
- completion: number;
781
- total: number;
782
- } & {}>;
783
- estimate: number;
888
+ category: "usage";
889
+ usage: Readonly<{
890
+ prompt: number;
891
+ completion: number;
892
+ total: number;
893
+ } & {}>;
894
+ estimate: number;
784
895
  } & {}> | Readonly<{
785
- category: "ask";
786
- id: string;
787
- name: string;
788
- zone: string;
789
- arguments: string;
896
+ category: "ask";
897
+ id: string;
898
+ name: string;
899
+ zone: string;
900
+ arguments: string;
790
901
  } & {}> | Readonly<{
791
- category: "finish";
792
- content: string;
793
- partial: boolean;
902
+ category: "finish";
903
+ content: string;
904
+ partial: boolean;
794
905
  } & {
795
- usage?: Readonly<{
796
- prompt: number;
797
- completion: number;
798
- total: number;
799
- } & {}>;
800
- layer?: "budget" | "meter" | "model";
906
+ usage?: Readonly<{
907
+ prompt: number;
908
+ completion: number;
909
+ total: number;
910
+ } & {}>;
911
+ layer?: "budget" | "meter" | "model";
801
912
  }> | Readonly<{
802
- category: "error";
913
+ category: "error";
803
914
  } & {}>>;
804
915
 
805
916
  /**
@@ -906,9 +1017,10 @@ export declare interface AgentInterface {
906
1017
  * `budget` or `allowance` is an instance a live run holds, or when a live run is bound to the
907
1018
  * run's conversation; a run whose `limit` is not a positive safe
908
1019
  * 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
1020
+ * `budget` or `allowance` that does not implement `BudgetInterface`, a `conversation` that does
1021
+ * not implement `ConversationInterface`, a `scope` that does not implement `ScopeInterface`, or a
1022
+ * `workspace` that is not a string throws a `ContractError` with code
1023
+ * `'placement'` before either bound starts. Each throws synchronously, before any `Promise` is returned, and
912
1024
  * leaves the run's conversation unchanged. A fire-and-forget `agent.generate().catch(...)`
913
1025
  * therefore will not catch them (the throw happens on the call itself, ahead of the `.catch` ever
914
1026
  * attaching) — await the call (inside a `try`/`catch`) or wrap the call expression itself in
@@ -917,7 +1029,7 @@ export declare interface AgentInterface {
917
1029
  * @param options - Optional per-run {@link AgentRunOptions} (for example `think`); omitted ⇒ defaults
918
1030
  * @returns The settled {@link AgentResult} (`partial: true` when cancelled)
919
1031
  * @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.
1032
+ * @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
1033
  */
922
1034
  generate(options?: AgentRunOptions): Promise<AgentResult>;
923
1035
  /**
@@ -930,7 +1042,8 @@ export declare interface AgentInterface {
930
1042
  * instance, or a live run's conversation throws an {@link import('./errors.js').AgentError} with
931
1043
  * `code: 'CONCURRENCY'`, a `limit` that is not a positive safe integer throws one with `code: 'LIMIT'`, and a `prompt` that
932
1044
  * `agentPromptContract` refuses, a `budget` or `allowance` that does not implement
933
- * `BudgetInterface`, or a `conversation` that does not implement `ConversationInterface` throws a
1045
+ * `BudgetInterface`, a `conversation` that does not implement `ConversationInterface`, a `scope`
1046
+ * that does not implement `ScopeInterface`, or a `workspace` that is not a string throws a
934
1047
  * `ContractError` with code `'placement'`, synchronously — before the
935
1048
  * {@link AgentStreamInterface} handle is even returned, so it cannot be caught by chaining
936
1049
  * off the (never-produced) handle; wrap the call itself in `try`/`catch`. Each of those leaves
@@ -944,7 +1057,7 @@ export declare interface AgentInterface {
944
1057
  * @param options - Optional per-run {@link AgentRunOptions} (for example `think`); omitted ⇒ defaults
945
1058
  * @returns A live {@link AgentStreamInterface} handle (events + result + abort)
946
1059
  * @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.
1060
+ * @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
1061
  */
949
1062
  stream(options?: AgentRunOptions): AgentStreamInterface;
950
1063
  /**
@@ -958,33 +1071,40 @@ export declare interface AgentInterface {
958
1071
 
959
1072
  /** Checks a durable agent job exactly at `AgentRegistry.build`. */
960
1073
  export declare const agentJobContract: ContractInterface<Readonly<{
961
- provider: string;
1074
+ provider: string;
962
1075
  } & {
963
- messages?: readonly Readonly<{
964
- role: "assistant" | "system" | "tool" | "user";
965
- content: string;
966
- } & {
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
- }[];
1076
+ messages?: readonly Readonly<{
1077
+ content: string;
1078
+ role: "assistant" | "tool" | "user";
1079
+ } & {
1080
+ calls?: readonly Readonly<{
1081
+ id: string;
1082
+ name: string;
1083
+ arguments: {
1084
+ readonly [k: string]: JSONValue;
1085
+ };
1086
+ } & {}>[];
1087
+ call?: string;
1088
+ images?: readonly string[];
1089
+ thinking?: string;
1090
+ }>[];
1091
+ system?: string;
1092
+ tools?: readonly string[];
1093
+ authority?: string;
1094
+ scheduler?: string;
1095
+ limit?: number;
1096
+ timeout?: number;
1097
+ budget?: number;
1098
+ scope?: Readonly<{
1099
+ skills: readonly string[];
1100
+ memos: readonly string[];
1101
+ workspaces: readonly string[];
1102
+ } & {}>;
1103
+ workspace?: string;
1104
+ builtins?: readonly ("load" | "memo" | "remember" | "switch" | "unload")[];
1105
+ children?: readonly {
1106
+ readonly [k: string]: JSONValue;
1107
+ }[];
988
1108
  }>>;
989
1109
 
990
1110
  /**
@@ -1027,7 +1147,11 @@ export declare class AgentJobError extends Error {
1027
1147
  * to run); `messages` defaults to an empty seed. `tools` lists registry keys whose
1028
1148
  * resolved tools are loaded into the agent's manager; `authority` / `scheduler` are
1029
1149
  * single registry keys (their live objects carry functions, so they can't serialize).
1030
- * `budget` is a token ceiling rebuilt into a `createTokenBudget({ max })`.
1150
+ * `budget` is a token ceiling rebuilt into a `createTokenBudget({ max })`. A job holds what it
1151
+ * names: `scope` lists the skills, memos, and workspaces it holds of the registry's managers, so a
1152
+ * job with no `scope` holds none, as a job with no `tools` holds no tool; `workspace` renders within
1153
+ * that scope; and `builtins` names the built-in tools it serves itself, which pass the authority
1154
+ * `authority` names as its tools do.
1031
1155
  */
1032
1156
  export declare interface AgentJobInput {
1033
1157
  /** Names the registry key of the {@link ProviderInterface} the job runs against. */
@@ -1038,7 +1162,7 @@ export declare interface AgentJobInput {
1038
1162
  readonly system?: string;
1039
1163
  /** Names the registry keys of the values of {@link ToolInterface} loaded into the agent's tool manager; a non-empty list requires `authority`. */
1040
1164
  readonly tools?: readonly string[];
1041
- /** Names the registry key of the {@link AuthorityInterface} policy gate; required when `tools` names any. */
1165
+ /** Names the registry key of the {@link AuthorityInterface} policy gate; required when `tools` or `builtins` names any. */
1042
1166
  readonly authority?: string;
1043
1167
  /** Names the registry key of an optional {@link SchedulerInterface} pacing the loop. */
1044
1168
  readonly scheduler?: string;
@@ -1048,6 +1172,15 @@ export declare interface AgentJobInput {
1048
1172
  readonly timeout?: number;
1049
1173
  /** Sets a token ceiling rebuilt into a `createTokenBudget({ max })` cost bound. */
1050
1174
  readonly budget?: number;
1175
+ /**
1176
+ * Holds the job's ceiling over the `skills`, `memos`, and `workspaces` managers of the registry,
1177
+ * each list required, `[]` for none. Omitted ⇒ the job holds no skill, memo, or workspace.
1178
+ */
1179
+ readonly scope?: Required<Pick<ScopeFilter, 'skills' | 'memos' | 'workspaces'>>;
1180
+ /** Names the workspace the job renders in place of the active one, within its `scope` (see {@link AgentOptions.workspace}). */
1181
+ readonly workspace?: string;
1182
+ /** Lists the built-in tools the job serves itself (see {@link AgentOptions.builtins}); a non-empty list requires `authority`. */
1183
+ readonly builtins?: readonly AgentBuiltin[];
1051
1184
  /**
1052
1185
  * Lists the sub-agent jobs this job fans out — each a nested {@link AgentJobInput} (so the whole
1053
1186
  * tree stays serializable). On a `createAgentRunner`, the handler calls `controller.spawn` for
@@ -1063,14 +1196,16 @@ export declare interface AgentJobInput {
1063
1196
  * refuses instead of running an agent without it.
1064
1197
  *
1065
1198
  * @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.
1199
+ * `children` holds JSON records, because each child crosses this shape at its own `build`. Each
1200
+ * bound states what the build reads: `limit` an integer from 1 through `Number.MAX_SAFE_INTEGER`,
1201
+ * `timeout` an integer from 0 through `MAX_TIMEOUT_MS`, and `budget` a number of at least 0. A seed
1202
+ * message plays a `ConversationRole`, so a `system` message refuses here. A `scope` holds the
1203
+ * `skills`, `memos`, and `workspaces` lists, each required, and no other member; `builtins` admits
1204
+ * only the names of `AgentBuiltin`, and `collectJobRefusals` reads what a list of them cannot state.
1069
1205
  */
1070
1206
  export declare const agentJobShape: ObjectShape< {
1071
1207
  provider: StringShape;
1072
1208
  messages: OptionalShape<ArrayShape<ObjectShape< {
1073
- role: LiteralShape<readonly ["system", "user", "assistant", "tool"]>;
1074
1209
  content: StringShape;
1075
1210
  calls: OptionalShape<ArrayShape<ObjectShape< {
1076
1211
  id: StringShape;
@@ -1080,6 +1215,7 @@ arguments: ObjectShape<Record<never, never>, JSONShape>;
1080
1215
  call: OptionalShape<StringShape>;
1081
1216
  images: OptionalShape<ArrayShape<StringShape>>;
1082
1217
  thinking: OptionalShape<StringShape>;
1218
+ role: LiteralShape<readonly ["user", "assistant", "tool"]>;
1083
1219
  }, boolean | ContractShape>>>;
1084
1220
  system: OptionalShape<StringShape>;
1085
1221
  tools: OptionalShape<ArrayShape<StringShape>>;
@@ -1088,6 +1224,13 @@ scheduler: OptionalShape<StringShape>;
1088
1224
  limit: OptionalShape<NumberShape>;
1089
1225
  timeout: OptionalShape<NumberShape>;
1090
1226
  budget: OptionalShape<NumberShape>;
1227
+ scope: OptionalShape<ObjectShape< {
1228
+ skills: ArrayShape<StringShape>;
1229
+ memos: ArrayShape<StringShape>;
1230
+ workspaces: ArrayShape<StringShape>;
1231
+ }, boolean | ContractShape>>;
1232
+ workspace: OptionalShape<StringShape>;
1233
+ builtins: OptionalShape<ArrayShape<LiteralShape<readonly ["load", "unload", "memo", "remember", "switch"]>>>;
1091
1234
  children: OptionalShape<ArrayShape<ObjectShape<Record<never, never>, JSONShape>>>;
1092
1235
  }, boolean | ContractShape>;
1093
1236
 
@@ -1190,10 +1333,14 @@ export declare interface AgentJudgeInterface extends JudgeInterface {
1190
1333
  * Configures `createAgent` — the loop's bounds and pacing, the reserved `on` hooks, the
1191
1334
  * construction-time context wiring (`instructions` / `skills` / `memos` / `workspaces` / `scope`), the `conversations`
1192
1335
  * 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.
1336
+ * compaction of the run's conversation, the `builtins` each run serves and the `workspace` it
1337
+ * renders, and the `strict` switch that settles the run `error` on
1338
+ * an automatic-compaction summarizer failure, a selection fault, or a request still over the
1339
+ * window, or continues past them when `false`.
1195
1340
  *
1196
1341
  * @remarks
1342
+ * An own enumerable member this type does not declare refuses at construction with a
1343
+ * `ContractError` coded `'structure'`, and a declared member holding `undefined` reads as omitted.
1197
1344
  * - `system` — an optional system prompt prepended to the turn (seeds the context).
1198
1345
  * - `tools` — an optional pre-built {@link ToolManagerInterface} the loop dispatches
1199
1346
  * the model's calls through; an empty one is created when omitted.
@@ -1213,9 +1360,10 @@ export declare interface AgentJudgeInterface extends JudgeInterface {
1213
1360
  * The loop races that yield against the run signal, so a scheduler that ignores its signal still ends on a cancel.
1214
1361
  * - `signal` — an optional external `AbortSignal` whose abort cancels the turn (a
1215
1362
  * 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.
1363
+ * - `authority` — an {@link AuthorityInterface} that decides each scope-admitted call; required
1364
+ * when `tools` is set or `builtins` lists a name, and construction throws an `AgentError` with
1365
+ * code `'AUTHORITY'` without it. Omitted with no `tools` ⇒ the agent holds no authority, and the
1366
+ * loop denies a call to a tool added later through `context.tools`.
1219
1367
  * - `conversations` — an optional {@link ConversationManagerInterface} forwarded to the agent's
1220
1368
  * context (so `context.messages` is its active conversation's live tail); a run binds that
1221
1369
  * active conversation when it names no `conversation` of its own. Omitted ⇒ a fresh registry
@@ -1234,11 +1382,11 @@ export declare interface AgentJudgeInterface extends JudgeInterface {
1234
1382
  * thrown handler, a returned `fault`, a conversation changed under the handler, a selected
1235
1383
  * message whose role is not a `ConversationRole`) settle the same way, and a request still over
1236
1384
  * 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.
1385
+ * `AgentError` coded `'WINDOW'` before the provider is called. When `false`, the run continues
1386
+ * over-window, or on `view()` after a selection fault. Default: `true`.
1239
1387
  * - `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
1388
+ * active scope's `select` overrides it, and a run scope's `select` overrides both for its run.
1389
+ * 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
1390
  * selection's usage to `budget` and the result's `usage`.
1243
1391
  * - `instructions` — an optional pre-built {@link InstructionManagerInterface} forwarded to the
1244
1392
  * agent's context; an empty one is created when omitted (mirrors {@link AgentContextOptions.instructions}).
@@ -1250,6 +1398,18 @@ export declare interface AgentJudgeInterface extends JudgeInterface {
1250
1398
  * agent's context; a fresh empty one is created when omitted (mirrors {@link AgentContextOptions.workspaces}).
1251
1399
  * - `scope` — an optional initial active {@link ScopeInterface} forwarded to the agent's context
1252
1400
  * (the context and tool-dispatch filter); `undefined` ⇒ every registered tool is admitted.
1401
+ * - `builtins` — the {@link AgentBuiltin} tools each run serves itself, each advertised only where
1402
+ * the turn's ceiling admits its name and each call passing the authority. `remember` and `switch`
1403
+ * are advertised only while the ceiling's `memos` or `workspaces` list names a key, and `load` and
1404
+ * `unload` are not advertised under an empty `skills` list; construction throws an
1405
+ * `AgentError` with code `'BUILTIN'` for a name that is no built-in, a repeated name, `unload`
1406
+ * without `load`, or a name the tool manager already holds. Omitted ⇒ none.
1407
+ * - `workspace` — the id of the workspace every run renders in place of the active one, from its
1408
+ * first request, until the thread's own `switch`, and only where the registry holds it and the
1409
+ * ceiling admits it; a run's own `workspace` replaces it. It selects for the run and never moves
1410
+ * the `workspaces` manager's active pointer, which every conversation of the agent reads.
1411
+ * Construction throws a `ContractError` with code `'placement'` for a value that is not a string.
1412
+ * Omitted ⇒ the active workspace.
1253
1413
  * - `on` — the reserved {@link EmitterHooks} key: initial listeners for the agent's
1254
1414
  * {@link AgentEventMap}, wired at construction (for example `{ finish: (r) => log(r) }`).
1255
1415
  */
@@ -1275,10 +1435,12 @@ export declare interface AgentOptions {
1275
1435
  * denied the same way, whatever the authority would decide.
1276
1436
  * Every scoped-out call, one in a turn advertising no tools included, produces a denial tool
1277
1437
  * 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.
1438
+ * A scope change through the context's `apply` method applies at the next turn's snapshot, which
1439
+ * a `turn` listener reaches for the same turn: the snapshot decides the advertised tools, and a
1440
+ * changed `instructions`, `skills`, `memos`, `files`, or `workspaces` list rebuilds the head for
1441
+ * that turn over the same messages. A `select` change, and an instruction text edit with no list
1442
+ * change, wait for the next build or select site: run entry, the pre-first-turn compaction fold,
1443
+ * or a compaction rebuild.
1282
1444
  */
1283
1445
  readonly scope?: ScopeInterface;
1284
1446
  /**
@@ -1374,12 +1536,17 @@ export declare interface AgentOptions {
1374
1536
  readonly strict?: boolean;
1375
1537
  /**
1376
1538
  * 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
1539
+ * `select` overrides it while that scope is active, and a run scope's `select` overrides both for
1540
+ * its run. The loop runs it at run entry and after
1378
1541
  * each automatic compaction rebuild, for the user message that ends the run's conversation, and
1379
1542
  * charges its usage to the cost `budget`. Omitted ⇒ with no scope handler either, the loop
1380
1543
  * builds from the run's conversation's `view()` and awaits nothing.
1381
1544
  */
1382
1545
  readonly select?: SelectionHandler;
1546
+ /** Lists the built-in tools each run serves itself, each subject to the ceiling and the authority. Default: none. */
1547
+ readonly builtins?: readonly AgentBuiltin[];
1548
+ /** Names the workspace every run renders in place of the active one, until the thread's own `switch`. Default: the active workspace. */
1549
+ readonly workspace?: string;
1383
1550
  }
1384
1551
 
1385
1552
  /**
@@ -1393,9 +1560,9 @@ export declare interface AgentPrompt {
1393
1560
 
1394
1561
  /** Validates and projects agent prompts at the run's `prompt` option and a page's request body. */
1395
1562
  export declare const agentPromptContract: ContractInterface<Readonly<{
1396
- content: string;
1563
+ content: string;
1397
1564
  } & {
1398
- images?: readonly string[];
1565
+ images?: readonly string[];
1399
1566
  }>>;
1400
1567
 
1401
1568
  /**
@@ -1584,16 +1751,22 @@ export declare interface AgentQueueOptions {
1584
1751
  * the message `unknown <category>: <name>` when it is absent — an unknown name in a
1585
1752
  * rehydrated job is a programmer / config error that must fail loudly at build time, never
1586
1753
  * 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` /
1754
+ * - **`build` rehydrates.** Refuse with `code: 'REGISTRY'` a job `agentJobContract` refuses,
1755
+ * its faults under `context.faults`, and a job `collectJobRefusals` refuses, its lines under
1756
+ * `context.refusals`: tools or built-ins with no `authority`, a `builtins` list an agent
1757
+ * refuses, and a built-in the job's `tools` also name. Then resolve the job's `provider`;
1758
+ * assemble a fresh {@link ToolManager} from the `tools` names; rebuild the token `budget` from
1759
+ * its ceiling (`createTokenBudget({ max })`); resolve the optional `authority` /
1591
1760
  * `scheduler` names; construct the {@link Agent} with `system` / `limit` / `timeout` /
1592
1761
  * the threaded `signal`; seed its context with the job's `messages`; return it. The
1593
1762
  * `signal` is the queue attempt's / runner unit's cancel, so a bounded abort propagates
1594
1763
  * 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.
1764
+ * decides success vs. retry). A job is a record, so a malformed `limit`, `timeout`, `budget`,
1765
+ * seed role, or `builtins` list refuses as one, with `code: 'REGISTRY'`.
1766
+ * - **A job holds what it names.** A job with a `scope` gets the registry's `skills`, `memos`, and
1767
+ * `workspaces` managers, which every scoped job shares, and a scope named `job` built from its
1768
+ * three lists; a job with no `scope` gets none of them. Its `workspace` and `builtins` pass to
1769
+ * the agent.
1597
1770
  * - **Event-free.** A pure resolver — no Emitter, no events.
1598
1771
  *
1599
1772
  * @example
@@ -1675,8 +1848,7 @@ export declare interface AgentRegistryInterface {
1675
1848
  * @param input - The serializable {@link AgentJobInput} to rehydrate
1676
1849
  * @param signal - An optional cancel threaded into the agent (a queue / runner abort)
1677
1850
  * @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
1851
+ * @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
1852
  */
1681
1853
  build(input: AgentJobInput, signal?: AbortSignal): AgentInterface;
1682
1854
  }
@@ -1694,7 +1866,10 @@ export declare interface AgentRegistryInterface {
1694
1866
  * build (minted by the seeded `add`), so concurrent builds never collide, and the store
1695
1867
  * accumulates one snapshot per built agent that later calls `save`. Persistence
1696
1868
  * stays caller-triggered (`open` / `save`) — `build` never hydrates, so `build` stays
1697
- * synchronous. Omitted ⇒ every built agent gets a registry-only manager.
1869
+ * synchronous. Omitted ⇒ every built agent gets a registry-only manager. `skills`, `memos`, and
1870
+ * `workspaces` are pre-built managers every job with a `scope` shares, each read through that
1871
+ * job's lists; a job with no `scope` is passed none of them. Omitted ⇒ a scoped job's agent
1872
+ * creates an empty one.
1698
1873
  */
1699
1874
  export declare interface AgentRegistryOptions {
1700
1875
  readonly providers: Readonly<Record<string, ProviderInterface>>;
@@ -1702,6 +1877,12 @@ export declare interface AgentRegistryOptions {
1702
1877
  readonly authorities?: Readonly<Record<string, AuthorityInterface>>;
1703
1878
  readonly schedulers?: Readonly<Record<string, SchedulerInterface>>;
1704
1879
  readonly store?: ConversationStoreInterface;
1880
+ /** Holds the skill registry every job with a `scope` shares, read through its `skills` list. */
1881
+ readonly skills?: SkillManagerInterface;
1882
+ /** Holds the memo set every job with a `scope` shares, read and written through its `memos` list. */
1883
+ readonly memos?: MemoManagerInterface;
1884
+ /** Holds the workspace registry every job with a `scope` shares, read through its `workspaces` list. */
1885
+ readonly workspaces?: WorkspaceManagerInterface;
1705
1886
  }
1706
1887
 
1707
1888
  /**
@@ -1830,17 +2011,22 @@ export declare interface AgentRunnerOptions {
1830
2011
  }
1831
2012
 
1832
2013
  /**
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.
2014
+ * 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
2015
  *
1835
2016
  * @remarks
2017
+ * An own enumerable member this type does not declare refuses the call synchronously with a
2018
+ * `ContractError` coded `'structure'`, before the run changes anything, and a declared member
2019
+ * holding `undefined` reads as omitted.
1836
2020
  * Every member is optional and resolved independently, so an omitted member leaves the
1837
2021
  * agent's constructed value in force and a caller that passes no options runs exactly the
1838
2022
  * agent it configured. `think` / `schema` ride through to the provider as
1839
2023
  * {@link ProviderStreamOptions}; `limit` / `timeout` / `budget` / `allowance` replace their construction
1840
2024
  * 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.
2025
+ * the run's bound abort) rather than replacing it. `conversation`, `prompt`, and `scope` have no
2026
+ * construction default: `conversation` names the conversation the run binds in place of the one
2027
+ * active at the call, `prompt` is the user turn the run appends to that conversation before it
2028
+ * starts, and the run `scope` narrows the construction `scope`, the context scope, at each turn of
2029
+ * the run and never replaces it.
1844
2030
  * Nothing here mutates the agent — the next run reads the construction defaults again.
1845
2031
  */
1846
2032
  export declare interface AgentRunOptions {
@@ -1910,6 +2096,25 @@ export declare interface AgentRunOptions {
1910
2096
  * run reads its request from the conversation's tail.
1911
2097
  */
1912
2098
  readonly prompt?: AgentPrompt;
2099
+ /**
2100
+ * Narrows this run's ceiling: each turn reads the context scope intersected with it, list by
2101
+ * list, one time, and each build site of the run filters instructions, skills, memos, files, and
2102
+ * workspaces by the same intersection. Its `select` runs in place of the context scope's. A later
2103
+ * `context.apply` still reaches the run at its next turn, and never past this scope, so a run
2104
+ * that needs a wider scope than the context scope needs another agent. The `stream` or
2105
+ * `generate` call throws a `ContractError` coded `'placement'` synchronously when the value does
2106
+ * not implement {@link ScopeInterface}, before the run appends its prompt or starts. Omitted ⇒ the
2107
+ * context scope alone.
2108
+ */
2109
+ readonly scope?: ScopeInterface;
2110
+ /**
2111
+ * Replaces {@link AgentOptions.workspace} for this run: the id of the workspace the run renders in
2112
+ * place of the active one, from its first request, until the thread's own `switch`, within the
2113
+ * ceiling. The `stream` or `generate` call throws a `ContractError` coded `'placement'`
2114
+ * synchronously when the value is not a string, before the run appends its prompt or starts.
2115
+ * Omitted ⇒ the agent's value.
2116
+ */
2117
+ readonly workspace?: string;
1913
2118
  }
1914
2119
 
1915
2120
  /**
@@ -2133,6 +2338,22 @@ export declare interface ApproverInterface {
2133
2338
  answer(answer: AgentAnswer): boolean;
2134
2339
  }
2135
2340
 
2341
+ /**
2342
+ * Matches a text that is blank: empty after white space and default-ignorable code points, such
2343
+ * as U+3164, are removed, frozen.
2344
+ */
2345
+ export declare const ARGUMENT_BLANK_PATTERN: Readonly<RegExp>;
2346
+
2347
+ /**
2348
+ * Matches one control, format, line-separator, or paragraph-separator code point — the class
2349
+ * `renderArguments` encodes and a memo's one-line name and description may not hold, frozen.
2350
+ *
2351
+ * @remarks
2352
+ * Not global, so a `test` call keeps no state between calls; a global replace builds its own
2353
+ * global copy from `source`.
2354
+ */
2355
+ export declare const ARGUMENT_CONTROL_PATTERN: Readonly<RegExp>;
2356
+
2136
2357
  /**
2137
2358
  * Arms signal propagation to a byte reader and returns the controller that removes the listener.
2138
2359
  *
@@ -2272,6 +2493,9 @@ export declare class Authority implements AuthorityInterface {
2272
2493
  */
2273
2494
  export declare const AUTHORITY_NOTES: AuthorityNote;
2274
2495
 
2496
+ /** Lists the members `AuthorityOptions` declares, frozen — the keys the `Authority` constructor admits. */
2497
+ export declare const AUTHORITY_OPTION_KEYS: readonly ["rules", "fallback", "ask"];
2498
+
2275
2499
  /**
2276
2500
  * Carries what an {@link AuthorityInterface} evaluates for one tool call — the call under
2277
2501
  * consideration.
@@ -2377,6 +2601,9 @@ export declare interface AuthorityRule {
2377
2601
  /** Names an authority's verdict on one tool call. */
2378
2602
  export declare type AuthorityVerdict = 'allow' | 'ask' | 'deny';
2379
2603
 
2604
+ /** Lists the members `ContextBuildOptions` declares, frozen — the keys the `build` method of an `AgentContext` admits. */
2605
+ export declare const BUILD_OPTION_KEYS: readonly ["selection", "scope", "disclosure", "switchable"];
2606
+
2380
2607
  /**
2381
2608
  * Merges the results of a judge request's calls into one result.
2382
2609
  *
@@ -2690,6 +2917,68 @@ export declare function buildRequestMessage(request: Message, records: string):
2690
2917
  */
2691
2918
  export declare function buildSummaryMessage(section: Section): Message;
2692
2919
 
2920
+ /**
2921
+ * Caps each built-in argument in code points, as the built-in argument shapes count them — a `name`
2922
+ * (a skill name, a memo name, or a workspace id), a memo `description`, and a memo `content` — and
2923
+ * the `candidates` one refusal lists, frozen.
2924
+ */
2925
+ export declare const BUILTIN_LIMITS: Readonly<{
2926
+ name: number;
2927
+ description: number;
2928
+ content: number;
2929
+ candidates: number;
2930
+ }>;
2931
+
2932
+ /**
2933
+ * Holds the texts the built-ins return on success — `loaded`, `unloaded`, `remembered`, and
2934
+ * `switched` — frozen.
2935
+ *
2936
+ * @remarks
2937
+ * `loaded`, `unloaded`, and `switched` are the texts the conversation's stored tool messages are
2938
+ * matched against to derive what a run shows, so each is one fixed constant. A stored message
2939
+ * counts only under a call to a built-in the run enables.
2940
+ */
2941
+ export declare const BUILTIN_NOTES: BuiltinNote;
2942
+
2943
+ /**
2944
+ * Declares each built-in tool's model-facing description and annotations, keyed by its
2945
+ * {@link AgentBuiltin} name, frozen.
2946
+ *
2947
+ * @remarks
2948
+ * `memo` is `pure` and `untrusted`, because it returns memo text a model can have written;
2949
+ * `remember` is `consequential`, so an `allow` verdict becomes an `ask`. A run's own tools and the
2950
+ * definitions `collectBuiltinDefinitions` returns both read their text and annotations here.
2951
+ */
2952
+ export declare const BUILTIN_TOOLS: Readonly<Record<AgentBuiltin, Readonly<{
2953
+ description: string;
2954
+ annotations?: ToolAnnotations;
2955
+ }>>>;
2956
+
2957
+ /** Holds the model-facing texts the built-ins return on success. */
2958
+ export declare interface BuiltinNote {
2959
+ readonly loaded: string;
2960
+ readonly unloaded: string;
2961
+ readonly remembered: string;
2962
+ readonly switched: string;
2963
+ }
2964
+
2965
+ /**
2966
+ * Pairs each built-in's argument shape, which its tool's door compiles, with its compiled contract,
2967
+ * keyed by its {@link AgentBuiltin} name, frozen.
2968
+ *
2969
+ * @remarks
2970
+ * The one map from a built-in to its arguments: `createBuiltinTool` builds the door from `shape`,
2971
+ * and `collectBuiltinDefinitions` and `collectDisclosure` read `contract`, so the advertised
2972
+ * parameters, the door, and the derivation admit by one rule. The record declares no shape: each
2973
+ * `shape` is a reference to the one `shapers.ts` declares, held beside the contract compiled from
2974
+ * it, because the tool door takes a shape and the derivation takes a compiled contract. The record
2975
+ * is data, as the rest of this file is.
2976
+ */
2977
+ export declare const builtinToolContracts: Readonly<Record<AgentBuiltin, Readonly<{
2978
+ shape: ContractShape;
2979
+ contract: ContractInterface<Readonly<Record<string, unknown>>>;
2980
+ }>>>;
2981
+
2693
2982
  /**
2694
2983
  * Buffers chunks in a minimal unbounded async channel — the eager pump writes them in (`push`)
2695
2984
  * and ends it (`close` / `fail`) regardless of consumption, while a consumer reads them back live
@@ -2875,6 +3164,9 @@ export declare class Classifier implements ClassifierInterface {
2875
3164
  classification(): LedgerClassification;
2876
3165
  }
2877
3166
 
3167
+ /** Lists the members `ClassifierOptions` declares, frozen — the keys the `Classifier` constructor admits. */
3168
+ export declare const CLASSIFIER_OPTION_KEYS: readonly ["strict", "conversation", "judge", "questions", "topics", "thresholds", "assign", "entities", "correction", "scheduler"];
3169
+
2878
3170
  /**
2879
3171
  * Carries what became of one filing question: its judgment key, its phase, its outcome, and the time spent resolving it.
2880
3172
  *
@@ -3040,6 +3332,61 @@ export declare interface CodedErrorOptions {
3040
3332
  */
3041
3333
  export declare function collectAmendments(input: LedgerProjectionInput, byId: ReadonlyMap<string, Message>, live: readonly string[]): readonly LedgerAmendment[];
3042
3334
 
3335
+ /**
3336
+ * Collects the definitions of the tools an agent serves itself, as a run advertises them.
3337
+ *
3338
+ * @remarks
3339
+ * Each definition carries the name, description, and annotations `BUILTIN_TOOLS` declares and the
3340
+ * parameters of the built-in's compiled contract in `builtinToolContracts`, in the order `builtins` lists them, so
3341
+ * it equals the definition of the tool `createBuiltinTool` creates. A relay server lists these
3342
+ * among its declared definitions to forward a page's built-ins. A name that is no built-in
3343
+ * contributes nothing.
3344
+ *
3345
+ * @param options - The agent options whose `builtins` to project
3346
+ * @returns The definitions, empty when `builtins` is absent
3347
+ *
3348
+ * @example
3349
+ * ```ts
3350
+ * collectBuiltinDefinitions({ builtins: ['load', 'unload'] }).map((definition) => definition.name) // ['load', 'unload']
3351
+ * ```
3352
+ */
3353
+ export declare function collectBuiltinDefinitions(options: Pick<AgentOptions, 'builtins'>): readonly ToolDefinition[];
3354
+
3355
+ /**
3356
+ * Collects the loaded skills and the selected workspace a conversation's stored built-in calls
3357
+ * record, counting only the built-ins a run enables.
3358
+ *
3359
+ * @remarks
3360
+ * Pure. It reads each section's retained originals, oldest first, then the live tail, and pairs
3361
+ * each tool message with the call that owns it through {@link collectToolGroups} and
3362
+ * {@link findToolCall}. It then folds the pairs in message order: a `load` whose message content
3363
+ * equals `BUILTIN_NOTES.loaded` adds its `skill`, an `unload` with `BUILTIN_NOTES.unloaded` removes
3364
+ * it, and a `switch` with `BUILTIN_NOTES.switched` selects its `workspace`. Each call's arguments
3365
+ * are admitted through the built-in's contract in `builtinToolContracts`, lossless repairs
3366
+ * included, as its tool's door admits them, so a `{ skill: 1 }` the door repaired to `'1'` counts
3367
+ * as `'1'`; arguments the contract refuses change nothing. A skill loaded again while shown keeps
3368
+ * its place, and one loaded again after its unload goes last. Any other message and a denied or
3369
+ * refused call change nothing. The result holds `workspace` only when a switch succeeded.
3370
+ *
3371
+ * A record counts only while its built-in is in `builtins`, so a host tool that holds a built-in's
3372
+ * name on a run that does not enable it shows nothing; with none of `load`, `unload`, and `switch`
3373
+ * enabled, nothing is read. A stored record cannot tell its writer, so one a host tool wrote under a
3374
+ * built-in's name while that built-in was off counts after a run enables it, bounded by the registry
3375
+ * and the ceiling as every record is.
3376
+ *
3377
+ * @param conversation - The conversation whose stored messages record the calls
3378
+ * @param builtins - The built-ins the run enables
3379
+ * @returns The skills in load order and the last selected workspace
3380
+ *
3381
+ * @example
3382
+ * ```ts
3383
+ * import { collectDisclosure, createConversation } from '@orkestrel/agent'
3384
+ *
3385
+ * collectDisclosure(createConversation(), ['load', 'unload']) // { skills: [] }
3386
+ * ```
3387
+ */
3388
+ export declare function collectDisclosure(conversation: Pick<ConversationInterface, 'sections' | 'messages'>, builtins: readonly AgentBuiltin[]): AgentDisclosure;
3389
+
3043
3390
  /**
3044
3391
  * Collects whole exchanges, joining every exchange spanned by a tool group.
3045
3392
  *
@@ -3079,6 +3426,28 @@ export declare function collectExchanges(messages: readonly Message[]): Readonly
3079
3426
  */
3080
3427
  export declare function collectImageData(files: readonly FileInterface[]): readonly string[];
3081
3428
 
3429
+ /**
3430
+ * Collects the refusals a job the contract admitted would meet at its build: tools or built-ins with
3431
+ * no authority, a `builtins` list `requireBuiltins` refuses, and a built-in its own `tools` name.
3432
+ *
3433
+ * @remarks
3434
+ * Each line names the member first, then the refusal and its remedy. The `builtins` line of a list
3435
+ * `requireBuiltins` refuses carries that error's message; a job's tool manager holds exactly its
3436
+ * `tools`, so a built-in its `tools` list also names is the name a manager would already hold.
3437
+ * `AgentRegistry.build` refuses a job with any line, and `scanJobTree` refuses each such job of a
3438
+ * tree before anything spawns.
3439
+ *
3440
+ * @param job - The `tools`, `builtins`, and `authority` of a job `agentJobContract` admitted
3441
+ * @returns One line a refusal, in member order; empty when the job builds
3442
+ *
3443
+ * @example
3444
+ * ```ts
3445
+ * collectJobRefusals({ provider: 'main', tools: ['search'] })
3446
+ * // ["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"]
3447
+ * ```
3448
+ */
3449
+ export declare function collectJobRefusals(job: Pick<AgentJobInput, 'tools' | 'builtins' | 'authority'>): readonly string[];
3450
+
3082
3451
  /**
3083
3452
  * Captures source bytes and direct amendment edges for a held window.
3084
3453
  * @param messages - Current stored messages
@@ -3271,6 +3640,9 @@ export declare function collectToolGroups(messages: readonly Message[]): Readonl
3271
3640
  */
3272
3641
  export declare function collectWriteSupersessions(messages: readonly Message[], findings: readonly LedgerLookupFinding[]): ReadonlyMap<string, readonly string[]>;
3273
3642
 
3643
+ /** Lists the members `CompactOptions` declares, frozen — the keys the `compact` method of a `Conversation` admits. */
3644
+ export declare const COMPACT_OPTION_KEYS: readonly ["keep", "sections", "signal"];
3645
+
3274
3646
  /**
3275
3647
  * Configures one {@link ConversationInterface.compact} call — the retained-tail size, the
3276
3648
  * `sections` cap, or both, overridden for one fold.
@@ -3316,6 +3688,26 @@ export declare interface CompactOptions {
3316
3688
  */
3317
3689
  export declare function computeLedgerChecksum(text: string): string;
3318
3690
 
3691
+ /**
3692
+ * Computes the tokens loading a skill adds: its body, and the definitions it names beyond an advertised set.
3693
+ *
3694
+ * @remarks
3695
+ * The body is the text `renderSkillBody` renders, priced at `scale`, and a blank `content` renders
3696
+ * no body. The caller passes the definitions the skill names that the turn does not advertise,
3697
+ * priced as {@link computeToolPrice} prices an addition.
3698
+ *
3699
+ * @param skill - The skill to load
3700
+ * @param added - The definitions the skill names that the advertised set leaves out
3701
+ * @param calibrated - The definitions the gauge's overhead priced
3702
+ * @param gauge - The gauge's scale and overhead
3703
+ * @returns The tokens the load adds
3704
+ * @example
3705
+ * ```ts
3706
+ * computeSkillPrice({ name: 'refunds', content: 'Check the order first.' }, [], [], { scale: 1, overhead: 0 }) // 9
3707
+ * ```
3708
+ */
3709
+ export declare function computeSkillPrice(skill: Pick<Skill, 'name' | 'content'>, added: readonly ToolDefinition[], calibrated: readonly ToolDefinition[], gauge: LedgerGauge): number;
3710
+
3319
3711
  /**
3320
3712
  * Computes the completion tokens attributable to a message's thinking.
3321
3713
  *
@@ -3336,6 +3728,78 @@ export declare function computeLedgerChecksum(text: string): string;
3336
3728
  */
3337
3729
  export declare function computeThinking(message: Pick<Message, 'thinking' | 'content' | 'calls'>, completion: number): number;
3338
3730
 
3731
+ /**
3732
+ * Computes the tokens one estimate unit of a definition costs beyond the calibrated set.
3733
+ *
3734
+ * @remarks
3735
+ * The larger of `scale` and the calibrated set's overhead per estimate unit, or `scale` for an
3736
+ * empty set or one that estimates 0. A set's estimate is `estimateTokens` over its JSON text.
3737
+ *
3738
+ * @param calibrated - The definitions the gauge's overhead priced
3739
+ * @param gauge - The gauge's scale and overhead
3740
+ * @returns The tokens one estimate unit of a definition costs
3741
+ * @example
3742
+ * ```ts
3743
+ * computeToolDensity([], { scale: 1.1, overhead: 400 }) // 1.1
3744
+ * ```
3745
+ */
3746
+ export declare function computeToolDensity(calibrated: readonly ToolDefinition[], gauge: LedgerGauge): number;
3747
+
3748
+ /**
3749
+ * Computes what a call's advertised set spares of the calibrated overhead and adds beyond it.
3750
+ *
3751
+ * @remarks
3752
+ * Definitions compare by their JSON text, so a definition replaced under its name by another text
3753
+ * is both left out and added. An empty advertised set spares the whole overhead. Otherwise the
3754
+ * calibrated definitions the call leaves out spare the lower of `scale` and the calibrated set's
3755
+ * overhead per estimate unit, times their estimate, so a credit never exceeds their proportional
3756
+ * share of the overhead; the definitions it advertises beyond the calibrated set add
3757
+ * {@link computeToolDensity}, the higher of the two, times theirs. A set's estimate is
3758
+ * `estimateTokens` over its JSON text, 0 for an empty set. The call's price is
3759
+ * `overhead - spared + added`.
3760
+ *
3761
+ * @param calibrated - The definitions the gauge's overhead priced
3762
+ * @param advertised - The definitions the call advertises
3763
+ * @param gauge - The gauge's scale and overhead
3764
+ * @returns The tokens the call spares and adds
3765
+ * @example
3766
+ * ```ts
3767
+ * computeToolPrice([], [], { scale: 1.1, overhead: 400 }) // { spared: 400, added: 0 }
3768
+ * ```
3769
+ */
3770
+ export declare function computeToolPrice(calibrated: readonly ToolDefinition[], advertised: readonly ToolDefinition[], gauge: LedgerGauge): Required<Pick<GaugeCall, 'spared' | 'added'>>;
3771
+
3772
+ /** Lists the members `AgentContextOptions` declares, frozen — the keys the `AgentContext` constructor admits. */
3773
+ export declare const CONTEXT_OPTION_KEYS: readonly ["system", "tools", "instructions", "skills", "memos", "workspaces", "scope", "conversations", "select"];
3774
+
3775
+ /**
3776
+ * Selects what one `build` call renders.
3777
+ *
3778
+ * @remarks
3779
+ * `selection` holds the conversation part in place of the active conversation's `view()`. `scope`
3780
+ * holds a run's scope: the build filters by the context scope intersected with it, list by list,
3781
+ * so a run scope narrows the context scope and never widens it. `disclosure` names the skills
3782
+ * whose bodies close the `system` message and the workspace to render in place of the active one,
3783
+ * each kept only where its registry holds it and that intersection admits it. `switchable` lists
3784
+ * the admitted workspace ids in the context message, as an agent run does while it advertises
3785
+ * `switch`.
3786
+ *
3787
+ * @example
3788
+ * ```ts
3789
+ * context.build({ selection: { messages: conversation.view(), judgments: [] }, scope })
3790
+ * ```
3791
+ */
3792
+ export declare interface ContextBuildOptions {
3793
+ /** Holds the messages that replace `view()`; omitted ⇒ the active conversation's `view()`. */
3794
+ readonly selection?: Selection;
3795
+ /** Holds a run's scope; the build filters by the context scope intersected with it. */
3796
+ readonly scope?: ScopeInterface;
3797
+ /** Holds the skills whose bodies close the system message and the workspace to render. Default: no body, the active workspace. */
3798
+ readonly disclosure?: AgentDisclosure;
3799
+ /** If `true`, the context message lists the admitted workspace ids; if `false`, it lists none. Default: `false`. */
3800
+ readonly switchable?: boolean;
3801
+ }
3802
+
3339
3803
  /**
3340
3804
  * Reports a context snapshot that `isMemoSnapshot` refuses, thrown by the construction of a
3341
3805
  * {@link import('./memos/MemoManager.js').MemoManager} before it seats any state or by a memo store,
@@ -3505,6 +3969,15 @@ export declare class Conversation implements ConversationInterface {
3505
3969
  snapshot(): ConversationSnapshot;
3506
3970
  }
3507
3971
 
3972
+ /** Lists the members `ConversationInput` declares, frozen — the keys the `add` method of a `ConversationManager` admits. */
3973
+ export declare const CONVERSATION_INPUT_KEYS: readonly ["id", "summarize", "keep", "sections", "cumulative", "on", "error", "snapshot"];
3974
+
3975
+ /** Lists the members `ConversationManagerOptions` declares, frozen — the keys the `ConversationManager` constructor admits. */
3976
+ export declare const CONVERSATION_MANAGER_KEYS: readonly ["summarize", "keep", "sections", "store"];
3977
+
3978
+ /** Lists the members `ConversationOptions` declares, frozen — the keys the `Conversation` constructor admits. */
3979
+ export declare const CONVERSATION_OPTION_KEYS: readonly ["id", "on", "error", "summarize", "keep", "sections", "cumulative", "snapshot"];
3980
+
3508
3981
  /**
3509
3982
  * Names the framing label the `view()` method of a {@link ConversationInterface} prefixes onto the
3510
3983
  * summary of each compacted section so a small model reads it as a condensed recap of earlier turns — the lean
@@ -3553,7 +4026,8 @@ export declare const CONVERSATION_ROLES: readonly ["user", "assistant", "tool"];
3553
4026
  * `'SUMMARY'`. A stored message plays a `ConversationRole`: `add` refuses any other role with
3554
4027
  * `'ROLE'` before it stores any message of the batch, a hydrating snapshot that holds one throws
3555
4028
  * `'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`,
4029
+ * that is not a plain record, before its role is read, or whose other members fail `isMessageInput`
4030
+ * with `'MESSAGE'`, its `context` holding the `faults`,
3557
4031
  * before it stores any message of the batch. A hydrating snapshot that fails
3558
4032
  * `isConversationSnapshot` or repeats an id, and a store row or written snapshot that does, throw
3559
4033
  * `'SNAPSHOT'`; a judgment the guard admits but JSON cannot carry still throws `'JUDGMENT'`. A
@@ -3561,7 +4035,7 @@ export declare const CONVERSATION_ROLES: readonly ["user", "assistant", "tool"];
3561
4035
  * {@link isConversationError} and branch on `error.code`.
3562
4036
  */
3563
4037
  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. */
4038
+ /** 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
4039
  readonly code: ConversationErrorCode;
3566
4040
  /** Holds the values that locate the failure, such as the `question` id of a malformed question, or `undefined` when none were supplied. */
3567
4041
  readonly context: Readonly<Record<string, unknown>> | undefined;
@@ -4870,6 +5344,30 @@ export declare function createApprover(): ApproverInterface;
4870
5344
  */
4871
5345
  export declare function createAuthority(options: AuthorityOptions): AuthorityInterface;
4872
5346
 
5347
+ /**
5348
+ * Creates the tool a run serves for one built-in: its description and annotations from
5349
+ * `BUILTIN_TOOLS`, its argument shape from `builtinToolContracts`, and the given handler.
5350
+ *
5351
+ * @remarks
5352
+ * The tool's door refuses a missing, empty, over-long, or extra argument before the handler runs,
5353
+ * and repairs a value that converts to a string without loss, such as a number, so the handler
5354
+ * reads only arguments the shape admits. Its definition equals the one `collectBuiltinDefinitions`
5355
+ * returns for the same name.
5356
+ *
5357
+ * @param name - The built-in to create
5358
+ * @param execute - The handler the door hands admitted arguments to
5359
+ * @returns The tool
5360
+ *
5361
+ * @example
5362
+ * ```ts
5363
+ * import { createBuiltinTool } from '@orkestrel/agent'
5364
+ *
5365
+ * const memo = createBuiltinTool('memo', (args) => `read ${String(args.name)}`)
5366
+ * memo.annotations // { pure: true, untrusted: true }
5367
+ * ```
5368
+ */
5369
+ export declare function createBuiltinTool(name: AgentBuiltin, execute: ToolOptions['execute']): ToolInterface;
5370
+
4873
5371
  /**
4874
5372
  * Creates an empty unbounded async channel — a {@link ChannelInterface} a producer writes
4875
5373
  * values into (`push`) and ends (`close` / `fail`) regardless of consumption, while a
@@ -5433,6 +5931,34 @@ export declare function createThinkSplitter(): ThinkSplitterInterface;
5433
5931
  */
5434
5932
  export declare function cutListing(entries: readonly string[], room: number, kind?: 'older' | 'more', first?: boolean): string;
5435
5933
 
5934
+ /**
5935
+ * Cuts the workspace text a calibration sample adds over its head to a number of characters, or
5936
+ * returns `undefined` when the sample adds anything else.
5937
+ *
5938
+ * @remarks
5939
+ * The head and the shown sample are what a context's `build` returns for an empty turn without and
5940
+ * with the workspace: the shown sample holds the head's messages with the workspace section appended
5941
+ * to the context message, or one context message added where the head holds none. The cut keeps the
5942
+ * first `limit` characters of that added text and every other message as the sample holds it. A
5943
+ * sample whose messages differ from the head's in any other way, or that adds no text, returns
5944
+ * `undefined`.
5945
+ *
5946
+ * @param head - The head built with no workspace
5947
+ * @param shown - The head built with the workspace a request renders
5948
+ * @param limit - The characters of added text to keep
5949
+ * @returns The cut sample, or `undefined` when the sample adds no trailing text to one message
5950
+ *
5951
+ * @example
5952
+ * ```ts
5953
+ * import { cutWorkspaceSample } from '@orkestrel/agent'
5954
+ *
5955
+ * const head = [{ id: 's', role: 'system', content: 'Serve the desk.' }] as const
5956
+ * const shown = [...head, { id: 'c', role: 'user', content: '## Workspace\n\nFile: a.md' }] as const
5957
+ * cutWorkspaceSample(head, shown, 12)?.[1]?.content // '## Workspace'
5958
+ * ```
5959
+ */
5960
+ export declare function cutWorkspaceSample(head: readonly Message[], shown: readonly Message[], limit: number): readonly Message[] | undefined;
5961
+
5436
5962
  /**
5437
5963
  * Backs a {@link ConversationStoreInterface} with one table of the `databases` layer — a
5438
5964
  * conversation's durable state is a row holding the snapshot as one opaque JSON column, narrowed
@@ -5636,7 +6162,7 @@ export declare const DEFAULT_CONVERSATION_KEEP = 0;
5636
6162
  export declare const DEFAULT_LEDGER_LIMIT = 8;
5637
6163
 
5638
6164
  /**
5639
- * Supplies the default prompt and tail shares.
6165
+ * Supplies the default prompt, tail, and skills shares.
5640
6166
  */
5641
6167
  export declare const DEFAULT_LEDGER_SHARE: LedgerShare;
5642
6168
 
@@ -5681,6 +6207,28 @@ export declare const DEFAULT_RELAY_LIMIT = 1048576;
5681
6207
  */
5682
6208
  export declare function denyCall(call: ToolCall, reason: string | undefined): ToolResult;
5683
6209
 
6210
+ /**
6211
+ * Returns the refusal that names a subject and at most `BUILTIN_LIMITS.candidates` of the names a
6212
+ * caller can use.
6213
+ *
6214
+ * @remarks
6215
+ * The subject reads after "No", so it names what the caller may use, such as `'skill you can load'`.
6216
+ * The text echoes no argument, so an absent name and a name outside the ceiling read byte for byte
6217
+ * the same. Each name is JSON-encoded and capped by `preview`, in the order given. Past the cap one
6218
+ * fixed sentence sends the reader to the index in its prompt.
6219
+ *
6220
+ * @param subject - What the caller may name, such as `'skill you can load'`
6221
+ * @param names - The names the caller can use, in registry order
6222
+ * @returns The refusal text
6223
+ *
6224
+ * @example
6225
+ * ```ts
6226
+ * describeCandidates('skill you can load', ['refunds', 'billing'])
6227
+ * // 'No skill you can load has that name. Use one of: "refunds", "billing".'
6228
+ * ```
6229
+ */
6230
+ export declare function describeCandidates(subject: string, names: readonly string[]): string;
6231
+
5684
6232
  /**
5685
6233
  * Describes why a judge question refuses, in the text both of its doors throw.
5686
6234
  *
@@ -5748,9 +6296,10 @@ export declare const DETERMINISTIC_JUDGE_ERROR: RegExp;
5748
6296
  * Digests tool definitions as the JSON a provider request carries them, in order.
5749
6297
  *
5750
6298
  * @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.
6299
+ * A ledger stores this digest with its gauge and compares it at a hydrate and at each `respond`
6300
+ * call, so it reuses the gauge only for the same definitions: an added, removed, reordered, or
6301
+ * edited definition changes the digest. The digest is a {@link computeLedgerChecksum} checksum and
6302
+ * makes no security claim.
5754
6303
  *
5755
6304
  * @param definitions - The tool definitions, as a tool manager's `definitions` method returns them
5756
6305
  * @returns The 16-digit hexadecimal digest, or undefined when JSON cannot render the definitions
@@ -5939,6 +6488,34 @@ export declare interface FailureRead {
5939
6488
  readonly cause?: unknown;
5940
6489
  }
5941
6490
 
6491
+ /**
6492
+ * Returns the definitions a turn advertises from the allow-list, the registered skills, and the
6493
+ * shown skills.
6494
+ *
6495
+ * @remarks
6496
+ * The allow-list admits first, as `filterAllowList` does. When no skill is passed, or an allow-list
6497
+ * admits no `load` definition, the admitted list returns as it is. Otherwise a tool any registered
6498
+ * skill names is held back unless a shown skill names it too; `load` and `unload` are never held
6499
+ * back. A caller passes the registered skills only while `load` is enabled, so with no allow-list a
6500
+ * ceiling whose empty `skills` list withholds `load` from the candidates still holds the skills'
6501
+ * tools back. Holding a tool back is presentation, never authority: a call to it is denied as
6502
+ * outside the turn's scope.
6503
+ *
6504
+ * @param definitions - The candidate definitions, in advertisement order
6505
+ * @param names - The turn's `tools` allow-list (`undefined` ⇒ all, `[]` ⇒ none)
6506
+ * @param skills - The registered skills whose `tools` gate, or none while `load` is not enabled
6507
+ * @param shown - The names of the skills the turn shows
6508
+ * @returns The advertised definitions, in candidate order
6509
+ *
6510
+ * @example
6511
+ * ```ts
6512
+ * const skills = [{ id: '1', name: 'refunds', description: 'Refunds', content: '', tools: ['refund'], files: [] }]
6513
+ * filterAdvertisedTools([{ name: 'load' }, { name: 'refund' }], undefined, skills, []) // [{ name: 'load' }]
6514
+ * filterAdvertisedTools([{ name: 'load' }, { name: 'refund' }], undefined, skills, ['refunds']).length // 2
6515
+ * ```
6516
+ */
6517
+ export declare function filterAdvertisedTools(definitions: readonly ToolDefinition[], names: readonly string[] | undefined, skills: readonly Skill[], shown: readonly string[]): readonly ToolDefinition[];
6518
+
5942
6519
  /**
5943
6520
  * Filters a list of members by a {@link import('./contexts/index.js').ScopeInterface} allow-list of keys —
5944
6521
  * `undefined` passes everything, `[]` passes nothing, and a non-empty list passes the listed keys
@@ -5971,16 +6548,27 @@ export declare interface FailureRead {
5971
6548
  export declare function filterAllowList<T>(allow: readonly string[] | undefined, members: readonly T[], key: (member: T) => string): readonly T[];
5972
6549
 
5973
6550
  /**
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
6551
+ * Returns the definitions a run offers before the allow-list, without `remember` unless the
6552
+ * ceiling's `memos` list names a memo, without `switch` unless its `workspaces` list names a
6553
+ * workspace, and without `load` and `unload` while its `skills` list is empty.
6554
+ *
6555
+ * @remarks
6556
+ * `remember` writes and `switch` selects only a name its list holds, so an absent list and an empty
6557
+ * list each leave the built-in nothing to act on, and it is not advertised. An absent `skills` list
6558
+ * admits every registered skill, so `load` and `unload` are withheld only when the list is empty.
6559
+ * Every other definition keeps its place.
6560
+ *
6561
+ * @param definitions - The candidate definitions, in advertisement order
6562
+ * @param ceiling - The turn's ceiling
6563
+ * @returns The definitions, in candidate order
6564
+ *
5978
6565
  * @example
5979
6566
  * ```ts
5980
- * findLedgerCall(group, result)?.arguments
6567
+ * filterBuiltinCandidates([{ name: 'memo' }, { name: 'remember' }], { memos: [] }) // [{ name: 'memo' }]
6568
+ * filterBuiltinCandidates([{ name: 'memo' }, { name: 'remember' }], { memos: ['tone'] }).length // 2
5981
6569
  * ```
5982
6570
  */
5983
- export declare function findLedgerCall(group: readonly Message[], message: Message): ToolCall | undefined;
6571
+ export declare function filterBuiltinCandidates(definitions: readonly ToolDefinition[], ceiling: ScopeFilter): readonly ToolDefinition[];
5984
6572
 
5985
6573
  /**
5986
6574
  * Finds the first cut in a range whose probe returns a value, by bisection.
@@ -6000,6 +6588,18 @@ export declare function findLedgerCall(group: readonly Message[], message: Messa
6000
6588
  */
6001
6589
  export declare function findLedgerCut<T>(low: number, high: number, probe: (cut: number) => T | undefined, found?: T): T | undefined;
6002
6590
 
6591
+ /**
6592
+ * Finds the call that owns a tool message within a collected tool group.
6593
+ * @param group - The assistant leader followed by its tool results, as {@link collectToolGroups} returns it
6594
+ * @param message - The tool result to pair; distinct leader ids pair by result id when any result has one
6595
+ * @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
6596
+ * @example
6597
+ * ```ts
6598
+ * findToolCall(group, result)?.arguments
6599
+ * ```
6600
+ */
6601
+ export declare function findToolCall(group: readonly Message[], message: Message): ToolCall | undefined;
6602
+
6003
6603
  /**
6004
6604
  * Fits the marginal tokens one estimate unit adds within a request.
6005
6605
  *
@@ -6082,6 +6682,9 @@ export declare class Gauge implements GaugeInterface {
6082
6682
  observe(calls: readonly GaugeCall[], reply?: GaugeCall): void;
6083
6683
  }
6084
6684
 
6685
+ /** Lists the members `GaugeOptions` declares, frozen — the keys the `Gauge` constructor admits. */
6686
+ export declare const GAUGE_OPTION_KEYS: readonly ["scale", "overhead", "capacity", "predict", "replay"];
6687
+
6085
6688
  /**
6086
6689
  * Carries one agent call as the gauge reads it.
6087
6690
  *
@@ -6089,9 +6692,11 @@ export declare class Gauge implements GaugeInterface {
6089
6692
  * `estimate` is the `estimateMessages` estimate of the call's messages. `prompt` and `completion`
6090
6693
  * are the tokens the provider reported, absent when it reported none. `tools` is the count of tool
6091
6694
  * 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.
6695
+ * estimated use subtracts it from overhead, floored at 0. `added` is the tokens of definitions it
6696
+ * advertised beyond the calibrated set; estimated use adds it. Omission means 0 for both.
6697
+ * Observation rescales only with exact overhead: `spared` absent or zero retains all overhead, and
6698
+ * `spared` at or above overhead retains none. A partially spared first call, and a first call with
6699
+ * `added` above 0, keep the prior scale.
6095
6700
  * `thinking` estimates the completion tokens spent on thinking from its share of the generated
6096
6701
  * characters, rounded to the nearest integer and capped at `completion`. With replay `'none'`,
6097
6702
  * the measured call uses `prompt + completion - thinking`; other policies retain the whole
@@ -6101,6 +6706,8 @@ export declare interface GaugeCall {
6101
6706
  readonly estimate: number;
6102
6707
  /** Tokens spared by tool definitions this call did not advertise. Default: 0. */
6103
6708
  readonly spared?: number;
6709
+ /** Tokens of definitions this call advertised beyond the calibrated set. Default: 0. */
6710
+ readonly added?: number;
6104
6711
  readonly prompt?: number;
6105
6712
  readonly completion?: number;
6106
6713
  readonly thinking?: number;
@@ -6172,7 +6779,7 @@ export declare interface GaugeInterface extends LedgerGauge {
6172
6779
  * `'CAPACITY'` otherwise. `replay` names the thinking the next request carries. Default: `'none'`.
6173
6780
  * Measured use is `prompt + completion - (thinking ?? 0)` for `'none'`, and `prompt + completion`
6174
6781
  * otherwise; absent completion counts as 0. Without prompt usage, use is
6175
- * `max(0, overhead - (spared ?? 0)) + scale * estimate`.
6782
+ * `max(0, overhead - (spared ?? 0)) + (added ?? 0) + scale * estimate`.
6176
6783
  * Capacity left is `max(0, capacity - used)`. The reply reserve adds recall uniform at the marginal
6177
6784
  * rate to the largest observed reply's `completion - (thinking ?? 0)` for every policy.
6178
6785
  * Without a positive reply observation, it prices the longest reply text at that rate. The room formula
@@ -6321,8 +6928,10 @@ export declare function inferStop(reason: unknown, allowance: BudgetInterface<To
6321
6928
  * A thin immutable value object (mirroring {@link import('@orkestrel/tool').Tool}): the
6322
6929
  * constructor mints a fresh `id` (`crypto.randomUUID()`), copies the input's `name` /
6323
6930
  * `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
6931
+ * per-item `override` value when supplied; otherwise the instance owns no `override` member, so
6932
+ * its own keys and a JSON copy carry no member holding `undefined`. The input meets its exact
6933
+ * contract first, so a missing required member, an undeclared member, and a declared member holding
6934
+ * `undefined` refuse with a `ContractError` coded `'structure'`. Never mutated after construction. An
6326
6935
  * {@link import('./InstructionManager.js').InstructionManager} keys it by `name` and
6327
6936
  * renders it (highest `priority` first) under its section header.
6328
6937
  *
@@ -6341,6 +6950,9 @@ export declare class Instruction implements InstructionInterface {
6341
6950
  constructor(input: InstructionInput);
6342
6951
  }
6343
6952
 
6953
+ /** Lists the members `InstructionManagerOptions` declares, frozen — the keys the `InstructionManager` constructor admits. */
6954
+ export declare const INSTRUCTION_MANAGER_KEYS: readonly ["on", "error", "format"];
6955
+
6344
6956
  /**
6345
6957
  * Carries the minimal data to author an {@link InstructionInterface} — the `id` is minted by
6346
6958
  * the {@link InstructionManagerInterface} that stores it, so a caller supplies only
@@ -6360,15 +6972,38 @@ export declare interface InstructionInput {
6360
6972
  readonly override?: string;
6361
6973
  }
6362
6974
 
6975
+ /** Admits an instruction input exactly, and reads the faults of a refused one. */
6976
+ export declare const instructionInputContract: ContractInterface<Readonly<{
6977
+ name: string;
6978
+ content: string;
6979
+ } & {
6980
+ priority?: number;
6981
+ override?: string;
6982
+ }>>;
6983
+
6363
6984
  /**
6364
- * Represents an immutable instruction — a named directive a richer context places between the
6365
- * system prompt and the conversation, ordered by descending {@link priority}.
6985
+ * Describes an instruction input exactly: a string `name` and `content`, and an optional finite
6986
+ * `priority` and string `override`.
6366
6987
  *
6367
6988
  * @remarks
6368
- * Assembled once from its {@link InstructionInput} (the `id` minted by the storing
6369
- * layer) and never mutated. `name` keys it in an {@link InstructionManagerInterface}
6370
- * (last write wins); `priority` orders the rendered list (higher first). Default: `0`.
6371
- * The {@link import('./AgentContext.js').AgentContext} build step renders it through
6989
+ * An unknown member, a missing required member, and a declared member holding `undefined` refuse.
6990
+ */
6991
+ export declare const instructionInputShape: ObjectShape< {
6992
+ name: StringShape;
6993
+ content: StringShape;
6994
+ priority: OptionalShape<NumberShape>;
6995
+ override: OptionalShape<StringShape>;
6996
+ }, boolean | ContractShape>;
6997
+
6998
+ /**
6999
+ * Represents an immutable instruction — a named directive a richer context places between the
7000
+ * system prompt and the conversation, ordered by descending {@link priority}.
7001
+ *
7002
+ * @remarks
7003
+ * Assembled once from its {@link InstructionInput} (the `id` minted by the storing
7004
+ * layer) and never mutated. `name` keys it in an {@link InstructionManagerInterface}
7005
+ * (last write wins); `priority` orders the rendered list (higher first). Default: `0`.
7006
+ * The {@link import('./AgentContext.js').AgentContext} build step renders it through
6372
7007
  * its manager's `render` (`content`) under the manager's `open` header.
6373
7008
  */
6374
7009
  export declare interface InstructionInterface {
@@ -6496,6 +7131,7 @@ export declare interface InstructionManagerInterface {
6496
7131
  *
6497
7132
  * @param input - One {@link InstructionInput}, or a batch
6498
7133
  * @returns The stored instruction, or the stored batch in input order
7134
+ * @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
7135
  */
6500
7136
  add(input: InstructionInput): InstructionInterface;
6501
7137
  add(inputs: readonly InstructionInput[]): readonly InstructionInterface[];
@@ -6554,6 +7190,30 @@ export declare interface InstructionManagerOptions {
6554
7190
  readonly format?: ContextSectionFormat<InstructionInterface>;
6555
7191
  }
6556
7192
 
7193
+ /**
7194
+ * Intersects two scope filters list by list; an absent side constrains nothing.
7195
+ *
7196
+ * @remarks
7197
+ * Pure, and it can only tighten. Each list of the result is {@link intersectKeys} over the two
7198
+ * sides' lists, each read one time, in the order `instructions`, `skills`, `memos`, `tools`,
7199
+ * `files`, and `workspaces`. A list neither side constrains is omitted, and every returned list is
7200
+ * a fresh copy.
7201
+ * `Scope.narrow`, a run's build, and a ledger's answer-pass scope compose their layers through it.
7202
+ *
7203
+ * @param parent - The outer filter, such as the context scope (`undefined` ⇒ no constraint)
7204
+ * @param child - The inner filter, such as a run scope (`undefined` ⇒ no constraint)
7205
+ * @returns The intersected filter
7206
+ *
7207
+ * @example
7208
+ * ```ts
7209
+ * import { intersectFilters } from '@orkestrel/agent'
7210
+ *
7211
+ * intersectFilters({ tools: ['read', 'write'] }, { tools: ['write', 'admin'], files: [] })
7212
+ * // { tools: ['write'], files: [] }
7213
+ * ```
7214
+ */
7215
+ export declare function intersectFilters(parent: ScopeFilter | undefined, child: ScopeFilter | undefined): ScopeFilter;
7216
+
6557
7217
  /**
6558
7218
  * Intersects two scope category lists under the "`undefined` is the universal set" rule — a
6559
7219
  * fresh copy that can only tighten, and the primitive a scope narrows through.
@@ -6585,6 +7245,20 @@ export declare function intersectKeys(parent: readonly string[] | undefined, chi
6585
7245
  */
6586
7246
  export declare const INVALID_RELAY_STATUS = 400;
6587
7247
 
7248
+ /**
7249
+ * Checks whether a value names a built-in: `load`, `unload`, `memo`, `remember`, or `switch`.
7250
+ *
7251
+ * @param value - The unknown name candidate
7252
+ * @returns True if the value names a built-in; false otherwise
7253
+ *
7254
+ * @example
7255
+ * ```ts
7256
+ * isAgentBuiltin('load') // true
7257
+ * isAgentBuiltin('open') // false
7258
+ * ```
7259
+ */
7260
+ export declare function isAgentBuiltin(value: unknown): value is AgentBuiltin;
7261
+
6588
7262
  /**
6589
7263
  * Narrows an unknown caught value to an {@link AgentError} through its identity brand and declared members, so a `catch`
6590
7264
  * can branch on its `code`.
@@ -7027,13 +7701,17 @@ export declare function isMemoSnapshot(value: unknown): value is MemoSnapshot;
7027
7701
  export declare function isMessage(value: unknown): value is Message;
7028
7702
 
7029
7703
  /**
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.
7704
+ * Checks whether a value is a message input a conversation can store: a `ConversationRole`, a string
7705
+ * `content`, and `calls`, `call`, `images`, and `thinking` absent or of their declared types.
7032
7706
  *
7033
7707
  * @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.
7708
+ * An exact record, because a stored message is one: a value that is not a plain record, such as a
7709
+ * class instance or an object that inherits its `role`, returns false through `recordOf`'s own plain
7710
+ * record check, as does a member `MessageInput` does not declare or a declared optional member holding
7711
+ * `undefined`. Each tool call crosses `isToolCall` of
7712
+ * `@orkestrel/tool`, whose interface admits more members, so the store keeps `id`, `name`, and
7713
+ * `arguments` and leaves the rest. `add` reads the role through `requireRole` first, so its text can
7714
+ * name the role received. An unreadable member returns false.
7037
7715
  *
7038
7716
  * @param value - The unknown input candidate
7039
7717
  * @returns True if the input's members are valid; false otherwise
@@ -7043,7 +7721,7 @@ export declare function isMessage(value: unknown): value is Message;
7043
7721
  * isMessageInput({ role: 'user' }) // false
7044
7722
  * ```
7045
7723
  */
7046
- export declare function isMessageInput(value: unknown): value is MessageInput;
7724
+ export declare const isMessageInput: Guard<MessageInput>;
7047
7725
 
7048
7726
  /**
7049
7727
  * Checks whether a value is a non-negative safe integer, `-0` included.
@@ -7130,6 +7808,30 @@ export declare function isProviderError(value: unknown): value is ProviderError;
7130
7808
  */
7131
7809
  export declare const isProviderResult: Guard<ProviderResult>;
7132
7810
 
7811
+ /**
7812
+ * Checks whether a value implements `ScopeInterface`; total, each member read one time, any
7813
+ * implementation admitted.
7814
+ *
7815
+ * @remarks
7816
+ * A scope is a string `id` and `name`, each of `instructions`, `skills`, `memos`, `tools`, `files`,
7817
+ * and `workspaces` absent or a dense array of strings, `select` absent or a function, and a `narrow`
7818
+ * function. The guard reads each of those members one time and never calls a method. It admits
7819
+ * unknown members, a class instance, and a transparent proxy, and returns false for a throwing
7820
+ * getter, a revoked proxy, and any other malformed input.
7821
+ *
7822
+ * @param value - The value to test
7823
+ * @returns True if `value` carries the members of a {@link ScopeInterface}; false otherwise
7824
+ *
7825
+ * @example
7826
+ * ```ts
7827
+ * import { createScope, isScope } from '@orkestrel/agent'
7828
+ *
7829
+ * isScope(createScope({ name: 'reader', tools: ['search'] })) // true
7830
+ * isScope({ id: 's1', name: 'reader' }) // false
7831
+ * ```
7832
+ */
7833
+ export declare function isScope(value: unknown): value is ScopeInterface;
7834
+
7133
7835
  /**
7134
7836
  * Checks whether an `unknown` is structurally a {@link Section} record — a `string` `id` and
7135
7837
  * `summary` beside a `messages` array of valid {@link Message} records, the per-section step of
@@ -7193,6 +7895,18 @@ export declare function isSystemOneAnswer(value: unknown): value is SystemOneAns
7193
7895
  */
7194
7896
  export declare function isSystemOneResponse(value: unknown): value is SystemOneResponse;
7195
7897
 
7898
+ /**
7899
+ * Opens a job tree finding that refuses a whole job, which sets it apart from a finding that names an exceeded member.
7900
+ *
7901
+ * @remarks
7902
+ * The `scanJobTree` helper writes it before the path of a job the contract refuses or a member read
7903
+ * makes unreadable, and the `AgentFanout` class reads it to open its refusal with the rule that
7904
+ * finding breaks. An
7905
+ * exceeded member's finding opens with `job`, so text later in a finding cannot pass for this
7906
+ * prefix.
7907
+ */
7908
+ export declare const JOB_REFUSAL_PREFIX = "refused ";
7909
+
7196
7910
  /**
7197
7911
  * Joins the reasoning a run's provider calls separated from the answer — the first call
7198
7912
  * seeds the accumulation, a later call appends blank-line separated so each turn's reasoning
@@ -7218,6 +7932,9 @@ export declare function isSystemOneResponse(value: unknown): value is SystemOneR
7218
7932
  */
7219
7933
  export declare function joinThinking(prior: string | undefined, next: string): string;
7220
7934
 
7935
+ /** Lists the members `AgentJudgeInput` declares, frozen — the keys the `AgentJudge` constructor admits. */
7936
+ export declare const JUDGE_INPUT_KEYS: readonly ["url", "path", "model", "batch", "timeout", "fetch", "headers"];
7937
+
7221
7938
  /**
7222
7939
  * Reports a judge call cancelled by the caller's signal or its deadline, carrying the
7223
7940
  * {@link JudgeResult} merged from the calls that completed before the cancel and the
@@ -7728,10 +8445,10 @@ export declare class Ledger implements LedgerInterface {
7728
8445
  */
7729
8446
  constructor(provider: ProviderInterface, options: LedgerOptions);
7730
8447
  /**
7731
- * Returns the owned request engine.
7732
- * @returns The engine serving this conversation
8448
+ * Returns the record of the owned request engine, which starts no run.
8449
+ * @returns The frozen record of the agent serving this conversation
7733
8450
  */
7734
- get agent(): AgentInterface;
8451
+ get agent(): LedgerAgentInterface;
7735
8452
  /**
7736
8453
  * Returns the owned message history.
7737
8454
  * @returns The history filed and served by this ledger
@@ -7744,9 +8461,10 @@ export declare class Ledger implements LedgerInterface {
7744
8461
  get gauge(): LedgerGauge | undefined;
7745
8462
  /**
7746
8463
  * 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
8464
+ * @param signal - The signal bounding every calibration call; an abort rejects with its reason
7748
8465
  * @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'`)
8466
+ * @throws {LedgerError} Thrown when a calibration call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)
8467
+ * @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
8468
  * @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)
7751
8469
  */
7752
8470
  calibrate(signal: AbortSignal): Promise<LedgerGauge>;
@@ -7759,18 +8477,31 @@ export declare class Ledger implements LedgerInterface {
7759
8477
  /**
7760
8478
  * Appends a request and serves it, recovering an unfinished or rejected first pass with one answer pass.
7761
8479
  * 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.
8480
+ * 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
8481
  * 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
8482
  * @param content - The request text
7765
8483
  * @param signal - The caller's cancellation signal; an abort during calibration rejects with its reason
7766
8484
  * @returns The final pass, the usage of every pass, and the filing attempts of this request alone
7767
8485
  * @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)
7768
8486
  * @throws {LedgerError} Thrown when a calibration call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)
8487
+ * @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'`)
8488
+ * @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
8489
  * @throws {ContractError} Thrown when `signal` is defined and is not a native `AbortSignal`
7770
8490
  */
7771
8491
  respond(content: string, signal?: AbortSignal): Promise<LedgerResult>;
7772
8492
  }
7773
8493
 
8494
+ /**
8495
+ * Lists the members the `LedgerAgentOptions` pick declares, frozen — the keys a ledger's `agent`
8496
+ * option admits.
8497
+ *
8498
+ * @remarks
8499
+ * The `Ledger` constructor passes the list to `refuseOptionKeys` of `@orkestrel/contract`, so an
8500
+ * own enumerable member outside it, an `AgentOptions` member the pick leaves out included, refuses
8501
+ * with a `ContractError` coded `'structure'`.
8502
+ */
8503
+ export declare const LEDGER_AGENT_KEYS: readonly ["limit", "timeout", "on", "scheduler", "instructions", "skills", "memos", "workspaces", "strict", "authority", "builtins", "workspace"];
8504
+
7774
8505
  /**
7775
8506
  * Lists the categories the ledger files a message under, in the order the category question
7776
8507
  * names them — the one list the {@link LedgerCategory} union derives from.
@@ -7780,9 +8511,22 @@ export declare const LEDGER_CATEGORIES: readonly ["fact", "rule", "correction",
7780
8511
  /**
7781
8512
  * Supplies the text of each ledger note, worded for a model that answers in its final
7782
8513
  * message.
8514
+ *
8515
+ * @remarks
8516
+ * `overflow` names `unload` because a skill the thread shows is the room a model can give back: a
8517
+ * successful `unload` reopens every call the room denied in that request.
7783
8518
  */
7784
8519
  export declare const LEDGER_NOTES: LedgerNote;
7785
8520
 
8521
+ /**
8522
+ * Lists the members `LedgerOptions` declares, frozen — the keys the `Ledger` constructor admits.
8523
+ *
8524
+ * @remarks
8525
+ * The constructor passes the list to `refuseOptionKeys` of `@orkestrel/contract`, so an own
8526
+ * enumerable member outside it refuses with a `ContractError` coded `'structure'`.
8527
+ */
8528
+ export declare const LEDGER_OPTION_KEYS: readonly ["judge", "system", "topics", "questions", "thresholds", "capacity", "predict", "think", "gauge", "lookups", "writes", "share", "recall", "correction", "agent", "snapshot"];
8529
+
7786
8530
  /** Prefixes the key of an owner's record, which the owner's id follows. */
7787
8531
  export declare const LEDGER_OWNER_PREFIX = "owner:";
7788
8532
 
@@ -7803,6 +8547,17 @@ export declare const LEDGER_RECALL_LABELS: Readonly<{
7803
8547
  /** Names the key of the record that holds the rules no owner claims. */
7804
8548
  export declare const LEDGER_RULES_KEY = "rules";
7805
8549
 
8550
+ /**
8551
+ * Sets the 3 UTF-8 bytes one UTF-16 code unit encodes to at most, the divisor that sizes the
8552
+ * workspace text a calibration's third call carries.
8553
+ *
8554
+ * @remarks
8555
+ * A tokenizer that falls back to bytes charges at most one token a byte, so workspace text cut to the
8556
+ * capacity the call without definitions left, divided by this figure, in characters, reports at most
8557
+ * `capacity` apart from a template's few tokens for an added message.
8558
+ */
8559
+ export declare const LEDGER_SAMPLE_BYTES = 3;
8560
+
7806
8561
  /**
7807
8562
  * Holds back the share of the prompt budget the scale can rise by between calibration and a
7808
8563
  * request's first call.
@@ -7831,6 +8586,30 @@ export declare const LEDGER_SLICE = 5;
7831
8586
  */
7832
8587
  export declare const LEDGER_WORD: RegExp;
7833
8588
 
8589
+ /**
8590
+ * Holds the members of a ledger's agent a host reads: its emitter, id, status, context, and abort.
8591
+ *
8592
+ * @remarks
8593
+ * It is one frozen record the ledger builds at construction, and it holds no `generate` or `stream`
8594
+ * member, own or inherited, so the ledger's `respond` method is the only caller that starts a run on
8595
+ * the agent: every run is a pass of the active `respond` call, on the ledger's `conversation`. The
8596
+ * `emitter`, `id`, and `context` members are the agent's own. The `status` member reads the agent's
8597
+ * live status, and `abort` ends the active pass partial with the reason it takes; because the caller
8598
+ * did not abort, the ledger then runs the answer pass. To serve another conversation, build another
8599
+ * ledger or another agent for it.
8600
+ *
8601
+ * @example
8602
+ * ```ts
8603
+ * import { createLedger } from '@orkestrel/agent'
8604
+ *
8605
+ * const ledger = createLedger(provider, options) // `provider` and `options` come from the host
8606
+ * ledger.agent.emitter.on('request', (_index, request) => log(request.tools?.length))
8607
+ * ledger.agent.status // 'idle'
8608
+ * 'generate' in ledger.agent // false
8609
+ * ```
8610
+ */
8611
+ export declare type LedgerAgentInterface = Pick<AgentInterface, 'emitter' | 'id' | 'status' | 'context' | 'abort'>;
8612
+
7834
8613
  /**
7835
8614
  * Selects the agent bounds, hooks, scheduler, and context libraries a ledger passes through to the agent it builds.
7836
8615
  *
@@ -7854,9 +8633,14 @@ export declare const LEDGER_WORD: RegExp;
7854
8633
  * unanswered as a repeat, before its `evaluate` method and with no ask, and its `ask` refuses the
7855
8634
  * identical twin in the same batch of a declined or unanswered ask without calling this authority's
7856
8635
  * `ask`, so a person is asked about such a call once per request. The agent still reports that
7857
- * twin's `ask` event.
8636
+ * twin's `ask` event. `builtins` enables the built-in tools and `workspace` names the workspace
8637
+ * every request renders, as `AgentOptions` describes them. A ledger with `builtins` requires `authority`:
8638
+ * construction throws `AgentError` with code `'AUTHORITY'` without it. The ledger tests each
8639
+ * built-in call for a repeat and for room before this authority reads it, and every call it admits
8640
+ * reaches this authority's `evaluate` and, when asked, its `ask`. While `builtins` enables `load`,
8641
+ * calibration measures every definition but the tools a registered skill holds back.
7858
8642
  */
7859
- export declare type LedgerAgentOptions = Pick<AgentOptions, 'limit' | 'timeout' | 'on' | 'scheduler' | 'instructions' | 'skills' | 'memos' | 'workspaces' | 'strict' | 'authority'>;
8643
+ export declare type LedgerAgentOptions = Pick<AgentOptions, 'limit' | 'timeout' | 'on' | 'scheduler' | 'instructions' | 'skills' | 'memos' | 'workspaces' | 'strict' | 'authority' | 'builtins' | 'workspace'>;
7860
8644
 
7861
8645
  /** Identifies an accepted direct message amendment whose sentence scope remains unresolved. */
7862
8646
  export declare interface LedgerAmendment {
@@ -7891,6 +8675,13 @@ export declare interface LedgerClassification {
7891
8675
  readonly supersessions: ReadonlyMap<string, readonly string[]>;
7892
8676
  }
7893
8677
 
8678
+ /** Carries one price a request committed: the tokens, the count of calls observed when it was committed, and the skill a `load` names. */
8679
+ export declare interface LedgerCommit {
8680
+ readonly price: number;
8681
+ readonly turn: number;
8682
+ readonly skill?: string;
8683
+ }
8684
+
7894
8685
  /**
7895
8686
  * Narrows the pair questions the ledger asks about each correction.
7896
8687
  *
@@ -7928,7 +8719,9 @@ export declare type LedgerEntityHandler = (text: string, partial: boolean) => Re
7928
8719
  * @remarks
7929
8720
  * A threshold, share, capacity, limit, topic, lookup, write, question, or gauge outside its bounds is a
7930
8721
  * 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
8722
+ * no prompt usage, or a calibration call, with the tool definitions, without them, or with the workspace text, that reports a prompt
8723
+ * over `capacity`, the head included, throws this with `'GAUGE'`; the second holds `capacity` and
8724
+ * `prompt` in its `context`. A snapshot option that `isLedgerSnapshot` refuses
7932
8725
  * throws this with `'SNAPSHOT'`, its `context` holding the `faults`. Narrow a caught value with {@link isLedgerError} and
7933
8726
  * branch on `error.code`. A selection without an active `respond` call, for a conversation other
7934
8727
  * than the ledger's, or for a request other than that call's request or a ledger note, reports
@@ -7965,7 +8758,7 @@ export declare type LedgerErrorCode =
7965
8758
  | 'TOPIC'
7966
8759
  /** Reports a lookup tool named `recall` or a name another lookup tool carries. */
7967
8760
  | '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. */
8761
+ /** 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
8762
  | 'GAUGE'
7970
8763
  /** Reports a render context that holds no reference for a source it annotates. */
7971
8764
  | 'REFERENCE'
@@ -7974,7 +8767,9 @@ export declare type LedgerErrorCode =
7974
8767
  /** Reports filing wording that `isLedgerQuestion` refuses. */
7975
8768
  | 'QUESTION'
7976
8769
  /** 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';
8770
+ | 'WRITE'
8771
+ /** 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. */
8772
+ | 'OVERFLOW';
7978
8773
 
7979
8774
  /** Captures held message identities and the accepted edges used to validate their copies. */
7980
8775
  export declare interface LedgerEvidence {
@@ -8014,9 +8809,13 @@ export declare interface LedgerGauge {
8014
8809
  * Carries a stored gauge: its price and the digest of the tool definitions that price measured.
8015
8810
  *
8016
8811
  * @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.
8812
+ * `digest` is what the `digestLedgerTools` helper returns for the calibrated definitions: those the
8813
+ * calibration request carried, or, when the options supplied the gauge, the ledger's calibrated
8814
+ * definitions at construction. The calibrated set is every definition a turn can advertise but the
8815
+ * tools a registered skill holds back while `agent.builtins` enables `load`. A hydrate reuses the
8816
+ * price only when the hydrated ledger's calibrated definitions have the same digest, and each
8817
+ * `respond` call compares the digest again, so a calibrated definition added or removed since drops
8818
+ * the gauge.
8020
8819
  */
8021
8820
  export declare interface LedgerGaugeSnapshot extends LedgerGauge {
8022
8821
  readonly digest: string;
@@ -8063,8 +8862,11 @@ export declare interface LedgerIndex {
8063
8862
  * selection handler.
8064
8863
  */
8065
8864
  export declare interface LedgerInterface {
8066
- /** Holds the agent the ledger drives, with the ledger's tools and selection handler. */
8067
- readonly agent: AgentInterface;
8865
+ /**
8866
+ * Holds the record of the agent the ledger drives, with the ledger's tools and selection handler;
8867
+ * it starts no run, so the `respond` method runs every pass.
8868
+ */
8869
+ readonly agent: LedgerAgentInterface;
8068
8870
  /** Holds the one conversation the ledger files and serves. */
8069
8871
  readonly conversation: ConversationInterface;
8070
8872
  /** 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 +8875,9 @@ export declare interface LedgerInterface {
8073
8875
  * Appends `content` as a user message and serves it through to its reply.
8074
8876
  *
8075
8877
  * @remarks
8076
- * The ledger calibrates first while `gauge` is undefined. When the first pass ends without final
8878
+ * The ledger calibrates first while `gauge` is undefined, and again when the digest of its tool
8879
+ * definitions at this call differs from the one its gauge priced. When the first pass ends
8880
+ * without final
8077
8881
  * text and the caller did not abort, the ledger adds the results and cue notes and makes one
8078
8882
  * answer pass that advertises no tools. In either pass, a call the model makes in a turn that
8079
8883
  * advertises no tools runs nothing and ends the pass after that turn, so such a pass makes one
@@ -8082,23 +8886,25 @@ export declare interface LedgerInterface {
8082
8886
  * 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
8887
  * answer pass rejects as well, `respond` rejects with that pass's error. A `respond` or `calibrate` call while either is in flight
8084
8888
  * 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.
8889
+ * `LedgerError` code `'GAUGE'`; a provider error during calibration rejects with that error. A calibration call, with the
8890
+ * tool definitions, without them, or with the workspace text, that reports a prompt over `capacity`, the head included,
8891
+ * rejects with the same code and stores no request.
8892
+ * Every run on the ledger's agent is a pass of this method, because `agent` holds no `generate` or
8893
+ * `stream` member. A direct call to `agent.context.select` for a message no active `respond` call
8894
+ * owns returns a selection whose `fault` is a `LedgerError` with code `'REQUEST'`, on
8895
+ * `conversation` or another one, and asks the judge nothing; over another conversation, that
8896
+ * selection carries that conversation's view alone. Calibration owns no message, so a direct
8897
+ * selection during it faults the same way. Host code that calls a ledger tool by hand through
8898
+ * `agent.context.tools` while a request runs reaches that request's state: a lookup or a write
8899
+ * meets its repeat stop, and a `recall` call spends its recall limit. Between requests, and during
8900
+ * calibration, such a call reads no request's state and runs with no repeat stop, recall limit, or
8901
+ * close rule. Every rejection leaves the ledger free for a later call.
8097
8902
  *
8098
8903
  * @param content - The request text
8099
8904
  * @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
8905
  * @returns The reply, the passes the request took, and the filing attempts of this request alone
8101
8906
  * @throws {LedgerError} Thrown when a calibration call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)
8907
+ * @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
8908
  * @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)
8103
8909
  * @throws {ContractError} Thrown when `signal` is defined and is not a native `AbortSignal`
8104
8910
  */
@@ -8107,16 +8913,25 @@ export declare interface LedgerInterface {
8107
8913
  * Measures the gauge, holds it as `gauge`, and returns it.
8108
8914
  *
8109
8915
  * @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
8916
+ * The ledger sends the head its agent's context builds for an empty turn, with no workspace text and
8917
+ * no conversation message, to the provider with the calibrated tool definitions and then without
8918
+ * them, and the difference between the calls is the overhead cost. When the workspace the next
8919
+ * request renders adds text, a third call carries the head and that text with no definitions, cut
8920
+ * to the capacity the second call left over `LEDGER_SAMPLE_BYTES`, in characters. The scale is the
8921
+ * reported prompt of the head with the workspace over its estimate, a cut text's tokens scaled to the
8922
+ * whole text's estimate, and never under the head's own rate; with no workspace text it is the
8923
+ * second call's prompt over the head's estimate. When the call with the definitions reports a
8924
+ * prompt over `capacity`, the head included, the ledger sends no second call, stores no gauge, and
8925
+ * rejects with `LedgerError` code `'GAUGE'`, whose `context` holds `capacity` and `prompt`; the
8926
+ * call without them and the call with the workspace text refuse the same way. The ledger records the digest of the
8113
8927
  * definitions the call with tools carried, and its snapshot stores that digest with the gauge.
8114
8928
  * An abort during calibration rejects with the abort reason. A call during `respond` or `calibrate` rejects
8115
8929
  * with `AgentError` code `'CONCURRENCY'`.
8116
8930
  *
8117
- * @param signal - The signal that aborts both calls
8931
+ * @param signal - The signal that aborts every calibration call
8118
8932
  * @returns The measured gauge
8119
8933
  * @throws {LedgerError} Thrown when a call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)
8934
+ * @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
8935
  * @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)
8121
8936
  */
8122
8937
  calibrate(signal: AbortSignal): Promise<LedgerGauge>;
@@ -8124,10 +8939,9 @@ export declare interface LedgerInterface {
8124
8939
  * Serializes the conversation, the marked ids, and the gauge into a snapshot a later ledger hydrates from.
8125
8940
  *
8126
8941
  * @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`
8942
+ * The ledger first files every tool result whose message is appended; a result whose tool message
8943
+ * is not yet appended is not captured. A call while a `respond` or `calibrate` call is in flight
8944
+ * throws, because an entered, unanswered request would hydrate as a dangling request. The `gauge`
8131
8945
  * member carries the digest of the tool definitions the gauge priced.
8132
8946
  *
8133
8947
  * @returns The snapshot, each id list in conversation order and `gauge` present after the ledger holds one whose definitions JSON renders
@@ -8248,12 +9062,17 @@ export declare type LedgerLookupState = 'failed' | 'empty' | 'shown' | 'hidden';
8248
9062
  * and the reason of the denial the ledger gives the identical retry of a call the authority denied;
8249
9063
  * the ledger reads a failure with exactly this text, or that denial, as a repeat. `closure` is the
8250
9064
  * failure a `recall` call returns after the request's recalls are spent, repeated, or out of room.
9065
+ * `overflow` is the reason of the denial the ledger gives a `load`, a `remember`, or a `switch` the
9066
+ * request or the thread has no room for. That denial stays out of the repeat stop, and a successful
9067
+ * `unload` in the same request reopens the call.
8251
9068
  */
8252
9069
  export declare interface LedgerNote {
8253
9070
  readonly cue: string;
8254
9071
  readonly results: string;
8255
9072
  readonly repeat: string;
8256
9073
  readonly closure: string;
9074
+ /** Holds the reason the ledger denies a `load`, a `remember`, or a `switch` the request or the thread has no room for. */
9075
+ readonly overflow: string;
8257
9076
  }
8258
9077
 
8259
9078
  /** Carries a rendered sentence with its record placement. */
@@ -8270,11 +9089,20 @@ export declare interface LedgerOccurrence extends LedgerLine, LedgerReceipt {
8270
9089
  * 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
9090
  * topics. `questions` and `thresholds` are required with no default; pass the `LEDGER_QUESTIONS`
8272
9091
  * 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.
9092
+ * 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
9093
  * `predict` is the generation cap in tokens, including thinking. Default: 0. It must be a
8275
9094
  * nonnegative safe integer less than `capacity`; construction throws `LedgerError` with code
8276
9095
  * `'CAPACITY'` otherwise. The plan budgets
8277
- * `max(0, (capacity - predict) * share.prompt - overhead) / (1 + LEDGER_SCALE_DRIFT)`.
9096
+ * `max(0, (capacity - predict) * share.prompt - (overhead - spared + added) - holdback) / (1 + LEDGER_SCALE_DRIFT)`.
9097
+ * `spared` and `added` are what `computeToolPrice` returns for the definitions the first pass
9098
+ * advertises with the thread's shown skills, against the calibrated set. While that pass advertises
9099
+ * `load`, `holdback` is the `computeSkillPrice` of the largest skill the ceiling admits and the
9100
+ * thread does not show, plus the price of one result: the longer of the longest stored tool result
9101
+ * and the gauge's reply reserve. Otherwise it is 0.
9102
+ * The ledger sends no request it prices over `capacity - predict`. A first pass or a later turn that
9103
+ * does not fit ends with the agent's `abort` reason `overflow`, and the answer pass answers; an
9104
+ * answer pass that does not fit with its note left out rejects `respond` with `LedgerError` code
9105
+ * `'OVERFLOW'`.
8278
9106
  * The plan retains its `remainder - predict < 2 * reserve` admission rule. Runtime recall fits whole
8279
9107
  * results to measured remaining capacity at the larger of the gauge rate and the request's measured
8280
9108
  * rate, allowing `LEDGER_SCALE_DRIFT` for new text. Lack of room omits results without closing recall.
@@ -8283,6 +9111,9 @@ export declare interface LedgerOccurrence extends LedgerLine, LedgerReceipt {
8283
9111
  * the marked ids a ledger's `snapshot()` returned; construction throws `LedgerError` with code
8284
9112
  * `'SNAPSHOT'` when `isLedgerSnapshot` refuses it, and `ConversationError` with code `'ROLE'` or
8285
9113
  * `'SNAPSHOT'` when its conversation holds a `system` message or repeats an id.
9114
+ * An own enumerable member this type or the `agent` pick does not declare refuses at construction
9115
+ * with a `ContractError` coded `'structure'`, an `AgentOptions` member the pick leaves out included,
9116
+ * and a declared member holding `undefined` reads as omitted.
8286
9117
  */
8287
9118
  export declare interface LedgerOptions {
8288
9119
  readonly judge: JudgeInterface;
@@ -8569,6 +9400,9 @@ export declare class LedgerRequest implements LedgerRequestInterface {
8569
9400
  /** Returns recall results with their accepted whole groups and provider-turn positions. */
8570
9401
  get listings(): readonly LedgerListing[];
8571
9402
  lines(result: string): ReadonlyMap<string, string> | undefined;
9403
+ commit(price: number, skill?: string): void;
9404
+ get committed(): number;
9405
+ get loads(): readonly string[];
8572
9406
  }
8573
9407
 
8574
9408
  /**
@@ -8578,7 +9412,7 @@ export declare class LedgerRequest implements LedgerRequestInterface {
8578
9412
  *
8579
9413
  * @remarks
8580
9414
  * 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`
9415
+ * 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
9416
  * starts one, and `selection`, `boundary`, `usage`, `signal`, and `aborted` read the current pass,
8583
9417
  * the last one opened.
8584
9418
  * `calls` lists the gauge calls of every pass in order. A call stays in flight, taking its usage and
@@ -8743,6 +9577,17 @@ export declare interface LedgerRequestInterface {
8743
9577
  * @returns Each listed lookup line mapped to its stored first line, or undefined when no recall returned `result`
8744
9578
  */
8745
9579
  lines(result: string): ReadonlyMap<string, string> | undefined;
9580
+ /**
9581
+ * Records the tokens one cleared call commits to the next prompt.
9582
+ *
9583
+ * @param price - The tokens the call commits
9584
+ * @param skill - The skill the call loads, for a `load`
9585
+ */
9586
+ commit(price: number, skill?: string): void;
9587
+ /** Holds the tokens committed after the call in flight started. */
9588
+ readonly committed: number;
9589
+ /** Holds the skills the loads committed after the call in flight started name, in commit order. */
9590
+ readonly loads: readonly string[];
8746
9591
  }
8747
9592
 
8748
9593
  /**
@@ -8773,11 +9618,17 @@ export declare interface LedgerResult extends AgentResult {
8773
9618
  * with a delta copy, then its newest plain exchange with a full copy, then no exchange are priced
8774
9619
  * in that order. Admission cannot close an otherwise open recall or displace a selected record
8775
9620
  * line or seed message. A seed stub reads visibility across the window and the copy together.
9621
+ * `skills` is the share of the prompt budget, `(capacity - predict) * prompt`, that a thread's shown
9622
+ * skills can take: their bodies and the definitions they add beyond the calibrated set. A `load`
9623
+ * that would take the shown skills, the loads its batch already admitted, and its own skill past it
9624
+ * is denied with the {@link LedgerNote} `overflow` text.
8776
9625
  * Each share must be finite, greater than 0, and at most 1.
8777
9626
  */
8778
9627
  export declare interface LedgerShare {
8779
9628
  readonly prompt: number;
8780
9629
  readonly tail: number;
9630
+ /** Holds the share of the prompt budget a thread's shown skills can take, bodies and tools together. */
9631
+ readonly skills: number;
8781
9632
  }
8782
9633
 
8783
9634
  /**
@@ -9314,6 +10165,30 @@ export declare interface LiteralSet {
9314
10165
  readonly numbers: ReadonlySet<number>;
9315
10166
  }
9316
10167
 
10168
+ /**
10169
+ * Names the section header the loaded skills' bodies render under at the end of the system
10170
+ * message — `'## Loaded skills'`.
10171
+ */
10172
+ export declare const LOADED_SECTION_HEADER = "## Loaded skills";
10173
+
10174
+ /** Checks the arguments of the `load` and `unload` built-ins; its schema is the parameters they advertise. */
10175
+ export declare const loadToolContract: ContractInterface<Readonly<{
10176
+ skill: string;
10177
+ } & {}>>;
10178
+
10179
+ /**
10180
+ * Describes the arguments of the `load` and `unload` built-ins — one `skill` name, non-empty and
10181
+ * at most `BUILTIN_LIMITS.name` code points.
10182
+ *
10183
+ * @remarks
10184
+ * The tool's door refuses a missing, empty, over-long, or extra member before the handler runs,
10185
+ * and repairs a value that converts to a string without loss, such as a number. A value of white
10186
+ * space alone passes the door; the handler refuses it as it refuses any name it cannot use.
10187
+ */
10188
+ export declare const loadToolShape: ObjectShape< {
10189
+ skill: StringShape;
10190
+ }, boolean | ContractShape>;
10191
+
9317
10192
  /**
9318
10193
  * Matches the registry ids and owners a text names.
9319
10194
  *
@@ -9358,6 +10233,27 @@ export declare function matchEntities(index: LedgerIndex, text: string, partial:
9358
10233
  */
9359
10234
  export declare function matchesCutLine(line: string): boolean;
9360
10235
 
10236
+ /**
10237
+ * Checks whether two ceilings carry the same lists of what a head renders: `instructions`,
10238
+ * `skills`, `memos`, `files`, and `workspaces`.
10239
+ *
10240
+ * @remarks
10241
+ * Each list compares by its members in order, and an absent list equals only an absent list,
10242
+ * because `undefined` admits everything and `[]` admits nothing. The `tools` list is not compared:
10243
+ * it reaches the tools block, never the head.
10244
+ *
10245
+ * @param left - One ceiling's lists
10246
+ * @param right - The other ceiling's lists
10247
+ * @returns True if every compared list matches; false otherwise
10248
+ *
10249
+ * @example
10250
+ * ```ts
10251
+ * matchesHeadLists({ skills: ['refunds'] }, { skills: ['refunds'], tools: [] }) // true
10252
+ * matchesHeadLists({ skills: [] }, {}) // false
10253
+ * ```
10254
+ */
10255
+ export declare function matchesHeadLists(left: ScopeFilter, right: ScopeFilter): boolean;
10256
+
9361
10257
  /**
9362
10258
  * 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
10259
  *
@@ -9411,6 +10307,27 @@ export declare function matchesJudgment(judgment: Judgment, question: JudgeQuest
9411
10307
  */
9412
10308
  export declare function matchesLookup(left: LedgerLookupFinding, right: LedgerLookupFinding): boolean;
9413
10309
 
10310
+ /**
10311
+ * Checks whether a text is one nonblank line: it holds a code point other than white space and
10312
+ * default-ignorable code points (`ARGUMENT_BLANK_PATTERN`), and no control, format, line-separator, or
10313
+ * paragraph-separator code point (`ARGUMENT_CONTROL_PATTERN`).
10314
+ *
10315
+ * @remarks
10316
+ * The class is the one `renderArguments` encodes. A memo's name and description render in the memos
10317
+ * index one line each, so `remember` refuses a value outside this check.
10318
+ *
10319
+ * @param text - The text to check
10320
+ * @returns True if the text is one nonblank line; false otherwise
10321
+ *
10322
+ * @example
10323
+ * ```ts
10324
+ * matchesPlainLine('Reply tone') // true
10325
+ * matchesPlainLine('Reply\ntone') // false
10326
+ * matchesPlainLine(' ') // false
10327
+ * ```
10328
+ */
10329
+ export declare function matchesPlainLine(text: string): boolean;
10330
+
9414
10331
  /**
9415
10332
  * Bounds the decoded error excerpt's input in bytes — `2048`, the leading bytes of a non-OK
9416
10333
  * response body handed to the decoder before the read cancels the remainder, so a `ProviderError`
@@ -9520,6 +10437,9 @@ export declare interface Memo {
9520
10437
  readonly origin?: MemoOrigin;
9521
10438
  }
9522
10439
 
10440
+ /** Lists the members `MemoManagerOptions` declares, frozen — the keys the `MemoManager` constructor admits. */
10441
+ export declare const MEMO_MANAGER_KEYS: readonly ["id", "on", "error", "format", "snapshot"];
10442
+
9523
10443
  /**
9524
10444
  * Names the built-in section header a {@link import('./types.js').MemoManagerInterface} renders
9525
10445
  * its index under — `'## Memos'`, the `open` value when no `format.open` overrides it.
@@ -9557,6 +10477,37 @@ export declare interface MemoInput {
9557
10477
  readonly origin?: MemoOrigin;
9558
10478
  }
9559
10479
 
10480
+ /** Admits a memo input exactly, and reads the faults of a refused one. */
10481
+ export declare const memoInputContract: ContractInterface<Readonly<{
10482
+ name: string;
10483
+ description: string;
10484
+ content: string;
10485
+ } & {
10486
+ origin?: Readonly<{
10487
+ conversation: string;
10488
+ } & {
10489
+ message?: string;
10490
+ }>;
10491
+ }>>;
10492
+
10493
+ /**
10494
+ * Describes a memo input exactly: the members of a stored revision less the `id` and `time` the
10495
+ * manager mints, each taken from {@link memoShape}.
10496
+ *
10497
+ * @remarks
10498
+ * An unknown member, a missing required member, and a declared member holding `undefined` refuse, so
10499
+ * a revision `add` stores is one its own snapshot hydrates.
10500
+ */
10501
+ export declare const memoInputShape: ObjectShape< {
10502
+ name: StringShape;
10503
+ description: StringShape;
10504
+ content: StringShape;
10505
+ origin: OptionalShape<ObjectShape< {
10506
+ conversation: StringShape;
10507
+ message: OptionalShape<StringShape>;
10508
+ }, boolean | ContractShape>>;
10509
+ }, boolean | ContractShape>;
10510
+
9560
10511
  /**
9561
10512
  * Registers the revisions of a memo set — durable facts keyed by `name`, where a same-name `add`
9562
10513
  * with changed text appends a revision and the earlier ones stay readable — carrying the `open` /
@@ -9672,6 +10623,7 @@ export declare interface MemoManagerInterface {
9672
10623
  *
9673
10624
  * @param input - One {@link MemoInput}, or a batch
9674
10625
  * @returns The appended or unchanged current revision, or the batch's results in input order
10626
+ * @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
10627
  */
9676
10628
  add(input: MemoInput): Memo;
9677
10629
  add(inputs: readonly MemoInput[]): readonly Memo[];
@@ -10003,6 +10955,24 @@ export declare interface MemoStoreInterface {
10003
10955
  delete(id: string): Promise<void>;
10004
10956
  }
10005
10957
 
10958
+ /** Checks the arguments of the `memo` built-in; its schema is the parameters it advertises. */
10959
+ export declare const memoToolContract: ContractInterface<Readonly<{
10960
+ name: string;
10961
+ } & {}>>;
10962
+
10963
+ /**
10964
+ * Describes the arguments of the `memo` built-in — one memo `name`, non-empty and at most
10965
+ * `BUILTIN_LIMITS.name` code points.
10966
+ *
10967
+ * @remarks
10968
+ * The tool's door refuses a missing, empty, over-long, or extra member before the handler runs,
10969
+ * and repairs a value that converts to a string without loss, such as a number. A value of white
10970
+ * space alone passes the door; the handler refuses it as it refuses any name it cannot use.
10971
+ */
10972
+ export declare const memoToolShape: ObjectShape< {
10973
+ name: StringShape;
10974
+ }, boolean | ContractShape>;
10975
+
10006
10976
  /**
10007
10977
  * Merges supersession edges into a classification, adding each edge to both its supersessions and its amendments.
10008
10978
  *
@@ -10364,6 +11334,9 @@ export declare const PLACED_CATEGORIES: readonly LedgerCategory[];
10364
11334
  */
10365
11335
  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
11336
 
11337
+ /** Lists the members `AgentProviderInput` declares, frozen — the keys the `AgentProvider` constructor admits. */
11338
+ export declare const PROVIDER_INPUT_KEYS: readonly ["url", "path", "split", "strict", "timeout", "replay", "fetch", "headers"];
11339
+
10367
11340
  /**
10368
11341
  * Reports a provider stream cancelled mid-flight by its bound signal — thrown by the
10369
11342
  * `stream` method of a {@link ProviderInterface}, carrying the {@link ProviderResult} assembled from
@@ -10728,6 +11701,9 @@ export declare interface ProviderStreamOptions {
10728
11701
  */
10729
11702
  export declare function questionToSystemOne(question: JudgeQuestion): SystemOneQuestion;
10730
11703
 
11704
+ /** Lists the members `AgentQueueOptions` declares, frozen — the keys `createAgentQueue` admits. */
11705
+ export declare const QUEUE_OPTION_KEYS: readonly ["registry", "partial", "concurrency", "retries", "timeout", "store"];
11706
+
10731
11707
  /** Lists the categories whose messages the projection leaves out as quiet. */
10732
11708
  export declare const QUIET_CATEGORIES: readonly LedgerCategory[];
10733
11709
 
@@ -10866,6 +11842,9 @@ export declare function readJudgeOutcome(result: JudgeResult, id: string): {
10866
11842
  */
10867
11843
  export declare function readProviderDelta(value: unknown): ProviderDelta | undefined;
10868
11844
 
11845
+ /** Lists the members `ConversationReferenceOptions` declares, frozen — the keys the `reference` method of a `Conversation` admits. */
11846
+ export declare const REFERENCE_OPTION_KEYS: readonly ["label", "messages"];
11847
+
10869
11848
  /** Reports a question a wire could not read a candidate for; it lists the caller's keys and invents no probability. */
10870
11849
  export declare interface Refusal {
10871
11850
  readonly missing: readonly string[];
@@ -10884,12 +11863,21 @@ export declare const REFUSED_RELAY_CONTENT_TYPE = "text/plain; charset=utf-8";
10884
11863
  */
10885
11864
  export declare const REFUSED_RELAY_STATUS = 422;
10886
11865
 
11866
+ /** Lists the members `AgentRegistryOptions` declares, frozen — the keys the `AgentRegistry` constructor admits. */
11867
+ export declare const REGISTRY_OPTION_KEYS: readonly ["providers", "tools", "authorities", "schedulers", "store", "skills", "memos", "workspaces"];
11868
+
10887
11869
  /**
10888
11870
  * Names the relay's newline-delimited JSON content type — `'application/x-ndjson; charset=utf-8'`,
10889
11871
  * the header a relay response carries beside `cache-control: no-store`.
10890
11872
  */
10891
11873
  export declare const RELAY_CONTENT_TYPE = "application/x-ndjson; charset=utf-8";
10892
11874
 
11875
+ /** Lists the members `RelayOptions` declares, frozen — the keys `createRelay` admits. */
11876
+ export declare const RELAY_OPTION_KEYS: readonly ["provider", "authorize", "limit", "system", "tools"];
11877
+
11878
+ /** Lists the members `RelayProviderOptions` declares, frozen — the keys the `RelayProvider` constructor admits. */
11879
+ export declare const RELAY_PROVIDER_KEYS: readonly ["url", "parser", "timeout", "replay", "fetch", "headers"];
11880
+
10893
11881
  /**
10894
11882
  * Names the public message for an unexpected upstream relay failure — `'relay provider failed'`,
10895
11883
  * the fixed text every `error` frame carries, so an upstream failure's own message never reaches
@@ -10897,6 +11885,9 @@ export declare const RELAY_CONTENT_TYPE = "application/x-ndjson; charset=utf-8";
10897
11885
  */
10898
11886
  export declare const RELAY_PROVIDER_MESSAGE = "relay provider failed";
10899
11887
 
11888
+ /** Lists the members `RelayStreamOptions` declares, frozen — the keys the `RelayStream` constructor admits. */
11889
+ export declare const RELAY_STREAM_KEYS: readonly ["provider", "request", "signal"];
11890
+
10900
11891
  /** Carries a relay delta, settled result, remote abort, or remote failure. */
10901
11892
  export declare type RelayFrame = ProviderDelta | {
10902
11893
  readonly channel: 'result';
@@ -11221,6 +12212,28 @@ export declare interface RelayToolOptions {
11221
12212
  */
11222
12213
  export declare function releaseReader(reader: ReadableStreamDefaultReader<Uint8Array>): Promise<void>;
11223
12214
 
12215
+ /** Checks the arguments of the `remember` built-in; its schema is the parameters it advertises. */
12216
+ export declare const rememberToolContract: ContractInterface<Readonly<{
12217
+ name: string;
12218
+ description: string;
12219
+ content: string;
12220
+ } & {}>>;
12221
+
12222
+ /**
12223
+ * Describes the arguments of the `remember` built-in — a memo `name`, the one-line `description`
12224
+ * the memos index shows, and the `content`, each non-empty and within its `BUILTIN_LIMITS` cap.
12225
+ *
12226
+ * @remarks
12227
+ * The tool's door refuses a missing, empty, over-long, or extra member before the handler runs,
12228
+ * and repairs a value that converts to a string without loss, such as a number. A value of white
12229
+ * space alone passes the door; the handler refuses it as it refuses any name it cannot use.
12230
+ */
12231
+ export declare const rememberToolShape: ObjectShape< {
12232
+ name: StringShape;
12233
+ description: StringShape;
12234
+ content: StringShape;
12235
+ }, boolean | ContractShape>;
12236
+
11224
12237
  /**
11225
12238
  * Removes each key through a single-key remover and folds the outcomes, so a batch `remove`
11226
12239
  * reports whether the whole batch applied.
@@ -11328,6 +12341,26 @@ export declare function renderFencedFile(path: string, language: string, content
11328
12341
  */
11329
12342
  export declare function renderIndexEntry(entry: Pick<Memo, 'name' | 'description'>): string;
11330
12343
 
12344
+ /**
12345
+ * Renders one index line from its text as `- text`, with each run of line-break code points as one
12346
+ * space.
12347
+ *
12348
+ * @remarks
12349
+ * Pure and total. The memo and skill index lines and the workspace index lines render through it,
12350
+ * so text in an index never opens another line or heading.
12351
+ *
12352
+ * @param text - The line's text
12353
+ * @returns The index line
12354
+ *
12355
+ * @example
12356
+ * ```ts
12357
+ * import { renderIndexLine } from '@orkestrel/agent'
12358
+ *
12359
+ * renderIndexLine('orders') // '- orders'
12360
+ * ```
12361
+ */
12362
+ export declare function renderIndexLine(text: string): string;
12363
+
11331
12364
  /**
11332
12365
  * Renders a value as the JSON text `JSON.stringify` produces, or `undefined` when JSON cannot
11333
12366
  * carry the value.
@@ -11441,22 +12474,52 @@ export declare function renderLookupCall(name: string, args: Readonly<Record<str
11441
12474
  */
11442
12475
  export declare function renderSection<T>(open: string, members: readonly T[], render: (member: T) => string, close: string | undefined): string | undefined;
11443
12476
 
12477
+ /**
12478
+ * Renders one loaded skill's body: `### name`, a blank line, then its content.
12479
+ *
12480
+ * @remarks
12481
+ * Pure and total. The context build renders each shown skill through it under the loaded skills
12482
+ * header, last in the system message.
12483
+ *
12484
+ * @param skill - The skill whose name and content the body shows
12485
+ * @returns The body
12486
+ *
12487
+ * @example
12488
+ * ```ts
12489
+ * import { renderSkillBody } from '@orkestrel/agent'
12490
+ *
12491
+ * renderSkillBody({ name: 'refunds', content: 'Check the order first.' })
12492
+ * // '### refunds\n\nCheck the order first.'
12493
+ * ```
12494
+ */
12495
+ export declare function renderSkillBody(skill: Pick<Skill, 'name' | 'content'>): string;
12496
+
11444
12497
  /**
11445
12498
  * Renders the tail stub of a lookup result from an earlier request.
11446
12499
  *
12500
+ * @remarks
12501
+ * A `hidden` stub names the `recall` call that finds its result, with the first string argument,
12502
+ * trimmed, or `its id` when no argument is a string or that one is blank, only while `offered` is `true`. The ledger plans the
12503
+ * tail with every stub naming `recall`, then renders the tail's stubs again after it admits a window
12504
+ * rung, with `offered` set to whether that rung offers `recall` and the scope admits it, so the
12505
+ * second render can only shorten a stub and raises no price. `offered` changes no other state.
12506
+ *
11447
12507
  * @param name - The lookup tool name
11448
12508
  * @param args - The arguments the call carried; arguments JSON cannot carry leave the call as its bare tool name, per {@link renderLookupCall}
11449
12509
  * @param state - What became of the result: `failed`, `empty`, `shown` in the records, or `hidden` from them
11450
12510
  * @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`
12511
+ * @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
12512
  * @returns The stub text, which carries the call and its state
11452
12513
  *
11453
12514
  * @example
11454
12515
  * ```ts
11455
12516
  * renderStub('lookup_order', { id: 'BW-5512' }, 'hidden')
11456
12517
  * // 'lookup_order {"id":"BW-5512"}: result not shown; call recall with BW-5512'
12518
+ * renderStub('lookup_order', { id: 'BW-5512' }, 'hidden', false, false)
12519
+ * // 'lookup_order {"id":"BW-5512"}: result not shown'
11457
12520
  * ```
11458
12521
  */
11459
- export declare function renderStub(name: string, args: Readonly<Record<string, unknown>>, state: LedgerLookupState, write?: boolean): string;
12522
+ export declare function renderStub(name: string, args: Readonly<Record<string, unknown>>, state: LedgerLookupState, write?: boolean, offered?: boolean): string;
11460
12523
 
11461
12524
  /**
11462
12525
  * Renders a tool's output as the string content of its tool message, or returns `undefined` when JSON
@@ -11575,6 +12638,28 @@ export declare function requireAnswer(content: string, schema: Readonly<Record<s
11575
12638
  */
11576
12639
  export declare function requireBudget(value: BudgetInterface<TokenUsage> | undefined, key: 'budget' | 'allowance'): BudgetInterface<TokenUsage> | undefined;
11577
12640
 
12641
+ /**
12642
+ * Returns an agent's `builtins` option as an owned, frozen list, or throws a coded error before the
12643
+ * agent is built.
12644
+ *
12645
+ * @remarks
12646
+ * `undefined` returns an empty list. The option must be an array of distinct {@link AgentBuiltin}
12647
+ * names; `unload` needs `load`, because only a loaded skill can be unloaded; and the host's tool
12648
+ * manager may hold no tool under an enabled name, because the run serves that name itself.
12649
+ *
12650
+ * @param value - The `builtins` option
12651
+ * @param tools - The host's tool manager
12652
+ * @returns The enabled names, in the order given
12653
+ * @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'`)
12654
+ *
12655
+ * @example
12656
+ * ```ts
12657
+ * requireBuiltins(['load', 'unload'], createToolManager()) // ['load', 'unload']
12658
+ * requireBuiltins(['unload'], createToolManager()) // throws AgentError ('BUILTIN')
12659
+ * ```
12660
+ */
12661
+ export declare function requireBuiltins(value: unknown, tools: Pick<ToolManagerInterface, 'tool'>): readonly AgentBuiltin[];
12662
+
11578
12663
  /**
11579
12664
  * Returns a run's `conversation` option after checking it implements `ConversationInterface`, or
11580
12665
  * throws a coded error before the run starts.
@@ -11767,14 +12852,17 @@ export declare function requireLimit(limit: number): number;
11767
12852
  * Returns a message input after checking its role and its members, or throws a coded error.
11768
12853
  *
11769
12854
  * @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.
12855
+ * A value that is not a plain record, such as a class instance or an object that inherits its
12856
+ * `role`, refuses first, through `isRecord` of `@orkestrel/contract`, with a text saying so. The role
12857
+ * goes next, through {@link requireRole}, so its refusal names what it received. The members
12858
+ * cross {@link isMessageInput}, an exact record guard, so a member `MessageInput` does not declare or a
12859
+ * declared member holding `undefined` refuses, and `audit` runs only after a refusal. Tool-call
12860
+ * arguments must also be JSON values before a message is stored.
11773
12861
  *
11774
12862
  * @param input - The message input to check
11775
12863
  * @param contract - The message input contract, whose `audit` is read only on a refusal
11776
12864
  * @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`
12865
+ * @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
12866
  *
11779
12867
  * @example
11780
12868
  * ```ts
@@ -11805,6 +12893,34 @@ export declare function requireMessageInput(input: unknown, contract: Pick<Contr
11805
12893
  */
11806
12894
  export declare function requireProviderResult(value: unknown): ProviderResult;
11807
12895
 
12896
+ /**
12897
+ * Checks a stored record's input against its exact contract, and throws a `ContractError` coded
12898
+ * `'structure'` when it fails.
12899
+ *
12900
+ * @remarks
12901
+ * The input must pass the contract's `is` guard: a missing required member, a member the input type
12902
+ * does not declare, a declared member holding `undefined`, and a member of another type each refuse,
12903
+ * so nothing a refused input carries is stored. A class instance refuses, and the contract reads own
12904
+ * enumerable string keys alone, as every option door does. The contract's `audit` runs only after a refusal, and
12905
+ * the message names the owner, the input type, and every fault with the members to send. The
12906
+ * `context` holds the first fault's `path` and the input type as its `shape`.
12907
+ *
12908
+ * @param input - The input to check
12909
+ * @param contract - The input's compiled contract
12910
+ * @param owner - The entity named at the head of the refusal
12911
+ * @param shape - The input type named in the refusal and its `context`
12912
+ * @throws ContractError Thrown when the input fails the contract (code `'structure'`)
12913
+ *
12914
+ * @example
12915
+ * ```ts
12916
+ * import { memoInputContract, requireRecordInput } from '@orkestrel/agent'
12917
+ *
12918
+ * requireRecordInput({ name: 'tone', description: 'Prefers short replies.', content: 'Answer briefly.' }, memoInputContract, 'MemoManager', 'MemoInput') // returns
12919
+ * requireRecordInput({ name: 'tone', description: undefined, content: 'Answer briefly.' }, memoInputContract, 'MemoManager', 'MemoInput') // throws ContractError ('structure')
12920
+ * ```
12921
+ */
12922
+ export declare function requireRecordInput(input: unknown, contract: Pick<ContractInterface<unknown>, 'is' | 'audit' | 'schema'>, owner: string, shape: string): void;
12923
+
11808
12924
  /**
11809
12925
  * Returns a stored message role after checking it is a conversation role, or throws a coded error.
11810
12926
  *
@@ -11845,6 +12961,28 @@ export declare function requireRole(role: unknown): ConversationRole;
11845
12961
  */
11846
12962
  export declare function requireRules(rules: readonly AuthorityRule[] | undefined): readonly AuthorityRule[];
11847
12963
 
12964
+ /**
12965
+ * Returns a scope a run can bind, or throws a `ContractError` coded `'placement'`; `undefined`
12966
+ * passes through.
12967
+ *
12968
+ * @remarks
12969
+ * The check is {@link isScope}, a total guard that reads each member one time and admits any
12970
+ * implementation of `ScopeInterface`. `undefined` passes, because an absent option leaves the
12971
+ * context scope alone as the run's ceiling. The error's `context` carries the option path, the
12972
+ * limit `'ScopeInterface'`, and a preview of the refused value.
12973
+ *
12974
+ * @param value - The run's `scope` option, or `undefined`
12975
+ * @returns The value unchanged
12976
+ * @throws {ContractError} Thrown when `value` is defined and does not implement `ScopeInterface` (code `'placement'`)
12977
+ *
12978
+ * @example
12979
+ * ```ts
12980
+ * requireScope(createScope({ name: 'reader', tools: ['search'] })) // the scope
12981
+ * requireScope({ id: 's1', name: 'reader' }) // throws ContractError ('placement')
12982
+ * ```
12983
+ */
12984
+ export declare function requireScope(value: unknown): ScopeInterface | undefined;
12985
+
11848
12986
  /**
11849
12987
  * Returns a `sections` cap after checking it is a positive safe integer, or throws a coded error.
11850
12988
  *
@@ -11885,6 +13023,27 @@ export declare function requireSectionsCap(cap: number | undefined): number | un
11885
13023
  */
11886
13024
  export declare function requireSummary(summary: string): string;
11887
13025
 
13026
+ /**
13027
+ * Returns a `workspace` option unchanged, or throws a `ContractError` coded `'placement'`;
13028
+ * `undefined` passes through.
13029
+ *
13030
+ * @remarks
13031
+ * The check is `isString`. An id the workspace registry does not hold, or the ceiling does not
13032
+ * admit, passes here and renders nothing. The error's `context` carries the option path, the limit
13033
+ * `'string'`, and a preview of the refused value.
13034
+ *
13035
+ * @param value - The `workspace` option of an agent, a run, or a ledger's agent, or `undefined`
13036
+ * @returns The value unchanged
13037
+ * @throws {ContractError} Thrown when `value` is defined and is not a string (code `'placement'`)
13038
+ *
13039
+ * @example
13040
+ * ```ts
13041
+ * requireWorkspace('orders') // 'orders'
13042
+ * requireWorkspace(7) // throws ContractError ('placement')
13043
+ * ```
13044
+ */
13045
+ export declare function requireWorkspace(value: unknown): string | undefined;
13046
+
11888
13047
  /**
11889
13048
  * Applies the `consequential` floor to one {@link AuthorityDecision} — an `allow` for a tool
11890
13049
  * whose advertised definition is annotated `consequential` becomes an `ask`.
@@ -11906,6 +13065,32 @@ export declare function requireSummary(summary: string): string;
11906
13065
  */
11907
13066
  export declare function resolveDecision(decision: AuthorityDecision, definition: ToolDefinition | undefined): AuthorityDecision;
11908
13067
 
13068
+ /**
13069
+ * Resolves what a turn shows: the conversation's record, and the given workspace, within the
13070
+ * ceiling and the registries.
13071
+ *
13072
+ * @remarks
13073
+ * The caller reads the ceiling, so a turn reads each scope list one time. The skills are those
13074
+ * {@link collectDisclosure} reads from the conversation, in load order, keeping each that the skill
13075
+ * registry holds and the ceiling's `skills` list admits; an unregistered or excluded name shows
13076
+ * nothing. The workspace is the conversation's last switch, else the given one, kept only when the
13077
+ * workspace registry holds it and the ceiling's `workspaces` list admits it. The record counts only
13078
+ * the built-ins in `builtins`, as {@link collectDisclosure} states.
13079
+ *
13080
+ * @param context - The agent's context, whose scope, skills, and workspaces it reads
13081
+ * @param conversation - The conversation whose record to read
13082
+ * @param workspace - The `workspace` option of the run or the agent, or `undefined`
13083
+ * @param ceiling - The ceiling the turn read: the context scope intersected with the run scope
13084
+ * @param builtins - The built-ins the run enables
13085
+ * @returns The shown skills, in order, and the shown workspace when one is
13086
+ *
13087
+ * @example
13088
+ * ```ts
13089
+ * resolveDisclosure(agent.context, agent.context.messages, 'orders', {}, []) // { skills: [], workspace: 'orders' } when orders is registered
13090
+ * ```
13091
+ */
13092
+ export declare function resolveDisclosure(context: AgentContextInterface, conversation: Pick<ConversationInterface, 'sections' | 'messages'>, workspace: string | undefined, ceiling: ScopeFilter, builtins: readonly AgentBuiltin[]): AgentDisclosure;
13093
+
11909
13094
  /**
11910
13095
  * Resolves the generation cap and checks it against the context capacity.
11911
13096
  *
@@ -11920,6 +13105,9 @@ export declare function resolveDecision(decision: AuthorityDecision, definition:
11920
13105
  */
11921
13106
  export declare function resolvePredict(predict: number | undefined, capacity: number): number;
11922
13107
 
13108
+ /** Lists the members `AgentRunnerOptions` declares, frozen — the keys `createAgentRunner` admits. */
13109
+ export declare const RUNNER_OPTION_KEYS: readonly ["registry", "partial", "concurrency", "retries", "timeout"];
13110
+
11923
13111
  /**
11924
13112
  * Sanitizes one reported token count into a non-negative integer — a non-finite or
11925
13113
  * non-positive value becomes `0`, and a positive fractional value floors down.
@@ -11969,6 +13157,39 @@ export declare function sanitizeUsage(usage: TokenUsage): TokenUsage;
11969
13157
  */
11970
13158
  export declare function scanAmendments(amendments: ReadonlyMap<string, readonly string[]>, start: string, admit: (id: string) => boolean): readonly string[];
11971
13159
 
13160
+ /**
13161
+ * Scans every job under a root for a member that exceeds its own parent's; an empty result clears the tree.
13162
+ *
13163
+ * @remarks
13164
+ * The walk audits each job, the root included, through `agentJobContract` before it reads a member,
13165
+ * because a job's `children` cross that contract as JSON records, and then reads each job the
13166
+ * contract admits through `collectJobRefusals`. A job the contract refuses yields one finding with its
13167
+ * faults, or with an unreadable note when a member read throws; a job its build would refuse yields
13168
+ * one finding a refusal, its path, a dot, and the line; and the walk reads nothing under either. A
13169
+ * child is within its parent when each of
13170
+ * its `tools` is one its parent names (a parent with no `tools` names none), each of its `builtins`
13171
+ * is one its parent names (a parent with no `builtins` names none), each name in each list of its
13172
+ * `scope` is in its parent's same list (a job with no `scope` holds the three lists empty), its
13173
+ * `authority` and `scheduler` are absent or its parent's, its `provider` is its parent's, its `limit`
13174
+ * is at most its parent's (an absent `limit` reads `DEFAULT_AGENT_LIMIT`), and, where its parent
13175
+ * holds a `timeout` or a `budget`, it holds one no larger. `system`, `messages`, and `workspace` are
13176
+ * free: a `workspace` renders nothing its own `scope` omits. A refused job's finding
13177
+ * opens with `JOB_REFUSAL_PREFIX` and then the job's path from `job`; an exceeded member's opens
13178
+ * with that path, a dot, and the member. The walk is total: an unreadable job yields a finding,
13179
+ * never a throw. The `AgentFanout` class runs it on every attempt of a unit, before the unit spawns
13180
+ * or runs.
13181
+ *
13182
+ * @param root - The root job of the tree
13183
+ * @returns One finding per refused job and per exceeded member, in walk order
13184
+ *
13185
+ * @example
13186
+ * ```ts
13187
+ * scanJobTree({ provider: 'main', children: [{ provider: 'other' }] })
13188
+ * // ['job.children[0].provider: "other" differs from its parent\'s, which is "main"']
13189
+ * ```
13190
+ */
13191
+ export declare function scanJobTree(root: AgentJobInput): readonly string[];
13192
+
11972
13193
  /**
11973
13194
  * Scans what a judge's answer must hold to its question: the same form, every probability in
11974
13195
  * `[0, 1]`, a choice's keys equal to the criteria keys, and a score as long as its levels.
@@ -12004,9 +13225,9 @@ export declare function scanProbability(value: number | undefined, path: readonl
12004
13225
 
12005
13226
  /**
12006
13227
  * 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:
13228
+ * category (`instructions` / `skills` / `memos` / `tools` / `files` / `workspaces`), each keyed by
13229
+ * that category's identity (an instruction's, a skill's, a memo's, or a tool's `name`, a workspace
13230
+ * file's `path`, a workspace's `id`) and read as an allow-list:
12010
13231
  * `undefined` lets everything pass, `[]` lets nothing pass, and a non-empty list passes the listed
12011
13232
  * keys alone. `narrow` composes a tighter child by set intersection.
12012
13233
  *
@@ -12024,6 +13245,10 @@ export declare function scanProbability(value: number | undefined, path: readonl
12024
13245
  * `undefined` with a list yields the list, and `undefined` with `undefined` stays
12025
13246
  * `undefined`. Narrowing can only tighten, never widen — a key excluded by a parent
12026
13247
  * can never be re-admitted by a child. The child keeps this scope's `name` and `select` handler.
13248
+ * - **Exact.** The constructor refuses an own enumerable member of its input outside
13249
+ * `SCOPE_KEYS`, and `narrow` one of its filter outside `SCOPE_FILTER_KEYS`, with a
13250
+ * `ContractError` coded `'structure'`, so a misspelled list never builds an open scope. A
13251
+ * declared member holding `undefined` reads as omitted.
12027
13252
  *
12028
13253
  * @example
12029
13254
  * ```ts
@@ -12043,38 +13268,70 @@ export declare class Scope implements ScopeInterface {
12043
13268
  readonly memos?: readonly string[];
12044
13269
  readonly tools?: readonly string[];
12045
13270
  readonly files?: readonly string[];
13271
+ readonly workspaces?: readonly string[];
12046
13272
  readonly select?: SelectionHandler;
12047
13273
  constructor(input: ScopeInput);
12048
13274
  narrow(config: ScopeFilter): ScopeInterface;
12049
13275
  }
12050
13276
 
13277
+ /**
13278
+ * Lists the members `ScopeFilter` declares, frozen — the keys the `narrow` method of a scope admits.
13279
+ *
13280
+ * @remarks
13281
+ * The `narrow` method passes the list to `refuseOptionKeys` of `@orkestrel/contract`, so an own
13282
+ * enumerable member outside it refuses with a `ContractError` coded `'structure'`.
13283
+ */
13284
+ export declare const SCOPE_FILTER_KEYS: readonly ["instructions", "skills", "memos", "tools", "files", "workspaces"];
13285
+
13286
+ /**
13287
+ * Lists the members `ScopeInput` declares, frozen — the keys a `Scope` is built from.
13288
+ *
13289
+ * @remarks
13290
+ * The `Scope` constructor passes the list to `refuseOptionKeys` of `@orkestrel/contract`, so an
13291
+ * own enumerable member outside it, a misspelled list included, refuses with a `ContractError`
13292
+ * coded `'structure'` instead of building a scope with no constraint.
13293
+ */
13294
+ export declare const SCOPE_KEYS: readonly ["name", "select", "instructions", "skills", "memos", "tools", "files", "workspaces"];
13295
+
13296
+ /** Lists the members `ScopeManagerOptions` declares, frozen — the keys the `ScopeManager` constructor admits. */
13297
+ export declare const SCOPE_MANAGER_KEYS: readonly ["on", "error"];
13298
+
12051
13299
  /**
12052
13300
  * 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.
13301
+ * outside the turn's tool ceiling, the context scope's tool allow-list intersected with the run
13302
+ * scope's, or whose name no definition advertises this turn.
12054
13303
  */
12055
13304
  export declare const SCOPE_NOTE = "it is not one of the listed tools. Use a listed tool or answer with what you have.";
12056
13305
 
12057
13306
  /**
12058
13307
  * 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.
13308
+ * string[]` for `instructions`, for `skills`, for `memos`, for `tools`, for `files`, and for
13309
+ * `workspaces`, each keyed by that category's identity (an instruction's, a skill's, a memo's, or a
13310
+ * tool's `name`, a workspace file's `path`, a workspace's `id`) and read as an allow-list:
13311
+ * `undefined` lets everything pass, `[]` lets nothing pass, and a non-empty list passes the listed
13312
+ * keys alone.
12063
13313
  *
12064
13314
  * @remarks
12065
13315
  * Each list is three-way (see {@link import('../helpers.js').filterAllowList}): `undefined`
12066
13316
  * ⇒ no constraint on that category (all pass); `[]` ⇒ none pass; a non-empty list ⇒ only
12067
13317
  * 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.
13318
+ * accept (a `name`-less narrowing config). `files` filters the rendered workspace's files (by
13319
+ * `path`) in {@link AgentContextInterface.build} — both the text files folded into the context
13320
+ * message and the image files attached to the last user message — and `workspaces` decides
13321
+ * whether that workspace renders at all. Two lists bound a write as well as a read: the
13322
+ * `remember` built-in writes only a name a defined `memos` list holds, and the `switch` built-in
13323
+ * selects only an id a defined `workspaces` list holds.
12071
13324
  */
12072
13325
  export declare interface ScopeFilter {
12073
13326
  /** Lists the allowed instruction names matched against the `name` property (`undefined` ⇒ all, `[]` ⇒ none, else only-listed). */
12074
13327
  readonly instructions?: readonly string[];
12075
13328
  /** Lists the allowed skill names matched against the `name` property (`undefined` ⇒ all, `[]` ⇒ none, else only-listed). */
12076
13329
  readonly skills?: readonly string[];
12077
- /** Lists the allowed memo names matched against the `name` property (`undefined` ⇒ all, `[]` ⇒ none, else only-listed). */
13330
+ /**
13331
+ * Lists the allowed memo names matched against the `name` property (`undefined` ⇒ all, `[]` ⇒ none, else only-listed).
13332
+ * A write is the exception: the `remember` built-in writes only a name a defined list holds, so
13333
+ * `undefined` lets it write none.
13334
+ */
12078
13335
  readonly memos?: readonly string[];
12079
13336
  /**
12080
13337
  * Lists the allowed tool names matched against the `name` property (`undefined` ⇒ all, `[]` ⇒ none, else only-listed).
@@ -12084,11 +13341,17 @@ export declare interface ScopeFilter {
12084
13341
  readonly tools?: readonly string[];
12085
13342
  /**
12086
13343
  * 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
13344
+ * the filter {@link AgentContextInterface.build} applies to the rendered workspace's
12088
13345
  * {@link import('@orkestrel/workspace').WorkspaceInterface.files} before rendering them (text → the context message, image →
12089
13346
  * the last user message).
12090
13347
  */
12091
13348
  readonly files?: readonly string[];
13349
+ /**
13350
+ * Lists the allowed workspace ids matched against the `id` property (`undefined` ⇒ all, `[]` ⇒ none, else only-listed).
13351
+ * A selection is the exception: the `switch` built-in selects only an id a defined list holds, so
13352
+ * `undefined` lets it select none.
13353
+ */
13354
+ readonly workspaces?: readonly string[];
12092
13355
  }
12093
13356
 
12094
13357
  /**
@@ -12097,7 +13360,10 @@ export declare interface ScopeFilter {
12097
13360
  */
12098
13361
  export declare interface ScopeInput extends ScopeFilter {
12099
13362
  readonly name: string;
12100
- /** Holds the selection handler that overrides the agent default while this scope is active. */
13363
+ /**
13364
+ * Holds the selection handler that overrides the agent default while this scope is active, and
13365
+ * overrides the active scope's too while this scope is a run's.
13366
+ */
12101
13367
  readonly select?: SelectionHandler;
12102
13368
  }
12103
13369
 
@@ -12116,7 +13382,10 @@ export declare interface ScopeInput extends ScopeFilter {
12116
13382
  export declare interface ScopeInterface extends ScopeFilter {
12117
13383
  readonly id: string;
12118
13384
  readonly name: string;
12119
- /** Holds the selection handler that overrides the agent default while this scope is active. */
13385
+ /**
13386
+ * Holds the selection handler that overrides the agent default while this scope is active, and
13387
+ * overrides the active scope's too while this scope is a run's.
13388
+ */
12120
13389
  readonly select?: SelectionHandler;
12121
13390
  /**
12122
13391
  * Composes a tighter child scope — each category is the set intersection of this scope's
@@ -12454,8 +13723,8 @@ export declare function settleToolResult(result: ToolResult): {
12454
13723
  };
12455
13724
 
12456
13725
  /**
12457
- * Holds one skill: a name and a description the index shows, the instructions loading adds, and
12458
- * bundled files.
13726
+ * Holds one skill: a name and a description the index shows, the body a run shows, the tools it
13727
+ * holds back, and bundled files.
12459
13728
  *
12460
13729
  * @remarks
12461
13730
  * A {@link SkillManagerInterface} mints it from a {@link SkillInput} and never mutates it. Its
@@ -12468,12 +13737,23 @@ export declare interface Skill {
12468
13737
  readonly name: string;
12469
13738
  /** Holds the one-line entry the skill index shows. */
12470
13739
  readonly description: string;
12471
- /** Holds the instructions loading the skill adds. */
13740
+ /**
13741
+ * Holds the body a run renders while it shows the skill: last in the `system` message, under
13742
+ * `## Loaded skills`, for the run's conversation alone. A blank body renders nothing.
13743
+ */
12472
13744
  readonly content: string;
13745
+ /**
13746
+ * Names the tools the skill holds back: while a turn advertises `load`, each is advertised only
13747
+ * while a shown skill names it, within the turn's ceiling.
13748
+ */
13749
+ readonly tools: readonly string[];
12473
13750
  /** Lists the bundled files. */
12474
13751
  readonly files: readonly FileInterface[];
12475
13752
  }
12476
13753
 
13754
+ /** Lists the members `SkillManagerOptions` declares, frozen — the keys the `SkillManager` constructor admits. */
13755
+ export declare const SKILL_MANAGER_KEYS: readonly ["on", "error", "format"];
13756
+
12477
13757
  /**
12478
13758
  * Names the built-in section header a {@link import('./types.js').SkillManagerInterface} renders
12479
13759
  * its index under — `'## Skills'`, the `open` value when no `format.open` overrides it.
@@ -12492,10 +13772,43 @@ export declare interface SkillInput {
12492
13772
  readonly name: string;
12493
13773
  readonly description: string;
12494
13774
  readonly content: string;
13775
+ /**
13776
+ * Names the tools the skill holds back until it is shown. The manager copies the list, and
13777
+ * refuses a value that is neither absent nor an array of strings with a `ContractError` coded
13778
+ * `'placement'`. Default: none.
13779
+ */
13780
+ readonly tools?: readonly string[];
12495
13781
  /** Lists the bundled files to mint with `createFile`. Default: none. */
12496
13782
  readonly files?: readonly FileInput[];
12497
13783
  }
12498
13784
 
13785
+ /** Admits a skill input exactly, and reads the faults of a refused one. */
13786
+ export declare const skillInputContract: ContractInterface<Readonly<{
13787
+ name: string;
13788
+ description: string;
13789
+ content: string;
13790
+ } & {
13791
+ tools?: readonly string[];
13792
+ files?: readonly unknown[];
13793
+ }>>;
13794
+
13795
+ /**
13796
+ * Describes a skill input exactly: a string `name`, `description`, and `content`, optional `tools`
13797
+ * names, and optional `files`.
13798
+ *
13799
+ * @remarks
13800
+ * An unknown member, a missing required member, and a declared member holding `undefined` refuse.
13801
+ * Each file is the `FileInput` interface of `@orkestrel/workspace`, which publishes no guard for it,
13802
+ * so the shape admits any defined element and `createFile`, that package's own door, reads it.
13803
+ */
13804
+ export declare const skillInputShape: ObjectShape< {
13805
+ name: StringShape;
13806
+ description: StringShape;
13807
+ content: StringShape;
13808
+ tools: OptionalShape<ArrayShape<StringShape>>;
13809
+ files: OptionalShape<ArrayShape<RawShape>>;
13810
+ }, boolean | ContractShape>;
13811
+
12499
13812
  /**
12500
13813
  * Registers the skills a host supplies — instruction bundles keyed by `name`, listed in insertion
12501
13814
  * order, where adding a skill whose name is already stored overwrites it, last write wins —
@@ -12586,11 +13899,17 @@ export declare interface SkillManagerInterface {
12586
13899
  /** Holds the line after the skills: the manager-options `close`, or `undefined` when none. */
12587
13900
  readonly close: string | undefined;
12588
13901
  /**
12589
- * Adds one {@link SkillInput}, or a batch: mints each `id` and file, and overwrites a
12590
- * same-name skill, last write wins.
13902
+ * Adds one {@link SkillInput}, or a batch: mints each `id` and file, copies each `tools` list,
13903
+ * and overwrites a same-name skill, last write wins.
13904
+ *
13905
+ * @remarks
13906
+ * Each input is checked and minted before any skill is stored or emitted, so a refused batch
13907
+ * stores nothing. A `tools` member is read first, then the input meets `skillInputContract`.
12591
13908
  *
12592
13909
  * @param input - One {@link SkillInput}, or a batch
12593
13910
  * @returns The stored skill, or the stored batch in input order
13911
+ * @throws {ContractError} Thrown when a `tools` member is neither absent nor an array of strings (`code: 'placement'`)
13912
+ * @throws {ContractError} Thrown when an input fails `skillInputContract`: a missing required member, an undeclared member, or a declared member holding `undefined` (`code: 'structure'`)
12594
13913
  */
12595
13914
  add(input: SkillInput): Skill;
12596
13915
  add(inputs: readonly SkillInput[]): readonly Skill[];
@@ -12699,6 +14018,9 @@ export declare function splitTopic(topic: string): readonly string[];
12699
14018
  */
12700
14019
  export declare function splitWords(part: string): readonly string[];
12701
14020
 
14021
+ /** Lists the members `ProviderStreamOptions` declares, frozen — the keys the `generate` and `stream` methods of an `AgentProvider` admits. */
14022
+ export declare const STREAM_OPTION_KEYS: readonly ["think", "schema"];
14023
+
12702
14024
  /**
12703
14025
  * Pairs a live event stream with the eventual settled result and a cancel — the
12704
14026
  * generic pull/streaming handle a long-running operation hands back.
@@ -12772,6 +14094,27 @@ export declare function stripThinking(messages: readonly Message[], replay: Thin
12772
14094
  */
12773
14095
  export declare function sumUsage(prior: TokenUsage | undefined, next: TokenUsage): TokenUsage;
12774
14096
 
14097
+ /** Checks the arguments of the `switch` built-in; its schema is the parameters it advertises. */
14098
+ export declare const switchToolContract: ContractInterface<Readonly<{
14099
+ workspace: string;
14100
+ } & {}>>;
14101
+
14102
+ /**
14103
+ * Describes the arguments of the `switch` built-in — one `workspace` id, non-empty and at most
14104
+ * `BUILTIN_LIMITS.name` code points.
14105
+ *
14106
+ * @remarks
14107
+ * The tool's door refuses a missing, empty, over-long, or extra member before the handler runs,
14108
+ * and repairs a value that converts to a string without loss, such as a number. A value of white
14109
+ * space alone passes the door; the handler refuses it as it refuses any name it cannot use.
14110
+ */
14111
+ export declare const switchToolShape: ObjectShape< {
14112
+ workspace: StringShape;
14113
+ }, boolean | ContractShape>;
14114
+
14115
+ /** Lists the members `SystemOneJudgeOptions` declares, frozen — the keys the `SystemOneJudge` constructor admits. */
14116
+ export declare const SYSTEM_ONE_OPTION_KEYS: readonly ["url", "model", "timeout", "fetch", "headers"];
14117
+
12775
14118
  /** Names the System One decision endpoint shared by compatible servers. */
12776
14119
  export declare const SYSTEM_ONE_PATH = "/v1/systemone";
12777
14120
 
@@ -13108,6 +14451,12 @@ export declare const UNAUTHORIZED_RELAY_STATUS = 401;
13108
14451
  */
13109
14452
  export declare const UPSTREAM_RELAY_STATUS = 502;
13110
14453
 
14454
+ /**
14455
+ * Names the section header the admitted workspace ids render under in the user context message —
14456
+ * `'## Workspaces'`, rendered only while a run can select a workspace.
14457
+ */
14458
+ export declare const WORKSPACE_INDEX_HEADER = "## Workspaces";
14459
+
13111
14460
  /**
13112
14461
  * Names the section header the `build()` method of {@link import('./AgentContext.js').AgentContext}
13113
14462
  * renders the active workspace's text files under — `'## Workspace'`, the line that opens the