/** Resolve the Exa API key: EXA_API_KEY env first, then ~/.crouter/exa.key. * Never prompts and never proceeds keyless — throws a usage error naming both * options when neither is present. */ export declare function getApiKey(): string; /** One Exa result row as returned by /search and /contents. Fields are present * only when the API supplies them. */ export interface ExaResult { title?: string; url?: string; publishedDate?: string; author?: string; highlights?: string[]; text?: string; score?: number; /** Set when the row came from a fallback fetcher (e.g. 'pure.md') rather than Exa. */ source?: string; } export interface ExaSearchResponse { results?: ExaResult[]; } export interface ExaAnswerResponse { answer?: string; citations?: Array<{ title?: string; url?: string; }>; } /** Per-URL fetch status returned by /contents (and /search livecrawls). */ export interface ExaStatus { id?: string; status?: string; error?: { tag?: string; httpStatusCode?: number; } | string; } export interface ExaContentsResponse { results?: ExaResult[]; statuses?: ExaStatus[]; } export declare function exaSearch(body: Record): Promise; export declare function exaAnswer(body: Record): Promise; export declare function exaContents(body: Record): Promise; /** Cap (characters) applied to full-text extraction so a single call cannot * blow up the caller's context. Highlights remain the default content mode. */ export declare const TEXT_MAX_CHARACTERS = 4000; /** Split a positional URL argument on commas or whitespace into a clean list. */ export declare function parseUrls(raw: string): string[]; /** Split a comma-separated domain flag into a clean list, or undefined when empty. */ export declare function parseDomains(raw: string | undefined): string[] | undefined; /** Render one result as agent-ready markdown: a numbered heading with title + * metadata line, then highlights as bullets or capped text as a blockquote. */ export declare function renderResult(r: ExaResult, index: number): string;