import type { AgentMessage } from "../internal/harness-types.js";
import type { DocumentContent, ImageContent } from "../internal/llm.js";
/**
 * Aggregate MEDIA (image) byte budget — the multimodal sibling of {@link AGGREGATE_TOOL_RESULT_BUDGET_CHARS}
 * (which only counts TEXT, design/64 §17.2). batch-C added image reads (`Read` → `ImageContent`); each is bounded
 * per-image (`MAX_IMAGE_READ_BYTES`), but N images accumulate ACROSS turns in the context and would otherwise grow
 * the request unboundedly (a real gap — CC 2.1.196 added the same cap, `tengu_media_byte_cap`, validating it).
 *
 * This caps the SUM of inline image bytes across the whole message list: while over budget, the OLDEST images are
 * stripped (replaced with a short text marker) until it fits — recent media (most relevant) is kept. Like the text
 * budget it is a REQUEST-ONLY, NON-DESTRUCTIVE transform (returns a new array; the durable session keeps the full
 * image, and the model can re-`Read` the file if it still needs it) applied in the `harness.on("context")` hook,
 * and DETERMINISTIC (same messages + limit → same strip set → byte-identical request → prompt-cache safe).
 */
/** Default aggregate inline-media budget (bytes). Generous — only the pathological "N parallel huge image reads"
 *  case strips. Bounds the request while leaving normal multimodal use untouched. Overridable per-deployment. */
export declare const AGGREGATE_MEDIA_BUDGET_BYTES: number;
/** The one reading of a deployment's media budget (`RunnerDeps.mediaByteCapBytes`, screened by {@link checkedMediaByteCap}
 *  at `new Runner`), for both of its readers — the request strip below and the `tool_end.output` projection: absent ⇒
 *  {@link AGGREGATE_MEDIA_BUDGET_BYTES}; a finite positive number ⇒ itself; `0` or `Infinity` ⇒ no budget, `Infinity`
 *  (a direct caller of {@link capAggregateMediaBytes} that passes a negative or `NaN` meets the same no-op). */
export declare function mediaBudgetBytes(cap: number | undefined): number;
/** The deployment's media budget, screened once at `new Runner`: absent, a non-negative number of bytes, or `Infinity`
 *  (`0` and `Infinity` both mean "no budget"). A non-number, `NaN` or a negative is refused (`config.invalid_argument`),
 *  never read as "no budget". */
export declare function checkedMediaByteCap(value: unknown, seat: string): void;
/** A media block: an image or a document whose payload is a base64 string. */
export type MediaBlock = ImageContent | DocumentContent;
/** The media type a block claims — its `type`, read once, when that is a media type — or `undefined` for any other value. */
export declare function claimedMediaType(block: unknown): MediaBlock["type"] | undefined;
/** Whether a value is a media block: its `type` is a media type and its `data` a string. A block of a media type with no
 *  string `data` is not one — a {@link MediaDescriptor} is such a block. */
export declare function isMediaBlock(block: unknown): block is MediaBlock;
/** What media becomes where its bytes do not ride: one block's identity (its type, its media type when it can be one, its
 *  decoded size), or one summary of every block from there on. Never a string, never the bytes. */
export type MediaDescriptor = {
    type: MediaBlock["type"];
    mimeType?: string;
    bytes: number;
    truncated: true;
} | {
    type: "omitted";
    blocks: number;
    bytes: number;
    truncated: true;
};
/** A media block's descriptor. The media type is echoed only when it can be one (RFC 6838: type and subtype are at most
 *  127 characters each); `bytes` is {@link imageBytes}. */
export declare function mediaBlockDescriptor(block: MediaBlock): MediaDescriptor;
/** The one summary of media blocks that leave together: how many, and their decoded size. */
export declare function omittedMediaDescriptor(blocks: readonly MediaBlock[]): MediaDescriptor;
/** Decoded byte size of a base64 media payload (4 base64 chars ≈ 3 bytes). Approximate — fine for a budget.
 *  PDF read: `document` blocks (base64 PDFs) count against the SAME aggregate budget — same class of inline
 *  media bytes, same unbounded-accumulation failure mode. */
export declare function imageBytes(b: ImageContent | DocumentContent): number;
/** Telemetry for one strip pass (mirrors CC's `tengu_media_byte_cap_stripped` fields). */
export interface MediaStripInfo {
    totalBytes: number;
    limitBytes: number;
    removedCount: number;
    removedBytes: number;
}
/**
 * Cap the aggregate inline-image bytes across `messages` to `limitBytes`, stripping OLDEST images first. Returns the
 * SAME array when already within budget or the limit is non-positive/non-finite (no allocation, no-op). Otherwise a
 * shallow-cloned array with the stripped messages replaced (originals untouched). `onStripped` fires once if anything
 * was removed.
 */
export declare function capAggregateMediaBytes(messages: AgentMessage[], opts: {
    limitBytes: number;
    onStripped?: (info: MediaStripInfo) => void;
}): AgentMessage[];
