import type { DocumentContent, ImageContent, TextContent } from "../../internal/llm.js";
import type { AgentTool, ExecutionEnv } from "../../internal/harness-types.js";
import { errorResult } from "../../core/tools.js";
import type { ToolReturn } from "../../core/tool-spec.js";
import { type ReadEntry, type ReadFileState, type RootsSeat } from "./safety.js";
import { type ImageDimensions } from "../../core/mcp.js";
import { type PdfModelCapabilities } from "./pdf.js";
import { type ReadImageDownsamplerOption, type CwdRef } from "./fs-shared.js";
import { type ReminderDisclosureCounts, type ReminderDisclosureEffects, type ReminderDisclosureVerdict } from "../../core/reminder-disclosure.js";
/**
 * The Read tool, and the ONE read of a file for the model it is built on, split into three steps so every
 * carrier shares it:
 *
 *   readForModel(args) → a value: the external data blocks, the engine's STRUCTURED notes about the read,
 *                        the read-state observation, the deferred effects, an outcome word;
 *   commit(result)     → the side effects, applied when the carrier actually delivers the result (the
 *                        read-state entry, the disclosure throttle windows and counters);
 *   render             → per carrier. {@link renderReadToolResult} is the Read tool's: it reproduces the
 *                        tool result byte for byte (the Read pins are the proof); a carrier that delivers
 *                        a file somewhere else renders the same notes in its own words.
 *
 * `readForModel` is side-effect free toward the run: it reads the filesystem (and, on the PDF lane, runs
 * the poppler readers), it READS the read state and the throttle windows, and it writes neither.
 *
 * What is DATA and what is a NOTE. `data` holds what the file itself supplies, in order — the
 * line-numbered body, the notebook cell blocks, the image block. Everything the engine says ABOUT the
 * read (empty file, offset past the end, already in context, unchanged since the last read, the range
 * header, the partial-view marker, the corrupt-notebook prefix, the 0-cell placeholder, the resize
 * coordinates, the disclosure verdict) is a structured {@link ReadNote} — never a pre-rendered string, so
 * no carrier inherits the tool carrier's wording (a name inside an engine sentence is the tool
 * carrier's own byte, not a rule for other carriers). The PDF lane is the one exception: its blocks are
 * the Read tool's PDF projection as-is (engine headers interleaved with the fenced text layer) — a
 * carrier other than the Read tool does not present them as file data.
 *
 * A refusal is the Read tool's own error envelope (`refusal`), minted where it is decided, with
 * `outcome: "not_attached"`.
 */
/** What happened to the file's contents. `partial` = a default read the token cap cut (the partial-view
 *  marker); `unchanged` = the dedup answers (same window and hash, or a seeded file already in context);
 *  `not_attached` = nothing of the contents was served (a refusal, an offset past the end, a PDF whose
 *  degradation chain bottomed out). Exported to carriers by the seat that needs it, not from the package. */
export declare const READ_OUTCOMES: readonly ["attached", "partial", "unchanged", "not_attached"];
export type ReadOutcome = (typeof READ_OUTCOMES)[number];
/** The lane the read took. Absent on a refusal raised before the lane was known. A corrupt notebook served
 *  as raw text is `text` (with the `notebook_fallback` note). */
export type ReadKind = "text" | "notebook" | "image" | "pdf";
/** The engine's statements about one read, as data. The Read carrier's rendering is
 *  {@link renderReadNoteForTool}; the frame carrier renders the same members its own way. */
export type ReadNote = {
    kind: "empty_file";
} | {
    kind: "past_eof";
    offset: number;
    totalLines: number;
}
/** A default read of a startup-seeded file that is unchanged on disk. `key` is the canonical path. */
 | {
    kind: "already_in_context";
    key: string;
}
/** The same window of an unchanged file was already served. `path` is the caller's spelling. */
 | {
    kind: "unchanged";
    path: string;
    start: number;
    end: number;
    total: number;
}
/** A served window that is not the whole file (an explicit slice), no partial-view marker. */
 | {
    kind: "range";
    path: string;
    start: number;
    end: number;
    total: number;
}
/** A default read the token cap cut by lines. */
 | {
    kind: "partial_page";
    end: number;
    total: number;
    approxTokens: number;
}
/** A default read whose first line alone overflows the cap, served as a character prefix. */
 | {
    kind: "partial_chars";
    cut: number;
    totalChars: number;
    approxTokens: number;
}
/** A `.ipynb` that does not parse, served as raw text. */
 | {
    kind: "notebook_fallback";
}
/** A parsed notebook with no cells. */
 | {
    kind: "notebook_no_cells";
}
/** The image was downsampled; the coordinates map back to the original. */
 | {
    kind: "image_resized";
    dimensions: ImageDimensions;
}
/** External bytes carried reminder- or envelope-shaped text. */
 | {
    kind: "disclosure";
    verdict: ReminderDisclosureVerdict;
};
/** The read-state entry a delivery records, minus the delivery's own facts (when, which transmission). */
export interface ReadObservation {
    key: string;
    entry: Pick<ReadEntry, "hash" | "totalLines" | "truncated" | "isPartialView" | "view">;
}
/** The Read tool's error envelope for a refusal. */
export type ReadRefusal = ReturnType<typeof errorResult>;
export interface ReadForModelResult {
    outcome: ReadOutcome;
    kind?: ReadKind;
    data: Array<TextContent | ImageContent | DocumentContent>;
    notes: ReadNote[];
    /** The host face (the Read tool's `details`), shared by every carrier. */
    details?: Record<string, unknown>;
    /** The Read tool's refusal (its error envelope: the sentence and its structured details) — present exactly on a
     *  refusal. */
    refusal?: ReadRefusal;
    /** Present when a delivery records read state. */
    observation?: ReadObservation;
    effects: {
        disclosure: ReminderDisclosureEffects[];
    };
}
/** The facts of the read the caller supplies (the tool context's subset). */
export interface ReadForModelContext {
    signal?: AbortSignal;
    toolCallId?: string;
    taskId?: string;
    principal?: string;
}
export interface ModelFileReaderOptions {
    env: ExecutionEnv;
    state: ReadFileState;
    rootCanonical: string;
    cwdRef?: CwdRef;
    additionalRoots?: RootsSeat;
    imageDownsampler?: ReadImageDownsamplerOption;
    pdfCapabilities?: PdfModelCapabilities;
    /** See createReadFileTool's seat of the same name. */
    bgOutputReadExemption?: (canonicalKey: string, ctx: {
        taskId?: string;
        principal?: string;
        toolCallId?: string;
    }) => boolean;
    readDeny?: import("./read-deny.js").ReadDenyMatcher;
    readFace?: import("./containment-face.js").ContainmentFace;
    reminderMark?: string;
    reminderDisclosureCounts?: ReminderDisclosureCounts;
    /** The bare-form disclosure throttle windows, keyed by canonical file key. Owned by whoever builds the
     *  reader; every carrier that reads through the same reader shares them. Absent ⇒ a fresh map. */
    disclosureWindows?: Map<string, number>;
}
export interface ModelFileReader {
    readForModel(args: unknown, ctx: ReadForModelContext): Promise<ReadForModelResult>;
    /** Apply the result's effects: the read-state entry (stamped `lastReadAt` and the transmission that
     *  carried it) and the disclosure windows / counters. Once per result: a second commit throws. */
    commit(result: ReadForModelResult, at?: {
        transmittedByToolCallId?: string;
        now?: number;
    }): void;
}
export declare function createModelFileReader(opts: ModelFileReaderOptions): ModelFileReader;
/** The Read carrier's sentence for one note — the bytes the Read tool has always emitted for it. The
 *  data-adjacent notes (range header, partial marker, fallback prefix, 0-cell placeholder, resize line,
 *  disclosure trailer) render without their joining separators; {@link renderReadToolResult} places them. */
export declare function renderReadNoteForTool(note: ReadNote, mark: string | undefined): string;
/** The Read tool's result for one read — the composition each lane has always returned. */
export declare function renderReadToolResult(r: ReadForModelResult, mark: string | undefined): ToolReturn;
export declare function createReadFileTool(env: ExecutionEnv, state: ReadFileState, rootCanonical: string, cwdRef?: CwdRef, additionalRoots?: RootsSeat, imageDownsampler?: ReadImageDownsamplerOption, pdfCapabilities?: PdfModelCapabilities, bgOutputReadExemption?: (canonicalKey: string, ctx: {
    taskId?: string;
    principal?: string;
    toolCallId?: string;
}) => boolean, readDeny?: import("./read-deny.js").ReadDenyMatcher, readFace?: import("./containment-face.js").ContainmentFace, reminderMark?: string, reminderDisclosureCounts?: ReminderDisclosureCounts): AgentTool;
