/** * JIT layer-2 tools — content-aware previews (the soul of the offload handle) * plus the L1 "structure" summaries for tm_fetch mode:"structure". * * Five branches, chosen by content_type (path hint) with sniffing fallback: * json -> first 3 keys: path + type + magnitude * csv -> header + 2 sample rows + total rows x cols * log -> first 3 lines + pattern stats (ERROR x N, ...) + path:line refs * code -> function/class signature list (with line numbers) * binary -> type + size + "不可预览" * * RED LINE: previews are hard-capped at TM_PREVIEW_MAX_TOKENS (default 80 * estimated tokens). A bloated preview is an R4 regression — the cap is * enforced by composition (body budget = cap - meta) so clue + hint lines * always survive truncation. */ export type ContentType = "json" | "csv" | "log" | "text" | "code" | "binary"; /** Content type derived from the file extension (deterministic hint). */ export declare function contentTypeForPath(p: string): ContentType; /** * Sniff content type when no path hint exists (or the hint was plain "text"). * Order: binary -> json -> csv -> code -> text. Logs and plain text share * the same preview branch, so no separate sniff rule is needed for them. */ export declare function sniffContentType(content: string): ContentType; /** * Resolve the effective branch: a path-derived hint wins (deterministic); * plain-text hints and missing hints fall through to sniffing (which may * still upgrade the content to json / csv / code / binary). */ export declare function detectContentType(content: string, hint?: ContentType): ContentType; /** * Hard cap by estimated tokens (CJK-aware, see config.tokenCostOf): never * exceed maxTokens. Truncation walks the ACTUAL per-char token cost (a * chars/4 char-count cut would under-count CJK bodies up to 4×), and the * marker's own cost is reserved up front so it always survives the cut. */ /** * Cap an ADDRESSING payload — a browser accessibility snapshot, whose [ref=eN] tokens * are the arguments of the next click. * * A head cut (what capTokens does) is the wrong shape here: the interactive nodes are * spread through the tree, so a plain budget loses the tail's refs while keeping * hundreds of tokens of static text nobody will address by. This keeps every line that * carries an addressing token and spends the rest of the budget on the other lines in * their original order. When the addressing lines alone do not fit, it says HOW MANY * were dropped — "some refs are not in front of you" is the fact the model needs, and * a silent tail cut is how a wrong-element click gets reported as 已点击. * * The addressing pattern is deliberately wide (any `key=value` token whose key ends in * `ref` / `id`, plus the `[uid=…]` shape a snapshot may mint), because matching * the host's future snapshot format is a guess; over-collecting only costs budget. */ /** How far an addressing payload may overtake its nominal budget: every ref line is * kept up to `budget × this`, because the alternative is a click against a ref the * model cannot see. Past that, the note says how many addressing lines were dropped. */ export declare const ADDRESSING_OVERTAKE_FACTOR = 4; export declare function capKeepingAddressing(text: string, maxTokens: number): { text: string; kept: number; dropped: number; total: number; addressesDropped: number; fellBack: boolean; }; /** How far a table payload may overtake its nominal budget — same reasoning as the * snapshot cap: a truncated row is not a smaller table, it is an unreadable one. */ export declare const TABLE_OVERTAKE_FACTOR = 4; /** Does this payload carry a Markdown table? A line starting with `|` followed by an * alignment row is the whole test — prose that merely quotes a pipe is not a report. */ export declare function hasMarkdownTable(text: string): boolean; /** * Cap a REPORT payload: keep the tables, drop the prose around them. * * The generic offload (≤80-token preview + handle) is right for a 50 KB log and wrong * for a report, and on this host the wrongness reaches the user: a `tm_stats` call made * from inside Code Mode comes back as the `execute` result, is offloaded whole, and the * lead ends up describing a table it had to page back in row by row. A live session * measured exactly that on a 2 917-token report. * * Table lines are structural: a row is only readable with its header and alignment row, * so they are kept as a unit, along with the heading above each table. Everything else * is filler. Same rule as capKeepingAddressing and for the same reason — spend the * budget on the part the reader cannot reconstruct. */ export declare function capKeepingTables(text: string, maxTokens: number): { text: string; kept: number; dropped: number; total: number; tablesDropped: number; }; export declare function capTokens(text: string, maxTokens: number): string; export interface PreviewOptions { /** Raw-line scan budget for the branch builders (TM_PREVIEW_LINES). */ lines?: number; /** Hard cap in estimated tokens (TM_PREVIEW_MAX_TOKENS). */ maxTokens?: number; /** Retrieval clue embedded into the preview (path / pattern / cmd). */ clue?: string; } /** Build the governed preview for offloaded content. Never throws. */ export declare function buildPreview(content: string, contentType: ContentType, opts?: PreviewOptions): string; /** ~100-token-level L1 map of an offloaded payload (TOC / key tree / error lines). */ export declare function buildStructureSummary(content: string, contentType: string): string; //# sourceMappingURL=preview.d.ts.map