@orkestrel/agent 0.0.30 → 0.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/core/index.cjs +2337 -1298
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +1379 -253
- package/dist/src/core/index.d.ts +1379 -253
- package/dist/src/core/index.js +2320 -1300
- package/dist/src/core/index.js.map +1 -1
- package/package.json +19 -11
|
@@ -42,22 +42,25 @@ import type { WorkspaceManagerInterface } from '@orkestrel/workspace';
|
|
|
42
42
|
*
|
|
43
43
|
* @remarks
|
|
44
44
|
* - **One loop, two faces.** A single private async generator (`#execute`) drives the
|
|
45
|
-
* whole
|
|
46
|
-
*
|
|
45
|
+
* whole run. `stream` drives it eagerly into a private {@link Channel} and settles `result`
|
|
46
|
+
* from the outcome the generator returns, through one `.then` — so `result` settles
|
|
47
47
|
* whether or not the live `events` are drained; `generate` awaits that same
|
|
48
48
|
* settled `result` — so the two can never diverge.
|
|
49
|
-
* - **The turn.** `#execute` builds the provider input once
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* append
|
|
55
|
-
*
|
|
49
|
+
* - **The turn.** `#execute` builds the provider input once, then runs up to `limit` turns,
|
|
50
|
+
* each appending one readonly {@link AgentTurn} record: drive `provider.stream(...)`,
|
|
51
|
+
* yielding each content delta as a `token` chunk and charging its estimate to the
|
|
52
|
+
* `allowance` when one is set; reconcile the turn's usage against the `budget`, before a
|
|
53
|
+
* genuine provider error rejects the run too, and yield a `usage` chunk; if the model
|
|
54
|
+
* requested tools, append the assistant turn, pass them to the tool manager's `execute`
|
|
55
|
+
* method, yield a `tool` chunk per call, append each tool result message, and continue;
|
|
56
|
+
* otherwise append the final assistant message and stop. The run's content,
|
|
57
|
+
* thinking, usage, and stop derive from the turn records. Each assistant message stores its
|
|
58
|
+
* call's non-empty thinking.
|
|
56
59
|
* Provider calls and prompt estimates apply the provider's `replay` policy to the working
|
|
57
60
|
* array; an absent policy means `'none'`.
|
|
58
61
|
* - **Bounded.** Each run arms one cancel through `createAbort({ signal: AbortSignal.any([
|
|
59
|
-
* …]) })` folding the external `signal`, the `timeout` deadline, and the `budget`
|
|
60
|
-
*
|
|
62
|
+
* …]) })` folding the external `signal`, the `timeout` deadline, and the `budget` and
|
|
63
|
+
* `allowance` signals; `abort()` fires it. Any trip stops the loop and commits a partial result
|
|
61
64
|
* (the `result` promise resolves, never rejects, on a cancel) — only a genuine
|
|
62
65
|
* provider / tool error rejects.
|
|
63
66
|
* - **Paced + capped.** The loop calls the `scheduler` object's `yield` method between turns when given; tool
|
|
@@ -105,6 +108,8 @@ export declare class Agent implements AgentInterface {
|
|
|
105
108
|
* emitted after the tool runs (so a consumer sees what was called and what came back).
|
|
106
109
|
* - `usage` — one provider call's {@link TokenUsage}, emitted after each turn's
|
|
107
110
|
* provider response that reported it (folded into the running total + any budget).
|
|
111
|
+
* `estimate` is the token estimate of the answer the call streamed, the meter layer's reading
|
|
112
|
+
* beside the reported usage.
|
|
108
113
|
*/
|
|
109
114
|
export declare type AgentChunk = {
|
|
110
115
|
readonly category: 'token';
|
|
@@ -119,6 +124,7 @@ export declare type AgentChunk = {
|
|
|
119
124
|
} | {
|
|
120
125
|
readonly category: 'usage';
|
|
121
126
|
readonly usage: TokenUsage;
|
|
127
|
+
readonly estimate: number;
|
|
122
128
|
};
|
|
123
129
|
|
|
124
130
|
/**
|
|
@@ -314,8 +320,9 @@ export declare interface AgentContextInterface {
|
|
|
314
320
|
* `scope.files` (a three-way allow-list; `undefined` ⇒ all active files), then split by
|
|
315
321
|
* carrier: text files ({@link import('@orkestrel/workspace').isText}) render into a dedicated
|
|
316
322
|
* `## Workspace` section in the system block — each a fenced
|
|
317
|
-
* `` File: <path>\n```<language>\n<text>\n``` `` block
|
|
318
|
-
*
|
|
323
|
+
* `` File: <path>\n```<language>\n<text>\n``` `` block whose fence is one backtick longer than
|
|
324
|
+
* the longest backtick run in the text, and never shorter than three — placed immediately after
|
|
325
|
+
* the instructions section; binary files whose MIME starts with `image/` have their `base64` payload
|
|
319
326
|
* attached to the last user message (a vision provider reads images off a user turn).
|
|
320
327
|
* Active-only — never the other registered workspaces; with no active workspace nothing is
|
|
321
328
|
* rendered for workspaces.
|
|
@@ -411,25 +418,41 @@ export declare interface AgentContextOptions {
|
|
|
411
418
|
}
|
|
412
419
|
|
|
413
420
|
/**
|
|
414
|
-
* Reports a
|
|
421
|
+
* Reports a run sharing accounting with a live run, a `limit` that is not a nonnegative safe integer, a name absent from a registry pool, 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. Await the call inside `try`/`catch` to catch it.
|
|
415
422
|
*
|
|
416
423
|
* @remarks
|
|
417
|
-
* `'CONCURRENCY'` reports a run
|
|
418
|
-
* `window` (a shared context budget) or
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
* `
|
|
424
|
+
* `'CONCURRENCY'` reports a run started while another run on the same agent is live, when the
|
|
425
|
+
* agent carries a `window` (a shared context budget) or when the run's effective `budget` or
|
|
426
|
+
* `allowance` is an instance a live run holds — the second run's `start()` would replace that
|
|
427
|
+
* instance's signal and race its charges against the first run's. Use separate agents, or
|
|
428
|
+
* distinct budget and allowance instances per run with no `window`, for concurrent runs. Its
|
|
429
|
+
* `context` names the `agent` id.
|
|
430
|
+
* `'LIMIT'` reports a construction or per-run `limit` that is not a nonnegative safe integer,
|
|
431
|
+
* including one a rehydrated job carries into `build`. `'REGISTRY'` reports a rehydration name
|
|
432
|
+
* absent from its registry pool, on `provider` / `tool` / `authority` / `scheduler` / `build`;
|
|
433
|
+
* its `context` names the `category` and the `name`. `'WINDOW'` reports a `strict` run whose
|
|
434
|
+
* complete provider request is still over the `window` budget, equal to its `max` included, after
|
|
435
|
+
* the one permitted fold or with no fold possible; it settles the run `error` before the provider
|
|
436
|
+
* is called, and its `context` holds the `agent` id, the measured `consumed`, and the window `max`.
|
|
437
|
+
* Narrow a caught value with {@link isAgentError} and branch on `error.code`.
|
|
424
438
|
*/
|
|
425
439
|
export declare class AgentError extends Error {
|
|
426
|
-
/** Names the machine-readable condition — `'CONCURRENCY'`: a
|
|
440
|
+
/** Names the machine-readable condition — `'CONCURRENCY'`: a run sharing accounting with a live run; `'LIMIT'`: a `limit` that is not a nonnegative safe integer; `'REGISTRY'`: a rehydration name absent from its registry pool; `'WINDOW'`: a strict run whose complete request is still over its window budget. */
|
|
427
441
|
readonly code: AgentErrorCode;
|
|
428
|
-
|
|
442
|
+
/** Holds the values that locate the failure, such as the `agent` id of a refused run, or `undefined` when none were supplied. */
|
|
443
|
+
readonly context: Readonly<Record<string, unknown>> | undefined;
|
|
444
|
+
/**
|
|
445
|
+
* Creates the error with its code, message, and optional cause and context.
|
|
446
|
+
*
|
|
447
|
+
* @param code - The machine-readable {@link AgentErrorCode}
|
|
448
|
+
* @param message - The human-readable description
|
|
449
|
+
* @param options - The optional {@link CodedErrorOptions}; `cause` reaches `Error.cause` only when present
|
|
450
|
+
*/
|
|
451
|
+
constructor(code: AgentErrorCode, message: string, options?: CodedErrorOptions);
|
|
429
452
|
}
|
|
430
453
|
|
|
431
|
-
/** Names the machine-readable agent concurrency
|
|
432
|
-
export declare type AgentErrorCode = 'CONCURRENCY' | 'REGISTRY';
|
|
454
|
+
/** Names the machine-readable agent concurrency, limit, registry, and window failures. */
|
|
455
|
+
export declare type AgentErrorCode = 'CONCURRENCY' | 'LIMIT' | 'REGISTRY' | 'WINDOW';
|
|
433
456
|
|
|
434
457
|
/**
|
|
435
458
|
* Maps the push observation surface of an {@link AgentInterface} — the lifecycle, usage, and tool
|
|
@@ -466,8 +489,12 @@ export declare type AgentEventMap = {
|
|
|
466
489
|
readonly turn: readonly [index: number];
|
|
467
490
|
/** Reports a dispatched {@link ToolCall} paired with its {@link ToolResult} (executed or a denial). */
|
|
468
491
|
readonly tool: readonly [call: ToolCall, result: ToolResult];
|
|
469
|
-
/**
|
|
470
|
-
|
|
492
|
+
/**
|
|
493
|
+
* Reports a turn's {@link TokenUsage} — emitted after a usage-bearing provider call. Carries the
|
|
494
|
+
* call's streamed-answer `estimate` beside its reported usage, so the meter's allowance can be
|
|
495
|
+
* calibrated without a failure.
|
|
496
|
+
*/
|
|
497
|
+
readonly usage: readonly [usage: TokenUsage, estimate: number];
|
|
471
498
|
/**
|
|
472
499
|
* Reports a call denied by scope or authority, before dispatch.
|
|
473
500
|
* A turn advertising no tools drops each call with `no tool is advertised in the active scope`.
|
|
@@ -490,7 +517,7 @@ export declare type AgentEventMap = {
|
|
|
490
517
|
readonly exhaust: readonly [turns: number];
|
|
491
518
|
/**
|
|
492
519
|
* Reports automatic compaction's summarizer throwing — a non-fatal warn channel (the run continues; see
|
|
493
|
-
* {@link AgentOptions.window}). When the loop's
|
|
520
|
+
* {@link AgentOptions.window}). When the loop's pre-dispatch auto-compaction
|
|
494
521
|
* (`conversation.compact()`) rejects, the run does not crash: the loop skips compaction that
|
|
495
522
|
* turn and surfaces the caught error here so the failure is observable, never silently lost.
|
|
496
523
|
* The run still settles through the other events — `finish` for the lenient default, and
|
|
@@ -511,21 +538,67 @@ export declare type AgentEventMap = {
|
|
|
511
538
|
readonly select: readonly [selection: Selection];
|
|
512
539
|
};
|
|
513
540
|
|
|
541
|
+
/**
|
|
542
|
+
* Executes one runner's agent jobs — spawning each unit's declared children on its first attempt
|
|
543
|
+
* only, then rehydrating the unit through a registry with the controller signal and settling it
|
|
544
|
+
* under the shared partial-result policy.
|
|
545
|
+
*
|
|
546
|
+
* @remarks
|
|
547
|
+
* One instance serves one runner, because it records every unit it has fanned out. The runner
|
|
548
|
+
* calls its handler once per attempt with the same unit id, so a retried attempt finds its unit
|
|
549
|
+
* recorded and spawns no child again. Children are fired through the controller without being
|
|
550
|
+
* awaited inline, so a bounded runner frees the parent's slot for them. `createAgentRunner`
|
|
551
|
+
* creates one instance per runner and binds its `execute` method as the runner's handler.
|
|
552
|
+
*
|
|
553
|
+
* @example
|
|
554
|
+
* ```ts
|
|
555
|
+
* import type { AgentJobInput, ProviderInterface } from '@orkestrel/agent'
|
|
556
|
+
* import { AgentFanout, createAgentRegistry } from '@orkestrel/agent'
|
|
557
|
+
* import { createRunner } from '@orkestrel/workflow'
|
|
558
|
+
*
|
|
559
|
+
* declare const provider: ProviderInterface // any concrete implementation supplied by the host app
|
|
560
|
+
* const fanout = new AgentFanout(createAgentRegistry({ providers: { main: provider } }), false)
|
|
561
|
+
* const runner = createRunner({ handler: fanout.execute.bind(fanout), retries: 1 })
|
|
562
|
+
* const child: AgentJobInput = { provider: 'main', messages: [{ role: 'user', content: 'child' }] }
|
|
563
|
+
* const parent: AgentJobInput = { ...child, messages: [{ role: 'user', content: 'parent' }], children: [child] }
|
|
564
|
+
* const results = await runner.execute([parent]) // the parent's result, then the child's
|
|
565
|
+
* ```
|
|
566
|
+
*/
|
|
567
|
+
export declare class AgentFanout {
|
|
568
|
+
#private;
|
|
569
|
+
/**
|
|
570
|
+
* Creates the fan-out for one runner over a registry and a partial policy.
|
|
571
|
+
*
|
|
572
|
+
* @param registry - The registry that rehydrates each serializable job
|
|
573
|
+
* @param partial - The partial policy. If `true`, a partial result resolves; if `false`, it throws an `AgentJobError`
|
|
574
|
+
*/
|
|
575
|
+
constructor(registry: AgentRegistryInterface, partial: boolean);
|
|
576
|
+
/**
|
|
577
|
+
* Executes one unit: spawns its declared children unless an earlier attempt of the unit already
|
|
578
|
+
* did, then runs the rehydrated agent and settles it under the partial policy.
|
|
579
|
+
*
|
|
580
|
+
* @param controller - The runner controller for this unit's attempt
|
|
581
|
+
* @returns The settled agent result of the unit
|
|
582
|
+
* @throws {AgentJobError} Thrown when the run ended partial and the partial policy is `false`
|
|
583
|
+
*/
|
|
584
|
+
execute(controller: ControllerInterface<AgentJobInput, AgentResult>): Promise<AgentResult>;
|
|
585
|
+
}
|
|
586
|
+
|
|
514
587
|
/**
|
|
515
588
|
* Composes a {@link ProviderInterface}, an {@link AgentContextInterface}, and a
|
|
516
589
|
* {@link ToolManagerInterface} into a bounded context → provider → tools → repeat turn.
|
|
517
590
|
*
|
|
518
591
|
* @remarks
|
|
519
592
|
* - **One loop, two faces.** `generate` and `stream` share one private run, so they
|
|
520
|
-
* can never diverge: `generate`
|
|
521
|
-
*
|
|
593
|
+
* can never diverge: `generate` awaits the settled {@link AgentResult} of the run `stream`
|
|
594
|
+
* exposes and leaves its live chunks undrained.
|
|
522
595
|
* - **Bounded.** Each turn arms a single cancel folded from the external `signal`, the
|
|
523
|
-
* `timeout` deadline, and the `budget`
|
|
524
|
-
* or `abort()` — stops the loop and settles the result `partial: true`.
|
|
596
|
+
* `timeout` deadline, and the `budget` and `allowance` signals (through `AbortSignal.any`); any
|
|
597
|
+
* of them — or `abort()` — stops the loop and settles the result `partial: true`.
|
|
525
598
|
* Tool handlers receive that run's signal through their `ToolContext`. An agent abort,
|
|
526
|
-
* stream abort, external signal, or deadline can reach a running handler. The
|
|
527
|
-
* charged during provider streaming and
|
|
528
|
-
* ends the run without dispatching, never inside a handler. An abort before dispatch
|
|
599
|
+
* stream abort, external signal, or deadline can reach a running handler. The allowance is
|
|
600
|
+
* charged during provider streaming and the budget after each provider call and between turns,
|
|
601
|
+
* before tool dispatch; exhaustion ends the run without dispatching, never inside a handler. An abort before dispatch
|
|
529
602
|
* appends neither the assistant call turn nor tool messages and emits no tool chunk;
|
|
530
603
|
* streamed content remains in the partial result. Cancellation after entry is cooperative:
|
|
531
604
|
* the loop awaits a running handler even when it ignores the signal, records its tool message,
|
|
@@ -550,20 +623,24 @@ export declare interface AgentInterface {
|
|
|
550
623
|
readonly status: AgentStatus;
|
|
551
624
|
readonly context: AgentContextInterface;
|
|
552
625
|
/**
|
|
553
|
-
* Runs the turn to completion
|
|
554
|
-
*
|
|
626
|
+
* Runs the turn to completion — awaits the settled {@link AgentResult} (`partial: true` when
|
|
627
|
+
* cancelled) and leaves the live chunks undrained.
|
|
555
628
|
*
|
|
556
629
|
* @remarks
|
|
557
|
-
* A
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
562
|
-
*
|
|
630
|
+
* A run started while another is live throws an {@link import('./errors.js').AgentError} with
|
|
631
|
+
* `code: 'CONCURRENCY'` when the agent carries a `window`, or when the run's effective
|
|
632
|
+
* `budget` or `allowance` is an instance a live run holds; a run whose `limit` is not a nonnegative safe
|
|
633
|
+
* integer throws one with `code: 'LIMIT'`. A `budget` or `allowance` that does not implement
|
|
634
|
+
* `BudgetInterface` throws a `ContractError` with code `'placement'` before either bound starts.
|
|
635
|
+
* Each throws synchronously, before any `Promise` is
|
|
636
|
+
* returned. A fire-and-forget `agent.generate().catch(...)` therefore will not catch them (the
|
|
637
|
+
* throw happens on the call itself, ahead of the `.catch` ever attaching) — await the call
|
|
638
|
+
* (inside a `try`/`catch`) or wrap the call expression itself in `try`/`catch`.
|
|
563
639
|
*
|
|
564
640
|
* @param options - Optional per-run {@link AgentRunOptions} (for example `think`); omitted ⇒ defaults
|
|
565
641
|
* @returns The settled {@link AgentResult} (`partial: true` when cancelled)
|
|
566
|
-
* @throws {AgentError} Thrown when a
|
|
642
|
+
* @throws {AgentError} Thrown when a live run shares the `window` or a budget or allowance instance (`code: 'CONCURRENCY'`) or the `limit` is not a nonnegative safe integer (`code: 'LIMIT'`), synchronously before a handle returns.
|
|
643
|
+
* @throws {ContractError} Thrown when the `budget` or `allowance` does not implement `BudgetInterface` (`code: 'placement'`), synchronously before a handle returns.
|
|
567
644
|
*/
|
|
568
645
|
generate(options?: AgentRunOptions): Promise<AgentResult>;
|
|
569
646
|
/**
|
|
@@ -572,14 +649,18 @@ export declare interface AgentInterface {
|
|
|
572
649
|
* on a genuine error.
|
|
573
650
|
*
|
|
574
651
|
* @remarks
|
|
575
|
-
* Like `generate()`, a
|
|
576
|
-
* {@link import('./errors.js').AgentError}
|
|
652
|
+
* Like `generate()`, a run that would share the `window` or a live run's budget or allowance
|
|
653
|
+
* instance throws an {@link import('./errors.js').AgentError} with `code: 'CONCURRENCY'`, an
|
|
654
|
+
* invalid `limit` throws one with `code: 'LIMIT'`, and a `budget` or `allowance` that does not
|
|
655
|
+
* implement `BudgetInterface` throws a `ContractError` with code `'placement'`, synchronously — before the
|
|
577
656
|
* {@link AgentStreamInterface} handle is even returned, so it cannot be caught by chaining
|
|
578
|
-
* off the (never-produced) handle; wrap the call itself in `try`/`catch`.
|
|
657
|
+
* off the (never-produced) handle; wrap the call itself in `try`/`catch`. A `signal` that
|
|
658
|
+
* `AbortSignal.any` refuses throws its `TypeError` the same way, before any deadline is armed.
|
|
579
659
|
*
|
|
580
660
|
* @param options - Optional per-run {@link AgentRunOptions} (for example `think`); omitted ⇒ defaults
|
|
581
661
|
* @returns A live {@link AgentStreamInterface} handle (events + result + abort)
|
|
582
|
-
* @throws {AgentError} Thrown when a
|
|
662
|
+
* @throws {AgentError} Thrown when a live run shares the `window` or a budget or allowance instance (`code: 'CONCURRENCY'`) or the `limit` is not a nonnegative safe integer (`code: 'LIMIT'`), synchronously before a handle returns.
|
|
663
|
+
* @throws {ContractError} Thrown when the `budget` or `allowance` does not implement `BudgetInterface` (`code: 'placement'`), synchronously before a handle returns.
|
|
583
664
|
*/
|
|
584
665
|
stream(options?: AgentRunOptions): AgentStreamInterface;
|
|
585
666
|
/**
|
|
@@ -766,13 +847,17 @@ export declare interface AgentJudgeInterface extends JudgeInterface {
|
|
|
766
847
|
* - `system` — an optional system prompt prepended to the turn (seeds the context).
|
|
767
848
|
* - `tools` — an optional pre-built {@link ToolManagerInterface} the loop dispatches
|
|
768
849
|
* the model's calls through; an empty one is created when omitted.
|
|
769
|
-
* - `limit` — the maximum number of tool-iteration turns before the loop stops
|
|
850
|
+
* - `limit` — the maximum number of tool-iteration turns before the loop stops, a nonnegative
|
|
851
|
+
* safe integer; construction throws an `AgentError` with code `'LIMIT'` when it is not.
|
|
770
852
|
* Default: `DEFAULT_AGENT_LIMIT`.
|
|
771
853
|
* - `timeout` — an optional wall-clock deadline (ms) for the whole turn; its signal
|
|
772
854
|
* folds into the turn's bound, committing a partial result on expiry.
|
|
773
855
|
* - `budget` — an optional token {@link BudgetInterface} cost bound; the loop charges
|
|
774
856
|
* each provider call's usage and its signal folds into the turn's bound, committing
|
|
775
857
|
* a partial result after the budget is exhausted.
|
|
858
|
+
* - `allowance` — an optional token {@link BudgetInterface} the meter layer charges each content
|
|
859
|
+
* delta's mid-stream estimate against; its signal folds into the turn's bound beside the
|
|
860
|
+
* `budget`'s. Pass the `budget` itself to share one ceiling. Omitted ⇒ no meter layer.
|
|
776
861
|
* - `scheduler` — an optional {@link SchedulerInterface} that paces the loop —
|
|
777
862
|
* the loop calls its `yield` method between turns, so the host regains control between expensive provider calls.
|
|
778
863
|
* - `signal` — an optional external `AbortSignal` whose abort cancels the turn (a
|
|
@@ -781,17 +866,20 @@ export declare interface AgentJudgeInterface extends JudgeInterface {
|
|
|
781
866
|
* context as the message source (so `context.messages` is its active conversation's live tail);
|
|
782
867
|
* omitted ⇒ a fresh registry holding one default conversation. Auto-compaction (`window`) folds
|
|
783
868
|
* the active conversation when it is summarizable.
|
|
784
|
-
* - `window` — an optional context {@link BudgetInterface}
|
|
785
|
-
* compaction: when set, the loop measures the
|
|
786
|
-
*
|
|
787
|
-
*
|
|
788
|
-
*
|
|
869
|
+
* - `window` — an optional context {@link BudgetInterface} over the complete
|
|
870
|
+
* {@link ProviderRequest} for automatic conversation compaction: when set, the loop measures the
|
|
871
|
+
* exact request, messages after replay, advertised tools, and per-call options, before every
|
|
872
|
+
* provider dispatch (its `consumer` is a token estimator, its `max` the context window) and, when
|
|
873
|
+
* the request reaches the window and the active conversation is summarizable, compacts the active
|
|
874
|
+
* conversation once + dispatches the rebuilt smaller request — compact-and-continue, distinct from
|
|
789
875
|
* hard abort of the `budget` object. Omitted ⇒ no auto-compaction.
|
|
790
876
|
* - `strict` — when `true`, a summarizer failure during automatic compaction aborts the run
|
|
791
877
|
* (rethrown after the `fault` event, propagating through `#execute` to a genuine `error`
|
|
792
878
|
* settle) instead of skipping compaction and continuing over-window. The selection faults (a
|
|
793
879
|
* thrown handler, a returned `fault`, a conversation changed under the handler) settle the same
|
|
794
|
-
* way
|
|
880
|
+
* way, and a request still over the `window` after the permitted fold, or one that cannot fold,
|
|
881
|
+
* settles `error` with an `AgentError` coded `'WINDOW'` before the provider is called.
|
|
882
|
+
* Default: `false`. The run continues over-window, or on `view()` after a selection fault.
|
|
795
883
|
* - `select` — an optional default {@link SelectionHandler} forwarded to the agent's context; the
|
|
796
884
|
* active scope's `select` overrides it. The loop runs it at run entry and after each automatic
|
|
797
885
|
* compaction rebuild, emits each {@link Selection} it builds from on `select`, and charges the
|
|
@@ -830,12 +918,33 @@ export declare interface AgentOptions {
|
|
|
830
918
|
* compaction fold, or a compaction rebuild.
|
|
831
919
|
*/
|
|
832
920
|
readonly scope?: ScopeInterface;
|
|
833
|
-
/**
|
|
921
|
+
/**
|
|
922
|
+
* Caps the tool-iteration turns before the loop stops, as a nonnegative safe integer.
|
|
923
|
+
* Thrown as an `AgentError` with code `'LIMIT'` when it is not. Default: `DEFAULT_AGENT_LIMIT`.
|
|
924
|
+
*/
|
|
834
925
|
readonly limit?: number;
|
|
835
926
|
/** Sets a wall-clock deadline (ms) for the whole turn; its abort commits a partial result. */
|
|
836
927
|
readonly timeout?: number;
|
|
837
|
-
/**
|
|
928
|
+
/**
|
|
929
|
+
* Bounds the token cost; each provider call's usage is charged and its abort commits a partial.
|
|
930
|
+
* A call that reports no usage charges the `budget` its streamed-answer estimate, unless the
|
|
931
|
+
* `allowance` is the `budget` and already charged it.
|
|
932
|
+
*/
|
|
838
933
|
readonly budget?: BudgetInterface<TokenUsage>;
|
|
934
|
+
/**
|
|
935
|
+
* Holds the meter layer's allowance: the token budget each content delta's mid-stream estimate is
|
|
936
|
+
* charged against, beside the reported usage the cost `budget` is reconciled to.
|
|
937
|
+
* The meter charges completion growth as `{ prompt: 0, completion: n, total: n }`, so a
|
|
938
|
+
* `completion`- or `total`-scoped allowance tracks the answer, while a `prompt`-scoped allowance
|
|
939
|
+
* is charged `0` and never trips through the meter. Its signal folds into the run's bound with
|
|
940
|
+
* the `budget`'s, so the estimate can stop a stream before the provider
|
|
941
|
+
* reports usage. Pass the `budget` itself to make the estimate and the reported usage share one
|
|
942
|
+
* ceiling; pass a separate budget with a smaller `max` to let the estimate stop the run first, or
|
|
943
|
+
* a larger one to let the reported usage or the model's own limit stop it instead. Cumulative
|
|
944
|
+
* across turns and runs, like the `budget`. Default: no meter layer; the estimate is still
|
|
945
|
+
* measured for the `usage` event and charges nothing mid-stream.
|
|
946
|
+
*/
|
|
947
|
+
readonly allowance?: BudgetInterface<TokenUsage>;
|
|
839
948
|
/** Paces the loop — the loop yields to it between turns so the host regains control. */
|
|
840
949
|
readonly scheduler?: SchedulerInterface;
|
|
841
950
|
/** Carries an external cancel; its abort commits a partial result. */
|
|
@@ -858,22 +967,34 @@ export declare interface AgentOptions {
|
|
|
858
967
|
*/
|
|
859
968
|
readonly conversations?: ConversationManagerInterface;
|
|
860
969
|
/**
|
|
861
|
-
* Holds an optional context {@link BudgetInterface}
|
|
862
|
-
* token estimator
|
|
863
|
-
* its `max` is the context window.
|
|
864
|
-
*
|
|
865
|
-
* the
|
|
866
|
-
* the
|
|
867
|
-
*
|
|
868
|
-
|
|
869
|
-
|
|
970
|
+
* Holds an optional context {@link BudgetInterface} that admits each provider request. Its
|
|
971
|
+
* `consumer` is a token estimator over the complete {@link ProviderRequest} (for example the
|
|
972
|
+
* exported {@link import('./helpers.js').estimateRequest}) and its `max` is the context window.
|
|
973
|
+
* Before every provider dispatch the loop measures the exact request it will send: the messages
|
|
974
|
+
* after the provider's `replay` policy, the tools the turn advertises after the scope's
|
|
975
|
+
* allow-list, and the per-call `options` (`think`, `schema`). The budget is cleared, consumes that
|
|
976
|
+
* request, and the request is over the window when the budget is `exhausted`, which includes a
|
|
977
|
+
* request equal to `max`. When it is over and the active conversation is summarizable, the loop
|
|
978
|
+
* **compacts the active conversation once, rebuilds with the same tools and options, measures the
|
|
979
|
+
* rebuilt request, and dispatches it** (compact-and-continue) — the same consume-to-a-ceiling
|
|
980
|
+
* primitive as the cost `budget`, but compaction is the ceiling action instead of abort. A
|
|
981
|
+
* non-summarizable conversation is still measured, but cannot fold. After a run `consumed` holds
|
|
982
|
+
* the last measured request. With {@link AgentOptions.strict}, a request still over the window
|
|
983
|
+
* after the one permitted fold, or one that cannot fold, is refused before dispatch with an
|
|
984
|
+
* `AgentError` coded `'WINDOW'`. Omit to disable.
|
|
985
|
+
*/
|
|
986
|
+
readonly window?: BudgetInterface<ProviderRequest>;
|
|
870
987
|
/**
|
|
871
988
|
* If `true`, a summarizer failure during automatic compaction emits `fault` and settles the
|
|
872
989
|
* run `error`; a thrown selection handler, a returned selection `fault`, and a conversation
|
|
873
|
-
* changed during selection follow the same rule.
|
|
874
|
-
*
|
|
875
|
-
*
|
|
876
|
-
*
|
|
990
|
+
* changed during selection follow the same rule. A request that the {@link AgentOptions.window}
|
|
991
|
+
* still finds over the window, equal to `max` included, after the one permitted fold, or that
|
|
992
|
+
* cannot fold, is refused before the provider is called: the run settles `error` with an
|
|
993
|
+
* `AgentError` coded `'WINDOW'` whose `context` holds the `agent`, the measured `consumed`, and
|
|
994
|
+
* the window `max`, and no `fault` fires for it. If `false`, the run continues — over-window
|
|
995
|
+
* after a summarizer failure or a futile fold, and on the active conversation's `view()` after a
|
|
996
|
+
* selection fault. A cancel at a selection site or a fold, a `fault` listener's included, settles
|
|
997
|
+
* partial instead of `error`. Default: `false`.
|
|
877
998
|
*/
|
|
878
999
|
readonly strict?: boolean;
|
|
879
1000
|
/**
|
|
@@ -1058,7 +1179,8 @@ export declare interface AgentQueueOptions {
|
|
|
1058
1179
|
* the threaded `signal`; seed its context with the job's `messages`; return it. The
|
|
1059
1180
|
* `signal` is the queue attempt's / runner unit's cancel, so a bounded abort propagates
|
|
1060
1181
|
* into the agent (which commits a partial — the job's `partial` policy then
|
|
1061
|
-
* decides success vs. retry).
|
|
1182
|
+
* decides success vs. retry). A job `limit` that is not a nonnegative safe integer throws an
|
|
1183
|
+
* {@link AgentError} carrying `code: 'LIMIT'` from the agent's construction.
|
|
1062
1184
|
* - **Event-free.** A pure resolver — no Emitter, no events.
|
|
1063
1185
|
*
|
|
1064
1186
|
* @example
|
|
@@ -1140,7 +1262,7 @@ export declare interface AgentRegistryInterface {
|
|
|
1140
1262
|
* @param input - The serializable {@link AgentJobInput} to rehydrate
|
|
1141
1263
|
* @param signal - An optional cancel threaded into the agent (a queue / runner abort)
|
|
1142
1264
|
* @returns The ready agent, its context seeded with the job's messages
|
|
1143
|
-
* @throws {AgentError} Thrown when a referenced provider, tool, authority, or scheduler name is unregistered (`code: 'REGISTRY'`)
|
|
1265
|
+
* @throws {AgentError} Thrown when a referenced provider, tool, authority, or scheduler name is unregistered (`code: 'REGISTRY'`), or when the job's `limit` is not a nonnegative safe integer (`code: 'LIMIT'`)
|
|
1144
1266
|
*/
|
|
1145
1267
|
build(input: AgentJobInput, signal?: AbortSignal): AgentInterface;
|
|
1146
1268
|
}
|
|
@@ -1191,7 +1313,10 @@ export declare interface AgentRegistryOptions {
|
|
|
1191
1313
|
* it stays out of `content`. Each call's non-empty thinking is recorded on the assistant
|
|
1192
1314
|
* message that call appends. The joined result also includes thinking from calls that appended
|
|
1193
1315
|
* no message, such as an aborted call. Only recorded thinking can return to a provider,
|
|
1194
|
-
* as its `replay` policy allows.
|
|
1316
|
+
* as its `replay` policy allows. A run stopped by the `meter` or `budget` layer settles
|
|
1317
|
+
* `partial: true`. A `model` stop settles `partial: false`, because its answer is complete as the
|
|
1318
|
+
* model ended it, unless that call's reconciled usage then exhausted a budget or a cancel landed
|
|
1319
|
+
* before the run settled, which settles `partial: true` with that reason on the `abort` event.
|
|
1195
1320
|
*/
|
|
1196
1321
|
export declare interface AgentResult {
|
|
1197
1322
|
readonly content: string;
|
|
@@ -1209,6 +1334,13 @@ export declare interface AgentResult {
|
|
|
1209
1334
|
* contains calls: those calls are dropped and observed through the `deny` event.
|
|
1210
1335
|
*/
|
|
1211
1336
|
readonly partial: boolean;
|
|
1337
|
+
/**
|
|
1338
|
+
* Names the layer that stopped the run — the meter's estimate allowance, the cost budget, or the
|
|
1339
|
+
* model's own token limit — with the readings it crossed. Absent when the run finished by
|
|
1340
|
+
* itself, reached its `limit`, or was cancelled by a signal, a deadline, or `abort()` before the
|
|
1341
|
+
* model ended its final answer.
|
|
1342
|
+
*/
|
|
1343
|
+
readonly stop?: AgentStop;
|
|
1212
1344
|
}
|
|
1213
1345
|
|
|
1214
1346
|
/**
|
|
@@ -1223,8 +1355,11 @@ export declare interface AgentResult {
|
|
|
1223
1355
|
* through Contract's sanctioned exception boundary, so conforming accessors and inherited
|
|
1224
1356
|
* properties are supported while a throwing getter or revoked proxy returns `undefined`.
|
|
1225
1357
|
* Present usage counts must be finite numbers; negative and fractional values are preserved,
|
|
1226
|
-
* not normalized.
|
|
1227
|
-
* and
|
|
1358
|
+
* not normalized. The result is exact `{ content, thinking?, usage?, partial, stop? }`. A present
|
|
1359
|
+
* `stop` is read once, then its `layer`, `id`, `max`, `consumed`, `estimate`, and `usage` once each
|
|
1360
|
+
* in that order, `max` and `consumed` only on a `meter` or `budget` arm; the arm is rebuilt
|
|
1361
|
+
* exactly, omitting absent readings, and a malformed `stop` refuses the whole value. Extra input
|
|
1362
|
+
* properties are dropped while a fresh exact plain object is rebuilt and deep-gated through
|
|
1228
1363
|
* {@link import('@orkestrel/contract').parseJSONValue}.
|
|
1229
1364
|
*
|
|
1230
1365
|
* @param value - The unknown value to project
|
|
@@ -1268,7 +1403,7 @@ export declare interface AgentRunnerOptions {
|
|
|
1268
1403
|
* Every member is optional and resolved independently, so an omitted member leaves the
|
|
1269
1404
|
* agent's constructed value in force and a caller that passes no options runs exactly the
|
|
1270
1405
|
* agent it configured. `think` / `schema` ride through to the provider as
|
|
1271
|
-
* {@link ProviderStreamOptions}; `limit` / `timeout` / `budget` replace their construction
|
|
1406
|
+
* {@link ProviderStreamOptions}; `limit` / `timeout` / `budget` / `allowance` replace their construction
|
|
1272
1407
|
* defaults for this run only; `signal` composes with the constructed `signal` (both fold into
|
|
1273
1408
|
* the run's bound abort) rather than replacing it. Nothing here mutates the agent — the next
|
|
1274
1409
|
* run reads the construction defaults again.
|
|
@@ -1289,7 +1424,8 @@ export declare interface AgentRunOptions {
|
|
|
1289
1424
|
readonly schema?: Readonly<Record<string, unknown>>;
|
|
1290
1425
|
/**
|
|
1291
1426
|
* Overrides {@link AgentOptions.limit} for this run only — the max tool-iteration turns
|
|
1292
|
-
* before the loop stops
|
|
1427
|
+
* before the loop stops, as a nonnegative safe integer; the call throws an `AgentError` with
|
|
1428
|
+
* code `'LIMIT'` when it is not. Omitted ⇒ the agent's constructed `limit` applies.
|
|
1293
1429
|
*/
|
|
1294
1430
|
readonly limit?: number;
|
|
1295
1431
|
/**
|
|
@@ -1303,6 +1439,11 @@ export declare interface AgentRunOptions {
|
|
|
1303
1439
|
* Omitted ⇒ the agent's constructed `budget` applies.
|
|
1304
1440
|
*/
|
|
1305
1441
|
readonly budget?: BudgetInterface<TokenUsage>;
|
|
1442
|
+
/**
|
|
1443
|
+
* Overrides {@link AgentOptions.allowance} for this run only; started for this run with
|
|
1444
|
+
* `start()`, as the constructed allowance is. Default: the agent's constructed `allowance`.
|
|
1445
|
+
*/
|
|
1446
|
+
readonly allowance?: BudgetInterface<TokenUsage>;
|
|
1306
1447
|
/**
|
|
1307
1448
|
* Carries an additional per-run external cancel, composed with {@link AgentOptions.signal} (both
|
|
1308
1449
|
* fold into the run's bound abort through `AbortSignal.any` — neither is dropped). Omitted ⇒
|
|
@@ -1322,7 +1463,8 @@ export declare interface AgentRunOptions {
|
|
|
1322
1463
|
* a provider call or a selection reported it), `partial` is `true` when a cancel committed the run early or
|
|
1323
1464
|
* when the loop exhausted its `limit` with unresolved tool intent, and `exhausted` is `true`
|
|
1324
1465
|
* in that second case specifically (a distinct, non-cancel cause the {@link AgentEventMap}
|
|
1325
|
-
* `exhaust` event observes)
|
|
1466
|
+
* `exhaust` event observes), and `stop` the {@link AgentStop} of the layer that stopped the run
|
|
1467
|
+
* (`undefined` when none did). It is the settled outcome one run returns, before the agent folds
|
|
1326
1468
|
* it into the {@link AgentResult} resolved by the stream handle's `result` promise.
|
|
1327
1469
|
*/
|
|
1328
1470
|
export declare interface AgentRunResult {
|
|
@@ -1331,6 +1473,7 @@ export declare interface AgentRunResult {
|
|
|
1331
1473
|
readonly usage: TokenUsage | undefined;
|
|
1332
1474
|
readonly partial: boolean;
|
|
1333
1475
|
readonly exhausted: boolean;
|
|
1476
|
+
readonly stop: AgentStop | undefined;
|
|
1334
1477
|
}
|
|
1335
1478
|
|
|
1336
1479
|
/**
|
|
@@ -1340,11 +1483,74 @@ export declare interface AgentRunResult {
|
|
|
1340
1483
|
*/
|
|
1341
1484
|
export declare type AgentStatus = 'idle' | 'running' | 'done' | 'error';
|
|
1342
1485
|
|
|
1486
|
+
/**
|
|
1487
|
+
* Represents why one of a run's three allowed failure layers stopped it — the meter's estimate
|
|
1488
|
+
* allowance, the cost budget, or the model's own token limit — with the readings that layer crossed.
|
|
1489
|
+
*
|
|
1490
|
+
* @remarks
|
|
1491
|
+
* `layer` names the failure point. A `meter` or `budget` stop copies the tripped budget's `id`, its
|
|
1492
|
+
* `max`, and its `consumed` tally at the crossing from the `BudgetError` that aborted the run; a
|
|
1493
|
+
* `meter` stop is a crossing of the run's `allowance`, a `budget` stop any other budget's, including
|
|
1494
|
+
* a budget folded into an external signal or linked as the allowance's own parent signal. A `model`
|
|
1495
|
+
* stop carries the provider instance's trace `id`, not the model's name: the provider reported that
|
|
1496
|
+
* the model ended its answer at its own token limit, and the reason the wire gave is not carried
|
|
1497
|
+
* beyond that. `estimate` is the token estimate of the answer the stopped provider call streamed,
|
|
1498
|
+
* and `usage` the sanitized usage that call reported; each is present only when the stop landed on
|
|
1499
|
+
* a provider call that produced it.
|
|
1500
|
+
*
|
|
1501
|
+
* @example
|
|
1502
|
+
* ```ts
|
|
1503
|
+
* const stop: AgentStop = { layer: 'meter', id: 'meter', max: 2_000, consumed: 2_001, estimate: 2_001 }
|
|
1504
|
+
* ```
|
|
1505
|
+
*/
|
|
1506
|
+
export declare type AgentStop = {
|
|
1507
|
+
readonly layer: 'meter' | 'budget';
|
|
1508
|
+
readonly id: string;
|
|
1509
|
+
readonly max: number;
|
|
1510
|
+
readonly consumed: number;
|
|
1511
|
+
readonly estimate?: number;
|
|
1512
|
+
readonly usage?: TokenUsage;
|
|
1513
|
+
} | {
|
|
1514
|
+
readonly layer: 'model';
|
|
1515
|
+
readonly id: string;
|
|
1516
|
+
readonly estimate?: number;
|
|
1517
|
+
readonly usage?: TokenUsage;
|
|
1518
|
+
};
|
|
1519
|
+
|
|
1343
1520
|
/**
|
|
1344
1521
|
* Names the agent turn's live handle carrying {@link AgentChunk} values and resolving an {@link AgentResult}.
|
|
1345
1522
|
*/
|
|
1346
1523
|
export declare type AgentStreamInterface = StreamInterface<AgentChunk, AgentResult>;
|
|
1347
1524
|
|
|
1525
|
+
/**
|
|
1526
|
+
* Holds what one agent loop turn contributed to its run and how the turn ended — the readonly
|
|
1527
|
+
* record the loop appends for each turn, from which the run derives its {@link AgentRunResult}.
|
|
1528
|
+
*
|
|
1529
|
+
* @remarks
|
|
1530
|
+
* `content` is the final answer on an `answer` turn and the content the provider streamed on any
|
|
1531
|
+
* other turn. `thinking` and `usage` are this turn's own non-empty reasoning and sanitized usage;
|
|
1532
|
+
* `spent` is the sanitized usage of a selection this turn's admission rebuilt through. `messages`
|
|
1533
|
+
* is the working conversation the next turn starts from. `partial` is the run's partial flag if the
|
|
1534
|
+
* run ends after this turn, and `futile` is the compaction latch after this turn's admission.
|
|
1535
|
+
* `estimate` is the token estimate of the content this turn's call streamed, `undefined` on a turn
|
|
1536
|
+
* a cancel stopped before its call. `interrupted` reports that the run's signal had aborted when
|
|
1537
|
+
* this turn's call returned, before its usage was reconciled. `truncated` reports that the model
|
|
1538
|
+
* ended this turn's final answer at its own token limit.
|
|
1539
|
+
*/
|
|
1540
|
+
export declare interface AgentTurn {
|
|
1541
|
+
readonly content: string;
|
|
1542
|
+
readonly thinking: string | undefined;
|
|
1543
|
+
readonly usage: TokenUsage | undefined;
|
|
1544
|
+
readonly spent: TokenUsage | undefined;
|
|
1545
|
+
readonly messages: readonly Message[];
|
|
1546
|
+
readonly ending: 'answer' | 'tools' | 'cancel';
|
|
1547
|
+
readonly partial: boolean;
|
|
1548
|
+
readonly futile: boolean;
|
|
1549
|
+
readonly estimate: number | undefined;
|
|
1550
|
+
readonly interrupted: boolean;
|
|
1551
|
+
readonly truncated: boolean;
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1348
1554
|
/**
|
|
1349
1555
|
* Arms signal propagation to a byte reader and returns the controller that removes the listener.
|
|
1350
1556
|
*
|
|
@@ -1362,22 +1568,23 @@ export declare type AgentStreamInterface = StreamInterface<AgentChunk, AgentResu
|
|
|
1362
1568
|
export declare function armReaderAbort(reader: ReadableStreamDefaultReader<Uint8Array>, signal: AbortSignal | undefined): Promise<AbortController>;
|
|
1363
1569
|
|
|
1364
1570
|
/**
|
|
1365
|
-
* Assembles the settled {@link AgentResult} from a run's {@link AgentRunResult} — `thinking
|
|
1366
|
-
* `usage` are carried only when the run surfaced them, and the loop-internal
|
|
1367
|
-
* left out.
|
|
1571
|
+
* Assembles the settled {@link AgentResult} from a run's {@link AgentRunResult} — `thinking`,
|
|
1572
|
+
* `usage`, and `stop` are carried only when the run surfaced them, and the loop-internal
|
|
1573
|
+
* `exhausted` flag is left out.
|
|
1368
1574
|
*
|
|
1369
1575
|
* @remarks
|
|
1370
1576
|
* Pure and total. An absent optional is omitted rather than stored as `undefined` (the
|
|
1371
1577
|
* present-when-given convention the message store follows), so a settled result JSON
|
|
1372
|
-
* round-trips without an explicit `undefined` field.
|
|
1373
|
-
*
|
|
1578
|
+
* round-trips without an explicit `undefined` field. The keys follow `content`, `partial`,
|
|
1579
|
+
* `thinking`, `usage`, then `stop`. `exhausted` is loop bookkeeping and does not reach the public
|
|
1580
|
+
* result — the `exhaust` event carries it instead.
|
|
1374
1581
|
*
|
|
1375
1582
|
* @param outcome - The run's settled outcome
|
|
1376
1583
|
* @returns The public {@link AgentResult}
|
|
1377
1584
|
*
|
|
1378
1585
|
* @example
|
|
1379
1586
|
* ```ts
|
|
1380
|
-
* assembleResult({ content: 'hi', thinking: undefined, usage: undefined, partial: false, exhausted: false })
|
|
1587
|
+
* assembleResult({ content: 'hi', thinking: undefined, usage: undefined, partial: false, exhausted: false, stop: undefined })
|
|
1381
1588
|
* // { content: 'hi', partial: false }
|
|
1382
1589
|
* ```
|
|
1383
1590
|
*/
|
|
@@ -1385,12 +1592,12 @@ export declare function assembleResult(outcome: AgentRunResult): AgentResult;
|
|
|
1385
1592
|
|
|
1386
1593
|
/**
|
|
1387
1594
|
* Copies a message with image data merged onto its `images` — the message's own images first,
|
|
1388
|
-
* then the attached data,
|
|
1595
|
+
* then the attached data, keeping every other field and never mutating the original.
|
|
1389
1596
|
*
|
|
1390
1597
|
* @remarks
|
|
1391
|
-
* Pure and total: the original message is never mutated.
|
|
1392
|
-
*
|
|
1393
|
-
* convention
|
|
1598
|
+
* Pure and total: the original message is never mutated. Every other field the source message
|
|
1599
|
+
* carries (`calls`, `call`, `thinking`) is kept as given, and an absent one stays absent,
|
|
1600
|
+
* mirroring the store's present-when-given convention.
|
|
1394
1601
|
*
|
|
1395
1602
|
* @param message - The message to copy (left unchanged)
|
|
1396
1603
|
* @param payloads - The base64 image data to attach
|
|
@@ -1414,7 +1621,8 @@ export declare function attachImages(message: Message, payloads: readonly string
|
|
|
1414
1621
|
* Pure and total: the conversation and its messages are never mutated, and the returned array
|
|
1415
1622
|
* replaces exactly the one target message with the copy {@link attachImages} builds. Empty
|
|
1416
1623
|
* data returns the conversation unchanged; a conversation with no user message returns it
|
|
1417
|
-
* unchanged too (there is nowhere to attach, and the images already rode the system block).
|
|
1624
|
+
* unchanged too (there is nowhere to attach, and the images already rode the system block). A hole
|
|
1625
|
+
* in a sparse conversation is not a user message.
|
|
1418
1626
|
*
|
|
1419
1627
|
* @param conversation - The messages to attach into (left unchanged)
|
|
1420
1628
|
* @param payloads - The base64 image data to attach
|
|
@@ -1647,13 +1855,14 @@ export declare function buildProviderHeaders(hook: ProviderOptions['headers'], s
|
|
|
1647
1855
|
* @param thinking - The joined reasoning
|
|
1648
1856
|
* @param tools - The accumulated calls
|
|
1649
1857
|
* @param usage - The reported token usage
|
|
1858
|
+
* @param truncated - Whether the model stopped at its own limit, or undefined when the wire did not report it
|
|
1650
1859
|
* @returns The assembled result
|
|
1651
1860
|
* @example
|
|
1652
1861
|
* ```ts
|
|
1653
|
-
* buildProviderResult('ok', '', [], undefined) // { content: 'ok' }
|
|
1862
|
+
* buildProviderResult('ok', '', [], undefined, undefined) // { content: 'ok' }
|
|
1654
1863
|
* ```
|
|
1655
1864
|
*/
|
|
1656
|
-
export declare function buildProviderResult(content: string, thinking: string, tools: readonly ToolCall[], usage: TokenUsage | undefined): ProviderResult;
|
|
1865
|
+
export declare function buildProviderResult(content: string, thinking: string, tools: readonly ToolCall[], usage: TokenUsage | undefined, truncated: boolean | undefined): ProviderResult;
|
|
1657
1866
|
|
|
1658
1867
|
/**
|
|
1659
1868
|
* Builds the placeholder assistant recall call used to price recall framing.
|
|
@@ -1734,8 +1943,8 @@ export declare function buildRecords(input: LedgerProjectionInput): LedgerProjec
|
|
|
1734
1943
|
*
|
|
1735
1944
|
* @remarks
|
|
1736
1945
|
* Pure and total. This is the unframed form a `sections` cap merge digests when it folds the
|
|
1737
|
-
* oldest sections into one (a summary over their section summaries); the recap label is
|
|
1738
|
-
*
|
|
1946
|
+
* oldest sections into one (a summary over their section summaries); the recap label is absent
|
|
1947
|
+
* from that merge input. A rolling fold instead re-reads the framed recap — see
|
|
1739
1948
|
* {@link buildRecapMessage}.
|
|
1740
1949
|
*
|
|
1741
1950
|
* @param section - The compacted section to render
|
|
@@ -1757,10 +1966,13 @@ export declare function buildSummaryMessage(section: Section): Message;
|
|
|
1757
1966
|
* its `events` are drained.
|
|
1758
1967
|
*
|
|
1759
1968
|
* @remarks
|
|
1760
|
-
*
|
|
1761
|
-
*
|
|
1762
|
-
* re-reads the buffer, and either
|
|
1763
|
-
* (on `fail`)
|
|
1969
|
+
* A waiting `drain` parks its void resolver in `#waiting`; `push` / `close` / `fail`
|
|
1970
|
+
* enqueue/flag, then fire and clear every parked resolver, so each parked reader wakes,
|
|
1971
|
+
* re-reads the shared buffer, and either takes the next chunk, returns (on `close`), throws
|
|
1972
|
+
* (on `fail`), or parks again when another reader took the chunk first. Taking a chunk is
|
|
1973
|
+
* synchronous, so each value reaches exactly one reader.
|
|
1974
|
+
* A `return()` issued while a read is parked waits for the next `push`, `close`, or `fail`.
|
|
1975
|
+
* The parked read takes a pushed value before that `return()` settles.
|
|
1764
1976
|
*
|
|
1765
1977
|
* @example
|
|
1766
1978
|
* ```ts
|
|
@@ -1818,6 +2030,14 @@ export declare interface ChannelInterface<T> {
|
|
|
1818
2030
|
/**
|
|
1819
2031
|
* Reads the values back live, in write order — returning on `close` and throwing on `fail`.
|
|
1820
2032
|
*
|
|
2033
|
+
* @remarks
|
|
2034
|
+
* Concurrent readers share one buffer: each value goes to exactly one reader, and `close` or
|
|
2035
|
+
* `fail` ends every reader, parked or not, after the buffer empties. A `push` after `close` or
|
|
2036
|
+
* `fail` is buffered rather than refused, so a reader still draining or a later `drain` yields
|
|
2037
|
+
* it before reporting the end.
|
|
2038
|
+
* A `return()` issued while a read is parked waits for the next `push`, `close`, or `fail`.
|
|
2039
|
+
* The parked read takes a pushed value before that `return()` settles.
|
|
2040
|
+
*
|
|
1821
2041
|
* @returns A generator yielding each pushed value, returning on `close` and throwing on `fail`
|
|
1822
2042
|
*/
|
|
1823
2043
|
drain(): AsyncGenerator<T, void>;
|
|
@@ -1825,11 +2045,12 @@ export declare interface ChannelInterface<T> {
|
|
|
1825
2045
|
|
|
1826
2046
|
/**
|
|
1827
2047
|
* Consumes a reported usage against a budget over what was already charged, so a turn's total
|
|
1828
|
-
* draw
|
|
2048
|
+
* draw is never less than the report and nothing is charged twice.
|
|
1829
2049
|
*
|
|
1830
2050
|
* @remarks
|
|
1831
2051
|
* The full `prompt` count is consumed because no earlier charge covers it. Each of `completion`
|
|
1832
|
-
* and `total` is consumed less `charged`, floored at 0.
|
|
2052
|
+
* and `total` is consumed less `charged`, floored at 0. An estimate above the report is not
|
|
2053
|
+
* refunded. The usage must already be sanitized: a
|
|
1833
2054
|
* non-finite field yields a non-finite charge, which the installed `Budget` refuses by throwing
|
|
1834
2055
|
* a `range` `ContractError`. Without a budget the call consumes nothing.
|
|
1835
2056
|
*
|
|
@@ -1883,7 +2104,7 @@ export declare class Classifier implements ClassifierInterface {
|
|
|
1883
2104
|
* Asks the judge every question the filing still lacks, in the measured order.
|
|
1884
2105
|
* @param requests - The request ids, which skip category questions and receive only enabled request-topic questions
|
|
1885
2106
|
* @param signal - The caller's signal; an abort returns a fault with completed judgments and usage
|
|
1886
|
-
* @returns The judgment keys and
|
|
2107
|
+
* @returns The judgment keys, summed usage, and one reading per logical question attempt, in asking order; a throw from the assign or entities handler, or a caller abort, returns the partial result with `fault`; a judge rejection under a live signal leaves that question undecided and sets no `fault`
|
|
1887
2108
|
*/
|
|
1888
2109
|
classify(requests: ReadonlySet<string>, signal: AbortSignal): Promise<ClassifierResult>;
|
|
1889
2110
|
/**
|
|
@@ -1930,7 +2151,7 @@ export declare interface ClassifierInterface {
|
|
|
1930
2151
|
*
|
|
1931
2152
|
* @param requests - The request ids, which skip category questions and receive only enabled request-topic questions
|
|
1932
2153
|
* @param signal - The signal that aborts the questions; completed judgments stay recorded
|
|
1933
|
-
* @returns The judgment keys and
|
|
2154
|
+
* @returns The judgment keys, usage spent, and one reading per logical question attempt; a throw from the assign or entities handler, or a caller abort, returns the partial result with `fault`; a judge rejection under a live signal leaves that question undecided and sets no `fault`
|
|
1934
2155
|
*/
|
|
1935
2156
|
classify(requests: ReadonlySet<string>, signal: AbortSignal): Promise<ClassifierResult>;
|
|
1936
2157
|
/**
|
|
@@ -1987,14 +2208,66 @@ export declare interface ClassifierOptions {
|
|
|
1987
2208
|
readonly entities: LedgerEntityHandler;
|
|
1988
2209
|
}
|
|
1989
2210
|
|
|
1990
|
-
/**
|
|
2211
|
+
/**
|
|
2212
|
+
* Names what became of one filing question.
|
|
2213
|
+
*
|
|
2214
|
+
* @remarks
|
|
2215
|
+
* `cached` means the conversation already held a matching judgment, so the classifier did not call the judgment manager.
|
|
2216
|
+
* `skipped` means the classifier held the question after a deterministic failure and did not call the judgment manager.
|
|
2217
|
+
* `resolved` means the judgment manager's resolve call fulfilled. `failed` means it rejected while the caller's signal was live.
|
|
2218
|
+
* `aborted` means it rejected with a `JudgeAbortError` or after the caller's signal aborted.
|
|
2219
|
+
*/
|
|
2220
|
+
export declare type ClassifierOutcome = 'cached' | 'skipped' | 'resolved' | 'failed' | 'aborted';
|
|
2221
|
+
|
|
2222
|
+
/** Names the filing question a classifier asked: a message's category, a message's topic, or an earlier and later message's amendment or supersession. */
|
|
2223
|
+
export declare type ClassifierPhase = 'category' | 'topic' | 'amends' | 'supersedes';
|
|
2224
|
+
|
|
2225
|
+
/**
|
|
2226
|
+
* Carries what became of one filing question: its judgment key, its phase, its outcome, and the time spent resolving it.
|
|
2227
|
+
*
|
|
2228
|
+
* @remarks
|
|
2229
|
+
* `key` is the judgment key the classifier asked or reused. `duration` is the monotonic milliseconds
|
|
2230
|
+
* the classifier waited on the judgment manager's resolve call, present for `resolved`, `failed`, and `aborted`
|
|
2231
|
+
* and absent for `cached` and `skipped`, which make no resolve call. A reading counts one logical
|
|
2232
|
+
* question attempt. It counts neither the physical wire calls a judge made nor a request that joined
|
|
2233
|
+
* another pending request, and a question the caller's signal aborted before its resolve call began
|
|
2234
|
+
* has no reading.
|
|
2235
|
+
*/
|
|
2236
|
+
export declare interface ClassifierReading {
|
|
2237
|
+
readonly key: string;
|
|
2238
|
+
readonly phase: ClassifierPhase;
|
|
2239
|
+
readonly outcome: ClassifierOutcome;
|
|
2240
|
+
readonly duration?: number;
|
|
2241
|
+
}
|
|
2242
|
+
|
|
2243
|
+
/**
|
|
2244
|
+
* Carries the judgment keys one classification rests on and the judge usage it spent.
|
|
2245
|
+
*
|
|
2246
|
+
* @remarks
|
|
2247
|
+
* `readings` lists one {@link ClassifierReading} per logical question attempt, in asking order, including
|
|
2248
|
+
* the attempt a caller abort interrupted. Each result owns its array.
|
|
2249
|
+
*/
|
|
1991
2250
|
export declare interface ClassifierResult {
|
|
1992
2251
|
readonly judgments: readonly string[];
|
|
1993
2252
|
readonly usage?: TokenUsage;
|
|
2253
|
+
readonly readings: readonly ClassifierReading[];
|
|
1994
2254
|
/** Holds the error when an assign or entities handler throw, or a caller abort, interrupts classification; judgments and usage retain the partial result. A judge rejection under a live signal sets no fault. */
|
|
1995
2255
|
readonly fault?: Error;
|
|
1996
2256
|
}
|
|
1997
2257
|
|
|
2258
|
+
/**
|
|
2259
|
+
* Carries the optional cause and context an error class with a machine-readable `code` takes at
|
|
2260
|
+
* construction.
|
|
2261
|
+
*
|
|
2262
|
+
* @remarks
|
|
2263
|
+
* `cause` holds the underlying failure. `context` holds the values that locate the failure, such
|
|
2264
|
+
* as the category and name of a missing entry.
|
|
2265
|
+
*/
|
|
2266
|
+
export declare interface CodedErrorOptions {
|
|
2267
|
+
readonly cause?: unknown;
|
|
2268
|
+
readonly context?: Readonly<Record<string, unknown>>;
|
|
2269
|
+
}
|
|
2270
|
+
|
|
1998
2271
|
/**
|
|
1999
2272
|
* Collects whole exchanges, joining every exchange spanned by a tool group.
|
|
2000
2273
|
*
|
|
@@ -2041,7 +2314,8 @@ export declare function collectImageData(files: readonly FileInterface[]): reado
|
|
|
2041
2314
|
* A message is live when it is a user message, or a tool message whose reading is the last reading of its
|
|
2042
2315
|
* call, and the input neither excludes it nor files it quiet or replaced. A reading replaces any
|
|
2043
2316
|
* earlier reading of the same call, an empty one included, so an empty lookup leaves the earlier
|
|
2044
|
-
* result out of every record.
|
|
2317
|
+
* result out of every record. A reading with no canonical identity stays live as its own source
|
|
2318
|
+
* and participates in no replacement.
|
|
2045
2319
|
*
|
|
2046
2320
|
* @param input - The messages, readings, and classification to read
|
|
2047
2321
|
* @returns The live message ids
|
|
@@ -2157,13 +2431,21 @@ export declare function collectToolGroups(messages: readonly Message[]): Readonl
|
|
|
2157
2431
|
* `DEFAULT_CONVERSATION_KEEP`). `sections` overrides the configured `sections` cap of the
|
|
2158
2432
|
* conversation for this compaction only — after the folded section is appended, an overflow past
|
|
2159
2433
|
* `sections` folds the oldest sections into one merged section. Default: the cap of the
|
|
2160
|
-
* conversation (or no cap).
|
|
2434
|
+
* conversation (or no cap). `keep` must be a nonnegative safe integer; any other value throws a
|
|
2435
|
+
* {@link import('./errors.js').ConversationError} with code `'KEEP'`. A `sections` cap on a
|
|
2436
|
+
* rolling conversation throws code `'SECTIONS'`. `signal` cancels this
|
|
2437
|
+
* compaction: an already-aborted signal rejects with its reason before the summarizer is called,
|
|
2438
|
+
* the signal is passed to the {@link ConversationSummaryHandler}, and an abort while the
|
|
2439
|
+
* summarizer runs rejects with the reason at once and commits nothing after the abort. A fold
|
|
2440
|
+
* committed before an aborted overflow merge stays. Default: no signal.
|
|
2161
2441
|
*/
|
|
2162
2442
|
export declare interface CompactOptions {
|
|
2163
2443
|
/** Overrides the retained-tail size for this compaction. Default: the `keep` of the conversation. */
|
|
2164
2444
|
readonly keep?: number;
|
|
2165
2445
|
/** Overrides the `sections` cap for this compaction. Default: the cap of the conversation (or no cap). */
|
|
2166
2446
|
readonly sections?: number;
|
|
2447
|
+
/** Cancels this compaction and is passed to the summarizer. Default: no signal. */
|
|
2448
|
+
readonly signal?: AbortSignal;
|
|
2167
2449
|
}
|
|
2168
2450
|
|
|
2169
2451
|
/**
|
|
@@ -2278,7 +2560,14 @@ export declare interface ContextSectionFormat<T> {
|
|
|
2278
2560
|
* exchanges. A cut inside an assistant call group, which only a group spanning two exchanges
|
|
2279
2561
|
* allows, moves before the group, so a tool result never stays live without its call. Returns
|
|
2280
2562
|
* the section, or `undefined` when nothing folds. A {@link ConversationError} is thrown when no
|
|
2281
|
-
* `#summarize` was supplied.
|
|
2563
|
+
* `#summarize` was supplied. Calls run one at a time, a fold commits only when its messages are
|
|
2564
|
+
* still the live entries after the summarizer settles, and `options.signal` rejects the call
|
|
2565
|
+
* with its reason at once and commits nothing after the abort.
|
|
2566
|
+
* - **Rolling.** With `rolling`, a fold makes one summarizer call over the framed recaps of all
|
|
2567
|
+
* prior sections then the slice, and replaces those sections with one that retains their
|
|
2568
|
+
* originals then the slice. It emits `compact` once and never `collapse`, commits nothing when
|
|
2569
|
+
* the call throws, aborts, or the slice or prior sections changed, and cannot combine with a
|
|
2570
|
+
* `sections` cap (`'SECTIONS'`).
|
|
2282
2571
|
* - **`rehydrate(id)` / `search(query)`.** `rehydrate` returns the full original messages of a
|
|
2283
2572
|
* known section and emits its `id` through `rehydrate`, even when the list is empty. An unknown
|
|
2284
2573
|
* id returns `undefined` without an event. The read never reinserts messages. `search` is a case-insensitive
|
|
@@ -2344,9 +2633,10 @@ export declare const CONVERSATION_RECAP_PREFIX = "[Summary of earlier messages]
|
|
|
2344
2633
|
|
|
2345
2634
|
/**
|
|
2346
2635
|
* Reports a conversation with no {@link ConversationSummaryHandler} to fold its messages with, a
|
|
2347
|
-
* `sections` cap below `1`,
|
|
2348
|
-
* `compact()` method of a
|
|
2349
|
-
*
|
|
2636
|
+
* `sections` cap below `1`, a `keep` that is not a nonnegative safe integer, or a judgment or
|
|
2637
|
+
* judge request that JSON cannot carry — thrown by the `compact()` method of a
|
|
2638
|
+
* {@link ConversationInterface}, its construction, or its judgment store, carrying the
|
|
2639
|
+
* machine-readable `code` `'SUMMARIZER' | 'SECTIONS' | 'JUDGMENT' | 'KEEP'`.
|
|
2350
2640
|
*
|
|
2351
2641
|
* @remarks
|
|
2352
2642
|
* Compaction requires a summarizer (it digests the folded slice into a section summary); a
|
|
@@ -2354,18 +2644,40 @@ export declare const CONVERSATION_RECAP_PREFIX = "[Summary of earlier messages]
|
|
|
2354
2644
|
* is a programmer error and throws this with `'SUMMARIZER'`.
|
|
2355
2645
|
* A `sections` cap (on {@link import('./types.js').ConversationOptions} /
|
|
2356
2646
|
* {@link import('./types.js').ConversationManagerOptions} /
|
|
2357
|
-
* {@link import('./types.js').CompactOptions}) must be `>= 1
|
|
2358
|
-
* error and throws this with `'SECTIONS'`. A
|
|
2359
|
-
*
|
|
2360
|
-
*
|
|
2361
|
-
*
|
|
2647
|
+
* {@link import('./types.js').CompactOptions}) must be `>= 1`, and cannot combine with
|
|
2648
|
+
* `rolling` — either is a programmer error and throws this with `'SECTIONS'`. A `keep` on the same options must be a nonnegative
|
|
2649
|
+
* safe integer — any other value is a programmer error and throws this with `'KEEP'`. A judgment
|
|
2650
|
+
* record or a judge request that JSON cannot carry, or whose copy fails its guard, is a
|
|
2651
|
+
* programmer error and throws this with `'JUDGMENT'`, its `context` naming the `question` id
|
|
2652
|
+
* where one exists. Narrow a caught value with {@link isConversationError} and branch on
|
|
2653
|
+
* `error.code`.
|
|
2362
2654
|
*/
|
|
2363
2655
|
export declare class ConversationError extends Error {
|
|
2364
|
-
/** Names the machine-readable condition — `'SUMMARIZER'`: a `compact()` with no summarizer; `'SECTIONS'`: a sub-1 `sections` cap
|
|
2365
|
-
readonly code:
|
|
2366
|
-
|
|
2656
|
+
/** Names the machine-readable condition — `'SUMMARIZER'`: a `compact()` with no summarizer; `'SECTIONS'`: a sub-1 `sections` cap, or a cap combined with `rolling`; `'JUDGMENT'`: a judgment or judge request that is not JSON; `'KEEP'`: a `keep` that is not a nonnegative safe integer. */
|
|
2657
|
+
readonly code: ConversationErrorCode;
|
|
2658
|
+
/** Holds the values that locate the failure, such as the `question` id of a malformed question, or `undefined` when none were supplied. */
|
|
2659
|
+
readonly context: Readonly<Record<string, unknown>> | undefined;
|
|
2660
|
+
/**
|
|
2661
|
+
* Creates the error with its code, message, and optional cause and context.
|
|
2662
|
+
*
|
|
2663
|
+
* @param code - The machine-readable {@link ConversationErrorCode}
|
|
2664
|
+
* @param message - The human-readable description
|
|
2665
|
+
* @param options - The optional {@link CodedErrorOptions}; `cause` reaches `Error.cause` only when present
|
|
2666
|
+
*/
|
|
2667
|
+
constructor(code: ConversationErrorCode, message: string, options?: CodedErrorOptions);
|
|
2367
2668
|
}
|
|
2368
2669
|
|
|
2670
|
+
/**
|
|
2671
|
+
* Names the machine-readable condition a {@link import('./errors.js').ConversationError} reports.
|
|
2672
|
+
*
|
|
2673
|
+
* @remarks
|
|
2674
|
+
* `'SUMMARIZER'`: a `compact()` with no summarizer. `'SECTIONS'`: a `sections` cap below `1`, or
|
|
2675
|
+
* any `sections` cap combined with `rolling`.
|
|
2676
|
+
* `'JUDGMENT'`: a judgment or judge request that JSON cannot carry, or whose copy fails its guard.
|
|
2677
|
+
* `'KEEP'`: a `keep` that is not a nonnegative safe integer.
|
|
2678
|
+
*/
|
|
2679
|
+
export declare type ConversationErrorCode = 'SUMMARIZER' | 'SECTIONS' | 'JUDGMENT' | 'KEEP';
|
|
2680
|
+
|
|
2369
2681
|
/**
|
|
2370
2682
|
* Maps the push observation surface of a {@link ConversationInterface} — the compaction
|
|
2371
2683
|
* moments a fire-and-forget observer subscribes to through `conversation.emitter.on`.
|
|
@@ -2395,15 +2707,18 @@ export declare type ConversationEventMap = {
|
|
|
2395
2707
|
/**
|
|
2396
2708
|
* Carries the data to author a {@link ConversationInterface} through a {@link
|
|
2397
2709
|
* ConversationManagerInterface} — the optional `id`, a `summarize` override, a `keep` override, a
|
|
2398
|
-
* `sections` cap override, the reserved `on` hooks, and a
|
|
2399
|
-
* from.
|
|
2710
|
+
* `sections` cap override, the `rolling` switch, the reserved `on` hooks, and a
|
|
2711
|
+
* {@link ConversationSnapshot} to hydrate from.
|
|
2400
2712
|
*
|
|
2401
2713
|
* @remarks
|
|
2402
2714
|
* `id` is the identity of the conversation. Default: a minted id. `summarize` overrides the
|
|
2403
2715
|
* default {@link ConversationSummaryHandler} of the manager for this conversation. Default: the
|
|
2404
2716
|
* manager default. `keep` overrides the default retained-tail size of the manager. `sections`
|
|
2405
|
-
* overrides the default `sections` cap of the manager. `
|
|
2406
|
-
*
|
|
2717
|
+
* overrides the default `sections` cap of the manager. `rolling` switches on rolling folds; a
|
|
2718
|
+
* manager `sections` default it would inherit throws `'SECTIONS'`. `on` is the reserved listener key
|
|
2719
|
+
* (initial {@link ConversationEventMap} listeners). `error` is the listener-error handler of the
|
|
2720
|
+
* conversation's emitter, so a throwing `on` listener reports there. Default: the emitter's own
|
|
2721
|
+
* handler. `snapshot` is the construction-time hydration
|
|
2407
2722
|
* seam — a {@link ConversationSnapshot} whose `id` / `sections` / live tail are restored into the
|
|
2408
2723
|
* conversation (the live `summarize` / `keep` / `on` re-supplied alongside it), the conversation
|
|
2409
2724
|
* analogue of the `seed` option of {@link import('@orkestrel/workspace').WorkspaceOptions},
|
|
@@ -2420,7 +2735,11 @@ export declare interface ConversationInput {
|
|
|
2420
2735
|
readonly keep?: number;
|
|
2421
2736
|
/** Overrides the default `sections` cap of the manager for this conversation. */
|
|
2422
2737
|
readonly sections?: number;
|
|
2738
|
+
/** Rolls every fold of this conversation into one section, passed on as {@link ConversationOptions.rolling}. Default: `false`; the manager holds no default. */
|
|
2739
|
+
readonly rolling?: boolean;
|
|
2423
2740
|
readonly on?: EmitterHooks<ConversationEventMap>;
|
|
2741
|
+
/** Holds the listener-error handler of the conversation's emitter — a listener throw routes here, not to a domain event. */
|
|
2742
|
+
readonly error?: EmitterErrorHandler;
|
|
2424
2743
|
/** Hydrates from a {@link ConversationSnapshot}, passed on as {@link ConversationOptions.snapshot}. */
|
|
2425
2744
|
readonly snapshot?: ConversationSnapshot;
|
|
2426
2745
|
}
|
|
@@ -2455,10 +2774,11 @@ export declare interface ConversationInput {
|
|
|
2455
2774
|
* thrown when no `summarize` was supplied.
|
|
2456
2775
|
* - **`summarizable` — whether a `compact()` can fold.** `true` when a
|
|
2457
2776
|
* {@link ConversationSummaryHandler} was supplied, `false` otherwise. The automatic compaction
|
|
2458
|
-
* of the agent loop (`AgentOptions.window`) gates on it so a conversation that has no
|
|
2777
|
+
* of the agent loop (`AgentOptions.window`) gates its fold on it so a conversation that has no
|
|
2459
2778
|
* summarizer is never auto-compacted (and the loop never throws the `compact()` `SUMMARIZER`
|
|
2460
|
-
* error from the auto path)
|
|
2461
|
-
*
|
|
2779
|
+
* error from the auto path); the loop still measures its requests against the window, and a
|
|
2780
|
+
* strict agent refuses one that is over. A manual `compact()` still throws without a summarizer
|
|
2781
|
+
* — only the auto path is guarded.
|
|
2462
2782
|
* - **`rehydrate(id)` / `search(query)` — read the retained originals.** `rehydrate` returns
|
|
2463
2783
|
* the full original messages of a known section and emits its `id` through `rehydrate`, even
|
|
2464
2784
|
* when the list is empty. An unknown id returns `undefined` without an event. The read never
|
|
@@ -2483,9 +2803,10 @@ export declare interface ConversationInterface {
|
|
|
2483
2803
|
readonly sections: readonly Section[];
|
|
2484
2804
|
/**
|
|
2485
2805
|
* Reports whether a `compact()` can fold — `true` when a {@link ConversationSummaryHandler} was supplied.
|
|
2486
|
-
* The automatic compaction of the agent loop (`AgentOptions.window`) gates on it (a
|
|
2806
|
+
* The automatic compaction of the agent loop (`AgentOptions.window`) gates its fold on it (a
|
|
2487
2807
|
* non-summarizable conversation is never auto-compacted, so the auto path never throws the
|
|
2488
|
-
* `SUMMARIZER` error); a manual `compact()` still throws
|
|
2808
|
+
* `SUMMARIZER` error, though its requests are still measured); a manual `compact()` still throws
|
|
2809
|
+
* without a summarizer.
|
|
2489
2810
|
*/
|
|
2490
2811
|
readonly summarizable: boolean;
|
|
2491
2812
|
/** Counts the live (uncompacted) messages stored in the tail. */
|
|
@@ -2549,16 +2870,46 @@ export declare interface ConversationInterface {
|
|
|
2549
2870
|
* a group moves before its assistant message, then back to whole exchanges again. Only a group
|
|
2550
2871
|
* that spans two exchanges reaches that rule.
|
|
2551
2872
|
*
|
|
2873
|
+
* A rolling conversation makes one summarizer call per fold, over the framed recaps of every
|
|
2874
|
+
* prior section followed by the slice with thinking stripped; the originals behind the recaps
|
|
2875
|
+
* are not sent. After the call settles, the slice and the prior sections must be unchanged; the
|
|
2876
|
+
* prior sections are then replaced atomically by one section retaining their originals in order
|
|
2877
|
+
* and then the slice, and the slice leaves the live tail. It emits `compact` once and never
|
|
2878
|
+
* `collapse`. A throw, an abort, or a changed input commits nothing. A fold with no eligible
|
|
2879
|
+
* slice makes no call. A `sections` cap, configured or supplied here, throws `'SECTIONS'`.
|
|
2880
|
+
*
|
|
2552
2881
|
* When a `sections` cap is set and the fold pushes the section count over it, an overflow
|
|
2553
2882
|
* merge step folds the oldest sections into one. If the `summarize` call of that merge throws,
|
|
2554
2883
|
* the merge is skipped (sections transiently sit at `cap + 1`, no loss), no `compact` is
|
|
2555
2884
|
* emitted, and the error propagates; the next successful `compact()` merges the section count
|
|
2556
2885
|
* back to `cap`.
|
|
2557
2886
|
*
|
|
2558
|
-
*
|
|
2559
|
-
*
|
|
2560
|
-
*
|
|
2561
|
-
* sections
|
|
2887
|
+
* Calls run one at a time: a call made while another is in flight waits for it, then computes
|
|
2888
|
+
* its own fold from the live tail it finds. A fold commits only when every folded message is
|
|
2889
|
+
* still the same live entry after the summarizer settles, and a merge commits only when the
|
|
2890
|
+
* folded sections are still the oldest; otherwise the call resolves `undefined` and emits
|
|
2891
|
+
* nothing, so a `remove` or `clear` during the summarizer leaves no section.
|
|
2892
|
+
*
|
|
2893
|
+
* A summarizer must not call `compact` on the conversation it serves. A call that finds no fold in
|
|
2894
|
+
* flight calls its summarizer before its own fold counts as in flight, so that summarizer's own
|
|
2895
|
+
* `compact` finds nothing to wait for and summarizes the same slice again; the commit check above
|
|
2896
|
+
* keeps one section, because the later fold finds its slice already folded and resolves
|
|
2897
|
+
* `undefined`. A call queued behind an earlier fold counts as in flight before its summarizer
|
|
2898
|
+
* runs, so its summarizer's own `compact` waits for the fold that called it.
|
|
2899
|
+
*
|
|
2900
|
+
* `options.signal` cancels the call. An already-aborted signal rejects with its reason before
|
|
2901
|
+
* the summarizer is called. An abort while waiting for an earlier call or while the summarizer
|
|
2902
|
+
* runs rejects with the reason at once, even when the summarizer ignores the signal, and the
|
|
2903
|
+
* call commits nothing afterwards; a fold committed before an aborted merge stays, as when the
|
|
2904
|
+
* merge throws.
|
|
2905
|
+
*
|
|
2906
|
+
* @param options - Optional {@link CompactOptions} (`keep`, `sections`, `signal`)
|
|
2907
|
+
* @returns The folded {@link Section}, or `undefined` when nothing folded or the folded
|
|
2908
|
+
* messages or sections changed while the summarizer ran
|
|
2909
|
+
* @throws ConversationError Thrown when no summarizer was supplied (code `'SUMMARIZER'`), when the
|
|
2910
|
+
* effective sections cap does not satisfy `>= 1` or combines with `rolling` (code `'SECTIONS'`,
|
|
2911
|
+
* including `NaN`), or when
|
|
2912
|
+
* the effective `keep` is not a nonnegative safe integer (code `'KEEP'`)
|
|
2562
2913
|
*/
|
|
2563
2914
|
compact(options?: CompactOptions): Promise<Section | undefined>;
|
|
2564
2915
|
/**
|
|
@@ -2750,7 +3101,11 @@ export declare interface ConversationManagerInterface {
|
|
|
2750
3101
|
* into a fresh {@link ConversationInterface} through the `snapshot` option
|
|
2751
3102
|
* (`add({ snapshot, ... })`, flowing the default `summarize` / `keep` of the manager in),
|
|
2752
3103
|
* which registers and activates it, and it is returned.
|
|
2753
|
-
* -
|
|
3104
|
+
* - A conversation registered under `id` while the store read was pending wins: it is
|
|
3105
|
+
* activated and returned, and the stored snapshot is discarded. So a concurrent `add({ id })`
|
|
3106
|
+
* keeps its turns, and concurrent `open(id)` calls return the one registered instance.
|
|
3107
|
+
* - Else (no store, a store miss, or a stored snapshot whose `id` is not `id`) ⇒ `undefined`
|
|
3108
|
+
* (lenient — no throw).
|
|
2754
3109
|
*
|
|
2755
3110
|
* @param id - The conversation id to open
|
|
2756
3111
|
* @returns The activated {@link ConversationInterface}, or `undefined` when neither registered nor stored
|
|
@@ -2759,12 +3114,12 @@ export declare interface ConversationManagerInterface {
|
|
|
2759
3114
|
/**
|
|
2760
3115
|
* Persists a registered conversation's {@link ConversationInterface.snapshot} to the optional
|
|
2761
3116
|
* {@link ConversationStoreInterface} (`store`) — `true` when persisted, `false` when there is
|
|
2762
|
-
* no store or the id is unknown
|
|
3117
|
+
* no store or the id is unknown; a store failure propagates.
|
|
2763
3118
|
*
|
|
2764
3119
|
* @remarks
|
|
2765
3120
|
* Lenient: when a `store` is set and `id` is registered, `store.set(conversation.snapshot())` is
|
|
2766
3121
|
* awaited and `true` is returned; otherwise (no store, or an unknown id) it is a no-op returning
|
|
2767
|
-
* `false
|
|
3122
|
+
* `false`. A failure from `store.set` propagates.
|
|
2768
3123
|
*
|
|
2769
3124
|
* @param id - The id of the registered conversation to persist
|
|
2770
3125
|
* @returns True if the snapshot was persisted; false otherwise (no store, or an unknown id)
|
|
@@ -2792,7 +3147,8 @@ export declare interface ConversationManagerInterface {
|
|
|
2792
3147
|
* `summarize` is the default summarizer flowed into every conversation the manager creates
|
|
2793
3148
|
* (a per-`add` {@link ConversationInput.summarize} overrides it); a conversation created
|
|
2794
3149
|
* with neither cannot `compact` (it throws a `ConversationError`). `keep` is the default
|
|
2795
|
-
* retained-tail size (a per-`add` {@link ConversationInput.keep} overrides it)
|
|
3150
|
+
* retained-tail size (a per-`add` {@link ConversationInput.keep} overrides it); it must be a
|
|
3151
|
+
* nonnegative safe integer, else construction throws a `ConversationError` with code `'KEEP'`. Default:
|
|
2796
3152
|
* {@link import('./constants.js').DEFAULT_CONVERSATION_KEEP}. `sections` is the default cap
|
|
2797
3153
|
* on the compacted `sections` list of a created conversation (a per-`add`
|
|
2798
3154
|
* {@link ConversationInput.sections} overrides it). Default: no cap.
|
|
@@ -2826,13 +3182,18 @@ export declare interface ConversationManagerOptions {
|
|
|
2826
3182
|
* {@link ConversationSummaryHandler} compaction needs — without it `compact()` throws a
|
|
2827
3183
|
* {@link import('./errors.js').ConversationError} (a conversation can still store + view a
|
|
2828
3184
|
* live tail; it cannot fold). `keep` is how many recent live messages a `compact()`
|
|
2829
|
-
* retains verbatim (folding only the older ones)
|
|
2830
|
-
* {@link import('./
|
|
3185
|
+
* retains verbatim (folding only the older ones); it must be a nonnegative safe integer, else
|
|
3186
|
+
* construction throws a {@link import('./errors.js').ConversationError} with code `'KEEP'`.
|
|
3187
|
+
* Default: {@link import('./constants.js').DEFAULT_CONVERSATION_KEEP} (`0` — a manual `compact()`
|
|
2831
3188
|
* folds every exchange before the newest user message into one section). `sections` is an
|
|
2832
3189
|
* optional cap on the compacted `sections` list — when set (`>= 1`), a `compact()` that would
|
|
2833
3190
|
* leave more than `sections` entries folds the oldest overflow into one merged section,
|
|
2834
3191
|
* emitting `collapse`. A successful capped merge retains at most `Math.ceil(sections)` entries;
|
|
2835
|
-
* fractions and positive infinity are accepted. Default: no cap.
|
|
3192
|
+
* fractions and positive infinity are accepted. Default: no cap. `rolling` makes each `compact()`
|
|
3193
|
+
* one summarizer call over the framed recaps of every prior section then the slice, replacing all
|
|
3194
|
+
* prior sections with one that retains their originals then the slice, with one `compact` event
|
|
3195
|
+
* and no `collapse`; it cannot combine with `sections`, which throws a `ConversationError` with
|
|
3196
|
+
* code `'SECTIONS'`. Default: `false`.
|
|
2836
3197
|
* `snapshot` is the hydration seam — a {@link ConversationSnapshot} whose `id`, compacted
|
|
2837
3198
|
* `sections`, and live tail are restored into the conversation, with the live `summarize` /
|
|
2838
3199
|
* `keep` / `on` supplied alongside it (a summarizer is a function, not serialized data).
|
|
@@ -2851,6 +3212,13 @@ export declare interface ConversationOptions {
|
|
|
2851
3212
|
readonly keep?: number;
|
|
2852
3213
|
/** Caps the compacted `sections` list (`>= 1`); overflow folds into one merged section. Default: no cap. */
|
|
2853
3214
|
readonly sections?: number;
|
|
3215
|
+
/**
|
|
3216
|
+
* Rolls every fold into one section: the summarizer digests the framed recaps of all prior
|
|
3217
|
+
* sections followed by the slice, and one section retaining their originals then the slice
|
|
3218
|
+
* replaces them. Combining it with a `sections` cap throws a `ConversationError` (`'SECTIONS'`).
|
|
3219
|
+
* Default: `false`.
|
|
3220
|
+
*/
|
|
3221
|
+
readonly rolling?: boolean;
|
|
2854
3222
|
/** Hydrates from a {@link ConversationSnapshot} — its `id` wins over `id`; restoring is silent. */
|
|
2855
3223
|
readonly snapshot?: ConversationSnapshot;
|
|
2856
3224
|
}
|
|
@@ -2995,10 +3363,16 @@ export declare interface ConversationStoreInterface {
|
|
|
2995
3363
|
* The core conversation layer treats it as an opaque async function — it never reads which
|
|
2996
3364
|
* backend produced the digest, keeping `core` free of any provider coupling.
|
|
2997
3365
|
*
|
|
3366
|
+
* `signal` is the {@link CompactOptions.signal} of the `compact()` call the fold serves, or
|
|
3367
|
+
* `undefined` when that call supplied none. A summarizer must stop its work when it aborts. One
|
|
3368
|
+
* that ignores it still cannot hold the caller: `compact()` races the summarizer against the
|
|
3369
|
+
* signal, rejects with the abort reason, and discards a digest that arrives later.
|
|
3370
|
+
*
|
|
2998
3371
|
* @param messages - The folded messages to digest into a summary
|
|
3372
|
+
* @param signal - The cancellation signal of the `compact()` call, or `undefined` when it supplied none
|
|
2999
3373
|
* @returns The summary text (the model-written digest of those messages)
|
|
3000
3374
|
*/
|
|
3001
|
-
export declare type ConversationSummaryHandler = (messages: readonly Message[]) => Promise<string>;
|
|
3375
|
+
export declare type ConversationSummaryHandler = (messages: readonly Message[], signal?: AbortSignal) => Promise<string>;
|
|
3002
3376
|
|
|
3003
3377
|
/**
|
|
3004
3378
|
* Owns a value by serializing it to JSON and parsing the text, so the copy shares nothing with its source.
|
|
@@ -3025,9 +3399,9 @@ export declare function copyJSON(value: unknown): unknown;
|
|
|
3025
3399
|
* `generate` and a live `stream`.
|
|
3026
3400
|
*
|
|
3027
3401
|
* @remarks
|
|
3028
|
-
* One private loop drives the turn; `generate`
|
|
3029
|
-
* exposes, so they can never diverge. Each turn is bounded by one cancel folded from
|
|
3030
|
-
* `signal` + `timeout` + `budget` (through `AbortSignal.any`) — any trip (or `abort()`)
|
|
3402
|
+
* One private loop drives the turn; `generate` awaits the settled result of the same run
|
|
3403
|
+
* `stream` exposes and leaves its live chunks undrained, so they can never diverge. Each turn is bounded by one cancel folded from
|
|
3404
|
+
* `signal` + `timeout` + `budget` + `allowance` (through `AbortSignal.any`) — any trip (or `abort()`)
|
|
3031
3405
|
* commits a partial result (the stream's `result` resolves on a cancel, rejects only
|
|
3032
3406
|
* on a genuine provider / tool error). The `scheduler` paces between turns; tool
|
|
3033
3407
|
* iteration is capped at `limit`. Default: `DEFAULT_AGENT_LIMIT`. Tools are advertised
|
|
@@ -3072,15 +3446,18 @@ export declare function createAgent(provider: ProviderInterface, options?: Agent
|
|
|
3072
3446
|
* `system` is the optional system prompt; `tools` / `instructions` / `workspaces` are pre-built
|
|
3073
3447
|
* managers to reuse (empty ones are created when omitted, so `context.workspaces` is always
|
|
3074
3448
|
* present); `scope` is the initial active filter (`undefined` ⇒ no filtering, changeable afterwards
|
|
3075
|
-
* through `context.apply(...)`).
|
|
3076
|
-
*
|
|
3077
|
-
*
|
|
3078
|
-
*
|
|
3079
|
-
*
|
|
3449
|
+
* through `context.apply(...)`). `conversations` is the message source: a supplied manager's
|
|
3450
|
+
* active conversation is reused as `messages`, and a default conversation is added only when it
|
|
3451
|
+
* has none (a fresh registry with one default conversation is created when omitted). `build()`
|
|
3452
|
+
* folds the scoped instructions — plus the active workspace's scope-filtered text files (fenced) —
|
|
3453
|
+
* into one leading `system` message and appends the active conversation's `view()` (attaching the
|
|
3454
|
+
* active workspace's scope-filtered image files' `base64` payload to the last user message), built
|
|
3455
|
+
* fresh each call; the scope never filters the conversation. The active workspace is the sole
|
|
3456
|
+
* document/image context. Tools are advertised structurally (through
|
|
3080
3457
|
* `tools.definitions()`, scope-filtered by the loop), never serialized into the prompt.
|
|
3081
3458
|
*
|
|
3082
|
-
* @param options - Optional `system` / `tools` / `instructions` / `workspaces` /
|
|
3083
|
-
* (see {@link AgentContextOptions})
|
|
3459
|
+
* @param options - Optional `system` / `tools` / `instructions` / `workspaces` /
|
|
3460
|
+
* `conversations` / `scope` / `select` (see {@link AgentContextOptions})
|
|
3084
3461
|
* @returns A working {@link AgentContextInterface}
|
|
3085
3462
|
*
|
|
3086
3463
|
* @example
|
|
@@ -3107,9 +3484,10 @@ export declare function createAgentContext(options?: AgentContextOptions): Agent
|
|
|
3107
3484
|
* through `store` (+ `restore()` after a crash) are all the backing Queue's. `enqueue`
|
|
3108
3485
|
* returns a per-job promise.
|
|
3109
3486
|
* - **Durable + serializable.** Because `AgentJobInput` is JSON-serializable, a `store`
|
|
3110
|
-
*
|
|
3111
|
-
*
|
|
3112
|
-
*
|
|
3487
|
+
* persists outstanding jobs; `restore()` re-enqueues them and the `registry` rehydrates the
|
|
3488
|
+
* live pieces from the names. A job survives a crash only through a store whose rows outlive
|
|
3489
|
+
* the process (for example `createDatabaseQueueStore`); a `createMemoryQueueStore` row is
|
|
3490
|
+
* gone when the process exits.
|
|
3113
3491
|
* - **Partial policy.** A partial result throws an
|
|
3114
3492
|
* {@link import('./errors.js').AgentJobError} by default, so a job cancelled by its
|
|
3115
3493
|
* attempt deadline / a queue abort retries while attempts remain; `partial: true`
|
|
@@ -3124,11 +3502,13 @@ export declare function createAgentContext(options?: AgentContextOptions): Agent
|
|
|
3124
3502
|
*
|
|
3125
3503
|
* @example
|
|
3126
3504
|
* ```ts
|
|
3505
|
+
* import type { AgentJobInput, ProviderInterface } from '@orkestrel/agent'
|
|
3506
|
+
* import type { QueueStoreInterface } from '@orkestrel/queue'
|
|
3127
3507
|
* import { createAgentQueue, createAgentRegistry } from '@orkestrel/agent'
|
|
3128
|
-
* import { createMemoryQueueStore } from '@orkestrel/queue'
|
|
3129
3508
|
*
|
|
3509
|
+
* declare const provider: ProviderInterface // any concrete implementation supplied by the host app
|
|
3510
|
+
* declare const store: QueueStoreInterface<AgentJobInput> // a durable store the host supplies
|
|
3130
3511
|
* const registry = createAgentRegistry({ providers: { main: provider } })
|
|
3131
|
-
* const store = createMemoryQueueStore(agentJobShape) // survives a restart through restore()
|
|
3132
3512
|
* const queue = createAgentQueue({ registry, concurrency: 2, retries: 1, store })
|
|
3133
3513
|
* const result = await queue.enqueue({ provider: 'main', messages: [{ role: 'user', content: 'ok?' }] })
|
|
3134
3514
|
* ```
|
|
@@ -3179,7 +3559,9 @@ export declare function createAgentRegistry(options: AgentRegistryOptions): Agen
|
|
|
3179
3559
|
* the handler adds only rehydration + the partial policy.
|
|
3180
3560
|
* - **Sub-agent fan-out.** Each unit's handler receives a `ControllerInterface` whose
|
|
3181
3561
|
* `spawn(childJob)` launches a child agent job through the same bounded queue (the
|
|
3182
|
-
* child's result joins the run after the declared units, in spawn order).
|
|
3562
|
+
* child's result joins the run after the declared units, in spawn order). A unit spawns its
|
|
3563
|
+
* declared `children` on its first attempt only, so a retried parent never runs a child
|
|
3564
|
+
* twice. On a bounded
|
|
3183
3565
|
* runner, fan out and return — do not await a spawn inline from within the handler (a
|
|
3184
3566
|
* slot-holding handler awaiting its own spawn can deadlock; see `ControllerInterface`).
|
|
3185
3567
|
* - **Partial policy + cancellation.** Same as `createAgentQueue`: a partial result
|
|
@@ -3294,14 +3676,14 @@ export declare function createChannel<T>(): ChannelInterface<T>;
|
|
|
3294
3676
|
* // Append the instruction as the FINAL user turn: a chat model emits nothing when the prompt
|
|
3295
3677
|
* // ends on an assistant turn, so a leading-system instruction is unreliable.
|
|
3296
3678
|
* const conversation = createConversation({
|
|
3297
|
-
* summarize: async (messages) =>
|
|
3679
|
+
* summarize: async (messages, signal) =>
|
|
3298
3680
|
* (
|
|
3299
3681
|
* await provider.generate(
|
|
3300
3682
|
* [
|
|
3301
3683
|
* ...messages,
|
|
3302
3684
|
* { id: 's', role: 'user', content: 'Summarize the conversation so far concisely.' },
|
|
3303
3685
|
* ],
|
|
3304
|
-
* AbortSignal.timeout(30_000),
|
|
3686
|
+
* signal ?? AbortSignal.timeout(30_000), // the compact() call's signal, when it passed one
|
|
3305
3687
|
* )
|
|
3306
3688
|
* ).content,
|
|
3307
3689
|
* keep: 2, // retain at least the 2 most recent messages verbatim on each compaction
|
|
@@ -3541,7 +3923,8 @@ export declare function createRelay(options: RelayOptions): RelayHandler;
|
|
|
3541
3923
|
* is the server half this one pairs with.
|
|
3542
3924
|
*
|
|
3543
3925
|
* @param options - The endpoint, parser factory, and HTTP call configuration
|
|
3544
|
-
* @returns The
|
|
3926
|
+
* @returns The relay provider behind the shared provider interface; construct
|
|
3927
|
+
* {@link RelayProvider} directly to reach its wire seams
|
|
3545
3928
|
* @example Reaching the relay from the browser
|
|
3546
3929
|
* ```ts
|
|
3547
3930
|
* import type { ProviderInterface, ProviderParserInterface } from '@orkestrel/agent'
|
|
@@ -3555,14 +3938,13 @@ export declare function createRelay(options: RelayOptions): RelayHandler;
|
|
|
3555
3938
|
* this.#pending += chunk
|
|
3556
3939
|
* const lines = this.#pending.split(/\r\n|\n/)
|
|
3557
3940
|
* this.#pending = lines.pop() ?? ''
|
|
3558
|
-
*
|
|
3559
|
-
*
|
|
3560
|
-
*
|
|
3561
|
-
*
|
|
3562
|
-
*
|
|
3563
|
-
*
|
|
3564
|
-
*
|
|
3565
|
-
* return records
|
|
3941
|
+
* return lines
|
|
3942
|
+
* .filter((line) => line.trim().length > 0)
|
|
3943
|
+
* .map((line) => {
|
|
3944
|
+
* const record = parseJSONAs(line, isRecord)
|
|
3945
|
+
* if (record === undefined) throw new ProviderError('PROTOCOL', 'invalid JSON record')
|
|
3946
|
+
* return record
|
|
3947
|
+
* })
|
|
3566
3948
|
* }
|
|
3567
3949
|
* clear(): void {
|
|
3568
3950
|
* this.#pending = ''
|
|
@@ -3581,7 +3963,7 @@ export declare function createRelay(options: RelayOptions): RelayHandler;
|
|
|
3581
3963
|
* const result = await browser.generate(messages, abort.signal) // a ProviderResult like a local provider's
|
|
3582
3964
|
* ```
|
|
3583
3965
|
*/
|
|
3584
|
-
export declare function createRelayProvider(options: RelayProviderOptions):
|
|
3966
|
+
export declare function createRelayProvider(options: RelayProviderOptions): ProviderInterface;
|
|
3585
3967
|
|
|
3586
3968
|
/**
|
|
3587
3969
|
* Creates a named scope — an immutable {@link ScopeInterface} from its `name` and its
|
|
@@ -3612,8 +3994,8 @@ export declare function createScope(input: ScopeInput): ScopeInterface;
|
|
|
3612
3994
|
* by their minted `id`, in insertion order.
|
|
3613
3995
|
*
|
|
3614
3996
|
* @remarks
|
|
3615
|
-
* Starts empty; `
|
|
3616
|
-
*
|
|
3997
|
+
* Starts empty; `add` mints each scope's `id` and stores it (keyed by `id`, so it
|
|
3998
|
+
* never overwrites — two scopes may share a `name`); `scopes()` lists them in insertion order;
|
|
3617
3999
|
* `remove` (one or a batch) reports `true` only when every supplied id was removed; `clear`
|
|
3618
4000
|
* empties it. Carries an observable `emitter`
|
|
3619
4001
|
* ({@link import('./types.js').ScopeManagerEventMap}) wired through the reserved `on`
|
|
@@ -3628,7 +4010,7 @@ export declare function createScope(input: ScopeInput): ScopeInterface;
|
|
|
3628
4010
|
* import { createScopeManager } from '@orkestrel/agent'
|
|
3629
4011
|
*
|
|
3630
4012
|
* const scopes = createScopeManager()
|
|
3631
|
-
* const reader = scopes.
|
|
4013
|
+
* const reader = scopes.add({ name: 'reader', tools: ['search'] })
|
|
3632
4014
|
* ```
|
|
3633
4015
|
*/
|
|
3634
4016
|
export declare function createScopeManager(options?: ScopeManagerOptions): ScopeManagerInterface;
|
|
@@ -3724,7 +4106,8 @@ export declare function cutListing(entries: readonly string[], room: number): st
|
|
|
3724
4106
|
* the row `{ id: snapshot.id, snapshot }`.
|
|
3725
4107
|
* - **`get(id)` resolves the stored snapshot for an id**, narrowing the opaque JSON column back to
|
|
3726
4108
|
* a {@link ConversationSnapshot} ({@link import('../validators.js').isConversationSnapshot} — the
|
|
3727
|
-
* total guard for an untrusted storage read), or `undefined` if none is stored
|
|
4109
|
+
* total guard for an untrusted storage read), or `undefined` if none is stored, the blob is
|
|
4110
|
+
* malformed, or the blob's own `id` is not the requested one.
|
|
3728
4111
|
* - **`delete(id)` drops a snapshot by id**; an absent id is a no-op (no throw).
|
|
3729
4112
|
*
|
|
3730
4113
|
* Unlike a session store there is no idle-TTL / eviction — a persisted conversation lives until an
|
|
@@ -3755,11 +4138,34 @@ export declare class DatabaseConversationStore implements ConversationStoreInter
|
|
|
3755
4138
|
* {@link ConversationSnapshotRow} `{ id; snapshot }` shape (the snapshot one opaque JSON column)
|
|
3756
4139
|
*/
|
|
3757
4140
|
constructor(table: TableInterface<ConversationSnapshotRow>);
|
|
3758
|
-
/**
|
|
4141
|
+
/**
|
|
4142
|
+
* Resolves the persisted snapshot for `id`, narrowing the opaque JSON column back to a
|
|
4143
|
+
* `ConversationSnapshot`.
|
|
4144
|
+
*
|
|
4145
|
+
* @remarks
|
|
4146
|
+
* The column is an untrusted storage read, so a blob that fails
|
|
4147
|
+
* {@link import('../validators.js').isConversationSnapshot}, or whose own `id` is not `id`,
|
|
4148
|
+
* resolves `undefined` rather than a conversation under the wrong key.
|
|
4149
|
+
*
|
|
4150
|
+
* @param id - The conversation id to resolve (the row key)
|
|
4151
|
+
* @returns The persisted snapshot, or `undefined` when no row is stored, the blob is malformed,
|
|
4152
|
+
* or the blob names another id
|
|
4153
|
+
*/
|
|
3759
4154
|
get(id: string): Promise<ConversationSnapshot | undefined>;
|
|
3760
|
-
/**
|
|
4155
|
+
/**
|
|
4156
|
+
* Inserts or replaces under the snapshot's own `id` (no separate id param) — the row is
|
|
4157
|
+
* `{ id, snapshot }`.
|
|
4158
|
+
*
|
|
4159
|
+
* @param snapshot - The snapshot to store, keyed by its `id`
|
|
4160
|
+
* @returns A promise that resolves once the row is written
|
|
4161
|
+
*/
|
|
3761
4162
|
set(snapshot: ConversationSnapshot): Promise<void>;
|
|
3762
|
-
/**
|
|
4163
|
+
/**
|
|
4164
|
+
* Drops a snapshot by id; an absent id is a no-op (no throw).
|
|
4165
|
+
*
|
|
4166
|
+
* @param id - The conversation id to drop
|
|
4167
|
+
* @returns A promise that resolves once the row is gone
|
|
4168
|
+
*/
|
|
3763
4169
|
delete(id: string): Promise<void>;
|
|
3764
4170
|
}
|
|
3765
4171
|
|
|
@@ -3844,8 +4250,8 @@ export declare const DETERMINISTIC_JUDGE_ERROR: RegExp;
|
|
|
3844
4250
|
/**
|
|
3845
4251
|
* Estimates the context-token footprint of a batch of messages — each message's content plus
|
|
3846
4252
|
* {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD}, a tool-call JSON estimate, a thinking estimate, and
|
|
3847
|
-
* {@link import('./constants.js').IMAGE_TOKEN_ESTIMATE} for each attached image. The
|
|
3848
|
-
*
|
|
4253
|
+
* {@link import('./constants.js').IMAGE_TOKEN_ESTIMATE} for each attached image. The {@link estimateRequest} message term
|
|
4254
|
+
* for an agent's context budget (the
|
|
3849
4255
|
* {@link import('./types.js').AgentOptions} `window`), a provider-independent approximation for conforming messages rather than an exact tokenizer count.
|
|
3850
4256
|
*
|
|
3851
4257
|
* @remarks
|
|
@@ -3855,12 +4261,12 @@ export declare const DETERMINISTIC_JUDGE_ERROR: RegExp;
|
|
|
3855
4261
|
* `calls` plus, when present, {@link estimateTokens} over its `thinking` plus `images.length * `{@link import('./constants.js').IMAGE_TOKEN_ESTIMATE} (a coarse,
|
|
3856
4262
|
* deliberately-approximate per-image cost — a base64 length is not a token proxy). Deterministic
|
|
3857
4263
|
* and provider-free — the same messages always yield the same estimate, with an empty batch `0`.
|
|
3858
|
-
* It is the
|
|
3859
|
-
*
|
|
3860
|
-
*
|
|
3861
|
-
*
|
|
4264
|
+
* It is the message term of the request estimate an agent's auto-compaction context budget
|
|
4265
|
+
* measures; a caller wanting a sharper count supplies its own `consumer` to `createBudget`
|
|
4266
|
+
* instead. A `calls` list JSON cannot carry (a circular or `BigInt`
|
|
4267
|
+
* `ToolCall.arguments`) contributes a fixed
|
|
3862
4268
|
* {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD} (the same per-message overhead scale)
|
|
3863
|
-
* instead of
|
|
4269
|
+
* instead of an estimate of the (unreachable) serialized length.
|
|
3864
4270
|
*
|
|
3865
4271
|
* @param messages - The messages to estimate (a turn's appended assistant + tool messages)
|
|
3866
4272
|
* @returns The summed estimated token count (`0` when empty)
|
|
@@ -3873,6 +4279,32 @@ export declare const DETERMINISTIC_JUDGE_ERROR: RegExp;
|
|
|
3873
4279
|
*/
|
|
3874
4280
|
export declare function estimateMessages(messages: readonly Message[]): number;
|
|
3875
4281
|
|
|
4282
|
+
/**
|
|
4283
|
+
* Estimates the context-token footprint of a complete provider request — its messages through
|
|
4284
|
+
* {@link estimateMessages}, plus the rendered advertised `tools`, plus the rendered
|
|
4285
|
+
* `options.schema`. The `consumer` estimator an agent's `window` budget measures every request
|
|
4286
|
+
* through, a provider-independent heuristic rather than an exact tokenizer count.
|
|
4287
|
+
*
|
|
4288
|
+
* @remarks
|
|
4289
|
+
* Adds {@link estimateTokens} over the JSON rendering of `tools` and of `options.schema` to the
|
|
4290
|
+
* message estimate. An absent or empty `tools` list and an absent or empty `schema` add `0`, so a
|
|
4291
|
+
* request that advertises neither equals {@link estimateMessages} of its messages. A value JSON
|
|
4292
|
+
* cannot carry contributes a fixed {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD}. The
|
|
4293
|
+
* estimate counts JSON characters, not a provider's template: the chat template's own tokens, how
|
|
4294
|
+
* a provider encodes tool definitions, and the `think` flag are not counted, and no tokenizer
|
|
4295
|
+
* runs. A model's real prompt count can exceed it, so choose the window `max` with headroom
|
|
4296
|
+
* measured against the provider.
|
|
4297
|
+
*
|
|
4298
|
+
* @param request - The {@link ProviderRequest} to estimate: messages, advertised tools, call options
|
|
4299
|
+
* @returns The estimated token count (`0` for an empty request)
|
|
4300
|
+
*
|
|
4301
|
+
* @example
|
|
4302
|
+
* ```ts
|
|
4303
|
+
* estimateRequest({ messages: [{ id: '1', role: 'user', content: 'hello' }] }) // 6, equal to estimateMessages
|
|
4304
|
+
* ```
|
|
4305
|
+
*/
|
|
4306
|
+
export declare function estimateRequest(request: ProviderRequest): number;
|
|
4307
|
+
|
|
3876
4308
|
/**
|
|
3877
4309
|
* Estimates the context-token footprint of a string — the deterministic `ceil(length / 4)`
|
|
3878
4310
|
* character heuristic {@link estimateMessages} sums over a conversation's messages (the default
|
|
@@ -3966,9 +4398,17 @@ export declare function extractTokens(text: string): LedgerTokenSet;
|
|
|
3966
4398
|
*/
|
|
3967
4399
|
export declare function extractWords(message: Message): LedgerWordSet;
|
|
3968
4400
|
|
|
3969
|
-
/**
|
|
4401
|
+
/**
|
|
4402
|
+
* Carries an HTTP failure message, the response status, and the underlying body-read cause when
|
|
4403
|
+
* available.
|
|
4404
|
+
*
|
|
4405
|
+
* @remarks
|
|
4406
|
+
* The members spread past `message` form the options of a coded HTTP error: `status` is the
|
|
4407
|
+
* response status, and `cause` is present only when the error body could not be read.
|
|
4408
|
+
*/
|
|
3970
4409
|
export declare interface FailureRead {
|
|
3971
4410
|
readonly message: string;
|
|
4411
|
+
readonly status: number;
|
|
3972
4412
|
readonly cause?: unknown;
|
|
3973
4413
|
}
|
|
3974
4414
|
|
|
@@ -4103,7 +4543,7 @@ export declare interface GaugeCall {
|
|
|
4103
4543
|
* Prices prompts in tokens and measures the room a request has left.
|
|
4104
4544
|
*
|
|
4105
4545
|
* @remarks
|
|
4106
|
-
* `scale`
|
|
4546
|
+
* `scale` holds the price from the last observation; `overhead` holds the construction price.
|
|
4107
4547
|
*/
|
|
4108
4548
|
export declare interface GaugeInterface extends LedgerGauge {
|
|
4109
4549
|
/**
|
|
@@ -4193,38 +4633,36 @@ export declare interface GaugeOptions extends LedgerGauge {
|
|
|
4193
4633
|
export declare function handleAgentQueueJob(registry: AgentRegistryInterface, partial: boolean, input: AgentJobInput, context: QueueContext): Promise<AgentResult>;
|
|
4194
4634
|
|
|
4195
4635
|
/**
|
|
4196
|
-
*
|
|
4197
|
-
* parent through a registry with the controller signal, and applying the shared
|
|
4198
|
-
* partial-result policy.
|
|
4636
|
+
* Checks whether a message carries at least one tool call.
|
|
4199
4637
|
*
|
|
4200
4638
|
* @remarks
|
|
4201
|
-
*
|
|
4202
|
-
*
|
|
4203
|
-
*
|
|
4204
|
-
* @param registry - The registry that rehydrates serializable jobs
|
|
4205
|
-
* @param partial - The partial policy. If `true`, a partial result resolves; if `false`, it throws
|
|
4206
|
-
* @param controller - The runner controller for this parent job
|
|
4207
|
-
* @returns The settled parent agent result
|
|
4639
|
+
* Pure and total. An absent `calls` member and an empty list both return false, so a tool-free
|
|
4640
|
+
* assistant turn and a turn whose provider reported an empty call list read alike.
|
|
4208
4641
|
*
|
|
4642
|
+
* @param message - The message to inspect; only its `calls` member is read
|
|
4643
|
+
* @returns True if `calls` holds at least one call; false otherwise
|
|
4209
4644
|
* @example
|
|
4210
4645
|
* ```ts
|
|
4211
|
-
*
|
|
4646
|
+
* hasCalls({ calls: [{ id: 'order', name: 'lookup', arguments: {} }] }) // true
|
|
4647
|
+
* hasCalls({ calls: [] }) // false
|
|
4648
|
+
* hasCalls({}) // false
|
|
4212
4649
|
* ```
|
|
4213
4650
|
*/
|
|
4214
|
-
export declare function
|
|
4651
|
+
export declare function hasCalls(message: Pick<Message, 'calls'>): boolean;
|
|
4215
4652
|
|
|
4216
4653
|
/**
|
|
4217
4654
|
* Identifies a lookup reading for projection by its tool name and normalized arguments.
|
|
4218
4655
|
*
|
|
4219
4656
|
* @remarks
|
|
4220
4657
|
* Two calls share an identity whatever the key order of their arguments at any depth. A top-level
|
|
4221
|
-
* string argument
|
|
4658
|
+
* string argument passes through {@link normalizeArgument} first, so `"lh-1 "` and `"LH-1"` name one call.
|
|
4222
4659
|
* The ledger's repeat stop instead compares the tool name and canonical arguments without this
|
|
4223
4660
|
* string normalization, so those argument spellings remain distinct within a request.
|
|
4661
|
+
* An uncanonicalizable call has no identity and neither replaces nor is replaced by another reading.
|
|
4224
4662
|
*
|
|
4225
4663
|
* @param name - The tool name
|
|
4226
4664
|
* @param args - The arguments the call carried
|
|
4227
|
-
* @returns The
|
|
4665
|
+
* @returns The name, a space, and the canonical arguments, or `undefined` when uncanonicalizable
|
|
4228
4666
|
*
|
|
4229
4667
|
* @example
|
|
4230
4668
|
* ```ts
|
|
@@ -4232,7 +4670,7 @@ export declare function handleAgentRunnerJob(registry: AgentRegistryInterface, p
|
|
|
4232
4670
|
* identifyLookup('lookup_order', { opts: { region: 'north', tier: 2 }, id: ' BW-5512' }) // true
|
|
4233
4671
|
* ```
|
|
4234
4672
|
*/
|
|
4235
|
-
export declare function identifyLookup(name: string, args: Readonly<Record<string, unknown>>): string;
|
|
4673
|
+
export declare function identifyLookup(name: string, args: Readonly<Record<string, unknown>>): string | undefined;
|
|
4236
4674
|
|
|
4237
4675
|
/**
|
|
4238
4676
|
* Names the coarse, deliberately approximate per-image token cost
|
|
@@ -4247,6 +4685,43 @@ export declare function identifyLookup(name: string, args: Readonly<Record<strin
|
|
|
4247
4685
|
*/
|
|
4248
4686
|
export declare const IMAGE_TOKEN_ESTIMATE = 512;
|
|
4249
4687
|
|
|
4688
|
+
/**
|
|
4689
|
+
* Infers which of a run's three failure layers stopped it — the meter allowance, a cost budget, or
|
|
4690
|
+
* the model's own token limit — and returns the stop record with the final call's readings, or
|
|
4691
|
+
* `undefined` when no layer stopped the run.
|
|
4692
|
+
*
|
|
4693
|
+
* @remarks
|
|
4694
|
+
* The layer that stopped the final provider call first wins. A model-truncated final answer whose
|
|
4695
|
+
* call returned unaborted is a `model` stop, even when that call's reconciled usage then exhausted a
|
|
4696
|
+
* budget or a cancel then landed before the run settled. Otherwise a `BudgetError` reason is a
|
|
4697
|
+
* `meter` stop when the allowance is exhausted, the reason is the allowance signal's own reason, its
|
|
4698
|
+
* context carries the allowance's `id` and `max`, and either the allowance is a separate instance or
|
|
4699
|
+
* the run had aborted when the call returned; any other `BudgetError` is a `budget` stop. The
|
|
4700
|
+
* identity test tells an allowance and a budget that share an `id` apart, and the readings test
|
|
4701
|
+
* tells a parent budget linked through the allowance's `signal` option apart from the allowance. An
|
|
4702
|
+
* external cancel, a deadline, or an `abort()` reason yields `undefined`. Two inputs still read as
|
|
4703
|
+
* the meter's: a charge a caller makes to the run's shared allowance from its own code while a call
|
|
4704
|
+
* streams, and a parent with the allowance's own `id` and `max` that aborted before `start()` when
|
|
4705
|
+
* the allowance then exhausts.
|
|
4706
|
+
*
|
|
4707
|
+
* @param reason - The run signal's abort reason (`undefined` while it is unaborted)
|
|
4708
|
+
* @param allowance - The run's meter allowance, or `undefined` for a run with no meter layer
|
|
4709
|
+
* @param budget - The run's cost budget, or `undefined` for an unbudgeted run
|
|
4710
|
+
* @param provider - The provider's trace `id`, named by a `model` stop
|
|
4711
|
+
* @param turn - The run's final turn record, or `undefined` when the run took no turn
|
|
4712
|
+
* @returns The stop record, or `undefined` when no layer stopped the run
|
|
4713
|
+
*
|
|
4714
|
+
* @example
|
|
4715
|
+
* ```ts
|
|
4716
|
+
* const allowance = createTokenBudget({ id: 'meter', max: 2 })
|
|
4717
|
+
* allowance.start()
|
|
4718
|
+
* allowance.consume({ prompt: 0, completion: 3, total: 3 })
|
|
4719
|
+
* inferStop(allowance.signal.reason, allowance, undefined, 'ollama', undefined)
|
|
4720
|
+
* // { layer: 'meter', id: 'meter', max: 2, consumed: 3 }
|
|
4721
|
+
* ```
|
|
4722
|
+
*/
|
|
4723
|
+
export declare function inferStop(reason: unknown, allowance: BudgetInterface<TokenUsage> | undefined, budget: BudgetInterface<TokenUsage> | undefined, provider: string, turn: AgentTurn | undefined): AgentStop | undefined;
|
|
4724
|
+
|
|
4250
4725
|
/**
|
|
4251
4726
|
* Represents an immutable named directive — an {@link InstructionInterface} assembled once from
|
|
4252
4727
|
* its input (`name` / `content` and an optional `priority`), the `id` minted at
|
|
@@ -4428,21 +4903,39 @@ export declare interface InstructionManagerInterface {
|
|
|
4428
4903
|
/**
|
|
4429
4904
|
* Adds one {@link InstructionInput}, or a batch — mints each `id`; adding an instruction whose
|
|
4430
4905
|
* name is already stored overwrites it, last write wins.
|
|
4906
|
+
*
|
|
4907
|
+
* @param input - One {@link InstructionInput}, or a batch
|
|
4908
|
+
* @returns The stored instruction, or the stored batch in input order
|
|
4431
4909
|
*/
|
|
4432
4910
|
add(input: InstructionInput): InstructionInterface;
|
|
4433
4911
|
add(inputs: readonly InstructionInput[]): readonly InstructionInterface[];
|
|
4434
|
-
/**
|
|
4912
|
+
/**
|
|
4913
|
+
* Looks up one instruction by name (`undefined` when absent).
|
|
4914
|
+
*
|
|
4915
|
+
* @param name - The instruction name to look up
|
|
4916
|
+
* @returns The stored instruction, or `undefined` when absent
|
|
4917
|
+
*/
|
|
4435
4918
|
instruction(name: string): InstructionInterface | undefined;
|
|
4436
|
-
/**
|
|
4919
|
+
/**
|
|
4920
|
+
* Lists every instruction, sorted by descending `priority` (stable for equal priorities).
|
|
4921
|
+
*
|
|
4922
|
+
* @returns Every stored instruction, highest `priority` first
|
|
4923
|
+
*/
|
|
4437
4924
|
instructions(): readonly InstructionInterface[];
|
|
4438
4925
|
/**
|
|
4439
4926
|
* Renders one instruction for the prompt — its `override`, else the manager-options
|
|
4440
4927
|
* `render`, else its `content`.
|
|
4928
|
+
*
|
|
4929
|
+
* @param instruction - The instruction to render
|
|
4930
|
+
* @returns The instruction's prompt text, `''` when its `override` is `''`
|
|
4441
4931
|
*/
|
|
4442
4932
|
render(instruction: InstructionInterface): string;
|
|
4443
4933
|
/**
|
|
4444
4934
|
* Removes one instruction by name, or a batch. True if every supplied name was removed; false
|
|
4445
4935
|
* otherwise.
|
|
4936
|
+
*
|
|
4937
|
+
* @param name - One instruction name, or a batch
|
|
4938
|
+
* @returns True if every supplied name was present and removed; false otherwise
|
|
4446
4939
|
*/
|
|
4447
4940
|
remove(name: string): boolean;
|
|
4448
4941
|
remove(names: readonly string[]): boolean;
|
|
@@ -4669,8 +5162,11 @@ export declare function isJudgeQuestion(value: unknown): value is JudgeQuestion;
|
|
|
4669
5162
|
* Checks whether a stored judgment carries a valid question and exactly one answer or refusal.
|
|
4670
5163
|
*
|
|
4671
5164
|
* @remarks
|
|
4672
|
-
*
|
|
4673
|
-
* value types; this storage guard does not impose a wire's probability or
|
|
5165
|
+
* Unknown members, malformed members, and unreadable inputs return false. Answer fields follow
|
|
5166
|
+
* the root judge value types; this storage guard does not impose a wire's probability or
|
|
5167
|
+
* candidate limits. The `time`, `noul`, and probability numbers must be finite, because a stored
|
|
5168
|
+
* record is owned through JSON, which turns `NaN` and the infinities into `null`; so every record
|
|
5169
|
+
* this guard accepts hydrates through a `JudgmentManager`.
|
|
4674
5170
|
*
|
|
4675
5171
|
* @param value - The unknown stored record
|
|
4676
5172
|
* @returns True if the record satisfies the judgment contract; false otherwise
|
|
@@ -4717,6 +5213,27 @@ export declare function isLedgerError(value: unknown): value is LedgerError;
|
|
|
4717
5213
|
*/
|
|
4718
5214
|
export declare function isMessage(value: unknown): value is Message;
|
|
4719
5215
|
|
|
5216
|
+
/**
|
|
5217
|
+
* Checks whether a value is a non-negative safe integer, `-0` included.
|
|
5218
|
+
*
|
|
5219
|
+
* @remarks
|
|
5220
|
+
* Total: a non-number, `NaN`, an infinity, a fraction, a negative number, and an integer past
|
|
5221
|
+
* `Number.MAX_SAFE_INTEGER` return false. It differs from `isNonNegativeInteger` in
|
|
5222
|
+
* `@orkestrel/contract` at two values: that guard rejects `-0` and admits an unsafe integer such
|
|
5223
|
+
* as `2 ** 53`, while this guard admits `-0` and rejects `2 ** 53`.
|
|
5224
|
+
*
|
|
5225
|
+
* @param value - The unknown count or limit candidate
|
|
5226
|
+
* @returns True if the value is a safe integer at or above zero; false otherwise
|
|
5227
|
+
* @example
|
|
5228
|
+
* ```ts
|
|
5229
|
+
* isNonNegativeSafeInteger(0) // true
|
|
5230
|
+
* isNonNegativeSafeInteger(-0) // true
|
|
5231
|
+
* isNonNegativeSafeInteger(2 ** 53) // false
|
|
5232
|
+
* isNonNegativeSafeInteger(1.5) // false
|
|
5233
|
+
* ```
|
|
5234
|
+
*/
|
|
5235
|
+
export declare function isNonNegativeSafeInteger(value: unknown): value is number;
|
|
5236
|
+
|
|
4720
5237
|
/**
|
|
4721
5238
|
* Checks whether a value is a positive safe integer.
|
|
4722
5239
|
* @param value - The value to inspect
|
|
@@ -5076,13 +5593,15 @@ export declare class Ledger implements LedgerInterface {
|
|
|
5076
5593
|
*/
|
|
5077
5594
|
calibrate(signal: AbortSignal): Promise<LedgerGauge>;
|
|
5078
5595
|
/**
|
|
5079
|
-
* Appends a request and serves it, recovering an unfinished first pass with one answer pass.
|
|
5596
|
+
* Appends a request and serves it, recovering an unfinished or rejected first pass with one answer pass.
|
|
5080
5597
|
* 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.
|
|
5598
|
+
* When the answer pass rejects, `respond` rejects with that error. Every rejection leaves the ledger free for a later call.
|
|
5081
5599
|
* @param content - The request text
|
|
5082
5600
|
* @param signal - The caller's cancellation signal; an abort during calibration rejects with its reason
|
|
5083
|
-
* @returns The final pass
|
|
5601
|
+
* @returns The final pass, the usage of every pass, and the filing readings of this request alone
|
|
5084
5602
|
* @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)
|
|
5085
5603
|
* @throws {LedgerError} Thrown when a calibration call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)
|
|
5604
|
+
* @throws {ContractError} Thrown when `signal` is defined and is not a native `AbortSignal`
|
|
5086
5605
|
*/
|
|
5087
5606
|
respond(content: string, signal?: AbortSignal): Promise<LedgerResult>;
|
|
5088
5607
|
}
|
|
@@ -5184,6 +5703,12 @@ export declare type LedgerEntityHandler = (text: string, partial: boolean) => Re
|
|
|
5184
5703
|
export declare class LedgerError extends Error {
|
|
5185
5704
|
/** Names the machine-readable condition; the {@link LedgerErrorCode} union describes each code. */
|
|
5186
5705
|
readonly code: LedgerErrorCode;
|
|
5706
|
+
/**
|
|
5707
|
+
* Records the failure condition and its description.
|
|
5708
|
+
*
|
|
5709
|
+
* @param code - The machine-readable condition, exposed as `error.code`
|
|
5710
|
+
* @param message - The human-readable description of the failure
|
|
5711
|
+
*/
|
|
5187
5712
|
constructor(code: LedgerErrorCode, message: string);
|
|
5188
5713
|
}
|
|
5189
5714
|
|
|
@@ -5242,17 +5767,22 @@ export declare interface LedgerInterface {
|
|
|
5242
5767
|
* @remarks
|
|
5243
5768
|
* The ledger calibrates first while `gauge` is undefined. When the first pass ends without final
|
|
5244
5769
|
* text and the caller did not abort, the ledger adds the results and cue notes and makes one
|
|
5245
|
-
* answer pass that advertises no tools. A
|
|
5770
|
+
* answer pass that advertises no tools. A rejected first pass counts as unfinished; when the
|
|
5771
|
+
* answer pass rejects as well, `respond` rejects with that pass's error. A `respond` or `calibrate` call while either is in flight
|
|
5246
5772
|
* 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
|
|
5247
5773
|
* `LedgerError` code `'GAUGE'`; a provider error during calibration rejects with that error.
|
|
5248
5774
|
* Direct agent runs share an active request's gauge readings and repeat stop, even when their
|
|
5249
5775
|
* selections fault. Only `respond` and `calibrate` calls are refused by the concurrency guard.
|
|
5776
|
+
* A run no `respond` call owns, including a run during calibration, reads no request's state:
|
|
5777
|
+
* its lookup and `recall` calls run with no repeat stop, recall limit, or close rule.
|
|
5778
|
+
* Every rejection leaves the ledger free for a later call.
|
|
5250
5779
|
*
|
|
5251
5780
|
* @param content - The request text
|
|
5252
5781
|
* @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
|
|
5253
|
-
* @returns The reply
|
|
5782
|
+
* @returns The reply, the passes the request took, and the filing readings of this request alone
|
|
5254
5783
|
* @throws {LedgerError} Thrown when a calibration call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)
|
|
5255
5784
|
* @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)
|
|
5785
|
+
* @throws {ContractError} Thrown when `signal` is defined and is not a native `AbortSignal`
|
|
5256
5786
|
*/
|
|
5257
5787
|
respond(content: string, signal?: AbortSignal): Promise<LedgerResult>;
|
|
5258
5788
|
/**
|
|
@@ -5519,6 +6049,202 @@ export declare interface LedgerRegistry {
|
|
|
5519
6049
|
readonly owners: ReadonlyMap<string, readonly string[]>;
|
|
5520
6050
|
}
|
|
5521
6051
|
|
|
6052
|
+
/**
|
|
6053
|
+
* Holds what one ledger request keeps while it is served: its message, its filing readings and
|
|
6054
|
+
* plan, the gauge calls of its passes, and its repeat and recall stops.
|
|
6055
|
+
*
|
|
6056
|
+
* @remarks
|
|
6057
|
+
* A ledger creates one request per `respond` call and drops it when the call settles. Each pass the
|
|
6058
|
+
* request opens holds its own selection, boundary, usage, and calls; the request reads the current
|
|
6059
|
+
* pass, the last one opened. {@link LedgerRequestInterface} describes each member.
|
|
6060
|
+
*
|
|
6061
|
+
* @example
|
|
6062
|
+
* ```ts
|
|
6063
|
+
* const request = new LedgerRequest('What approval is needed?', 1)
|
|
6064
|
+
* request.enter(conversation) // the appended user message
|
|
6065
|
+
* request.admit('lookup', { id: 'BW-20931' })
|
|
6066
|
+
* request.admit('lookup', { id: 'BW-20931' }) // throws Error(LEDGER_NOTES.repeat)
|
|
6067
|
+
* request.recall()
|
|
6068
|
+
* request.recall() // throws Error(LEDGER_NOTES.closure): the limit of 1 is spent
|
|
6069
|
+
* ```
|
|
6070
|
+
*/
|
|
6071
|
+
export declare class LedgerRequest implements LedgerRequestInterface {
|
|
6072
|
+
#private;
|
|
6073
|
+
/**
|
|
6074
|
+
* Holds the request's content and its recall limit.
|
|
6075
|
+
*
|
|
6076
|
+
* @param content - The request text `enter` appends
|
|
6077
|
+
* @param limit - The `recall` calls the request can make. Default: the `DEFAULT_RECALL_LIMIT` constant
|
|
6078
|
+
* @throws {LedgerError} Thrown when `limit` is not a nonnegative safe integer (code `'LIMIT'`)
|
|
6079
|
+
*/
|
|
6080
|
+
constructor(content: string, limit?: number);
|
|
6081
|
+
/**
|
|
6082
|
+
* Returns the request message.
|
|
6083
|
+
*
|
|
6084
|
+
* @returns The message `enter` appended, or undefined before it
|
|
6085
|
+
*/
|
|
6086
|
+
get message(): Message | undefined;
|
|
6087
|
+
/**
|
|
6088
|
+
* Returns the selection the request's last successful plan produced.
|
|
6089
|
+
*
|
|
6090
|
+
* @returns The planned selection, or undefined before one
|
|
6091
|
+
*/
|
|
6092
|
+
get plan(): Selection | undefined;
|
|
6093
|
+
/**
|
|
6094
|
+
* Returns the selection the current pass's run adopted last.
|
|
6095
|
+
*
|
|
6096
|
+
* @returns The selection, or undefined before one
|
|
6097
|
+
*/
|
|
6098
|
+
get selection(): Selection | undefined;
|
|
6099
|
+
/**
|
|
6100
|
+
* Returns the conversation length the current pass's calls count additions from.
|
|
6101
|
+
*
|
|
6102
|
+
* @returns The length, or undefined before a pass
|
|
6103
|
+
*/
|
|
6104
|
+
get boundary(): number | undefined;
|
|
6105
|
+
/**
|
|
6106
|
+
* Returns the summed usage of the current pass.
|
|
6107
|
+
*
|
|
6108
|
+
* @returns The summed usage, or undefined while none reported usage
|
|
6109
|
+
*/
|
|
6110
|
+
get usage(): TokenUsage | undefined;
|
|
6111
|
+
/**
|
|
6112
|
+
* Returns the gauge calls of every pass.
|
|
6113
|
+
*
|
|
6114
|
+
* @returns The calls in order, the call in flight last
|
|
6115
|
+
*/
|
|
6116
|
+
get calls(): readonly GaugeCall[];
|
|
6117
|
+
/**
|
|
6118
|
+
* Returns the filing readings of the request's planning selections.
|
|
6119
|
+
*
|
|
6120
|
+
* @returns The readings in asking order
|
|
6121
|
+
*/
|
|
6122
|
+
get readings(): readonly ClassifierReading[];
|
|
6123
|
+
enter(conversation: ConversationInterface): Message;
|
|
6124
|
+
open(boundary: number): void;
|
|
6125
|
+
adopt(selection: Selection, boundary: number): void;
|
|
6126
|
+
observe(call: GaugeCall, position: number): void;
|
|
6127
|
+
spend(usage: TokenUsage): void;
|
|
6128
|
+
think(messages: readonly Message[]): void;
|
|
6129
|
+
file(readings: readonly ClassifierReading[], plan?: Selection): void;
|
|
6130
|
+
admit(name: string, args: Readonly<Record<string, unknown>>): void;
|
|
6131
|
+
recall(): void;
|
|
6132
|
+
close(): void;
|
|
6133
|
+
list(result: string, lines: ReadonlyMap<string, string>): void;
|
|
6134
|
+
listing(result: string): ReadonlyMap<string, string> | undefined;
|
|
6135
|
+
}
|
|
6136
|
+
|
|
6137
|
+
/**
|
|
6138
|
+
* Holds what one `respond` call of a ledger keeps while it serves its request: the request message,
|
|
6139
|
+
* the filing readings and the plan its selections produced, the gauge calls of its passes, and its
|
|
6140
|
+
* repeat and recall stops.
|
|
6141
|
+
*
|
|
6142
|
+
* @remarks
|
|
6143
|
+
* A ledger creates one request per `respond` call and drops it when the call settles, so no request
|
|
6144
|
+
* state reaches a later call or a run no call owns. Each agent run the call makes is a pass: `open`
|
|
6145
|
+
* starts one, and `selection`, `boundary`, and `usage` read the current pass, the last one opened.
|
|
6146
|
+
* `calls` lists the gauge calls of every pass in order. A call stays in flight, taking its usage and
|
|
6147
|
+
* thinking, until its pass observes the next call, and is final from then on.
|
|
6148
|
+
*/
|
|
6149
|
+
export declare interface LedgerRequestInterface {
|
|
6150
|
+
/** Holds the request message, or undefined until `enter` appends it. */
|
|
6151
|
+
readonly message: Message | undefined;
|
|
6152
|
+
/** Holds the selection the request's last successful plan produced, or undefined before one. */
|
|
6153
|
+
readonly plan: Selection | undefined;
|
|
6154
|
+
/** Holds the selection the current pass's run adopted last, or undefined before one. */
|
|
6155
|
+
readonly selection: Selection | undefined;
|
|
6156
|
+
/** Holds the conversation length at the current pass's start or at its last adopted selection, or undefined before a pass. */
|
|
6157
|
+
readonly boundary: number | undefined;
|
|
6158
|
+
/** Holds the summed usage of the current pass's selections and calls, or undefined while none reported usage. */
|
|
6159
|
+
readonly usage: TokenUsage | undefined;
|
|
6160
|
+
/** Holds the gauge calls of every pass in order, the call in flight last. */
|
|
6161
|
+
readonly calls: readonly GaugeCall[];
|
|
6162
|
+
/** Holds the filing readings of every planning selection the request made, in asking order. */
|
|
6163
|
+
readonly readings: readonly ClassifierReading[];
|
|
6164
|
+
/**
|
|
6165
|
+
* Appends the request's content to a conversation as a user message, once, and holds it as `message`.
|
|
6166
|
+
*
|
|
6167
|
+
* @param conversation - The conversation the request is served from
|
|
6168
|
+
* @returns The request message; a later call returns it without appending again
|
|
6169
|
+
*/
|
|
6170
|
+
enter(conversation: ConversationInterface): Message;
|
|
6171
|
+
/**
|
|
6172
|
+
* Opens a pass, which becomes the current pass.
|
|
6173
|
+
*
|
|
6174
|
+
* @param boundary - The conversation length when the pass's run starts
|
|
6175
|
+
*/
|
|
6176
|
+
open(boundary: number): void;
|
|
6177
|
+
/**
|
|
6178
|
+
* Records the selection the current pass's run adopted and adds the usage it spent.
|
|
6179
|
+
*
|
|
6180
|
+
* @param selection - The selection the run built its prompt from
|
|
6181
|
+
* @param boundary - The conversation length when the run adopted it
|
|
6182
|
+
*/
|
|
6183
|
+
adopt(selection: Selection, boundary: number): void;
|
|
6184
|
+
/**
|
|
6185
|
+
* Starts a gauge call in the current pass, making that pass's call in flight final.
|
|
6186
|
+
*
|
|
6187
|
+
* @param call - The call's estimate and advertised tool count
|
|
6188
|
+
* @param position - The conversation length when the call starts
|
|
6189
|
+
*/
|
|
6190
|
+
observe(call: GaugeCall, position: number): void;
|
|
6191
|
+
/**
|
|
6192
|
+
* Adds one call's reported usage to the current pass and records it on the call in flight.
|
|
6193
|
+
*
|
|
6194
|
+
* @param usage - The usage the provider reported for the call
|
|
6195
|
+
*/
|
|
6196
|
+
spend(usage: TokenUsage): void;
|
|
6197
|
+
/**
|
|
6198
|
+
* Records the thinking share of the call in flight, read from the first assistant message after
|
|
6199
|
+
* the call's position.
|
|
6200
|
+
*
|
|
6201
|
+
* @remarks
|
|
6202
|
+
* Records nothing while the call in flight has no reported completion or no such message carries
|
|
6203
|
+
* thinking.
|
|
6204
|
+
*
|
|
6205
|
+
* @param messages - The conversation's messages
|
|
6206
|
+
*/
|
|
6207
|
+
think(messages: readonly Message[]): void;
|
|
6208
|
+
/**
|
|
6209
|
+
* Appends the readings of one planning selection and holds its plan when planning succeeded.
|
|
6210
|
+
*
|
|
6211
|
+
* @param readings - The selection's filing readings, in asking order
|
|
6212
|
+
* @param plan - The planned selection, or undefined when planning failed
|
|
6213
|
+
*/
|
|
6214
|
+
file(readings: readonly ClassifierReading[], plan?: Selection): void;
|
|
6215
|
+
/**
|
|
6216
|
+
* Admits one tool call of the request, compared by tool name and canonical arguments.
|
|
6217
|
+
*
|
|
6218
|
+
* @param name - The tool name
|
|
6219
|
+
* @param args - The call's arguments
|
|
6220
|
+
* @throws {Error} Thrown with the {@link LedgerNote} `repeat` text when the request already admitted the same call
|
|
6221
|
+
* @throws {Error} Thrown when the arguments have no canonical identity
|
|
6222
|
+
*/
|
|
6223
|
+
admit(name: string, args: Readonly<Record<string, unknown>>): void;
|
|
6224
|
+
/**
|
|
6225
|
+
* Counts one `recall` call, closing the request's recall tool when its recalls reach the limit.
|
|
6226
|
+
*
|
|
6227
|
+
* @throws {Error} Thrown with the {@link LedgerNote} `closure` text when the recall tool is closed
|
|
6228
|
+
*/
|
|
6229
|
+
recall(): void;
|
|
6230
|
+
/** Closes the request's recall tool, so every later `recall` call throws the closure note. */
|
|
6231
|
+
close(): void;
|
|
6232
|
+
/**
|
|
6233
|
+
* Holds the stored first line of each lookup a recall result listed, keyed by its listed line.
|
|
6234
|
+
*
|
|
6235
|
+
* @param result - The recall result text
|
|
6236
|
+
* @param lines - Each listed lookup line mapped to the first line of its stored content
|
|
6237
|
+
*/
|
|
6238
|
+
list(result: string, lines: ReadonlyMap<string, string>): void;
|
|
6239
|
+
/**
|
|
6240
|
+
* Returns the stored first lines a recall result listed.
|
|
6241
|
+
*
|
|
6242
|
+
* @param result - The recall result text
|
|
6243
|
+
* @returns Each listed lookup line mapped to its stored first line, or undefined when no recall returned `result`
|
|
6244
|
+
*/
|
|
6245
|
+
listing(result: string): ReadonlyMap<string, string> | undefined;
|
|
6246
|
+
}
|
|
6247
|
+
|
|
5522
6248
|
/**
|
|
5523
6249
|
* Carries the outcome of one request a ledger served: the agent result of its reply and every pass
|
|
5524
6250
|
* it took.
|
|
@@ -5526,10 +6252,14 @@ export declare interface LedgerRegistry {
|
|
|
5526
6252
|
* @remarks
|
|
5527
6253
|
* `passes` holds the first pass and, when the ledger ran one, the answer pass. `content` and
|
|
5528
6254
|
* `partial` are the last pass's, `usage` sums the passes' usage, and `thinking` joins the passes'
|
|
5529
|
-
* reasoning; each optional member is present when any pass reported it.
|
|
6255
|
+
* reasoning; each optional member is present when any pass reported it. `stop` is the last pass's
|
|
6256
|
+
* stop, when one stopped it. `readings` lists every {@link ClassifierReading} the request's
|
|
6257
|
+
* selections recorded, in asking order. A request's reading count is its logical questions, never
|
|
6258
|
+
* its physical wire calls.
|
|
5530
6259
|
*/
|
|
5531
6260
|
export declare interface LedgerResult extends AgentResult {
|
|
5532
6261
|
readonly passes: readonly AgentResult[];
|
|
6262
|
+
readonly readings: readonly ClassifierReading[];
|
|
5533
6263
|
}
|
|
5534
6264
|
|
|
5535
6265
|
/**
|
|
@@ -5695,6 +6425,54 @@ export declare function matchesJudgment(judgment: Judgment, question: JudgeQuest
|
|
|
5695
6425
|
*/
|
|
5696
6426
|
export declare const MAX_ERROR_BODY_LENGTH = 2048;
|
|
5697
6427
|
|
|
6428
|
+
/**
|
|
6429
|
+
* Measures the disjoint estimate components of one message — its content, framing, rendered calls,
|
|
6430
|
+
* thinking, and attached images — as the same heuristic units {@link estimateMessages} sums.
|
|
6431
|
+
*
|
|
6432
|
+
* @remarks
|
|
6433
|
+
* The result is a structural estimate, not a tokenizer allocation. `id` and `role` are joins back to
|
|
6434
|
+
* the message, not token components, and a provider's template effects and the estimation error are
|
|
6435
|
+
* not individually attributed. `content` is `ceil(length / 4)`, `framing` is
|
|
6436
|
+
* {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD}, `calls` is the estimate of the JSON-rendered
|
|
6437
|
+
* calls (`0` when the message carries none, the framing overhead when they cannot be rendered),
|
|
6438
|
+
* `thinking` is the estimate of the thinking (`0` when absent), and `images` is the attached image
|
|
6439
|
+
* count times {@link import('./constants.js').IMAGE_TOKEN_ESTIMATE}. The message is not mutated.
|
|
6440
|
+
*
|
|
6441
|
+
* @param message - The message to measure
|
|
6442
|
+
* @returns The message's identity and its estimate components
|
|
6443
|
+
*
|
|
6444
|
+
* @example
|
|
6445
|
+
* ```ts
|
|
6446
|
+
* measureMessage({ id: '1', role: 'user', content: 'hello' })
|
|
6447
|
+
* // { id: '1', role: 'user', content: 2, framing: 4, calls: 0, thinking: 0, images: 0 }
|
|
6448
|
+
* ```
|
|
6449
|
+
*/
|
|
6450
|
+
export declare function measureMessage(message: Message): MessageMeasure;
|
|
6451
|
+
|
|
6452
|
+
/**
|
|
6453
|
+
* Measures the disjoint estimate components of a complete provider request — each message through
|
|
6454
|
+
* {@link measureMessage}, plus the rendered advertised `tools` and `options.schema` — as the same
|
|
6455
|
+
* heuristic units {@link estimateRequest} sums.
|
|
6456
|
+
*
|
|
6457
|
+
* @remarks
|
|
6458
|
+
* The result is a structural estimate, not a tokenizer allocation; a provider's template effects, how
|
|
6459
|
+
* it encodes tool definitions, the `think` flag, and the estimation error are not individually
|
|
6460
|
+
* attributed. `messages` keeps the request's message order, duplicate ids included. `tools` and
|
|
6461
|
+
* `schema` are each `0` when absent or empty and the estimate of their JSON rendering otherwise, or
|
|
6462
|
+
* the {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD} when JSON cannot carry them. The request
|
|
6463
|
+
* is not mutated.
|
|
6464
|
+
*
|
|
6465
|
+
* @param request - The {@link ProviderRequest} to measure: messages, advertised tools, call options
|
|
6466
|
+
* @returns The per-message components and the tools and schema estimates
|
|
6467
|
+
*
|
|
6468
|
+
* @example
|
|
6469
|
+
* ```ts
|
|
6470
|
+
* measureRequest({ messages: [{ id: '1', role: 'user', content: 'hello' }] })
|
|
6471
|
+
* // { messages: [{ id: '1', role: 'user', content: 2, framing: 4, calls: 0, thinking: 0, images: 0 }], tools: 0, schema: 0 }
|
|
6472
|
+
* ```
|
|
6473
|
+
*/
|
|
6474
|
+
export declare function measureRequest(request: ProviderRequest): RequestMeasure;
|
|
6475
|
+
|
|
5698
6476
|
/**
|
|
5699
6477
|
* Implements the {@link ConversationStoreInterface} in memory — a process-lifetime `Map` of
|
|
5700
6478
|
* {@link ConversationSnapshot} records keyed by conversation id, the default store
|
|
@@ -5910,6 +6688,30 @@ export declare interface MessageManagerInterface {
|
|
|
5910
6688
|
clear(): void;
|
|
5911
6689
|
}
|
|
5912
6690
|
|
|
6691
|
+
/**
|
|
6692
|
+
* Holds the disjoint estimate components of one message, in heuristic estimate units.
|
|
6693
|
+
*
|
|
6694
|
+
* @remarks
|
|
6695
|
+
* The structural estimate is not a tokenizer allocation. `id` and `role` are joins back to the
|
|
6696
|
+
* message, not token components. A message's estimate is the sum of `content`, `framing`, `calls`,
|
|
6697
|
+
* `thinking`, and `images`; no total is stored. A provider's template effects and the estimation
|
|
6698
|
+
* error are not individually attributed.
|
|
6699
|
+
*/
|
|
6700
|
+
export declare interface MessageMeasure {
|
|
6701
|
+
readonly id: string;
|
|
6702
|
+
readonly role: MessageRole;
|
|
6703
|
+
/** Holds the `ceil(length / 4)` estimate of the message `content`. */
|
|
6704
|
+
readonly content: number;
|
|
6705
|
+
/** Holds the fixed per-message framing overhead. */
|
|
6706
|
+
readonly framing: number;
|
|
6707
|
+
/** Holds the estimate of the JSON-rendered `calls`, or the framing overhead when they cannot be rendered; `0` when the message carries none. */
|
|
6708
|
+
readonly calls: number;
|
|
6709
|
+
/** Holds the estimate of the message `thinking`; `0` when absent. */
|
|
6710
|
+
readonly thinking: number;
|
|
6711
|
+
/** Holds the per-image estimate times the attached image count; `0` when none. */
|
|
6712
|
+
readonly images: number;
|
|
6713
|
+
}
|
|
6714
|
+
|
|
5913
6715
|
/** Names the role a {@link Message} plays in a conversation turn. */
|
|
5914
6716
|
export declare type MessageRole = (typeof MESSAGE_ROLES)[number];
|
|
5915
6717
|
|
|
@@ -5934,6 +6736,23 @@ images: OptionalShape<ArrayShape<StringShape>>;
|
|
|
5934
6736
|
thinking: OptionalShape<StringShape>;
|
|
5935
6737
|
}, boolean | ContractShape>;
|
|
5936
6738
|
|
|
6739
|
+
/**
|
|
6740
|
+
* Normalizes a lookup argument string to the spelling that lookup identity and owner linking compare.
|
|
6741
|
+
*
|
|
6742
|
+
* @remarks
|
|
6743
|
+
* {@link identifyLookup} and {@link linkOwners} read an argument through this one form, so a reading
|
|
6744
|
+
* a later lookup replaces and the owner link of its argument agree on the spelling.
|
|
6745
|
+
*
|
|
6746
|
+
* @param value - The string argument a lookup call carried
|
|
6747
|
+
* @returns The argument trimmed and uppercased
|
|
6748
|
+
*
|
|
6749
|
+
* @example
|
|
6750
|
+
* ```ts
|
|
6751
|
+
* normalizeArgument(' bw-5512 ') // 'BW-5512'
|
|
6752
|
+
* ```
|
|
6753
|
+
*/
|
|
6754
|
+
export declare function normalizeArgument(value: string): string;
|
|
6755
|
+
|
|
5937
6756
|
/** Carries the probability that the answer is yes; the protocol's noul field. */
|
|
5938
6757
|
export declare interface NoulAnswer {
|
|
5939
6758
|
readonly form: 'noul';
|
|
@@ -5972,11 +6791,20 @@ export declare const PLACED_CATEGORIES: readonly LedgerCategory[];
|
|
|
5972
6791
|
* A message that is not live still places, because a correction joins where its earlier side would
|
|
5973
6792
|
* join.
|
|
5974
6793
|
*
|
|
6794
|
+
* With `settled`, the walk returns a placement the map holds without walking again, and records each
|
|
6795
|
+
* placement whose walk, its nested walks included, excluded no earlier side through `seen`. Such a
|
|
6796
|
+
* walk reaches no cycle. While every `seen` holds only the path that reached the message, as
|
|
6797
|
+
* {@link buildRecords} passes it, that path never holds a message the recorded walk reached, so a
|
|
6798
|
+
* fresh walk returns the same keys in the same order. A placement a cycle cut stays unrecorded,
|
|
6799
|
+
* because its keys depend on the path that reached it. Sharing one map across the members of one
|
|
6800
|
+
* input bounds a dense amendment graph to one walk per message.
|
|
6801
|
+
*
|
|
5975
6802
|
* @param input - The owners, entities, and classification to read
|
|
5976
6803
|
* @param links - The owner of each linked lookup argument, from {@link linkOwners}
|
|
5977
6804
|
* @param amending - The earlier sides of each message's amendment pairs
|
|
5978
6805
|
* @param id - The message id
|
|
5979
6806
|
* @param seen - The ids already visited, which stops a cycle of amendment pairs
|
|
6807
|
+
* @param settled - The placements already walked for the same `input`, `links`, and `amending`; the walk adds to it. Default: no map, so every call walks
|
|
5980
6808
|
* @returns The record keys, empty when the message is an orphan
|
|
5981
6809
|
*
|
|
5982
6810
|
* @example
|
|
@@ -5984,7 +6812,7 @@ export declare const PLACED_CATEGORIES: readonly LedgerCategory[];
|
|
|
5984
6812
|
* placeMember(input, new Map(), new Map(), 'user-1', new Set()) // Set { 'owner:BW-20931' }
|
|
5985
6813
|
* ```
|
|
5986
6814
|
*/
|
|
5987
|
-
export declare function placeMember(input: LedgerProjectionInput, links: ReadonlyMap<string, string>, amending: ReadonlyMap<string, readonly string[]>, id: string, seen: ReadonlySet<string
|
|
6815
|
+
export declare function placeMember(input: LedgerProjectionInput, links: ReadonlyMap<string, string>, amending: ReadonlyMap<string, readonly string[]>, id: string, seen: ReadonlySet<string>, settled?: Map<string, ReadonlySet<string>>): ReadonlySet<string>;
|
|
5988
6816
|
|
|
5989
6817
|
/**
|
|
5990
6818
|
* Reports a provider stream cancelled mid-flight by its bound signal — thrown by the
|
|
@@ -6008,8 +6836,8 @@ export declare class ProviderAbortError extends Error {
|
|
|
6008
6836
|
|
|
6009
6837
|
/**
|
|
6010
6838
|
* Represents one streamed delta the `stream` method of a {@link ProviderInterface} yields — a unit tagged by
|
|
6011
|
-
* the channel it belongs to, so the agent loop can
|
|
6012
|
-
* separately as
|
|
6839
|
+
* the channel it belongs to, so the agent loop can forward answer content and live reasoning
|
|
6840
|
+
* separately as each delta arrives.
|
|
6013
6841
|
*
|
|
6014
6842
|
* @remarks
|
|
6015
6843
|
* The discriminant `channel` names the axis that varies: a
|
|
@@ -6067,6 +6895,7 @@ export declare interface ProviderIncrement {
|
|
|
6067
6895
|
readonly thinking: string;
|
|
6068
6896
|
readonly tools: readonly ToolCall[];
|
|
6069
6897
|
readonly usage?: TokenUsage;
|
|
6898
|
+
readonly truncated?: boolean;
|
|
6070
6899
|
readonly result?: ProviderResult;
|
|
6071
6900
|
}
|
|
6072
6901
|
|
|
@@ -6238,7 +7067,9 @@ schema: OptionalShape<ObjectShape<Record<never, never>, JSONShape>>;
|
|
|
6238
7067
|
* allows. `tools` is present only when the model requests tool calls (an
|
|
6239
7068
|
* empty array is never surfaced — its absence means "no calls"). `usage` is present
|
|
6240
7069
|
* only when the wire reported it (on the stream's `done` line, or the non-stream
|
|
6241
|
-
* body), so a caller folds it into a token budget exactly when it exists.
|
|
7070
|
+
* body), so a caller folds it into a token budget exactly when it exists. `truncated` is present
|
|
7071
|
+
* only when the provider's wire reports that the model stopped at its limit; the agent attributes a
|
|
7072
|
+
* truncated final answer to the model layer.
|
|
6242
7073
|
*/
|
|
6243
7074
|
export declare interface ProviderResult {
|
|
6244
7075
|
readonly content: string;
|
|
@@ -6248,6 +7079,12 @@ export declare interface ProviderResult {
|
|
|
6248
7079
|
readonly tools?: readonly ToolCall[];
|
|
6249
7080
|
/** Carries token consumption for this turn when present (from the wire's `done` line / body). */
|
|
6250
7081
|
readonly usage?: TokenUsage;
|
|
7082
|
+
/**
|
|
7083
|
+
* Reports that the model ended its answer at its own token limit (an output cap or a full context
|
|
7084
|
+
* window) rather than by finishing; present only when the provider's wire reports that stop. It
|
|
7085
|
+
* is not the request's prompt `truncate` setting.
|
|
7086
|
+
*/
|
|
7087
|
+
readonly truncated?: boolean;
|
|
6251
7088
|
}
|
|
6252
7089
|
|
|
6253
7090
|
/** Validates and projects provider results at a JSON wire boundary. */
|
|
@@ -6267,6 +7104,7 @@ prompt: number;
|
|
|
6267
7104
|
completion: number;
|
|
6268
7105
|
total: number;
|
|
6269
7106
|
} & {}>;
|
|
7107
|
+
truncated?: boolean;
|
|
6270
7108
|
}>>;
|
|
6271
7109
|
|
|
6272
7110
|
/**
|
|
@@ -6289,6 +7127,7 @@ prompt: NumberShape;
|
|
|
6289
7127
|
completion: NumberShape;
|
|
6290
7128
|
total: NumberShape;
|
|
6291
7129
|
}, boolean | ContractShape>>;
|
|
7130
|
+
truncated: OptionalShape<BooleanShape>;
|
|
6292
7131
|
}, boolean | ContractShape>;
|
|
6293
7132
|
|
|
6294
7133
|
/**
|
|
@@ -6328,6 +7167,29 @@ export declare function questionToSystemOne(question: JudgeQuestion): SystemOneQ
|
|
|
6328
7167
|
/** Lists the categories whose messages the projection leaves out as quiet. */
|
|
6329
7168
|
export declare const QUIET_CATEGORIES: readonly LedgerCategory[];
|
|
6330
7169
|
|
|
7170
|
+
/**
|
|
7171
|
+
* Settles with a promise, or rejects with the reason of a signal that aborts first, so a caller
|
|
7172
|
+
* is released at once even when the work behind the promise ignores the signal.
|
|
7173
|
+
*
|
|
7174
|
+
* @remarks
|
|
7175
|
+
* An absent signal returns `promise` itself. An already-aborted signal rejects with its reason
|
|
7176
|
+
* without waiting. The abort listener is removed as soon as `promise` settles. A rejection of
|
|
7177
|
+
* `promise` after the abort is handled here and never surfaces as unhandled.
|
|
7178
|
+
*
|
|
7179
|
+
* @param promise - The work to wait for
|
|
7180
|
+
* @param signal - The cancellation signal, or `undefined` for none
|
|
7181
|
+
* @returns A promise that settles as `promise` does, or rejects with `signal.reason` on abort
|
|
7182
|
+
*
|
|
7183
|
+
* @example
|
|
7184
|
+
* ```ts
|
|
7185
|
+
* const controller = new AbortController()
|
|
7186
|
+
* const raced = raceSignal(new Promise<string>(() => {}), controller.signal)
|
|
7187
|
+
* controller.abort(new Error('stop'))
|
|
7188
|
+
* await raced // rejects with the Error 'stop'
|
|
7189
|
+
* ```
|
|
7190
|
+
*/
|
|
7191
|
+
export declare function raceSignal<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T>;
|
|
7192
|
+
|
|
6331
7193
|
/**
|
|
6332
7194
|
* Ranks a briefing source for removal before the next prompt.
|
|
6333
7195
|
*
|
|
@@ -6362,14 +7224,22 @@ export declare function readChunks(body: ReadableStream<Uint8Array>, signal?: Ab
|
|
|
6362
7224
|
/**
|
|
6363
7225
|
* Reads a bounded HTTP failure excerpt and preserves an unreadable body's cause.
|
|
6364
7226
|
*
|
|
7227
|
+
* @remarks
|
|
7228
|
+
* Both HTTP engines, the provider and the judge, translate a non-OK response here and throw
|
|
7229
|
+
* their own coded error from the result. When the excerpt is read and `signal` has aborted, the
|
|
7230
|
+
* abort is the call's outcome, so the signal's reason is thrown. When the body read fails, the
|
|
7231
|
+
* failure is returned as `cause` whether or not `signal` has aborted, so a read that raced the
|
|
7232
|
+
* abort stays recorded on the error the caller throws.
|
|
7233
|
+
*
|
|
6365
7234
|
* @param response - The failed HTTP response
|
|
6366
7235
|
* @param prefix - The error taxonomy prefix, including its trailing colon
|
|
6367
7236
|
* @param signal - The call's combined caller and deadline signal
|
|
6368
|
-
* @returns The status message with any excerpt
|
|
7237
|
+
* @returns The status message with any excerpt, the response status, and any body-read failure
|
|
7238
|
+
* @throws Thrown when the excerpt is read after `signal` aborts, with the signal's reason
|
|
6369
7239
|
* @example
|
|
6370
7240
|
* ```ts
|
|
6371
7241
|
* await readFailure(new Response('unavailable', { status: 503 }), 'provider error:', new AbortController().signal)
|
|
6372
|
-
* // { message: 'provider error: 503 - unavailable' }
|
|
7242
|
+
* // { message: 'provider error: 503 - unavailable', status: 503 }
|
|
6373
7243
|
* ```
|
|
6374
7244
|
*/
|
|
6375
7245
|
export declare function readFailure(response: Response, prefix: string, signal: AbortSignal): Promise<FailureRead>;
|
|
@@ -6459,6 +7329,7 @@ prompt: number;
|
|
|
6459
7329
|
completion: number;
|
|
6460
7330
|
total: number;
|
|
6461
7331
|
} & {}>;
|
|
7332
|
+
truncated?: boolean;
|
|
6462
7333
|
}>;
|
|
6463
7334
|
} & {}> | Readonly<{
|
|
6464
7335
|
channel: "abort";
|
|
@@ -6478,6 +7349,7 @@ prompt: number;
|
|
|
6478
7349
|
completion: number;
|
|
6479
7350
|
total: number;
|
|
6480
7351
|
} & {}>;
|
|
7352
|
+
truncated?: boolean;
|
|
6481
7353
|
}>;
|
|
6482
7354
|
} & {}> | Readonly<{
|
|
6483
7355
|
channel: "error";
|
|
@@ -6510,6 +7382,7 @@ prompt: NumberShape;
|
|
|
6510
7382
|
completion: NumberShape;
|
|
6511
7383
|
total: NumberShape;
|
|
6512
7384
|
}, boolean | ContractShape>>;
|
|
7385
|
+
truncated: OptionalShape<BooleanShape>;
|
|
6513
7386
|
}, boolean | ContractShape>;
|
|
6514
7387
|
}, boolean | ContractShape>, ObjectShape< {
|
|
6515
7388
|
channel: LiteralShape<readonly ["abort"]>;
|
|
@@ -6526,6 +7399,7 @@ prompt: NumberShape;
|
|
|
6526
7399
|
completion: NumberShape;
|
|
6527
7400
|
total: NumberShape;
|
|
6528
7401
|
}, boolean | ContractShape>>;
|
|
7402
|
+
truncated: OptionalShape<BooleanShape>;
|
|
6529
7403
|
}, boolean | ContractShape>;
|
|
6530
7404
|
}, boolean | ContractShape>, ObjectShape< {
|
|
6531
7405
|
channel: LiteralShape<readonly ["error"]>;
|
|
@@ -6725,10 +7599,13 @@ export declare function renderCauseChain(error: unknown): string;
|
|
|
6725
7599
|
*
|
|
6726
7600
|
* @remarks
|
|
6727
7601
|
* Produces `` File: <path>\n```<language>\n<content>\n``` `` — the `File:` label line, then a
|
|
6728
|
-
* fenced code block tagged with `language`, the `content` verbatim inside.
|
|
6729
|
-
*
|
|
6730
|
-
*
|
|
6731
|
-
*
|
|
7602
|
+
* fenced code block tagged with `language`, the `content` verbatim inside. The fence is one
|
|
7603
|
+
* backtick longer than the longest backtick run in `content`, and never shorter than three (the
|
|
7604
|
+
* CommonMark rule), so file text holding a triple backtick cannot close the block early and
|
|
7605
|
+
* land outside it; content with no run of three or more keeps the three-backtick fence. Pure
|
|
7606
|
+
* string assembly, total — never throws. The one fenced-file format string for the whole
|
|
7607
|
+
* module — `AgentContext.build()` frames an active workspace's text files with it (each carries
|
|
7608
|
+
* its own `language` on its {@link import('@orkestrel/workspace').FileContent} text arm).
|
|
6732
7609
|
*
|
|
6733
7610
|
* @param path - The file path shown on the `File:` label line
|
|
6734
7611
|
* @param language - The fenced-code language tag (for example `'typescript'`)
|
|
@@ -6745,6 +7622,27 @@ export declare function renderCauseChain(error: unknown): string;
|
|
|
6745
7622
|
*/
|
|
6746
7623
|
export declare function renderFencedFile(path: string, language: string, content: string): string;
|
|
6747
7624
|
|
|
7625
|
+
/**
|
|
7626
|
+
* Renders a value as the JSON text `JSON.stringify` produces, or `undefined` when JSON cannot
|
|
7627
|
+
* carry the value.
|
|
7628
|
+
*
|
|
7629
|
+
* @remarks
|
|
7630
|
+
* Pure and total. Where `JSON.stringify` returns text, the result is the same text, property order
|
|
7631
|
+
* included; `canonicalStringify` from `@orkestrel/contract` sorts keys instead. A value
|
|
7632
|
+
* `JSON.stringify` throws on, such as a `BigInt` or a cycle, and a value it renders as nothing,
|
|
7633
|
+
* such as `undefined`, a function, or a symbol, return `undefined`.
|
|
7634
|
+
*
|
|
7635
|
+
* @param value - The value to render
|
|
7636
|
+
* @returns The JSON text, or `undefined` when the value has no JSON text
|
|
7637
|
+
* @example
|
|
7638
|
+
* ```ts
|
|
7639
|
+
* renderJSON({ order: 'LH-81660', late: true }) // '{"order":"LH-81660","late":true}'
|
|
7640
|
+
* renderJSON(10n) // undefined
|
|
7641
|
+
* renderJSON(undefined) // undefined
|
|
7642
|
+
* ```
|
|
7643
|
+
*/
|
|
7644
|
+
export declare function renderJSON(value: unknown): string | undefined;
|
|
7645
|
+
|
|
6748
7646
|
/**
|
|
6749
7647
|
* Renders one owner record under a `###` heading, which the briefing nests under its one `## Pinned` heading.
|
|
6750
7648
|
*
|
|
@@ -6775,22 +7673,42 @@ export declare function renderLedgerPinned(record: Pick<LedgerRecord, 'title' |
|
|
|
6775
7673
|
*/
|
|
6776
7674
|
export declare function renderLedgerRecord(record: Pick<LedgerRecord, 'title' | 'lines'>): string;
|
|
6777
7675
|
|
|
7676
|
+
/**
|
|
7677
|
+
* Renders a lookup call as its tool name and its JSON arguments.
|
|
7678
|
+
*
|
|
7679
|
+
* @remarks
|
|
7680
|
+
* The arguments keep the text `JSON.stringify` writes, key order included. Arguments JSON cannot
|
|
7681
|
+
* carry, such as a `BigInt` or a cycle, render the bare tool name instead of throwing.
|
|
7682
|
+
*
|
|
7683
|
+
* @param name - The lookup tool name
|
|
7684
|
+
* @param args - The arguments the call carried
|
|
7685
|
+
* @returns The tool name, a space, and the JSON arguments; the bare tool name when JSON cannot carry them
|
|
7686
|
+
*
|
|
7687
|
+
* @example
|
|
7688
|
+
* ```ts
|
|
7689
|
+
* renderLookupCall('lookup_order', { id: 'BW-5512' }) // 'lookup_order {"id":"BW-5512"}'
|
|
7690
|
+
* renderLookupCall('lookup_order', { count: 1n }) // 'lookup_order'
|
|
7691
|
+
* ```
|
|
7692
|
+
*/
|
|
7693
|
+
export declare function renderLookupCall(name: string, args: Readonly<Record<string, unknown>>): string;
|
|
7694
|
+
|
|
6778
7695
|
/**
|
|
6779
7696
|
* Renders one context section — the resolved `open`, each item's rendering, and the resolved
|
|
6780
7697
|
* `close` when one exists, blank-line joined; `undefined` when the section has no items.
|
|
6781
7698
|
*
|
|
6782
7699
|
* @remarks
|
|
6783
7700
|
* Pure and total. A section with no items renders nothing (`undefined`), so an empty or fully
|
|
6784
|
-
* scoped-out manager stays silent — its `open` / `close` appear only when the section has items.
|
|
6785
|
-
*
|
|
6786
|
-
*
|
|
7701
|
+
* scoped-out manager stays silent — its `open` / `close` appear only when the section has items.
|
|
7702
|
+
* An empty or absent slot is dropped before the join, so an `open: ''`, a `close: ''`, an unset
|
|
7703
|
+
* `close` (there is no built-in close), and an item rendered to `''` each add no blank line; a
|
|
7704
|
+
* section whose every slot is empty renders nothing (`undefined`).
|
|
6787
7705
|
*
|
|
6788
7706
|
* @typeParam T - The section item being rendered
|
|
6789
7707
|
* @param open - The section's resolved leading text
|
|
6790
7708
|
* @param members - The already scope-filtered items
|
|
6791
7709
|
* @param render - Renders one item to its prompt text
|
|
6792
7710
|
* @param close - The section's resolved trailing text, or `undefined` for none
|
|
6793
|
-
* @returns The rendered section, or `undefined` when there are no items
|
|
7711
|
+
* @returns The rendered section, or `undefined` when there are no items or every slot is empty
|
|
6794
7712
|
*
|
|
6795
7713
|
* @example
|
|
6796
7714
|
* ```ts
|
|
@@ -6805,7 +7723,7 @@ export declare function renderSection<T>(open: string, members: readonly T[], re
|
|
|
6805
7723
|
* Renders the tail stub of a lookup result from an earlier request.
|
|
6806
7724
|
*
|
|
6807
7725
|
* @param name - The lookup tool name
|
|
6808
|
-
* @param args - The arguments the call carried
|
|
7726
|
+
* @param args - The arguments the call carried; arguments JSON cannot carry leave the call as its bare tool name, per {@link renderLookupCall}
|
|
6809
7727
|
* @param state - What became of the result: `failed`, `empty`, `shown` in the briefing, or `hidden` from it
|
|
6810
7728
|
* @returns The stub text, which carries the call and its state
|
|
6811
7729
|
*
|
|
@@ -6817,6 +7735,28 @@ export declare function renderSection<T>(open: string, members: readonly T[], re
|
|
|
6817
7735
|
*/
|
|
6818
7736
|
export declare function renderStub(name: string, args: Readonly<Record<string, unknown>>, state: LedgerLookupState): string;
|
|
6819
7737
|
|
|
7738
|
+
/**
|
|
7739
|
+
* Renders a tool's output as the string content of its tool message.
|
|
7740
|
+
*
|
|
7741
|
+
* @remarks
|
|
7742
|
+
* A string passes through unchanged and `undefined` renders as `''`. Any other value renders as
|
|
7743
|
+
* its `JSON.stringify` text, byte for byte, when JSON can carry it. A value JSON cannot carry (a
|
|
7744
|
+
* `BigInt`, a cycle, a symbol, a throwing `toJSON`) renders as `String(value)`, and as `''` when
|
|
7745
|
+
* that conversion throws too, so a tool's output never rejects the run that dispatched it.
|
|
7746
|
+
*
|
|
7747
|
+
* @param value - The tool's output (`ToolSuccess.value`, which may be `undefined`)
|
|
7748
|
+
* @returns The message content
|
|
7749
|
+
*
|
|
7750
|
+
* @example
|
|
7751
|
+
* ```ts
|
|
7752
|
+
* renderToolValue('sunny') // 'sunny'
|
|
7753
|
+
* renderToolValue({ count: 2 }) // '{"count":2}'
|
|
7754
|
+
* renderToolValue(undefined) // ''
|
|
7755
|
+
* renderToolValue(10n) // '10'
|
|
7756
|
+
* ```
|
|
7757
|
+
*/
|
|
7758
|
+
export declare function renderToolValue(value: unknown): string;
|
|
7759
|
+
|
|
6820
7760
|
/**
|
|
6821
7761
|
* Renders topic names as a comma-separated list in their supplied order.
|
|
6822
7762
|
* @param topics - The configured desk topics
|
|
@@ -6828,13 +7768,74 @@ export declare function renderStub(name: string, args: Readonly<Record<string, u
|
|
|
6828
7768
|
*/
|
|
6829
7769
|
export declare function renderTopicNames(topics: readonly LedgerTopic[]): string;
|
|
6830
7770
|
|
|
7771
|
+
/**
|
|
7772
|
+
* Holds the disjoint estimate components of one provider request, in heuristic estimate units.
|
|
7773
|
+
*
|
|
7774
|
+
* @remarks
|
|
7775
|
+
* `messages` keeps the request's message order, duplicate ids included. `tools` and `schema` are the
|
|
7776
|
+
* estimates of the rendered advertised tools and `options.schema`, each `0` when absent or empty and
|
|
7777
|
+
* the framing overhead when unrenderable. A request's estimate is the sum of every message component
|
|
7778
|
+
* plus `tools` and `schema`; no total is stored.
|
|
7779
|
+
*/
|
|
7780
|
+
export declare interface RequestMeasure {
|
|
7781
|
+
readonly messages: readonly MessageMeasure[];
|
|
7782
|
+
readonly tools: number;
|
|
7783
|
+
readonly schema: number;
|
|
7784
|
+
}
|
|
7785
|
+
|
|
7786
|
+
/**
|
|
7787
|
+
* Projects a provider request onto the declared members the relay wire carries.
|
|
7788
|
+
*
|
|
7789
|
+
* @remarks
|
|
7790
|
+
* Each message keeps `id`, `role`, `content`, and any `calls`, `call`, `images`, and `thinking`;
|
|
7791
|
+
* each call keeps only `id`, `name`, and `arguments`, so a local execution context never reaches
|
|
7792
|
+
* the wire. Each tool keeps `name` and any `description` and `parameters`, and the options keep
|
|
7793
|
+
* any `think` and `schema`. An absent member stays absent. The projection shares every nested
|
|
7794
|
+
* value with the input rather than copying it, so the caller snapshots and validates the result;
|
|
7795
|
+
* a throwing getter propagates its failure.
|
|
7796
|
+
*
|
|
7797
|
+
* @param request - The domain conversation and call configuration
|
|
7798
|
+
* @returns The request with only the members the relay wire declares
|
|
7799
|
+
* @example
|
|
7800
|
+
* ```ts
|
|
7801
|
+
* requestToRelay({
|
|
7802
|
+
* messages: [{ id: 'turn-1', role: 'user', content: 'Track BW-5512' }],
|
|
7803
|
+
* options: { think: false },
|
|
7804
|
+
* })
|
|
7805
|
+
* // { messages: [{ id: 'turn-1', role: 'user', content: 'Track BW-5512' }], options: { think: false } }
|
|
7806
|
+
* ```
|
|
7807
|
+
*/
|
|
7808
|
+
export declare function requestToRelay(request: ProviderRequest): ProviderRequest;
|
|
7809
|
+
|
|
7810
|
+
/**
|
|
7811
|
+
* Returns a run's budget or allowance after checking it implements `BudgetInterface`, or throws a
|
|
7812
|
+
* coded error before the run starts it.
|
|
7813
|
+
*
|
|
7814
|
+
* @remarks
|
|
7815
|
+
* The check is `isBudget` from `@orkestrel/budget`, a total guard. `undefined` passes, because an
|
|
7816
|
+
* absent bound is no bound. The error's `context` carries the option path, the limit
|
|
7817
|
+
* `'BudgetInterface'`, and a preview of the refused value.
|
|
7818
|
+
*
|
|
7819
|
+
* @param value - The effective `budget` or `allowance`, or `undefined`
|
|
7820
|
+
* @param key - The option the value came from, named in the error's path
|
|
7821
|
+
* @returns The value unchanged
|
|
7822
|
+
* @throws {ContractError} Thrown when `value` is defined and does not implement `BudgetInterface` (code `'placement'`)
|
|
7823
|
+
*
|
|
7824
|
+
* @example
|
|
7825
|
+
* ```ts
|
|
7826
|
+
* requireBudget(createTokenBudget({ max: 10 }), 'budget') // the budget
|
|
7827
|
+
* requireBudget({ consume() {} }, 'allowance') // throws ContractError ('placement')
|
|
7828
|
+
* ```
|
|
7829
|
+
*/
|
|
7830
|
+
export declare function requireBudget(value: BudgetInterface<TokenUsage> | undefined, key: 'budget' | 'allowance'): BudgetInterface<TokenUsage> | undefined;
|
|
7831
|
+
|
|
6831
7832
|
/**
|
|
6832
7833
|
* Returns a registered value or throws when its name is absent.
|
|
6833
7834
|
* @param pool - The named values
|
|
6834
7835
|
* @param category - The registry category named in an error
|
|
6835
7836
|
* @param name - The requested key
|
|
6836
7837
|
* @returns The registered value
|
|
6837
|
-
* @throws {AgentError} Thrown when the name is absent, with code REGISTRY
|
|
7838
|
+
* @throws {AgentError} Thrown when the name is absent, with code REGISTRY and a `context` naming the `category` and the `name`.
|
|
6838
7839
|
* @example
|
|
6839
7840
|
* ```ts
|
|
6840
7841
|
* requireEntry(new Map([['main', provider]]), 'provider', 'main') // provider
|
|
@@ -6861,6 +7862,71 @@ export declare function requireEntry<T>(pool: ReadonlyMap<string, T>, category:
|
|
|
6861
7862
|
*/
|
|
6862
7863
|
export declare function requireJudgment(value: unknown): Judgment;
|
|
6863
7864
|
|
|
7865
|
+
/**
|
|
7866
|
+
* Returns a retained-tail size after checking it is a nonnegative safe integer, or throws a coded
|
|
7867
|
+
* error.
|
|
7868
|
+
*
|
|
7869
|
+
* @remarks
|
|
7870
|
+
* The check is {@link import('../validators.js').isNonNegativeSafeInteger}, so `0` and `-0`
|
|
7871
|
+
* pass while `NaN`, a fraction, a negative, and either infinity are refused. The error's `context`
|
|
7872
|
+
* carries the refused value as `keep`.
|
|
7873
|
+
*
|
|
7874
|
+
* @param keep - The retained-tail size to check
|
|
7875
|
+
* @returns The size unchanged
|
|
7876
|
+
* @throws ConversationError Thrown when `keep` is not a nonnegative safe integer (code `'KEEP'`)
|
|
7877
|
+
*
|
|
7878
|
+
* @example
|
|
7879
|
+
* ```ts
|
|
7880
|
+
* requireKeep(2) // 2
|
|
7881
|
+
* requireKeep(1.5) // throws ConversationError ('KEEP')
|
|
7882
|
+
* ```
|
|
7883
|
+
*/
|
|
7884
|
+
export declare function requireKeep(keep: number): number;
|
|
7885
|
+
|
|
7886
|
+
/**
|
|
7887
|
+
* Returns a tool-iteration cap after checking it is a nonnegative safe integer, or throws a coded
|
|
7888
|
+
* error.
|
|
7889
|
+
*
|
|
7890
|
+
* @remarks
|
|
7891
|
+
* The check is {@link import('../validators.js').isNonNegativeSafeInteger}, so `0` and `-0`
|
|
7892
|
+
* pass while `NaN`, a fraction, a negative, and either infinity are refused. The error's `context`
|
|
7893
|
+
* carries the refused value as `limit`.
|
|
7894
|
+
*
|
|
7895
|
+
* @param limit - The tool-iteration cap to check
|
|
7896
|
+
* @returns The cap unchanged
|
|
7897
|
+
* @throws {AgentError} Thrown when `limit` is not a nonnegative safe integer (code `'LIMIT'`)
|
|
7898
|
+
*
|
|
7899
|
+
* @example
|
|
7900
|
+
* ```ts
|
|
7901
|
+
* requireLimit(3) // 3
|
|
7902
|
+
* requireLimit(1.5) // throws AgentError ('LIMIT')
|
|
7903
|
+
* ```
|
|
7904
|
+
*/
|
|
7905
|
+
export declare function requireLimit(limit: number): number;
|
|
7906
|
+
|
|
7907
|
+
/**
|
|
7908
|
+
* Returns the rolling switch after checking it does not combine with a `sections` cap, or throws a
|
|
7909
|
+
* coded error.
|
|
7910
|
+
*
|
|
7911
|
+
* @remarks
|
|
7912
|
+
* A rolling conversation keeps one section, so a cap has nothing to bound. The cap checked is the
|
|
7913
|
+
* effective one: inherited from a manager, configured on the conversation, or supplied to one
|
|
7914
|
+
* `compact()` call.
|
|
7915
|
+
*
|
|
7916
|
+
* @param rolling - Whether folds roll every prior section into one
|
|
7917
|
+
* @param cap - The effective `sections` cap, or `undefined` for none
|
|
7918
|
+
* @returns The rolling switch unchanged
|
|
7919
|
+
* @throws ConversationError Thrown when `rolling` is true and a cap is present (code `'SECTIONS'`)
|
|
7920
|
+
*
|
|
7921
|
+
* @example
|
|
7922
|
+
* ```ts
|
|
7923
|
+
* requireRolling(true, undefined) // true
|
|
7924
|
+
* requireRolling(false, 2) // false
|
|
7925
|
+
* requireRolling(true, 2) // throws ConversationError ('SECTIONS')
|
|
7926
|
+
* ```
|
|
7927
|
+
*/
|
|
7928
|
+
export declare function requireRolling(rolling: boolean, cap: number | undefined): boolean;
|
|
7929
|
+
|
|
6864
7930
|
/**
|
|
6865
7931
|
* Returns a `sections` cap after checking its lower bound, or throws a coded error.
|
|
6866
7932
|
*
|
|
@@ -6896,7 +7962,7 @@ export declare function requireSectionsCap(cap: number | undefined): number | un
|
|
|
6896
7962
|
export declare function resolvePredict(predict: number | undefined, capacity: number): number;
|
|
6897
7963
|
|
|
6898
7964
|
/**
|
|
6899
|
-
* Sanitizes one reported token count into a
|
|
7965
|
+
* Sanitizes one reported token count into a non-negative integer — a non-finite or
|
|
6900
7966
|
* non-positive value becomes `0`, and a positive fractional value floors down.
|
|
6901
7967
|
*
|
|
6902
7968
|
* @param value - The token count to sanitize
|
|
@@ -6911,7 +7977,7 @@ export declare function resolvePredict(predict: number | undefined, capacity: nu
|
|
|
6911
7977
|
export declare function sanitizeToken(value: number): number;
|
|
6912
7978
|
|
|
6913
7979
|
/**
|
|
6914
|
-
* Sanitizes a {@link TokenUsage} into
|
|
7980
|
+
* Sanitizes a {@link TokenUsage} into non-negative integers — the guard an agent's
|
|
6915
7981
|
* abort-usage path applies to a provider's partial usage before it is charged against a
|
|
6916
7982
|
* budget or folded into the run total.
|
|
6917
7983
|
*
|
|
@@ -6921,7 +7987,7 @@ export declare function sanitizeToken(value: number): number;
|
|
|
6921
7987
|
* non-negative integer part. No upper cap is applied. Total — never throws.
|
|
6922
7988
|
*
|
|
6923
7989
|
* @param usage - The token usage to sanitize (for example a provider's abort-partial usage)
|
|
6924
|
-
* @returns A new {@link TokenUsage} with every field a
|
|
7990
|
+
* @returns A new {@link TokenUsage} with every field a non-negative integer
|
|
6925
7991
|
*
|
|
6926
7992
|
* @example
|
|
6927
7993
|
* ```ts
|
|
@@ -7062,20 +8128,20 @@ export declare interface ScopeInterface extends ScopeFilter {
|
|
|
7062
8128
|
|
|
7063
8129
|
/**
|
|
7064
8130
|
* Registers the named filters a richer context reuses — immutable {@link Scope} instances keyed by their
|
|
7065
|
-
* minted `id`, in insertion order, where `
|
|
8131
|
+
* minted `id`, in insertion order, where `add` always mints and stores rather than overwriting,
|
|
7066
8132
|
* and an observable `emitter` reports each change.
|
|
7067
8133
|
*
|
|
7068
8134
|
* @remarks
|
|
7069
8135
|
* - **Registry.** Scopes live in an insertion-ordered `Map` keyed by their minted `id`;
|
|
7070
|
-
* `
|
|
8136
|
+
* `add` mints a {@link Scope} from a {@link ScopeInput} (an `id` plus the three
|
|
7071
8137
|
* allow-lists), stores it, and returns it. `count` is the map size, `scope(id)` looks
|
|
7072
8138
|
* one up, and `scopes()` lists them in insertion order. (Unlike the name-keyed
|
|
7073
8139
|
* instruction registry, a scope's key is its minted `id`, so two scopes may share a
|
|
7074
|
-
* `name`; `
|
|
8140
|
+
* `name`; `add` therefore never overwrites.)
|
|
7075
8141
|
* - **Removal.** `remove` drops one by id, or a batch — `true` only when every supplied id
|
|
7076
8142
|
* was removed; `clear` empties the registry.
|
|
7077
8143
|
* - **Observable.** The owned {@link emitter} ({@link ScopeManagerEventMap}) carries
|
|
7078
|
-
* `
|
|
8144
|
+
* `add` (the added scope) / `remove` (the id) / `clear`. Every event is emitted
|
|
7079
8145
|
* directly, strictly after the map mutation completes; the emitter isolates a listener
|
|
7080
8146
|
* throw and routes it to its `error` handler (the `error` option), so a buggy observer can
|
|
7081
8147
|
* never corrupt a mutation.
|
|
@@ -7083,7 +8149,7 @@ export declare interface ScopeInterface extends ScopeFilter {
|
|
|
7083
8149
|
* @example
|
|
7084
8150
|
* ```ts
|
|
7085
8151
|
* const manager = new ScopeManager()
|
|
7086
|
-
* const reader = manager.
|
|
8152
|
+
* const reader = manager.add({ name: 'reader', tools: ['search', 'read'] })
|
|
7087
8153
|
* manager.scope(reader.id) // the same scope
|
|
7088
8154
|
* manager.count // 1
|
|
7089
8155
|
* ```
|
|
@@ -7093,7 +8159,7 @@ export declare class ScopeManager implements ScopeManagerInterface {
|
|
|
7093
8159
|
constructor(options?: ScopeManagerOptions);
|
|
7094
8160
|
get emitter(): EmitterInterface<ScopeManagerEventMap>;
|
|
7095
8161
|
get count(): number;
|
|
7096
|
-
|
|
8162
|
+
add(input: ScopeInput): ScopeInterface;
|
|
7097
8163
|
scope(id: string): ScopeInterface | undefined;
|
|
7098
8164
|
scopes(): readonly ScopeInterface[];
|
|
7099
8165
|
remove(id: string): boolean;
|
|
@@ -7103,17 +8169,17 @@ export declare class ScopeManager implements ScopeManagerInterface {
|
|
|
7103
8169
|
|
|
7104
8170
|
/**
|
|
7105
8171
|
* Maps the push observation surface of a {@link ScopeManagerInterface} — analogous to
|
|
7106
|
-
* {@link InstructionManagerEventMap}, but keyed by the minted `id`
|
|
7107
|
-
*
|
|
8172
|
+
* {@link InstructionManagerEventMap}, but keyed by the minted `id`, so `add` never reports a
|
|
8173
|
+
* replaced scope.
|
|
7108
8174
|
*
|
|
7109
8175
|
* @remarks
|
|
7110
|
-
* `
|
|
8176
|
+
* `add` carries the added {@link ScopeInterface}; `remove` carries the removed
|
|
7111
8177
|
* scope's `id`; `clear` is a pure signal. The emitter isolates a listener throw and routes
|
|
7112
8178
|
* it to its `error` handler. A `type` alias so it satisfies `EventMap` structurally.
|
|
7113
8179
|
*/
|
|
7114
8180
|
export declare type ScopeManagerEventMap = {
|
|
7115
|
-
/** Reports a scope
|
|
7116
|
-
readonly
|
|
8181
|
+
/** Reports a scope added — the added scope. */
|
|
8182
|
+
readonly add: readonly [scope: ScopeInterface];
|
|
7117
8183
|
/** Reports a scope removed — its `id`. */
|
|
7118
8184
|
readonly remove: readonly [id: string];
|
|
7119
8185
|
/** Reports every scope removed. */
|
|
@@ -7121,16 +8187,16 @@ export declare type ScopeManagerEventMap = {
|
|
|
7121
8187
|
};
|
|
7122
8188
|
|
|
7123
8189
|
/**
|
|
7124
|
-
* Registers reusable {@link ScopeInterface} instances keyed by their minted `id` — `
|
|
8190
|
+
* Registers reusable {@link ScopeInterface} instances keyed by their minted `id` — `add`
|
|
7125
8191
|
* mints + stores one (never overwrites), `scopes()` lists them in insertion order.
|
|
7126
8192
|
*
|
|
7127
8193
|
* @remarks
|
|
7128
|
-
* - **Registry.** `
|
|
8194
|
+
* - **Registry.** `add(input)` mints a scope (an `id` + the per-category allow-lists) and
|
|
7129
8195
|
* stores it; `count` is how many are stored. `scope(id)` looks one up; `scopes()` lists
|
|
7130
8196
|
* them in insertion order. (Keyed by minted `id`, not `name`, so two scopes may share a
|
|
7131
|
-
* `name` and `
|
|
8197
|
+
* `name` and `add` never overwrites.)
|
|
7132
8198
|
* - **Observable.** The owned `emitter` ({@link ScopeManagerEventMap}) carries
|
|
7133
|
-
* `
|
|
8199
|
+
* `add` / `remove` / `clear` for fire-and-forget observers; the emitter isolates a
|
|
7134
8200
|
* listener throw and routes it to its `error` handler (the `error` option).
|
|
7135
8201
|
*/
|
|
7136
8202
|
export declare interface ScopeManagerInterface {
|
|
@@ -7139,13 +8205,30 @@ export declare interface ScopeManagerInterface {
|
|
|
7139
8205
|
/**
|
|
7140
8206
|
* Mints a scope from a {@link ScopeInput} (a `name` plus the per-category allow-lists) and
|
|
7141
8207
|
* stores it — always adds, never overwrites.
|
|
8208
|
+
*
|
|
8209
|
+
* @param input - The scope's `name`, allow-lists, and optional `select` handler
|
|
8210
|
+
* @returns The stored scope, carrying its minted `id`
|
|
8211
|
+
*/
|
|
8212
|
+
add(input: ScopeInput): ScopeInterface;
|
|
8213
|
+
/**
|
|
8214
|
+
* Looks up one scope by id (`undefined` when absent).
|
|
8215
|
+
*
|
|
8216
|
+
* @param id - The minted scope id to look up
|
|
8217
|
+
* @returns The stored scope, or `undefined` when absent
|
|
7142
8218
|
*/
|
|
7143
|
-
create(input: ScopeInput): ScopeInterface;
|
|
7144
|
-
/** Looks up one scope by id (`undefined` when absent). */
|
|
7145
8219
|
scope(id: string): ScopeInterface | undefined;
|
|
7146
|
-
/**
|
|
8220
|
+
/**
|
|
8221
|
+
* Lists every scope, in insertion order.
|
|
8222
|
+
*
|
|
8223
|
+
* @returns Every stored scope, in insertion order
|
|
8224
|
+
*/
|
|
7147
8225
|
scopes(): readonly ScopeInterface[];
|
|
7148
|
-
/**
|
|
8226
|
+
/**
|
|
8227
|
+
* Removes one scope by id, or a batch. True if every supplied id was removed; false otherwise.
|
|
8228
|
+
*
|
|
8229
|
+
* @param id - One scope id, or a batch
|
|
8230
|
+
* @returns True if every supplied id was present and removed; false otherwise
|
|
8231
|
+
*/
|
|
7149
8232
|
remove(id: string): boolean;
|
|
7150
8233
|
remove(ids: readonly string[]): boolean;
|
|
7151
8234
|
/** Removes every scope. */
|
|
@@ -7299,6 +8382,23 @@ export declare function selectRecords(projection: LedgerProjection, request: Led
|
|
|
7299
8382
|
*/
|
|
7300
8383
|
export declare function settleAgentJob(agent: AgentInterface, partial: boolean): Promise<AgentResult>;
|
|
7301
8384
|
|
|
8385
|
+
/**
|
|
8386
|
+
* Splits a tool result into its lines at each line feed, with or without a carriage return before it.
|
|
8387
|
+
*
|
|
8388
|
+
* @remarks
|
|
8389
|
+
* The recall listing keys each recalled line by its first line, and the answer note reads a result
|
|
8390
|
+
* line by line, so both read lines through this one split.
|
|
8391
|
+
*
|
|
8392
|
+
* @param text - The tool result text
|
|
8393
|
+
* @returns The lines in order, an empty line included; one empty line for an empty text
|
|
8394
|
+
*
|
|
8395
|
+
* @example
|
|
8396
|
+
* ```ts
|
|
8397
|
+
* splitResultLines('Account BW-20931.\r\nRefund is $148.50.') // ['Account BW-20931.', 'Refund is $148.50.']
|
|
8398
|
+
* ```
|
|
8399
|
+
*/
|
|
8400
|
+
export declare function splitResultLines(text: string): readonly string[];
|
|
8401
|
+
|
|
7302
8402
|
/**
|
|
7303
8403
|
* Splits a message into its sentences.
|
|
7304
8404
|
*
|
|
@@ -7591,9 +8691,9 @@ export declare const THINK_OPEN = "<think>";
|
|
|
7591
8691
|
export declare type ThinkingReplay = 'none' | 'turn' | 'all';
|
|
7592
8692
|
|
|
7593
8693
|
/**
|
|
7594
|
-
*
|
|
7595
|
-
*
|
|
7596
|
-
*
|
|
8694
|
+
* Separates `<think>…</think>` spans from raw content deltas with per-stream state: text inside a
|
|
8695
|
+
* span accumulates on `thinking`, and text outside it returns as clean content, so a provider
|
|
8696
|
+
* yields the answer alone and surfaces the reasoning as
|
|
7597
8697
|
* {@link import('./types.js').ProviderResult.thinking}. A tag split across deltas is held until
|
|
7598
8698
|
* disambiguated, `flush()` settles the stream end, and one splitter serves one stream.
|
|
7599
8699
|
*
|
|
@@ -7645,7 +8745,7 @@ export declare class ThinkSplitter implements ThinkSplitterInterface {
|
|
|
7645
8745
|
* - **Stateful across deltas.** A tag may arrive split across wire chunks (`'<thi'`
|
|
7646
8746
|
* ending one delta, `'nk>'` opening the next) — `split` holds any ambiguous tail
|
|
7647
8747
|
* back until the next delta (or `flush`) disambiguates it, so a partial tag is
|
|
7648
|
-
*
|
|
8748
|
+
* neither returned as content nor routed to thinking.
|
|
7649
8749
|
* - **`split(delta)`** feeds one raw content delta and returns the clean content to
|
|
7650
8750
|
* surface for it (possibly `''` — for example mid-think). Text inside a
|
|
7651
8751
|
* `<think>…</think>` span accumulates on `thinking`; multiple spans accumulate in
|
|
@@ -7676,8 +8776,8 @@ export declare interface ThinkSplitterInterface {
|
|
|
7676
8776
|
readonly thinking: string;
|
|
7677
8777
|
/**
|
|
7678
8778
|
* Feeds one raw delta and returns the clean, non-think content to surface for it (possibly
|
|
7679
|
-
* `''`) — a tag split across deltas is held until disambiguated,
|
|
7680
|
-
*
|
|
8779
|
+
* `''`) — a tag split across deltas is held until disambiguated, so it is neither returned
|
|
8780
|
+
* as content nor routed to thinking.
|
|
7681
8781
|
*/
|
|
7682
8782
|
split(delta: string): string;
|
|
7683
8783
|
/**
|
|
@@ -7687,6 +8787,31 @@ export declare interface ThinkSplitterInterface {
|
|
|
7687
8787
|
flush(): string;
|
|
7688
8788
|
}
|
|
7689
8789
|
|
|
8790
|
+
/**
|
|
8791
|
+
* Projects an unknown value onto a fresh, exact `TokenUsage` — capturing `prompt`, `completion`, and
|
|
8792
|
+
* `total` once each through a total boundary, preserving finite negative and fractional counts,
|
|
8793
|
+
* dropping extras, and resolving `undefined` for a non-object, a missing or non-finite count, a
|
|
8794
|
+
* throwing getter, or a hostile or revoked proxy.
|
|
8795
|
+
*
|
|
8796
|
+
* @remarks
|
|
8797
|
+
* The capture runs inside Contract's sanctioned exception boundary, so conforming accessors and
|
|
8798
|
+
* inherited properties are read while a throwing getter or a revoked proxy returns `undefined`.
|
|
8799
|
+
* Counts are not normalized. A caller that treats an absent usage as valid checks for `undefined`
|
|
8800
|
+
* before it projects, because this function refuses `undefined` like any other non-object.
|
|
8801
|
+
*
|
|
8802
|
+
* @param value - The unknown value to project
|
|
8803
|
+
* @returns A fresh `{ prompt, completion, total }`, or `undefined` when the value is not a finite usage triple
|
|
8804
|
+
*
|
|
8805
|
+
* @example
|
|
8806
|
+
* ```ts
|
|
8807
|
+
* import { tokenUsageToJSON } from '@orkestrel/agent'
|
|
8808
|
+
*
|
|
8809
|
+
* tokenUsageToJSON({ prompt: 2, completion: -1, total: 1.5, cached: 4 }) // { prompt: 2, completion: -1, total: 1.5 }
|
|
8810
|
+
* tokenUsageToJSON({ prompt: 2, completion: Infinity, total: 3 }) // undefined
|
|
8811
|
+
* ```
|
|
8812
|
+
*/
|
|
8813
|
+
export declare function tokenUsageToJSON(value: unknown): TokenUsage | undefined;
|
|
8814
|
+
|
|
7690
8815
|
/**
|
|
7691
8816
|
* Describes a tool call's JSON wire projection.
|
|
7692
8817
|
*
|
|
@@ -7717,15 +8842,16 @@ export declare const UPSTREAM_RELAY_STATUS = 502;
|
|
|
7717
8842
|
/**
|
|
7718
8843
|
* Names the section header the `build()` method of {@link import('./AgentContext.js').AgentContext}
|
|
7719
8844
|
* renders the active workspace's text files under — `'## Workspace'`, the leading line of the dedicated
|
|
7720
|
-
* workspace block in the system message
|
|
7721
|
-
* images section headers.
|
|
8845
|
+
* workspace block in the system message.
|
|
7722
8846
|
*
|
|
7723
8847
|
* @remarks
|
|
7724
8848
|
* `build()` owns the workspace render (a `Workspace` / `WorkspaceManager` stays file-focused — no
|
|
7725
8849
|
* `open` / `format` getters), so this header lives here as the contexts module's one
|
|
7726
8850
|
* workspace-section framing constant rather than on a manager. Each workspace text file renders
|
|
7727
|
-
* beneath it as a fenced `` File: <path>\n```<language>\n<text>\n``` `` block
|
|
7728
|
-
*
|
|
8851
|
+
* beneath it as a fenced `` File: <path>\n```<language>\n<text>\n``` `` block through
|
|
8852
|
+
* {@link import('./helpers.js').renderFencedFile}, and the block is placed immediately after the
|
|
8853
|
+
* instructions section in the system block. The workspace's image files render no section: their
|
|
8854
|
+
* `base64` payload attaches to the last user message.
|
|
7729
8855
|
*/
|
|
7730
8856
|
export declare const WORKSPACE_SECTION_HEADER = "## Workspace";
|
|
7731
8857
|
|