/** * Bridge from TypeScript to the vendored insane-search Python engine. * * Invokes `python3 -m engine "" --json` per fallback attempt (cwd + PYTHONPATH * pointed at the vendored engine), validates the JSON envelope, and maps it onto a * discriminated result. Hardened: clamped timeout, AbortSignal propagation that * kills+reaps the child, bounded stdout/stderr capture, and a per-process * concurrency cap so blocked reads cannot fork-storm. * * Fail-closed: missing dependencies / bad output / auth-required never throw past * the caller and never auto-install anything; they return ok:false with a stable, * bounded note so `read` can continue with its normal degraded result. */ import { spawn as nodeSpawn } from "node:child_process"; /** packages/coding-agent/vendor/insane-search */ export declare const INSANE_VENDOR_DIR: string; /** Stable note prefixes — tests assert on these without depending on full stderr. */ export declare const INSANE_NOTES: { readonly securityDisabled: `insane fallback disabled: remote renderer cannot preserve validated network routing`; readonly guardBlocked: (reason: string) => string; readonly vendorMissing: `insane fallback unavailable: vendor engine missing at packages/coding-agent/vendor/insane-search`; readonly noPython: `insane fallback unavailable: python3 not found; install python3 and curl_cffi, then retry with web.insaneFallback=true`; readonly noCurlCffi: `insane fallback unavailable: python3 cannot import curl_cffi; install curl_cffi for Phase 0-2`; readonly noBrowser: `insane fallback unavailable: node/playwright/stealth dependencies missing for Phase 3; install dependencies under packages/coding-agent/vendor/insane-search/engine/templates`; readonly timeout: (seconds: number) => string; readonly invalidJson: `insane fallback failed: engine returned invalid JSON`; readonly authRequired: `insane fallback stopped: authentication required`; readonly verdict: (verdict: string) => string; readonly untried: (routes: string) => string; readonly mustBrowserMcp: `insane fallback requires browser MCP/manual phase: must_invoke_playwright_mcp=true`; readonly concurrency: `insane fallback skipped: max concurrent engine attempts reached`; readonly emptyContent: `insane fallback failed: engine reported ok but returned no content`; }; /** Raw JSON envelope produced by `python3 -m engine --json`. */ export interface InsaneFetchResultRaw { ok?: boolean; verdict?: string; content?: string; profile_used?: string; trace?: unknown; untried_routes?: string[]; must_invoke_playwright_mcp?: boolean; } export interface InsaneSuccess { ok: true; content: string; profileUsed?: string; notes: string[]; } export interface InsaneFailure { ok: false; reason: string; verdict?: string; notes: string[]; } export type InsaneBridgeResult = InsaneSuccess | InsaneFailure; export interface EngineInvocation { url: string; timeoutMs: number; signal?: AbortSignal; } export interface EngineRawOutput { code: number | null; stdout: string; stderr: string; timedOut: boolean; aborted: boolean; } /** Seam: run the engine subprocess. Default spawns python3. */ export type EngineRunner = (inv: EngineInvocation) => Promise; export interface InsaneDependencyStatus { vendorPresent: boolean; python: boolean; curlCffi: boolean; browser: boolean; } /** Seam: probe dependencies. Default probes the real environment (cached). */ export type DependencyProber = () => Promise; type SpawnImpl = typeof nodeSpawn; /** Real engine runner: `python3 -m engine "" --json`. */ export declare function runEngineSubprocess(inv: EngineInvocation, options?: { spawnImpl?: SpawnImpl; }): Promise; /** Reset the probe cache between tests so probe state never leaks. */ export declare function resetInsaneProbeCacheForTest(): void; /** Probe (and cache) the insane-search runtime dependencies. */ export declare function probeInsaneDependencies(): Promise; export declare function resetInsaneConcurrencyForTest(): void; export interface TryInsaneFetchOptions { timeoutMs?: number; signal?: AbortSignal; concurrencyLimit?: number; /** Seam: dependency prober (default real, cached). */ prober?: DependencyProber; /** Seam: engine runner (default real subprocess). */ runner?: EngineRunner; } /** * Attempt to read `url` through the insane-search engine. The caller is * responsible for the opt-in gate, raw-mode skip, and the public-URL guard * (which MUST run before this is called). Never throws; always returns a result. */ export declare function tryInsaneFetch(url: string, options?: TryInsaneFetchOptions): Promise; export {};