/**
 * Swappable database provider — the seam that decouples the agent's persistence
 * from any one driver.
 *
 * The agent core (and the app's server modules) import a single `db` and use it
 * directly. That `db` is a lazy proxy: it forwards to whatever database instance
 * the runtime injects via {@link DatabaseProvider.setDatabase}. So the SAME core
 * runs on:
 *   - Cloudflare D1            (`setDatabase(drizzle(d1, schema))`)        — prod
 *   - SQLite / miniflare       (`setDatabase(drizzle(betterSqlite, schema))`) — eval / the portable inner shell
 *   - libsql / Turso, Postgres (`setDatabase(drizzle(client, schema))`)    — a future hosted DB
 *
 * Adding a new database is one adapter (a drizzle instance over a new driver) +
 * a `setDatabase` call. None of the modules importing `db` change. Substrate-
 * free and driver-agnostic: this module knows nothing about D1, drizzle, or any
 * schema — it only forwards property access to the injected instance.
 */
interface DatabaseProvider<DB> {
    /** The injected database, as a lazy proxy. Throws (with `notReadyMessage`)
     *  on any access before {@link setDatabase} is called. */
    readonly db: DB;
    /** Inject the active database instance (any driver's client). */
    setDatabase(database: DB): void;
    /** True once a database has been injected. */
    isReady(): boolean;
    /** Clear the injected database (next access throws again). Mainly for tests. */
    reset(): void;
}
/** Define options for configuring database provider behavior including error messaging */
interface DatabaseProviderOptions {
    /** Error thrown when `db` is accessed before injection. Keep the product's
     *  existing wording so callers see a familiar message. */
    notReadyMessage?: string;
}
/**
 * Create a swappable database provider. `DB` is the injected instance's type
 * (e.g. a drizzle `Database`); the proxy is typed as `DB` so callers keep full
 * typing and their existing query syntax.
 */
declare function createDatabaseProvider<DB extends object>(options?: DatabaseProviderOptions): DatabaseProvider<DB>;
/** Describe the result of listing keys with completion status and optional pagination cursor */
interface KVListResult {
    keys: {
        name: string;
    }[];
    list_complete: boolean;
    cursor?: string;
}
/** Define options for storing a key-value pair with expiration and metadata settings */
interface KVPutOptions {
    expiration?: number;
    expirationTtl?: number;
    metadata?: unknown;
}
/** Resolve a key-value pair retrieval including its associated metadata and value */
interface KVGetWithMetadataResult {
    value: string | null;
    metadata: unknown | null;
}
/** Define a key-value store interface for asynchronous data retrieval, storage, deletion, and listing */
interface KVStore {
    get(key: string): Promise<string | null>;
    /** Read a value with its stored metadata (e.g. the vault's encrypted/hasPII flags). */
    getWithMetadata(key: string): Promise<KVGetWithMetadataResult>;
    put(key: string, value: string, options?: KVPutOptions): Promise<void>;
    delete(key: string): Promise<void>;
    list(options?: {
        prefix?: string;
        cursor?: string;
        limit?: number;
    }): Promise<KVListResult>;
}
/**
 * In-memory {@link KVStore} — the portable vault backend for sandbox/eval runs.
 * Backed by a Map; `list` returns all prefix-matched keys in one complete page
 * (no real pagination needed in-process). Seed with `initial` entries if useful.
 */
declare function createInMemoryKV(initial?: Record<string, string>): KVStore;

export { type DatabaseProvider, type DatabaseProviderOptions, type KVGetWithMetadataResult, type KVListResult, type KVPutOptions, type KVStore, createDatabaseProvider, createInMemoryKV };
