/** Shared outcomes and bounded read windows. Host envelopes belong to the adapters. */ import { Type, type Static, type TSchema } from "typebox"; /** `details` is sanitized context for a caller, never a payload or a file body. */ export declare const OperationErrorSchema: Type.TObject<{ code: Type.TString; message: Type.TString; details: Type.TOptional>; }>; export type OperationError = Static; /** `data` exists without `error`, never both, never neither. */ export type Outcome = { ok: true; data: T; } | { ok: false; error: OperationError; }; export declare function success(data: T): Outcome; /** A code is an internal stable identifier and is never clipped; the dynamic message and details are the bounded surface. */ export declare const ERROR_MESSAGE_MAX_CHARS = 2000; export declare const ERROR_DETAILS_MAX_BYTES = 4096; export declare function failure(code: string, message: string, details?: Record): Outcome; export declare function outcomeSchema(dataSchema: S): Type.TUnion<[Type.TObject<{ ok: Type.TLiteral; data: S; }>, Type.TObject<{ ok: Type.TLiteral; error: Type.TObject<{ code: Type.TString; message: Type.TString; details: Type.TOptional>; }>; }>]>; /** A refusal reads as one short line; a success is the operation's own reading of its data. */ export declare function renderOutcome(result: Outcome, renderData: (data: T) => string): string; /** Bytes of the structured payload as delivered: compact JSON, not the model-facing text. A value with no JSON representation has no size to measure. */ export declare function structuredBytes(value: unknown): number; /** * The one bound: the rendered text and the structured payload must both fit, and the rendered * measure covers everything the renderer puts around the payload, headers and footers included. */ export declare function fitsResult(result: Outcome, render: (result: Outcome) => string): boolean; /** `text` is verbatim, with no marker inserted, so windows concatenate back into the source. */ export declare const TextWindowSchema: Type.TObject<{ text: Type.TString; offset_chars: Type.TInteger; total_chars: Type.TInteger; next_offset_chars: Type.TUnion<[Type.TInteger, Type.TNull]>; limited_by: Type.TUnion<[Type.TLiteral<"limit">, Type.TLiteral<"bytes">, Type.TNull]>; }>; export type TextWindow = Static; /** * Read one code-point window of `text` and build the operation's data around it. `offset` and * `limit` are the integers the parameter schema already admitted; a negative `offset` resolves to * `max(0, total + offset)`, and the caller refuses an offset past the end. * * An envelope that cannot fit even empty is refused instead of returned: a zero-length window * would resume at the offset it started from, so paging could never make progress. */ export declare function readTextWindow(text: string, offset: number | undefined, limit: number | undefined, makeData: (window: TextWindow) => T, render: (result: Outcome) => string): Outcome; /** The continuation line never becomes part of `window.text`, and a complete window has none. */ export declare function renderTextWindow(window: TextWindow): string; /** One outcome in, model-facing text out. */ export type Renderer = (result: Outcome) => string; /** What both host adapters register: parameters in, canonical outcome out, and its text. */ export type Operation = { readonly name: string; readonly label: string; readonly description: string; readonly parameters: TParams; /** Absent leaves concurrency to the host default. */ readonly executionMode?: "sequential" | "parallel"; readonly outputSchema: TSchema; readonly execute: (params: Static, ...rest: TRest) => Promise>; readonly render: Renderer; };