@orkestrel/agent 0.0.21 → 0.0.23
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/README.md +16 -13
- package/dist/src/core/index.cjs +973 -36
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +830 -26
- package/dist/src/core/index.d.ts +830 -26
- package/dist/src/core/index.js +948 -39
- package/dist/src/core/index.js.map +1 -1
- package/package.json +9 -7
package/dist/src/core/index.d.ts
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
|
+
import { ArrayShape } from '@orkestrel/contract';
|
|
2
|
+
import { BooleanShape } from '@orkestrel/contract';
|
|
1
3
|
import type { BudgetInterface } from '@orkestrel/budget';
|
|
4
|
+
import { ContractInterface } from '@orkestrel/contract';
|
|
5
|
+
import type { ContractShape } from '@orkestrel/contract';
|
|
2
6
|
import type { ControllerInterface } from '@orkestrel/workflow';
|
|
3
7
|
import type { DriverInterface } from '@orkestrel/database';
|
|
4
8
|
import type { EmitterErrorHandler } from '@orkestrel/emitter';
|
|
5
9
|
import type { EmitterHooks } from '@orkestrel/emitter';
|
|
6
10
|
import type { EmitterInterface } from '@orkestrel/emitter';
|
|
7
11
|
import type { FileInterface } from '@orkestrel/workspace';
|
|
8
|
-
import
|
|
12
|
+
import { JSONShape } from '@orkestrel/contract';
|
|
13
|
+
import { JSONValue } from '@orkestrel/contract';
|
|
14
|
+
import { LiteralShape } from '@orkestrel/contract';
|
|
15
|
+
import { NumberShape } from '@orkestrel/contract';
|
|
16
|
+
import { ObjectShape } from '@orkestrel/contract';
|
|
17
|
+
import { OptionalShape } from '@orkestrel/contract';
|
|
9
18
|
import type { QueueContext } from '@orkestrel/queue';
|
|
10
19
|
import type { QueueInterface } from '@orkestrel/queue';
|
|
11
20
|
import type { QueueStoreInterface } from '@orkestrel/queue';
|
|
12
21
|
import type { RunnerInterface } from '@orkestrel/workflow';
|
|
13
22
|
import type { SchedulerInterface } from '@orkestrel/workflow';
|
|
23
|
+
import { StringShape } from '@orkestrel/contract';
|
|
14
24
|
import type { TableInterface } from '@orkestrel/database';
|
|
15
25
|
import type { TokenUsage } from '@orkestrel/budget';
|
|
16
26
|
import type { ToolCall } from '@orkestrel/tool';
|
|
@@ -18,6 +28,7 @@ import type { ToolDefinition } from '@orkestrel/tool';
|
|
|
18
28
|
import type { ToolInterface } from '@orkestrel/tool';
|
|
19
29
|
import type { ToolManagerInterface } from '@orkestrel/tool';
|
|
20
30
|
import type { ToolResult } from '@orkestrel/tool';
|
|
31
|
+
import { UnionShape } from '@orkestrel/contract';
|
|
21
32
|
import type { WorkspaceManagerInterface } from '@orkestrel/workspace';
|
|
22
33
|
|
|
23
34
|
/**
|
|
@@ -475,6 +486,14 @@ export declare type AgentEventMap = {
|
|
|
475
486
|
* - **Bounded.** Each turn arms a single cancel folded from the external `signal`, the
|
|
476
487
|
* `timeout` deadline, and the `budget` signal (through `AbortSignal.any`); any of them —
|
|
477
488
|
* or `abort()` — stops the loop and settles the result `partial: true`.
|
|
489
|
+
* Tool handlers receive that run's signal through their `ToolContext`. An agent abort,
|
|
490
|
+
* stream abort, external signal, or deadline can reach a running handler. The budget is
|
|
491
|
+
* charged during provider streaming and between turns, before tool dispatch; exhaustion
|
|
492
|
+
* ends the run without dispatching, never inside a handler. An abort before dispatch
|
|
493
|
+
* appends neither the assistant call turn nor tool messages and emits no tool chunk;
|
|
494
|
+
* streamed content remains in the partial result. Cancellation after entry is cooperative:
|
|
495
|
+
* the loop awaits a running handler even when it ignores the signal.
|
|
496
|
+
* The agent supplies no caller identity.
|
|
478
497
|
* - **Paced + capped.** The `scheduler` (when given) yields between turns; tool
|
|
479
498
|
* iteration is capped at `limit` so the loop always terminates.
|
|
480
499
|
* - **Two observation surfaces.** Pull: the {@link AgentChunk} stream (`stream().events`)
|
|
@@ -711,6 +730,126 @@ export declare interface AgentOptions {
|
|
|
711
730
|
readonly strict?: boolean;
|
|
712
731
|
}
|
|
713
732
|
|
|
733
|
+
/**
|
|
734
|
+
* Implements bounded HTTP streaming and result assembly behind concrete wire seams.
|
|
735
|
+
*
|
|
736
|
+
* @remarks
|
|
737
|
+
* Every call owns its parser, splitter, deadline, and accumulation. Success bodies
|
|
738
|
+
* have no size limit. A qwen3 implicit-open reclassification corrects the final
|
|
739
|
+
* content while content deltas already yielded cannot be recalled. A subclass fills
|
|
740
|
+
* `name`, `frame`, `body`, `read`, and `finish`; the constructor takes the `split`
|
|
741
|
+
* and `strict` switches to control reasoning separation and settled-result requirements.
|
|
742
|
+
*
|
|
743
|
+
* @example Writing a provider for a new wire
|
|
744
|
+
* ```ts
|
|
745
|
+
* import type {
|
|
746
|
+
* ProviderIncrement,
|
|
747
|
+
* ProviderOptions,
|
|
748
|
+
* ProviderParserInterface,
|
|
749
|
+
* ProviderRequest,
|
|
750
|
+
* } from '@orkestrel/agent'
|
|
751
|
+
* import { AgentProvider } from '@orkestrel/agent'
|
|
752
|
+
*
|
|
753
|
+
* class TextFrame implements ProviderParserInterface<string> {
|
|
754
|
+
* parse(chunk: string): readonly string[] {
|
|
755
|
+
* return [chunk]
|
|
756
|
+
* }
|
|
757
|
+
* clear(): void {} // Raw text retains no framing state.
|
|
758
|
+
* }
|
|
759
|
+
*
|
|
760
|
+
* interface TextOptions extends ProviderOptions {
|
|
761
|
+
* readonly url: string
|
|
762
|
+
* }
|
|
763
|
+
*
|
|
764
|
+
* class TextProvider extends AgentProvider<string> {
|
|
765
|
+
* readonly name = 'text'
|
|
766
|
+
* constructor(options: TextOptions) {
|
|
767
|
+
* super({ ...options, path: '/generate' })
|
|
768
|
+
* }
|
|
769
|
+
* frame(): ProviderParserInterface<string> {
|
|
770
|
+
* return new TextFrame()
|
|
771
|
+
* }
|
|
772
|
+
* body(request: ProviderRequest): object {
|
|
773
|
+
* return { messages: request.messages }
|
|
774
|
+
* }
|
|
775
|
+
* read(record: string): ProviderIncrement {
|
|
776
|
+
* return { content: record, thinking: '', tools: [] }
|
|
777
|
+
* }
|
|
778
|
+
* finish(_parser: ProviderParserInterface<string>): readonly string[] {
|
|
779
|
+
* return [] // Raw text retains no records at end of input.
|
|
780
|
+
* }
|
|
781
|
+
* }
|
|
782
|
+
* ```
|
|
783
|
+
*/
|
|
784
|
+
export declare abstract class AgentProvider<TRecord = Readonly<Record<string, unknown>>> implements AgentProviderInterface<TRecord> {
|
|
785
|
+
#private;
|
|
786
|
+
constructor(input: AgentProviderInput);
|
|
787
|
+
/** Identifies the concrete backend. */
|
|
788
|
+
abstract readonly name: string;
|
|
789
|
+
/** Exposes the instance's minted UUID. */
|
|
790
|
+
get id(): string;
|
|
791
|
+
/** Exposes the context framing exactly as supplied. */
|
|
792
|
+
get format(): ContextFormat | undefined;
|
|
793
|
+
/** Creates fresh framing state for the call. */
|
|
794
|
+
abstract frame(): ProviderParserInterface<TRecord>;
|
|
795
|
+
/** Projects a domain request onto the concrete protocol's wire body. */
|
|
796
|
+
abstract body(request: ProviderRequest): object;
|
|
797
|
+
/** Decodes a framed record into a turn increment. */
|
|
798
|
+
abstract read(record: TRecord): ProviderIncrement;
|
|
799
|
+
/** Returns any records retained at end of input. */
|
|
800
|
+
abstract finish(parser: ProviderParserInterface<TRecord>): readonly TRecord[];
|
|
801
|
+
/**
|
|
802
|
+
* Generates a complete turn by draining the shared stream engine.
|
|
803
|
+
*
|
|
804
|
+
* @param messages - The conversation turns
|
|
805
|
+
* @param signal - The caller's cancellation bound
|
|
806
|
+
* @param tools - The advertised tool definitions
|
|
807
|
+
* @param options - The per-call generation configuration
|
|
808
|
+
* @returns The terminal stream result
|
|
809
|
+
*/
|
|
810
|
+
generate(messages: readonly Message[], signal: AbortSignal, tools?: readonly ToolDefinition[], options?: ProviderStreamOptions): Promise<ProviderResult>;
|
|
811
|
+
/**
|
|
812
|
+
* Streams decoded deltas and returns the authoritative or assembled turn result.
|
|
813
|
+
*
|
|
814
|
+
* @param messages - The conversation turns
|
|
815
|
+
* @param signal - The caller's cancellation bound
|
|
816
|
+
* @param tools - The advertised tool definitions
|
|
817
|
+
* @param options - The per-call generation configuration
|
|
818
|
+
* @returns Content and native thinking deltas followed by the settled result
|
|
819
|
+
* @throws ProviderAbortError Thrown when the combined cancellation bound fires
|
|
820
|
+
* @throws ProviderError Thrown for an HTTP or protocol failure
|
|
821
|
+
*/
|
|
822
|
+
stream(messages: readonly Message[], signal: AbortSignal, tools?: readonly ToolDefinition[], options?: ProviderStreamOptions): AsyncGenerator<ProviderDelta, ProviderResult>;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
/**
|
|
826
|
+
* Configures the HTTP destination and stream assembly of a provider base.
|
|
827
|
+
*
|
|
828
|
+
* @remarks
|
|
829
|
+
* `path` appends to `url`. If `split` is true, separates in-content reasoning;
|
|
830
|
+
* if false, preserves content verbatim. Default: true.
|
|
831
|
+
* If `strict` is true, requires a settled result record; if false, assembles at end of input.
|
|
832
|
+
* Default: false.
|
|
833
|
+
*/
|
|
834
|
+
export declare interface AgentProviderInput extends ProviderOptions {
|
|
835
|
+
readonly url: string;
|
|
836
|
+
readonly path?: string;
|
|
837
|
+
readonly split?: boolean;
|
|
838
|
+
readonly strict?: boolean;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
/** Defines the wire-specific seams of the shared HTTP provider engine. */
|
|
842
|
+
export declare interface AgentProviderInterface<TRecord = Readonly<Record<string, unknown>>> extends ProviderInterface {
|
|
843
|
+
/** Creates fresh framing state for a call. */
|
|
844
|
+
frame(): ProviderParserInterface<TRecord>;
|
|
845
|
+
/** Projects a request to the concrete protocol's serializable body. */
|
|
846
|
+
body(request: ProviderRequest): object;
|
|
847
|
+
/** Decodes a framed record into its contribution to the turn. */
|
|
848
|
+
read(record: TRecord): ProviderIncrement;
|
|
849
|
+
/** Returns records retained at end of input before the parser is cleared. */
|
|
850
|
+
finish(parser: ProviderParserInterface<TRecord>): readonly TRecord[];
|
|
851
|
+
}
|
|
852
|
+
|
|
714
853
|
/**
|
|
715
854
|
* Configures `createAgentQueue` — the registry that rehydrates jobs, the partial-result
|
|
716
855
|
* policy, and the substrate knobs threaded into the backing `createQueue`.
|
|
@@ -1211,6 +1350,21 @@ export declare interface AuthorityRule {
|
|
|
1211
1350
|
readonly reason?: string;
|
|
1212
1351
|
}
|
|
1213
1352
|
|
|
1353
|
+
/**
|
|
1354
|
+
* Assembles a provider result with only populated optional fields.
|
|
1355
|
+
*
|
|
1356
|
+
* @param content - The authoritative answer
|
|
1357
|
+
* @param thinking - The joined reasoning
|
|
1358
|
+
* @param tools - The accumulated calls
|
|
1359
|
+
* @param usage - The reported token usage
|
|
1360
|
+
* @returns The assembled result
|
|
1361
|
+
* @example
|
|
1362
|
+
* ```ts
|
|
1363
|
+
* buildProviderResult('ok', '', [], undefined) // { content: 'ok' }
|
|
1364
|
+
* ```
|
|
1365
|
+
*/
|
|
1366
|
+
export declare function buildProviderResult(content: string, thinking: string, tools: readonly ToolCall[], usage: TokenUsage | undefined): ProviderResult;
|
|
1367
|
+
|
|
1214
1368
|
/**
|
|
1215
1369
|
* Builds the framed recap message for one compacted section — the same role and stable `id` as
|
|
1216
1370
|
* {@link buildSummaryMessage}, with the content prefixed by {@link
|
|
@@ -2459,8 +2613,8 @@ export declare function createChannel<T>(): ChannelInterface<T>;
|
|
|
2459
2613
|
*
|
|
2460
2614
|
* @example Conversations & compaction
|
|
2461
2615
|
* ```ts
|
|
2462
|
-
* import { createConversation } from '@orkestrel/agent'
|
|
2463
2616
|
* import type { ProviderInterface } from '@orkestrel/agent'
|
|
2617
|
+
* import { createConversation } from '@orkestrel/agent'
|
|
2464
2618
|
*
|
|
2465
2619
|
* declare const provider: ProviderInterface // any concrete implementation supplied by the host app
|
|
2466
2620
|
* // The summarizer seam — built from the provider by the runtime; core stays provider-agnostic.
|
|
@@ -2651,6 +2805,77 @@ export declare function createInstructionManager(options?: InstructionManagerOpt
|
|
|
2651
2805
|
*/
|
|
2652
2806
|
export declare function createMemoryConversationStore(): ConversationStoreInterface;
|
|
2653
2807
|
|
|
2808
|
+
/**
|
|
2809
|
+
* Creates an authorized relay handler that validates a bounded JSON request before streaming.
|
|
2810
|
+
*
|
|
2811
|
+
* @remarks
|
|
2812
|
+
* Answers with the `401` status when authorization refuses or throws, the `400`
|
|
2813
|
+
* status when the body is missing, unreadable, or invalid, the `413` status when
|
|
2814
|
+
* the body fills its byte budget or the inbound read is aborted, and the `502`
|
|
2815
|
+
* status when the upstream provider call cannot be constructed. Refusals carry no body.
|
|
2816
|
+
*
|
|
2817
|
+
* @param options - The upstream provider, authorization decision, and optional byte budget
|
|
2818
|
+
* @returns A fetch-standard handler suitable for a router
|
|
2819
|
+
* @example Mounting the relay on your server
|
|
2820
|
+
* ```ts
|
|
2821
|
+
* import type { ProviderInterface } from '@orkestrel/agent'
|
|
2822
|
+
* import { createRelay } from '@orkestrel/agent'
|
|
2823
|
+
* import { createDispatcher } from '@orkestrel/router'
|
|
2824
|
+
* import { createServer } from '@orkestrel/server'
|
|
2825
|
+
*
|
|
2826
|
+
* declare const upstream: ProviderInterface // the server-side provider holding the credential
|
|
2827
|
+
* declare const bearer: string
|
|
2828
|
+
*
|
|
2829
|
+
* const handler = createRelay({
|
|
2830
|
+
* provider: upstream,
|
|
2831
|
+
* authorize: (request) => request.headers.get('authorization') === `Bearer ${bearer}`,
|
|
2832
|
+
* })
|
|
2833
|
+
* const dispatcher = createDispatcher({
|
|
2834
|
+
* routes: [{ method: 'POST', path: '/relay', handler }],
|
|
2835
|
+
* })
|
|
2836
|
+
*
|
|
2837
|
+
* export function serve(request: Request): Promise<Response> {
|
|
2838
|
+
* return dispatcher.handle(request, undefined)
|
|
2839
|
+
* }
|
|
2840
|
+
*
|
|
2841
|
+
* const server = createServer({ dispatcher, state: () => undefined })
|
|
2842
|
+
* await server.start()
|
|
2843
|
+
* process.on('SIGTERM', () => server.stop()) // signal cancellation, drain, then close the listener
|
|
2844
|
+
* ```
|
|
2845
|
+
*/
|
|
2846
|
+
export declare function createRelay(options: RelayOptions): RelayHandler;
|
|
2847
|
+
|
|
2848
|
+
/**
|
|
2849
|
+
* Creates a provider that carries calls through a relay endpoint.
|
|
2850
|
+
*
|
|
2851
|
+
* @remarks
|
|
2852
|
+
* This is the browser end alone. {@link createRelay} mounts the server end, and its example
|
|
2853
|
+
* is the server half this one pairs with.
|
|
2854
|
+
*
|
|
2855
|
+
* @param options - The endpoint, parser factory, and HTTP call configuration
|
|
2856
|
+
* @returns The concrete relay provider
|
|
2857
|
+
* @example Reaching the relay from the browser
|
|
2858
|
+
* ```ts
|
|
2859
|
+
* import type { ProviderInterface } from '@orkestrel/agent'
|
|
2860
|
+
* import { createRelayProvider } from '@orkestrel/agent'
|
|
2861
|
+
* import { createAbort } from '@orkestrel/abort'
|
|
2862
|
+
* // The browser application supplies this parser dependency.
|
|
2863
|
+
* import { createNDJSONParser } from '@orkestrel/ndjson'
|
|
2864
|
+
*
|
|
2865
|
+
* declare const bearer: string
|
|
2866
|
+
* const abort = createAbort()
|
|
2867
|
+
* const messages = [{ id: '1', role: 'user', content: 'Say hello.' }] as const
|
|
2868
|
+
*
|
|
2869
|
+
* const browser: ProviderInterface = createRelayProvider({
|
|
2870
|
+
* url: 'https://app.example/relay',
|
|
2871
|
+
* parser: createNDJSONParser,
|
|
2872
|
+
* headers: () => ({ authorization: `Bearer ${bearer}` }),
|
|
2873
|
+
* })
|
|
2874
|
+
* const result = await browser.generate(messages, abort.signal) // a ProviderResult like a local provider's
|
|
2875
|
+
* ```
|
|
2876
|
+
*/
|
|
2877
|
+
export declare function createRelayProvider(options: RelayProviderOptions): RelayProvider;
|
|
2878
|
+
|
|
2654
2879
|
/**
|
|
2655
2880
|
* Creates a named scope — an immutable {@link ScopeInterface} from its `name` and its
|
|
2656
2881
|
* per-category allow-lists, the `id` minted at construction.
|
|
@@ -2826,6 +3051,19 @@ export declare const DEFAULT_AUTHORITY_ZONE = "default";
|
|
|
2826
3051
|
*/
|
|
2827
3052
|
export declare const DEFAULT_CONVERSATION_KEEP = 0;
|
|
2828
3053
|
|
|
3054
|
+
/**
|
|
3055
|
+
* Holds the default provider deadline in milliseconds — `120_000`, the wall-clock bound a call
|
|
3056
|
+
* runs under when `AgentProviderInput.timeout` is omitted, folded with the caller's signal so
|
|
3057
|
+
* whichever trips first cancels the call.
|
|
3058
|
+
*/
|
|
3059
|
+
export declare const DEFAULT_PROVIDER_TIMEOUT = 120000;
|
|
3060
|
+
|
|
3061
|
+
/**
|
|
3062
|
+
* Holds the default relay request limit in bytes — `1_048_576`, the byte budget a relay applies
|
|
3063
|
+
* to an inbound body when `RelayOptions.limit` is omitted, refusing a body that reaches it.
|
|
3064
|
+
*/
|
|
3065
|
+
export declare const DEFAULT_RELAY_LIMIT = 1048576;
|
|
3066
|
+
|
|
2829
3067
|
/**
|
|
2830
3068
|
* Synthesizes the denial {@link ToolResult} an authority-blocked call is fed back with — the
|
|
2831
3069
|
* call's `id` / `name` keyed back, carrying a denial `error` instead of a value.
|
|
@@ -3223,6 +3461,13 @@ export declare interface InstructionManagerOptions {
|
|
|
3223
3461
|
*/
|
|
3224
3462
|
export declare function intersectKeys(parent: readonly string[] | undefined, child: readonly string[] | undefined): readonly string[] | undefined;
|
|
3225
3463
|
|
|
3464
|
+
/**
|
|
3465
|
+
* Names the status a relay answers for a body that is missing, unreadable, or rejected by
|
|
3466
|
+
* `providerRequestContract` — `400`, carried with no body and reaching the browser as a
|
|
3467
|
+
* `ProviderError` with the `HTTP` code.
|
|
3468
|
+
*/
|
|
3469
|
+
export declare const INVALID_RELAY_STATUS = 400;
|
|
3470
|
+
|
|
3226
3471
|
/**
|
|
3227
3472
|
* Narrows an unknown caught value to an {@link AgentError} through `instanceof`, so a `catch`
|
|
3228
3473
|
* can branch on its `code`.
|
|
@@ -3312,34 +3557,20 @@ export declare function isConversationError(value: unknown): value is Conversati
|
|
|
3312
3557
|
export declare function isConversationSnapshot(value: unknown): value is ConversationSnapshot;
|
|
3313
3558
|
|
|
3314
3559
|
/**
|
|
3315
|
-
* Checks whether
|
|
3316
|
-
* the {@link isConversationSnapshot} and {@link isSection} read-boundary narrows, where a present
|
|
3317
|
-
* `calls` must be an array of valid {@link import('@orkestrel/tool').ToolCall}s. Total, never
|
|
3318
|
-
* throwing, and never an assertion; the conversation analogue of
|
|
3319
|
-
* {@link import('@orkestrel/workspace').isFile}.
|
|
3560
|
+
* Checks whether a value satisfies the domain conversation-message contract.
|
|
3320
3561
|
*
|
|
3321
3562
|
* @remarks
|
|
3322
|
-
*
|
|
3323
|
-
*
|
|
3324
|
-
*
|
|
3325
|
-
* {@link import('@orkestrel/tool').ToolCall} ({@link isToolCall} — the
|
|
3326
|
-
* fail-closed deepening: a tampered `calls` element rejects the message, so the snapshot
|
|
3327
|
-
* reads back as absent rather than replaying a malformed call) and an `images` that is an array
|
|
3328
|
-
* (an absent optional passes). The `role` is left as a broad `string` here (an open
|
|
3329
|
-
* {@link import('./types.js').MessageRole}, so any storage-read role string is accepted
|
|
3330
|
-
* defensively rather than rejected against the current literal set). Enough to safely impose the
|
|
3331
|
-
* {@link Message} type at
|
|
3332
|
-
* a storage boundary without a cast.
|
|
3333
|
-
*
|
|
3334
|
-
* @param value - The value to test (one element of a snapshot's `messages` / a section's `messages`)
|
|
3335
|
-
* @returns True if `value` has the structural shape of a {@link Message}; false otherwise
|
|
3563
|
+
* Roles belong to MessageRole and image elements are strings. Tool arguments may
|
|
3564
|
+
* carry non-JSON values, as the domain type permits; the message wire contract is
|
|
3565
|
+
* narrower. Unreadable fields and hostile inputs return false.
|
|
3336
3566
|
*
|
|
3567
|
+
* @param value - The unknown message candidate
|
|
3568
|
+
* @returns True if the domain message fields are valid; false otherwise
|
|
3337
3569
|
* @example
|
|
3338
3570
|
* ```ts
|
|
3339
3571
|
* isMessage({ id: '1', role: 'user', content: 'hi' }) // true
|
|
3340
|
-
* isMessage({ id: '1', role: '
|
|
3341
|
-
* isMessage({ id: '1', role: 'user' }) // false
|
|
3342
|
-
* isMessage({ id: '1', role: 'assistant', content: '', calls: [null] }) // false (malformed call)
|
|
3572
|
+
* isMessage({ id: '1', role: 'other', content: '' }) // false
|
|
3573
|
+
* isMessage({ id: '1', role: 'user', content: '', images: [1] }) // false
|
|
3343
3574
|
* ```
|
|
3344
3575
|
*/
|
|
3345
3576
|
export declare function isMessage(value: unknown): value is Message;
|
|
@@ -3362,6 +3593,18 @@ export declare function isMessage(value: unknown): value is Message;
|
|
|
3362
3593
|
*/
|
|
3363
3594
|
export declare function isProviderAbortError(value: unknown): value is ProviderAbortError;
|
|
3364
3595
|
|
|
3596
|
+
/**
|
|
3597
|
+
* Narrows a caught value to the provider failure class through instanceof.
|
|
3598
|
+
*
|
|
3599
|
+
* @param value - The caught value
|
|
3600
|
+
* @returns True if the value is a provider failure; false otherwise
|
|
3601
|
+
* @example
|
|
3602
|
+
* ```ts
|
|
3603
|
+
* isProviderError(new ProviderError('HTTP', 'unavailable', { status: 503 })) // true
|
|
3604
|
+
* ```
|
|
3605
|
+
*/
|
|
3606
|
+
export declare function isProviderError(value: unknown): value is ProviderError;
|
|
3607
|
+
|
|
3365
3608
|
/**
|
|
3366
3609
|
* Checks whether an `unknown` is structurally a {@link Section} record — a `string` `id` and
|
|
3367
3610
|
* `summary` beside a `messages` array of valid {@link Message}s, the per-section step of the
|
|
@@ -3403,11 +3646,19 @@ export declare function isSection(value: unknown): value is Section;
|
|
|
3403
3646
|
* @example
|
|
3404
3647
|
* ```ts
|
|
3405
3648
|
* joinThinking(undefined, 'first') // 'first'
|
|
3649
|
+
* joinThinking('', 'x') // 'x'
|
|
3406
3650
|
* joinThinking('first', 'second') // 'first\n\nsecond'
|
|
3407
3651
|
* ```
|
|
3408
3652
|
*/
|
|
3409
3653
|
export declare function joinThinking(running: string | undefined, next: string): string;
|
|
3410
3654
|
|
|
3655
|
+
/**
|
|
3656
|
+
* Bounds the decoded error excerpt's input in bytes — `2048`, the leading bytes of a non-OK
|
|
3657
|
+
* response body handed to the decoder before the read cancels the remainder, so a `ProviderError`
|
|
3658
|
+
* message never carries a longer excerpt.
|
|
3659
|
+
*/
|
|
3660
|
+
export declare const MAX_ERROR_BODY_LENGTH = 2048;
|
|
3661
|
+
|
|
3411
3662
|
/**
|
|
3412
3663
|
* Implements the {@link ConversationStoreInterface} in memory — a process-lifetime `Map` of
|
|
3413
3664
|
* {@link ConversationSnapshot}s keyed by conversation id, the default store
|
|
@@ -3506,6 +3757,22 @@ export declare interface Message {
|
|
|
3506
3757
|
*/
|
|
3507
3758
|
export declare const MESSAGE_TOKEN_OVERHEAD = 4;
|
|
3508
3759
|
|
|
3760
|
+
/** Validates and projects conversation messages at a JSON wire boundary. */
|
|
3761
|
+
export declare const messageContract: ContractInterface<Readonly<{
|
|
3762
|
+
id: string;
|
|
3763
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
3764
|
+
content: string;
|
|
3765
|
+
} & {
|
|
3766
|
+
calls?: readonly Readonly<{
|
|
3767
|
+
id: string;
|
|
3768
|
+
name: string;
|
|
3769
|
+
arguments: {
|
|
3770
|
+
readonly [k: string]: JSONValue;
|
|
3771
|
+
};
|
|
3772
|
+
} & {}>[];
|
|
3773
|
+
images?: readonly string[];
|
|
3774
|
+
}>>;
|
|
3775
|
+
|
|
3509
3776
|
/**
|
|
3510
3777
|
* Carries the minimal data needed to author a {@link Message} — the `id` is
|
|
3511
3778
|
* assigned by the layer that stores it, so a caller supplies only role / content
|
|
@@ -3562,6 +3829,31 @@ export declare interface MessageManagerInterface {
|
|
|
3562
3829
|
/** Names the role a {@link Message} plays in a conversation turn. */
|
|
3563
3830
|
export declare type MessageRole = 'system' | 'user' | 'assistant' | 'tool';
|
|
3564
3831
|
|
|
3832
|
+
/**
|
|
3833
|
+
* Describes a conversation message's JSON wire projection.
|
|
3834
|
+
*
|
|
3835
|
+
* @remarks
|
|
3836
|
+
* The wire is strictly narrower than Message: non-JSON call arguments are refused,
|
|
3837
|
+
* and execution context stays local. The guard refuses extra members; the parser drops them.
|
|
3838
|
+
*/
|
|
3839
|
+
export declare const messageShape: ObjectShape< {
|
|
3840
|
+
id: StringShape;
|
|
3841
|
+
role: LiteralShape<readonly ["system", "user", "assistant", "tool"]>;
|
|
3842
|
+
content: StringShape;
|
|
3843
|
+
calls: OptionalShape<ArrayShape<ObjectShape< {
|
|
3844
|
+
id: StringShape;
|
|
3845
|
+
name: StringShape;
|
|
3846
|
+
arguments: ObjectShape<Record<never, never>, JSONShape>;
|
|
3847
|
+
}, boolean | ContractShape>>>;
|
|
3848
|
+
images: OptionalShape<ArrayShape<StringShape>>;
|
|
3849
|
+
}, boolean | ContractShape>;
|
|
3850
|
+
|
|
3851
|
+
/**
|
|
3852
|
+
* Names the status a relay answers for a request body at or above its byte budget — `413`,
|
|
3853
|
+
* carried with no body and answered for an aborted inbound read as well.
|
|
3854
|
+
*/
|
|
3855
|
+
export declare const OVERSIZED_RELAY_STATUS = 413;
|
|
3856
|
+
|
|
3565
3857
|
/**
|
|
3566
3858
|
* Reports a provider stream cancelled mid-flight by its bound signal — thrown by a
|
|
3567
3859
|
* {@link ProviderInterface}'s `stream`, carrying the {@link ProviderResult} assembled from
|
|
@@ -3571,13 +3863,15 @@ export declare type MessageRole = 'system' | 'user' | 'assistant' | 'tool';
|
|
|
3571
3863
|
* Lets a caller recover the partial content (and any tool calls / usage seen so far)
|
|
3572
3864
|
* on cancellation: `catch` the throw, narrow with {@link isProviderAbortError}, and
|
|
3573
3865
|
* read `partial`. `code` is the machine-readable condition (`'ABORT'` — the only one this
|
|
3574
|
-
* error reports), so a `catch` branches on it rather than on the message string.
|
|
3866
|
+
* error reports), so a `catch` branches on it rather than on the message string. `cause`
|
|
3867
|
+
* holds the failure the cancel superseded when a throw raced the abort — the wire decoder's
|
|
3868
|
+
* {@link ProviderError}, say — and is undefined when the cancel was the only failure.
|
|
3575
3869
|
*/
|
|
3576
3870
|
export declare class ProviderAbortError extends Error {
|
|
3577
3871
|
/** Names the machine-readable condition — `'ABORT'`: a stream cancelled mid-flight. */
|
|
3578
3872
|
readonly code: "ABORT";
|
|
3579
3873
|
readonly partial: ProviderResult;
|
|
3580
|
-
constructor(partial: ProviderResult);
|
|
3874
|
+
constructor(partial: ProviderResult, options?: ErrorOptions);
|
|
3581
3875
|
}
|
|
3582
3876
|
|
|
3583
3877
|
/**
|
|
@@ -3603,6 +3897,47 @@ export declare type ProviderDelta = {
|
|
|
3603
3897
|
readonly text: string;
|
|
3604
3898
|
};
|
|
3605
3899
|
|
|
3900
|
+
/**
|
|
3901
|
+
* Reports a coded provider failure with its HTTP status and underlying cause when available.
|
|
3902
|
+
*
|
|
3903
|
+
* @remarks
|
|
3904
|
+
* The provider base throws this error for a non-OK HTTP response, a missing response
|
|
3905
|
+
* body, or a missing settled result when strict assembly is enabled. Concrete wire
|
|
3906
|
+
* decoders also use it for malformed records and relayed provider failures.
|
|
3907
|
+
* `status` is present only for an `HTTP` failure; other codes leave it undefined.
|
|
3908
|
+
*/
|
|
3909
|
+
export declare class ProviderError extends Error {
|
|
3910
|
+
/** Names the machine-readable condition — `'HTTP'`: a non-OK response, including a relay refusing an oversized request with 413; `'PROTOCOL'`: a missing response body, a malformed wire record, or a strict stream with no settled result; `'PROVIDER'`: an upstream failure carried by a relay error record. */
|
|
3911
|
+
readonly code: ProviderErrorCode;
|
|
3912
|
+
/** Holds the response status for an HTTP failure, or undefined for other codes. */
|
|
3913
|
+
readonly status: number | undefined;
|
|
3914
|
+
constructor(code: ProviderErrorCode, message: string, options?: ProviderErrorOptions);
|
|
3915
|
+
}
|
|
3916
|
+
|
|
3917
|
+
/** Names the machine-readable provider failure conditions. */
|
|
3918
|
+
export declare type ProviderErrorCode =
|
|
3919
|
+
/** Reports a non-OK HTTP response, including a relay request rejected with status 413. */
|
|
3920
|
+
'HTTP'
|
|
3921
|
+
/** Reports a missing body, malformed wire record, or missing required settled result. */
|
|
3922
|
+
| 'PROTOCOL'
|
|
3923
|
+
/** Reports an upstream provider failure carried by a relay error record. */
|
|
3924
|
+
| 'PROVIDER';
|
|
3925
|
+
|
|
3926
|
+
/** Carries a provider failure's HTTP status and underlying cause. */
|
|
3927
|
+
export declare interface ProviderErrorOptions {
|
|
3928
|
+
readonly status?: number;
|
|
3929
|
+
readonly cause?: unknown;
|
|
3930
|
+
}
|
|
3931
|
+
|
|
3932
|
+
/** Holds the decoded contribution of a wire record to a provider turn. */
|
|
3933
|
+
export declare interface ProviderIncrement {
|
|
3934
|
+
readonly content: string;
|
|
3935
|
+
readonly thinking: string;
|
|
3936
|
+
readonly tools: readonly ToolCall[];
|
|
3937
|
+
readonly usage?: TokenUsage;
|
|
3938
|
+
readonly result?: ProviderResult;
|
|
3939
|
+
}
|
|
3940
|
+
|
|
3606
3941
|
/**
|
|
3607
3942
|
* Defines the pluggable LLM inference boundary — the one contract every agent chunk depends on. A
|
|
3608
3943
|
* provider turns a conversation (plus optional tools) into either a single assembled {@link
|
|
@@ -3659,6 +3994,102 @@ export declare interface ProviderInterface {
|
|
|
3659
3994
|
stream(messages: readonly Message[], signal: AbortSignal, tools?: readonly ToolDefinition[], options?: ProviderStreamOptions): AsyncGenerator<ProviderDelta, ProviderResult>;
|
|
3660
3995
|
}
|
|
3661
3996
|
|
|
3997
|
+
/**
|
|
3998
|
+
* Configures a provider's deadline, transport, headers, and context framing.
|
|
3999
|
+
*
|
|
4000
|
+
* @remarks
|
|
4001
|
+
* `timeout` is an integer duration in milliseconds. Default: 120_000.
|
|
4002
|
+
* `fetch` defaults to the global transport bound to its global receiver.
|
|
4003
|
+
* `headers` runs for each request inside its deadline and receives the combined caller
|
|
4004
|
+
* and deadline signal so token requests can share that bound. It overrides the JSON
|
|
4005
|
+
* content type only when it returns that header. `format` is exposed to context assembly.
|
|
4006
|
+
*/
|
|
4007
|
+
export declare interface ProviderOptions {
|
|
4008
|
+
readonly timeout?: number;
|
|
4009
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
4010
|
+
readonly headers?: (signal: AbortSignal) => Readonly<Record<string, string>> | Promise<Readonly<Record<string, string>>>;
|
|
4011
|
+
readonly format?: ContextFormat;
|
|
4012
|
+
}
|
|
4013
|
+
|
|
4014
|
+
/** Defines the structural framing seam supplied by a concrete provider. */
|
|
4015
|
+
export declare interface ProviderParserInterface<TRecord = Readonly<Record<string, unknown>>> {
|
|
4016
|
+
/** Parses a decoded chunk into complete records. */
|
|
4017
|
+
parse(chunk: string): readonly TRecord[];
|
|
4018
|
+
/** Clears retained framing state. */
|
|
4019
|
+
clear(): void;
|
|
4020
|
+
}
|
|
4021
|
+
|
|
4022
|
+
/** Carries the conversation and per-call configuration sent to a provider. */
|
|
4023
|
+
export declare interface ProviderRequest {
|
|
4024
|
+
readonly messages: readonly Message[];
|
|
4025
|
+
readonly tools?: readonly ToolDefinition[];
|
|
4026
|
+
readonly options?: ProviderStreamOptions;
|
|
4027
|
+
}
|
|
4028
|
+
|
|
4029
|
+
/** Validates and projects provider requests at a JSON wire boundary. */
|
|
4030
|
+
export declare const providerRequestContract: ContractInterface<Readonly<{
|
|
4031
|
+
messages: readonly Readonly<{
|
|
4032
|
+
id: string;
|
|
4033
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
4034
|
+
content: string;
|
|
4035
|
+
} & {
|
|
4036
|
+
calls?: readonly Readonly<{
|
|
4037
|
+
id: string;
|
|
4038
|
+
name: string;
|
|
4039
|
+
arguments: {
|
|
4040
|
+
readonly [k: string]: JSONValue;
|
|
4041
|
+
};
|
|
4042
|
+
} & {}>[];
|
|
4043
|
+
images?: readonly string[];
|
|
4044
|
+
}>[];
|
|
4045
|
+
} & {
|
|
4046
|
+
tools?: readonly Readonly<{
|
|
4047
|
+
name: string;
|
|
4048
|
+
} & {
|
|
4049
|
+
description?: string;
|
|
4050
|
+
parameters?: {
|
|
4051
|
+
readonly [k: string]: JSONValue;
|
|
4052
|
+
};
|
|
4053
|
+
}>[];
|
|
4054
|
+
options?: Readonly<{} & {
|
|
4055
|
+
think?: boolean;
|
|
4056
|
+
schema?: {
|
|
4057
|
+
readonly [k: string]: JSONValue;
|
|
4058
|
+
};
|
|
4059
|
+
}>;
|
|
4060
|
+
}>>;
|
|
4061
|
+
|
|
4062
|
+
/**
|
|
4063
|
+
* Describes a provider request's JSON wire projection.
|
|
4064
|
+
*
|
|
4065
|
+
* @remarks
|
|
4066
|
+
* The wire is strictly narrower than ProviderRequest: non-JSON arguments, parameters,
|
|
4067
|
+
* or schema members are refused. Execution context stays local; the guard refuses
|
|
4068
|
+
* extra members, and the parser drops them.
|
|
4069
|
+
*/
|
|
4070
|
+
export declare const providerRequestShape: ObjectShape< {
|
|
4071
|
+
messages: ArrayShape<ObjectShape< {
|
|
4072
|
+
id: StringShape;
|
|
4073
|
+
role: LiteralShape<readonly ["system", "user", "assistant", "tool"]>;
|
|
4074
|
+
content: StringShape;
|
|
4075
|
+
calls: OptionalShape<ArrayShape<ObjectShape< {
|
|
4076
|
+
id: StringShape;
|
|
4077
|
+
name: StringShape;
|
|
4078
|
+
arguments: ObjectShape<Record<never, never>, JSONShape>;
|
|
4079
|
+
}, boolean | ContractShape>>>;
|
|
4080
|
+
images: OptionalShape<ArrayShape<StringShape>>;
|
|
4081
|
+
}, boolean | ContractShape>>;
|
|
4082
|
+
tools: OptionalShape<ArrayShape<ObjectShape< {
|
|
4083
|
+
name: StringShape;
|
|
4084
|
+
description: OptionalShape<StringShape>;
|
|
4085
|
+
parameters: OptionalShape<ObjectShape<Record<never, never>, JSONShape>>;
|
|
4086
|
+
}, boolean | ContractShape>>>;
|
|
4087
|
+
options: OptionalShape<ObjectShape< {
|
|
4088
|
+
think: OptionalShape<BooleanShape>;
|
|
4089
|
+
schema: OptionalShape<ObjectShape<Record<never, never>, JSONShape>>;
|
|
4090
|
+
}, boolean | ContractShape>>;
|
|
4091
|
+
}, boolean | ContractShape>;
|
|
4092
|
+
|
|
3662
4093
|
/**
|
|
3663
4094
|
* Holds a single inference turn's structured outcome — the assembled assistant content,
|
|
3664
4095
|
* any reasoning the provider separated from it, any tool calls the model requested,
|
|
@@ -3684,6 +4115,47 @@ export declare interface ProviderResult {
|
|
|
3684
4115
|
readonly usage?: TokenUsage;
|
|
3685
4116
|
}
|
|
3686
4117
|
|
|
4118
|
+
/** Validates and projects provider results at a JSON wire boundary. */
|
|
4119
|
+
export declare const providerResultContract: ContractInterface<Readonly<{
|
|
4120
|
+
content: string;
|
|
4121
|
+
} & {
|
|
4122
|
+
thinking?: string;
|
|
4123
|
+
tools?: readonly Readonly<{
|
|
4124
|
+
id: string;
|
|
4125
|
+
name: string;
|
|
4126
|
+
arguments: {
|
|
4127
|
+
readonly [k: string]: JSONValue;
|
|
4128
|
+
};
|
|
4129
|
+
} & {}>[];
|
|
4130
|
+
usage?: Readonly<{
|
|
4131
|
+
prompt: number;
|
|
4132
|
+
completion: number;
|
|
4133
|
+
total: number;
|
|
4134
|
+
} & {}>;
|
|
4135
|
+
}>>;
|
|
4136
|
+
|
|
4137
|
+
/**
|
|
4138
|
+
* Describes a provider result's JSON wire projection.
|
|
4139
|
+
*
|
|
4140
|
+
* @remarks
|
|
4141
|
+
* The wire is strictly narrower than ProviderResult: non-JSON call arguments are
|
|
4142
|
+
* refused. Execution context stays local; the guard refuses extra members, and the parser drops them.
|
|
4143
|
+
*/
|
|
4144
|
+
export declare const providerResultShape: ObjectShape< {
|
|
4145
|
+
content: StringShape;
|
|
4146
|
+
thinking: OptionalShape<StringShape>;
|
|
4147
|
+
tools: OptionalShape<ArrayShape<ObjectShape< {
|
|
4148
|
+
id: StringShape;
|
|
4149
|
+
name: StringShape;
|
|
4150
|
+
arguments: ObjectShape<Record<never, never>, JSONShape>;
|
|
4151
|
+
}, boolean | ContractShape>>>;
|
|
4152
|
+
usage: OptionalShape<ObjectShape< {
|
|
4153
|
+
prompt: NumberShape;
|
|
4154
|
+
completion: NumberShape;
|
|
4155
|
+
total: NumberShape;
|
|
4156
|
+
}, boolean | ContractShape>>;
|
|
4157
|
+
}, boolean | ContractShape>;
|
|
4158
|
+
|
|
3687
4159
|
/**
|
|
3688
4160
|
* Carries the per-call options threaded into a {@link ProviderInterface}'s `generate` / `stream` —
|
|
3689
4161
|
* the bag a caller passes to influence one inference call without reconfiguring the provider
|
|
@@ -3707,6 +4179,301 @@ export declare interface ProviderStreamOptions {
|
|
|
3707
4179
|
readonly schema?: Readonly<Record<string, unknown>>;
|
|
3708
4180
|
}
|
|
3709
4181
|
|
|
4182
|
+
/**
|
|
4183
|
+
* Decodes UTF-8 chunks with a final flush and releases the stream on every exit.
|
|
4184
|
+
*
|
|
4185
|
+
* @param body - The readable byte stream
|
|
4186
|
+
* @param signal - The optional cancellation bound; abort ends iteration without further chunks
|
|
4187
|
+
* @returns Decoded text chunks, including a held decoder tail
|
|
4188
|
+
* @example
|
|
4189
|
+
* ```ts
|
|
4190
|
+
* const body = new Response('answer').body
|
|
4191
|
+
* if (body !== null) for await (const chunk of readChunks(body)) render(chunk)
|
|
4192
|
+
* ```
|
|
4193
|
+
*/
|
|
4194
|
+
export declare function readChunks(body: ReadableStream<Uint8Array>, signal?: AbortSignal): AsyncGenerator<string>;
|
|
4195
|
+
|
|
4196
|
+
/**
|
|
4197
|
+
* Reads a UTF-8 prefix of a byte stream and cancels its remainder.
|
|
4198
|
+
*
|
|
4199
|
+
* @remarks
|
|
4200
|
+
* The `limit` parameter bounds bytes passed to the decoder, including a partial final
|
|
4201
|
+
* character. An omitted limit reads to completion. A source may deliver a chunk larger
|
|
4202
|
+
* than the remaining limit; its unused bytes are discarded without decoding.
|
|
4203
|
+
* The read can overshoot by one source chunk. An abort leaves completion false.
|
|
4204
|
+
*
|
|
4205
|
+
* @param body - The readable byte stream
|
|
4206
|
+
* @param limit - The maximum byte prefix, or undefined for the complete stream
|
|
4207
|
+
* @param signal - The optional cancellation bound; abort returns the decoded prefix
|
|
4208
|
+
* @returns The decoded prefix and whether EOF occurred within the byte budget
|
|
4209
|
+
* @example
|
|
4210
|
+
* ```ts
|
|
4211
|
+
* import { readText } from '@orkestrel/agent'
|
|
4212
|
+
*
|
|
4213
|
+
* const body = new Response('answer').body
|
|
4214
|
+
* if (body !== null) await readText(body, 3) // { text: 'ans', complete: false }
|
|
4215
|
+
* ```
|
|
4216
|
+
*/
|
|
4217
|
+
export declare function readText(body: ReadableStream<Uint8Array>, limit?: number, signal?: AbortSignal): Promise<TextRead>;
|
|
4218
|
+
|
|
4219
|
+
/**
|
|
4220
|
+
* Names the relay's newline-delimited JSON content type — `'application/x-ndjson; charset=utf-8'`,
|
|
4221
|
+
* the header a relay response carries beside `cache-control: no-store`.
|
|
4222
|
+
*/
|
|
4223
|
+
export declare const RELAY_CONTENT_TYPE = "application/x-ndjson; charset=utf-8";
|
|
4224
|
+
|
|
4225
|
+
/**
|
|
4226
|
+
* Names the public message for an unexpected upstream relay failure — `'relay provider failed'`,
|
|
4227
|
+
* the fixed text every `error` frame carries, so an upstream failure's own message never reaches
|
|
4228
|
+
* the browser.
|
|
4229
|
+
*/
|
|
4230
|
+
export declare const RELAY_PROVIDER_MESSAGE = "relay provider failed";
|
|
4231
|
+
|
|
4232
|
+
/** Carries a relay delta, settled result, remote abort, or remote failure. */
|
|
4233
|
+
export declare type RelayFrame = ProviderDelta | {
|
|
4234
|
+
readonly channel: 'result';
|
|
4235
|
+
readonly result: ProviderResult;
|
|
4236
|
+
} | {
|
|
4237
|
+
readonly channel: 'abort';
|
|
4238
|
+
readonly partial: ProviderResult;
|
|
4239
|
+
} | {
|
|
4240
|
+
readonly channel: 'error';
|
|
4241
|
+
readonly message: string;
|
|
4242
|
+
};
|
|
4243
|
+
|
|
4244
|
+
/** Validates and projects channel-discriminated relay frames at a JSON wire boundary. */
|
|
4245
|
+
export declare const relayFrameContract: ContractInterface<Readonly<{
|
|
4246
|
+
channel: "content" | "thinking";
|
|
4247
|
+
text: string;
|
|
4248
|
+
} & {}> | Readonly<{
|
|
4249
|
+
channel: "result";
|
|
4250
|
+
result: Readonly<{
|
|
4251
|
+
content: string;
|
|
4252
|
+
} & {
|
|
4253
|
+
thinking?: string;
|
|
4254
|
+
tools?: readonly Readonly<{
|
|
4255
|
+
id: string;
|
|
4256
|
+
name: string;
|
|
4257
|
+
arguments: {
|
|
4258
|
+
readonly [k: string]: JSONValue;
|
|
4259
|
+
};
|
|
4260
|
+
} & {}>[];
|
|
4261
|
+
usage?: Readonly<{
|
|
4262
|
+
prompt: number;
|
|
4263
|
+
completion: number;
|
|
4264
|
+
total: number;
|
|
4265
|
+
} & {}>;
|
|
4266
|
+
}>;
|
|
4267
|
+
} & {}> | Readonly<{
|
|
4268
|
+
channel: "abort";
|
|
4269
|
+
partial: Readonly<{
|
|
4270
|
+
content: string;
|
|
4271
|
+
} & {
|
|
4272
|
+
thinking?: string;
|
|
4273
|
+
tools?: readonly Readonly<{
|
|
4274
|
+
id: string;
|
|
4275
|
+
name: string;
|
|
4276
|
+
arguments: {
|
|
4277
|
+
readonly [k: string]: JSONValue;
|
|
4278
|
+
};
|
|
4279
|
+
} & {}>[];
|
|
4280
|
+
usage?: Readonly<{
|
|
4281
|
+
prompt: number;
|
|
4282
|
+
completion: number;
|
|
4283
|
+
total: number;
|
|
4284
|
+
} & {}>;
|
|
4285
|
+
}>;
|
|
4286
|
+
} & {}> | Readonly<{
|
|
4287
|
+
channel: "error";
|
|
4288
|
+
message: string;
|
|
4289
|
+
} & {}>>;
|
|
4290
|
+
|
|
4291
|
+
/**
|
|
4292
|
+
* Describes the channel-discriminated JSON relay wire projection.
|
|
4293
|
+
*
|
|
4294
|
+
* @remarks
|
|
4295
|
+
* The wire is strictly narrower than RelayFrame through its result and partial
|
|
4296
|
+
* fields: non-JSON arguments are refused. Execution context stays local; the guard
|
|
4297
|
+
* refuses extra members, and the parser drops them.
|
|
4298
|
+
*/
|
|
4299
|
+
export declare const relayFrameShape: UnionShape<readonly [ObjectShape< {
|
|
4300
|
+
channel: LiteralShape<readonly ["content", "thinking"]>;
|
|
4301
|
+
text: StringShape;
|
|
4302
|
+
}, boolean | ContractShape>, ObjectShape< {
|
|
4303
|
+
channel: LiteralShape<readonly ["result"]>;
|
|
4304
|
+
result: ObjectShape< {
|
|
4305
|
+
content: StringShape;
|
|
4306
|
+
thinking: OptionalShape<StringShape>;
|
|
4307
|
+
tools: OptionalShape<ArrayShape<ObjectShape< {
|
|
4308
|
+
id: StringShape;
|
|
4309
|
+
name: StringShape;
|
|
4310
|
+
arguments: ObjectShape<Record<never, never>, JSONShape>;
|
|
4311
|
+
}, boolean | ContractShape>>>;
|
|
4312
|
+
usage: OptionalShape<ObjectShape< {
|
|
4313
|
+
prompt: NumberShape;
|
|
4314
|
+
completion: NumberShape;
|
|
4315
|
+
total: NumberShape;
|
|
4316
|
+
}, boolean | ContractShape>>;
|
|
4317
|
+
}, boolean | ContractShape>;
|
|
4318
|
+
}, boolean | ContractShape>, ObjectShape< {
|
|
4319
|
+
channel: LiteralShape<readonly ["abort"]>;
|
|
4320
|
+
partial: ObjectShape< {
|
|
4321
|
+
content: StringShape;
|
|
4322
|
+
thinking: OptionalShape<StringShape>;
|
|
4323
|
+
tools: OptionalShape<ArrayShape<ObjectShape< {
|
|
4324
|
+
id: StringShape;
|
|
4325
|
+
name: StringShape;
|
|
4326
|
+
arguments: ObjectShape<Record<never, never>, JSONShape>;
|
|
4327
|
+
}, boolean | ContractShape>>>;
|
|
4328
|
+
usage: OptionalShape<ObjectShape< {
|
|
4329
|
+
prompt: NumberShape;
|
|
4330
|
+
completion: NumberShape;
|
|
4331
|
+
total: NumberShape;
|
|
4332
|
+
}, boolean | ContractShape>>;
|
|
4333
|
+
}, boolean | ContractShape>;
|
|
4334
|
+
}, boolean | ContractShape>, ObjectShape< {
|
|
4335
|
+
channel: LiteralShape<readonly ["error"]>;
|
|
4336
|
+
message: StringShape;
|
|
4337
|
+
}, boolean | ContractShape>]>;
|
|
4338
|
+
|
|
4339
|
+
/** Defines a host-independent relay request handler. */
|
|
4340
|
+
export declare type RelayHandler = (request: Request) => Promise<Response>;
|
|
4341
|
+
|
|
4342
|
+
/** Configures the upstream provider, mandatory authorization, and request byte limit. */
|
|
4343
|
+
export declare interface RelayOptions {
|
|
4344
|
+
readonly provider: ProviderInterface;
|
|
4345
|
+
/**
|
|
4346
|
+
* Authorizes the request before its body is read.
|
|
4347
|
+
*
|
|
4348
|
+
* @remarks
|
|
4349
|
+
* The hook must not consume the request body; a body-reading hook locks the stream
|
|
4350
|
+
* and the handler answers with the `400` status. The relay performs no origin or
|
|
4351
|
+
* method check. An application trusting an ambient credential such as a cookie
|
|
4352
|
+
* must compose origin and CSRF middleware before the handler to prevent cross-site calls.
|
|
4353
|
+
*/
|
|
4354
|
+
readonly authorize: (request: Request) => boolean | Promise<boolean>;
|
|
4355
|
+
/**
|
|
4356
|
+
* Bounds the request body in bytes; the handler answers with the `413` status
|
|
4357
|
+
* for a body at or above the limit.
|
|
4358
|
+
*/
|
|
4359
|
+
readonly limit?: number;
|
|
4360
|
+
}
|
|
4361
|
+
|
|
4362
|
+
/**
|
|
4363
|
+
* Carries provider calls over an authenticated NDJSON relay endpoint.
|
|
4364
|
+
*
|
|
4365
|
+
* @remarks
|
|
4366
|
+
* Tool execution context stays local; calls carry only `id`, `name`, and `arguments`.
|
|
4367
|
+
* The wire body is an owned snapshot of
|
|
4368
|
+
* the projection read through property descriptors, so a serializer reachable only through a
|
|
4369
|
+
* `get` trap or a prototype is never consulted; an own function-valued property such as a
|
|
4370
|
+
* `toJSON` method is a value outside JSON and is refused before fetching, with the clone's
|
|
4371
|
+
* failure as the refusal's `cause`. A remote abort reconstructs a `ProviderAbortError` instance
|
|
4372
|
+
* without aborting the
|
|
4373
|
+
* local signal; the `Agent` runtime treats that instance as an error unless its own bound
|
|
4374
|
+
* signal is aborted.
|
|
4375
|
+
* Content is preserved verbatim, including literal thinking tags.
|
|
4376
|
+
* A refusal reaches the browser as a `ProviderError` instance with the `HTTP` code and status.
|
|
4377
|
+
* This is the browser end alone; {@link createRelay} mounts the server end, and
|
|
4378
|
+
* {@link createRelayProvider}'s example is the browser half of that pair.
|
|
4379
|
+
*
|
|
4380
|
+
* @example
|
|
4381
|
+
* ```ts
|
|
4382
|
+
* import type { ProviderResult } from '@orkestrel/agent'
|
|
4383
|
+
* import { RelayProvider } from '@orkestrel/agent'
|
|
4384
|
+
* // The browser application supplies this parser dependency.
|
|
4385
|
+
* import { createNDJSONParser } from '@orkestrel/ndjson'
|
|
4386
|
+
*
|
|
4387
|
+
* export function ask(bearer: string, signal: AbortSignal): Promise<ProviderResult> {
|
|
4388
|
+
* const browser = new RelayProvider({
|
|
4389
|
+
* url: 'https://relay.example/relay',
|
|
4390
|
+
* parser: createNDJSONParser,
|
|
4391
|
+
* headers: () => ({ authorization: `Bearer ${bearer}` }),
|
|
4392
|
+
* })
|
|
4393
|
+
* return browser.generate([{ id: 'ask', role: 'user', content: 'ping' }], signal)
|
|
4394
|
+
* }
|
|
4395
|
+
* ```
|
|
4396
|
+
*/
|
|
4397
|
+
export declare class RelayProvider extends AgentProvider {
|
|
4398
|
+
#private;
|
|
4399
|
+
constructor(options: RelayProviderOptions);
|
|
4400
|
+
/** Identifies the relay backend. */
|
|
4401
|
+
readonly name = "relay";
|
|
4402
|
+
/** Creates fresh framing state for each response. */
|
|
4403
|
+
frame(): ProviderParserInterface;
|
|
4404
|
+
/**
|
|
4405
|
+
* Projects declared request fields and refuses values the JSON wire cannot carry.
|
|
4406
|
+
*
|
|
4407
|
+
* @remarks
|
|
4408
|
+
* The snapshot is taken from property descriptors, so a custom serializer a projected
|
|
4409
|
+
* value carries is ignored rather than consulted and cannot reach the wire.
|
|
4410
|
+
*
|
|
4411
|
+
* @param request - The domain conversation and call configuration
|
|
4412
|
+
* @returns The validated wire request
|
|
4413
|
+
* @throws {ProviderError} Thrown when the snapshot cannot be taken — a hostile read or a
|
|
4414
|
+
* value outside JSON — carrying that failure as its `cause`, and when the snapshot the
|
|
4415
|
+
* projection produced is not a valid wire request
|
|
4416
|
+
*/
|
|
4417
|
+
body(request: ProviderRequest): object;
|
|
4418
|
+
/**
|
|
4419
|
+
* Validates a relay frame and translates its channel into the shared stream engine.
|
|
4420
|
+
*
|
|
4421
|
+
* @param record - The framed wire record
|
|
4422
|
+
* @returns A delta contribution or authoritative result
|
|
4423
|
+
* @throws {ProviderAbortError} Thrown for a remote abort carrying its partial
|
|
4424
|
+
* @throws {ProviderError} Thrown for a malformed frame or remote provider failure
|
|
4425
|
+
*/
|
|
4426
|
+
read(record: Readonly<Record<string, unknown>>): ProviderIncrement;
|
|
4427
|
+
/**
|
|
4428
|
+
* Recovers an unterminated final frame by completing its NDJSON line.
|
|
4429
|
+
*
|
|
4430
|
+
* @param parser - The call's retained framing state
|
|
4431
|
+
* @returns Records completed by the final newline
|
|
4432
|
+
*/
|
|
4433
|
+
finish(parser: ProviderParserInterface): ReadonlyArray<Readonly<Record<string, unknown>>>;
|
|
4434
|
+
}
|
|
4435
|
+
|
|
4436
|
+
/** Configures a relay destination and its fresh structural parser factory. */
|
|
4437
|
+
export declare interface RelayProviderOptions extends ProviderOptions {
|
|
4438
|
+
readonly url: string;
|
|
4439
|
+
/** Creates a fresh parser for each relay response stream. */
|
|
4440
|
+
readonly parser: () => ProviderParserInterface;
|
|
4441
|
+
}
|
|
4442
|
+
|
|
4443
|
+
/**
|
|
4444
|
+
* Streams a provider call as validated NDJSON frames under response backpressure.
|
|
4445
|
+
*
|
|
4446
|
+
* @remarks
|
|
4447
|
+
* Cancellation aborts upstream before returning its iterator. Request listeners are
|
|
4448
|
+
* released on settlement. Unexpected provider failures carry a fixed public message.
|
|
4449
|
+
* An inbound abort leaves the response body neither closed nor errored — a server runtime
|
|
4450
|
+
* cancels that body when the client disconnects — so a consumer that aborts the inbound
|
|
4451
|
+
* signal itself must cancel the body rather than keep reading it.
|
|
4452
|
+
*
|
|
4453
|
+
* @example
|
|
4454
|
+
* ```ts
|
|
4455
|
+
* import type { ProviderInterface } from '@orkestrel/agent'
|
|
4456
|
+
* import { RelayStream } from '@orkestrel/agent'
|
|
4457
|
+
*
|
|
4458
|
+
* export function respond(provider: ProviderInterface, signal: AbortSignal): Response {
|
|
4459
|
+
* return new RelayStream({ provider, request: { messages: [] }, signal }).response
|
|
4460
|
+
* }
|
|
4461
|
+
* ```
|
|
4462
|
+
*/
|
|
4463
|
+
export declare class RelayStream {
|
|
4464
|
+
#private;
|
|
4465
|
+
constructor(options: RelayStreamOptions);
|
|
4466
|
+
/** Exposes the pull-driven response for the provider call. */
|
|
4467
|
+
get response(): Response;
|
|
4468
|
+
}
|
|
4469
|
+
|
|
4470
|
+
/** Carries the upstream call and cancellation bound of a relay response stream. */
|
|
4471
|
+
export declare interface RelayStreamOptions {
|
|
4472
|
+
readonly provider: ProviderInterface;
|
|
4473
|
+
readonly request: ProviderRequest;
|
|
4474
|
+
readonly signal: AbortSignal;
|
|
4475
|
+
}
|
|
4476
|
+
|
|
3710
4477
|
/**
|
|
3711
4478
|
* Renders a path-addressed text body as a fenced reference block — a `File: <path>` label line
|
|
3712
4479
|
* over a language-tagged fence, the framing an
|
|
@@ -4182,6 +4949,16 @@ export declare interface StreamInterface<T, R> {
|
|
|
4182
4949
|
*/
|
|
4183
4950
|
export declare function sumUsage(running: TokenUsage | undefined, next: TokenUsage): TokenUsage;
|
|
4184
4951
|
|
|
4952
|
+
/** Carries a decoded stream prefix and whether the stream ended within its byte budget. */
|
|
4953
|
+
export declare interface TextRead {
|
|
4954
|
+
readonly text: string;
|
|
4955
|
+
/**
|
|
4956
|
+
* Reports true only when a read observes the `done` flag before exhausting the
|
|
4957
|
+
* byte budget; an abort reports false.
|
|
4958
|
+
*/
|
|
4959
|
+
readonly complete: boolean;
|
|
4960
|
+
}
|
|
4961
|
+
|
|
4185
4962
|
/**
|
|
4186
4963
|
* Names the closing tag that ends a {@link THINK_OPEN} reasoning span — `'</think>'`. A span the
|
|
4187
4964
|
* stream never closes (the model was cut off mid-reasoning) is treated as thinking to its end,
|
|
@@ -4294,6 +5071,33 @@ export declare interface ThinkSplitterInterface {
|
|
|
4294
5071
|
flush(): string;
|
|
4295
5072
|
}
|
|
4296
5073
|
|
|
5074
|
+
/**
|
|
5075
|
+
* Describes a tool call's JSON wire projection.
|
|
5076
|
+
*
|
|
5077
|
+
* @remarks
|
|
5078
|
+
* The wire is strictly narrower than the domain: non-JSON arguments are refused.
|
|
5079
|
+
* Calls carry only id, name, and arguments; execution context stays local.
|
|
5080
|
+
* The guard refuses every extra member; the contract parser drops extra members.
|
|
5081
|
+
*/
|
|
5082
|
+
export declare const toolCallShape: ObjectShape< {
|
|
5083
|
+
id: StringShape;
|
|
5084
|
+
name: StringShape;
|
|
5085
|
+
arguments: ObjectShape<Record<never, never>, JSONShape>;
|
|
5086
|
+
}, boolean | ContractShape>;
|
|
5087
|
+
|
|
5088
|
+
/**
|
|
5089
|
+
* Names the status a relay answers when the `authorize` callback returns anything but `true` or throws —
|
|
5090
|
+
* `401`, carried with no body and reaching the browser as a `ProviderError` with the `HTTP` code.
|
|
5091
|
+
*/
|
|
5092
|
+
export declare const UNAUTHORIZED_RELAY_STATUS = 401;
|
|
5093
|
+
|
|
5094
|
+
/**
|
|
5095
|
+
* Names the status a relay answers when the upstream provider call cannot be constructed — `502`,
|
|
5096
|
+
* carried with no body after `provider.stream` was entered and threw before returning its
|
|
5097
|
+
* iterator.
|
|
5098
|
+
*/
|
|
5099
|
+
export declare const UPSTREAM_RELAY_STATUS = 502;
|
|
5100
|
+
|
|
4297
5101
|
/**
|
|
4298
5102
|
* Names the section header {@link import('./AgentContext.js').AgentContext}'s `build()` renders the
|
|
4299
5103
|
* active workspace's text files under — `'## Workspace'`, the leading line of the dedicated
|