/** * context-compressor.ts * * Reusable utility for reducing the size of data before it is included in * AI prompts, preventing token budget overruns. * * This module addresses two core problems: * 1. Pages with many elements would produce prompts that are too large for * efficient AI processing if every element were included verbatim. * 2. Sending the full DOM snapshot to the healing prompt wastes tokens on * content that is irrelevant to finding the failed element. * * Solutions: * - compressElements(): deduplicates, caps per action type, enforces a total * element limit of 30 for the compact prompt table. * - compressSteps(): caps assertion count per step and total step count. * - compressElementContextForHealing(): strips all non-locator fields from an * ElementContext so the healing prompt is as small as possible. * - extractNearbyElements(): scans a full DOM snapshot for only the lines that * contain semantic elements near the failed locator. * - estimateTokens(): rough token count estimate (4 chars ≈ 1 token). * * A singleton compressor instance is exported for convenience. * * Role in the overall flow: * generate_test → compressor.compressElements() / compressSteps() * heal_test → compressor.extractNearbyElements() / compressElementContextForHealing() */ import { CompactElement, CompactStep, ElementContext } from '../types'; /** Statistics about how much compression was applied. */ export interface CompressionStats { originalElements: number; compressedElements: number; originalSteps: number; compressedSteps: number; /** Estimated number of AI tokens saved by compression. */ estimatedTokensSaved: number; } /** * Compresses element lists, step lists, and DOM snapshots to keep * AI prompt sizes within the recommended token budget. */ export declare class ContextCompressor { /** * Compress a list of CompactElements for inclusion in the AI prompt. * * Steps applied in order: * 1. Remove duplicate keys (keeps the first occurrence). * 2. Cap the number of elements per action type (see MAX_PER_ACTION). * 3. Hard cap the total at TOTAL_ELEMENT_CAP (30). * * @param elements - The full element list to compress. * @returns The compressed list and basic stats (original vs compressed count). */ compressElements(elements: CompactElement[]): { compressed: CompactElement[]; stats: Pick; }; /** * Compress a list of CompactSteps for inclusion in the spec-generation prompt. * * Steps applied in order: * 1. Limit total steps to maxSteps (default 20). * 2. Cap assertion count per step to 3. * * @param steps - The full step list to compress. * @param maxSteps - Maximum number of steps to keep. Defaults to 20. * @returns The compressed list and basic stats. */ compressSteps(steps: CompactStep[], maxSteps?: number): { compressed: CompactStep[]; stats: Pick; }; /** * Strip all non-locator fields from an ElementContext for use in a healing prompt. * * Keeps only the fields the healing engine needs to reason about alternative * locators: key, actionType, originalLocator, role, label, placeholder, text, testId. * Text is truncated to 40 characters. * * @param ec - The full ElementContext to compress. * @returns A plain object with only the healing-relevant fields. */ compressElementContextForHealing(ec: ElementContext): object; /** * Extract only the semantically meaningful lines from a DOM snapshot that are * near the failed locator hint. This avoids sending thousands of HTML lines to * the AI when only ~30 are relevant. * * The extraction finds the line most likely to contain the target element, * then returns a window of windowLines lines centered on that position. * Only lines that contain interactive elements, ARIA attributes, or form * controls are included (non-semantic lines are filtered out). * * @param domSnapshot - The full HTML source of the page. * @param failedLocatorHint - A hint string (e.g. the step description) used to * find the center of the relevant DOM region. * @param windowLines - Maximum number of lines to extract. Defaults to 30. * @returns A string of filtered, nearby HTML lines joined by newlines. */ extractNearbyElements(domSnapshot: string, failedLocatorHint: string, windowLines?: number): string; /** * Estimate the number of AI tokens a string would consume. * Uses the rough approximation of 4 characters per token. * * @param text - The string to estimate. * @returns Estimated token count (rounded up). */ estimateTokens(text: string): number; } /** Singleton compressor instance for use across all MCP tools. */ export declare const compressor: ContextCompressor; //# sourceMappingURL=context-compressor.d.ts.map