import type { ToolSpec } from "../core/types.js";
export interface SqlToolOptions {
    /**
     * Execute a query that has already passed read-only validation, returning rows.
     * IMPORTANT: back this with **read-only database credentials** — the validation here is
     * defense-in-depth, not the primary guarantee.
     */
    query: (sql: string) => Promise<unknown[]>;
    /**
     * If set, the query may only reference these tables (case-insensitive). **Best-effort, NOT a hard
     * isolation boundary.** Table extraction is regex-based; to stay sound it FAILS CLOSED — comma-joins
     * (`FROM a, b`), sub-queries in FROM/JOIN, and set operations (UNION/INTERSECT/EXCEPT) are REJECTED
     * (their full table set can't be reliably enumerated). Even so, do **NOT** rely on this alone for
     * multi-tenant / cross-tenant isolation: back it with **read-only DB credentials scoped to the tenant +
     * DB-level GRANTs**. The allowlist is a usability guardrail and defense-in-depth, not the security
     * boundary. (Full AST-parser coverage is deferred to preserve the zero-extra-dependency posture.)
     */
    allowTables?: string[];
    /** Maximum rows returned to the model. Default 100. */
    maxRows?: number;
    /** Tool name exposed to the model. Default "query_sql". */
    name?: string;
    /** Description override. */
    description?: string;
}
/** Validate that `sql` is a single, read-only SELECT/CTE query within the allowlist. */
export declare function validateReadOnlySql(sql: string, allowTables?: string[]): void;
/**
 * Build a safe, read-only `query_sql` tool.
 *
 * Layers of defense: (1) read-only DB credentials supplied by the caller's `query`,
 * (2) static validation (single SELECT/WITH only, no DML/DDL, no comments/multi-statement),
 * (3) optional table allowlist, (4) a row cap on what is returned to the model.
 */
export declare function createSqlTool(opts: SqlToolOptions): ToolSpec;
