/** * Does a `width x height` image fit the visual token budget — both per-side * cap and total patch count? * * Patch count is measured as continuous area (`w*h / patch^2`) rather than * `ceil(w/patch) * ceil(h/patch)`: the encoder resizes to a patch-aligned grid * before tiling, so area is what actually determines the token cost. */ export declare function fitsVisualBudget(width: number, height: number): boolean; /** * Largest aspect-preserving size that still satisfies {@link fitsVisualBudget}. * Returns the input untouched when it already fits (so ordinary screenshots are * never re-encoded). * * Binary-searches the long edge because the short edge is rounded to whole * pixels — the closed-form area scale can overshoot the budget by a patch or * two once that rounding is applied. */ export declare function boundedSize(width: number, height: number): { width: number; height: number; }; export declare const IMAGE_EXTENSIONS: Set; export declare const VIDEO_EXTENSIONS: Set; /** Max video size loaded into base64 at attach time (50 MB). Video is routed by * file path, so the bytes are only kept as a fallback for path-less clipboard * clips; larger clips keep `data` empty and rely on the path. Per-model upload * caps live in the model registry (`maxVideoBytes`) and drive compression. */ export declare const MAX_VIDEO_BYTES: number; export type VideoCompressionResult = { ok: true; path: string; originalBytes: number; compressedBytes: number; } | { ok: false; reason: string; }; /** * Transcode an oversized video down to fit under {@link COMPRESS_TARGET_BYTES} * using ffmpeg: downscale to {@link COMPRESS_MAX_WIDTH}px wide, drop to * {@link COMPRESS_FPS} fps, and target a bitrate computed from the clip's * duration. Video understanding samples frames, so aggressive downsampling * keeps the content analyzable while shrinking multi-GB clips to <100 MB. * * Writes to a temp file and returns its path; the caller owns deleting it. * Best-effort: returns `{ ok: false, reason }` if ffmpeg/ffprobe are missing, * the probe fails, or the result still exceeds the target. */ export declare function compressVideoToFit(inputPath: string, targetBytes?: number, signal?: AbortSignal): Promise; export declare const IMAGE_MEDIA_TYPES: Record; export declare const VIDEO_MEDIA_TYPES: Record; export interface ImageAttachment { kind: "image" | "video" | "text"; fileName: string; filePath: string; mediaType: string; data: string; } /** Check if a file path points to an image based on extension. */ export declare function isImagePath(filePath: string): boolean; /** Check if a file path points to a video based on extension. */ export declare function isVideoPath(filePath: string): boolean; /** Check if a file path points to an attachable file (image or text). */ export declare function isAttachablePath(filePath: string): boolean; /** * Extract attachable file paths from input text by checking if tokens resolve * to existing files on disk. Returns verified paths and the remaining text. * * Only tokens that look like explicit paths (contain `/`, `~`, `\`, or `file://`) * are considered. Bare filenames like "readme.md" are left as text. */ export declare function extractImagePaths(text: string, cwd: string): Promise<{ imagePaths: string[]; cleanText: string; }>; /** Alias of {@link extractImagePaths} that also picks up video paths (video * extensions are part of ATTACHABLE_EXTENSIONS). Name reflects the widened scope. */ export declare const extractMediaPaths: typeof extractImagePaths; /** * Validate that a base64-decoded buffer is a REAL, fully-decodable image in a * format the vision APIs accept. Returns the corrected media type on success, * or `null` when the data is corrupt or an unsupported format. * * Why this exists: an image content block with corrupt or unsupported bytes * (e.g. a malformed `.ico`, or a `.png` with a bad IDAT/CRC) makes the provider * reject the ENTIRE turn with "The image data you provided does not represent a * valid image" — the agent never gets to respond. Callers use the `null` return * to downgrade such an attachment to a plain file note (saved to disk, inspected * with tools) so the request still succeeds and the model can diagnose the file. * * The header sniff alone is insufficient (a corrupt PNG still has PNG magic), so * this forces a full pixel decode — resized small to bound memory — which makes * libvips surface mid-stream corruption here instead of at the provider. */ export declare function validateVisionImage(buffer: Buffer): Promise; /** * Downscale an image buffer so it fits within both the visual token budget * ({@link boundedSize}) and MAX_IMAGE_BYTES. Preserves format (PNG→PNG, * JPEG→JPEG, etc.) and aspect ratio — a lossless PNG screenshot of UI stays a * lossless PNG with its alpha channel intact. */ export declare function shrinkToFit(buffer: Buffer, mediaType: string): Promise<{ buffer: Buffer; mediaType: string; }>; /** * Downscale an image buffer for an inline terminal preview, capping its width * at PREVIEW_MAX_WIDTH so previews stay small in scrollback. The full-resolution * copy is kept separately for the model. Preserves format and aspect ratio. * * On any sharp failure the original buffer is returned unchanged — a preview is * cosmetic and must never break the turn. */ export declare function downscaleForPreview(buffer: Buffer): Promise; /** * Read a file and return an attachment (base64 for images, raw text for text files). * * Image decode / shrink failures degrade to a text placeholder instead of throwing, * so a corrupt or unsupported image doesn't crash the turn. The caller sees a * `kind: "text"` attachment the model can read as `` context. */ export declare function readImageFile(filePath: string): Promise; /** Alias of {@link readImageFile} that also handles video files. Name reflects * the widened scope. */ export declare const readMediaFile: typeof readImageFile; /** * Try to read image data from the system clipboard (macOS only). * Returns null if no image is on the clipboard. */ export declare function getClipboardImage(): Promise; //# sourceMappingURL=image.d.ts.map