import { PluginConfig } from './types.js';

/**
 * Thrown by `EmbeddingFallback.search()` (via `embed()`) when the embedding
 * backend is effectively unavailable on the lookup path — either because the
 * HTTP fetch exceeded its deadline OR because the endpoint returned a non-2xx
 * status code. Callers that need to distinguish a backend outage from "no
 * candidates" can `instanceof`-check against this class.
 *
 * Round 9 fix (Finding UZqB): previously a timeout returned null from embed(),
 * which caused search() to return [] silently. decideSemanticDedup then
 * classified the result as no_candidates instead of backend_unavailable, so
 * the per-batch batchBackendUnavailable short-circuit never activated and
 * batches of N facts each paid a full timeout roundtrip.
 *
 * Round 10 fix (Findings Ui1J + Ui1L): search() now only re-throws this error
 * when the caller explicitly passes `{ throwOnTimeout: true }`. Without that
 * flag search() catches it and returns [] instead, preserving fail-open
 * semantics for recall-path callers (searchEmbeddingFallback) that have no
 * try/catch. Only the semantic-dedup path (semanticDedupLookup) passes the
 * flag so it can still reach decideSemanticDedup's backend_unavailable branch.
 *
 * Round 11 fix (Finding Ur_J): `embed()` now also throws this error from the
 * lookup path when the HTTP response is non-2xx (e.g. 429, 500, 503). Without
 * this, repeated 5xx outages would each return null → [] → no_candidates and
 * subsequent facts in the same batch would all pay full roundtrips instead of
 * tripping the per-batch backend_unavailable short-circuit.
 *
 * The class name is kept for backward compatibility — `EmbeddingTimeoutError`
 * now signals "lookup backend unavailable" rather than strictly "timed out".
 */
declare class EmbeddingTimeoutError extends Error {
    readonly name: "EmbeddingTimeoutError";
    constructor(message: string);
}
/**
 * Options for the low-level embed() call.
 *
 * `mode` selects the timeout profile:
 *   - "lookup" (default): bounded by the short lookup budget; fails open fast.
 *   - "index": bounded by a much longer budget so slow backends can still
 *     index newly persisted memories.
 */
type EmbedMode = "lookup" | "index";
declare class EmbeddingFallback {
    private readonly config;
    private readonly indexPath;
    private loaded;
    constructor(config: PluginConfig);
    isAvailable(): Promise<boolean>;
    /**
     * Embed an array of texts and return their embedding vectors.
     *
     * This is the public batch-embed interface used by semantic chunking
     * (Finding 1, PR #420 post-merge). Texts are grouped into batches of
     * `embeddingBatchSize` (from `semanticChunkingConfig`, default 32) and
     * each batch is dispatched concurrently via `Promise.all()`. This
     * preserves the semantic intent of `embeddingBatchSize` — without batching,
     * every text incurred a sequential HTTP round-trip, making the batch size
     * config ineffective. (PR #439 post-merge Finding 2.)
     *
     * If the provider is unavailable or any single embedding fails, the method
     * throws so the caller can fall back to recursive chunking.
     */
    embedTexts(texts: string[]): Promise<number[][]>;
    /**
     * Nearest-neighbor search against the embedding index.
     *
     * @param query         The query string to embed and search for.
     * @param limit         Max number of hits to return.
     * @param options       Optional filters.
     *   - `pathPrefix`   Restrict candidates to entries whose indexed `path`
     *                    starts with this prefix (relative to `memoryDir`).
     *                    Used by the semantic dedup guard to scope lookups
     *                    to the target namespace so a high-similarity hit
     *                    from a different namespace can't suppress a write
     *                    in the target namespace. Default: no filter.
     *   - `pathExcludePrefixes`
     *                    Exclude any entry whose indexed `path` starts with
     *                    any of these prefixes. Used for the default
     *                    namespace case: when the default namespace lives at
     *                    `memoryDir` root (legacy layout) we still want to
     *                    exclude `namespaces/<other>/…` entries.
     */
    search(query: string, limit: number, options?: {
        pathPrefix?: string;
        pathExcludePrefixes?: readonly string[];
        /**
         * When true, an `EmbeddingTimeoutError` from the embedding backend is
         * re-thrown to the caller. Use this on the semantic-dedup path so
         * `decideSemanticDedup`'s catch block can classify the result as
         * `reason="backend_unavailable"` and activate the per-batch
         * short-circuit.
         *
         * When false (the default), a timeout is caught here and search()
         * returns [] instead — preserving fail-open semantics for the recall
         * path (`searchEmbeddingFallback`) which has no surrounding try/catch.
         * Without this gate a timed-out embedding request on the recall path
         * would propagate as an unhandled rejection and abort recall entirely.
         * (Round 10 fix, Findings Ui1J + Ui1L.)
         */
        throwOnTimeout?: boolean;
    }): Promise<Array<{
        id: string;
        score: number;
        path: string;
    }>>;
    indexFile(memoryId: string, content: string, filePath: string): Promise<void>;
    removeFromIndex(memoryId: string): Promise<void>;
    private resolveProvider;
    private embed;
    private loadIndex;
    private saveIndex;
}

export { type EmbedMode, EmbeddingFallback, EmbeddingTimeoutError };
