/** * PDF read pipeline (service [411]② + 审计 [485]⑤ — CC FileReadTool parity). * * CC ground truth (original-source-code, 取证 2026-07-07): * - Whole-PDF path (`FileReadTool.ts:987-1016` + `utils/pdf.ts:88-103`): the file bytes are base64'd and * sent as a native `{type:"document",source:{type:"base64",media_type:"application/pdf",data}}` content * block — the model reads the text layer directly (no local text extraction). * - Page-range path (`utils/pdf.ts:179-230`): CC does NOT split the PDF itself — it shells out to * poppler's `pdftoppm -jpeg -r 100 -f F -l L` and returns the rendered pages as IMAGE blocks. * - Page counting (`utils/pdf.ts:119-135`): poppler's `pdfinfo`, parsing `/^Pages:\s+(\d+)/m`; `null` * (tool absent/failed) fails OPEN. We add a zero-dependency byte-scan fallback for uncompressed PDFs. * - Limits (`constants/apiLimits.ts:46-84`): 20MB whole-send target, 100MB extraction ceiling, 20 pages * per request, >10 pages ⇒ the `pages` parameter is REQUIRED. * * sema follows the same shape with the ExecutionEnv seam (works against remote envs too) and honest * degradation when poppler is absent — never a fake success. */ import type { ExecutionEnv } from "../../internal/harness.js"; /** Max pages a single `pages` request may span (CC `PDF_MAX_PAGES_PER_READ`). */ export declare const PDF_MAX_PAGES_PER_READ = 20; /** Above this page count a whole-PDF read is refused and `pages` is required (CC `PDF_AT_MENTION_INLINE_THRESHOLD`). */ export declare const PDF_INLINE_PAGE_THRESHOLD = 10; /** Max raw size sent whole as a document block (CC `PDF_TARGET_RAW_SIZE`). */ export declare const PDF_TARGET_RAW_SIZE: number; /** Max raw size the page-extraction (pdftoppm) path accepts (CC `PDF_MAX_EXTRACT_SIZE`). */ export declare const PDF_MAX_EXTRACT_SIZE: number; /** True when the bytes start with the `%PDF-` magic. Magic outranks extension both ways: a mis-named * `.pdf` without it is refused, and a non-`.pdf` file carrying it is read AS a PDF. */ export declare function pdfMagicMatches(bytes: Uint8Array): boolean; /** A parsed 1-indexed inclusive page range. `last === Infinity` for an open range ("10-"). */ export interface PdfPageRange { first: number; last: number; } /** Parse the CC `pages` formats — "3", "1-5", "10-" (open range). `undefined` = invalid. */ export declare function parsePdfPageRange(pages: string): PdfPageRange | undefined; /** * Zero-dependency page-count estimate: count `/Type /Page` leaf objects in the raw bytes. Exact for * classically-serialized PDFs (incl. linearized — objects stay uncompressed); returns `undefined` when * nothing matches (page tree inside compressed object streams — modern writers), NEVER a guess. */ export declare function countPdfPagesFromBytes(bytes: Uint8Array): number | undefined; /** * Total page count via poppler `pdfinfo` (CC parity), falling back to {@link countPdfPagesFromBytes} * when the tool is absent/fails and the bytes were already read. `undefined` = unknown (fail-open, * matching CC's `getPDFPageCount → null`). */ export declare function getPdfPageCount(env: ExecutionEnv, absPath: string, bytes: Uint8Array | undefined, signal?: AbortSignal): Promise; /** How many leading pages the vision fallback (level 2) renders for a whole-PDF read on a model without * document input — conservative per-request budget; the note directs the model to `pages` for more. */ export declare const PDF_FALLBACK_RENDER_PAGES = 5; /** * PDF capability profile of the SERVING model, consumed by the Read tool's degradation chain (v2): * - `document` — the brain path can forward a native `{type:"document"}` block (today: anthropic-messages * WITH vision — anthropic.ts drops document blocks for no-vision models — or an explicit `input` * declaration containing "document" for a future capability bit). * - `vision` — `Model.input` contains "image" (absent metadata fails open = today's behavior). * Structural parameter (no deep Model import): `prepare-task` passes the task's resolved Model. */ export interface PdfModelCapabilities { document: boolean; vision: boolean; } /** Derive {@link PdfModelCapabilities} from a Model-shaped object. `undefined` model = fully capable * (fail-open: no metadata ⇒ preserve the native document-block behavior, brain-level placeholder guards). */ export declare function pdfModelCapabilitiesOf(model?: { api?: string; input?: readonly string[]; }): PdfModelCapabilities; export type PdfTextResult = { ok: true; text: string; } | { ok: false; toolMissing: boolean; error: string; }; /** * Extract the PDF text layer via poppler `pdftotext -layout` (degradation-chain level 1: models without * native document input get the text instead of a placeholder). Optional 1-indexed inclusive page range * (`-f`/`-l`). Output goes through a temp FILE (not exec stdout — env exec seams may cap/mangle stdout), * read back over the env seam so it works against remote envs too. `toolMissing` distinguishes * "install poppler" from a real extraction failure. */ export declare function extractPdfTextLayer(env: ExecutionEnv, absPath: string, range?: { first: number; last: number; }, signal?: AbortSignal): Promise; export type PdfExtractResult = { ok: true; pages: Array<{ pageNumber: number; jpeg: Uint8Array; }>; } | { ok: false; toolMissing: boolean; error: string; }; /** * Render pages [first..last] to JPEGs via poppler `pdftoppm` (CC `extractPDFPages` parity: `-jpeg -r 100`, * 120s timeout). Runs through the ExecutionEnv seam (temp dir + exec + readBinaryFile), so it works * wherever the env does. `toolMissing` distinguishes "install poppler" from a real extraction failure. */ export declare function extractPdfPagesAsImages(env: ExecutionEnv, absPath: string, first: number, last: number, signal?: AbortSignal): Promise; //# sourceMappingURL=pdf.d.ts.map