/**
 * Embedder — TF-IDF local embeddings + optional API mode
 *
 * Mode 1 (default): Pure TF-IDF, no API needed. Works offline, fast.
 * Mode 2: OpenAI-compatible API (set NEXUS_EMBED_MODE=api, NEXUS_EMBED_URL, NEXUS_EMBED_KEY)
 * Mode 3: Ollama (set NEXUS_EMBED_MODE=ollama, NEXUS_OLLAMA_ENDPOINT, NEXUS_OLLAMA_MODEL)
 * Mode 4: HuggingFace (set NEXUS_EMBED_MODE=huggingface, NEXUS_HF_API_KEY, NEXUS_HF_MODEL)
 *
 * Output: fixed 128-dim float32 vectors (TF-IDF), 768-dim (Ollama), 384-dim (HF), or 1536-dim (API)
 */
import type Database from 'better-sqlite3';
export interface PersistentVocabularyStatus {
    docCount: number;
    termCount: number;
    reset: boolean;
    needsRecovery: boolean;
}
export declare function isSqliteCorruptionError(error: unknown): error is {
    code?: string;
    message?: string;
};
/**
 * Poincare Ball model for hyperbolic space.
 * Hyperbolic distance is better suited for hierarchical structures (trees/code).
 */
export declare const HyperbolicMath: {
    /**
     * Hyperbolic distance between two points in the unit ball.
     * d(u, v) = arcosh(1 + 2 * ||u-v||^2 / ( (1-||u||^2)(1-||v||^2) ))
     */
    dist(u: number[], v: number[]): number;
    /**
     * Mobius addition: u ⊕ v
     * Used to translate points in hyperbolic space while staying in the unit ball.
     */
    mobiusAdd(u: number[], v: number[]): number[];
    /** Ensure vector is within unit ball (norm < 1) */
    project(v: number[]): number[];
};
export declare class Embedder {
    private vocabulary;
    private idf;
    private docCount;
    private vocabularyDb?;
    private embedMode;
    private apiUrl;
    private apiKey;
    private apiModel;
    private ollamaEndpoint;
    private ollamaModel;
    private hfEndpoint;
    private hfApiKey;
    private hfModel;
    constructor(vocabularyDb?: Database.Database);
    /** Embed a string → float32 vector */
    embed(text: string): Promise<number[]>;
    /** Synchronous local embedding for hot paths that cannot await remote providers. */
    embedSync(text: string): number[];
    /**
     * Generate a hierarchical embedding.
     * Shifts the vector "deeper" into the Poincare ball relative to a parent.
     */
    embedHierarchical(text: string, parentVector?: number[], depth?: number): number[];
    /** Update vocabulary with new documents (call as you store memories) */
    fitVocabulary(docs: string[]): PersistentVocabularyStatus;
    rebuildPersistentVocabulary(): PersistentVocabularyStatus;
    /** Dimension of vectors produced by this embedder */
    get dimensions(): number;
    localEmbed(text: string): number[];
    apiEmbed(text: string): Promise<number[]>;
    ollamaEmbed(text: string): Promise<number[]>;
    huggingfaceEmbed(text: string): Promise<number[]>;
    cosineSimilarity(a: number[], b: number[]): number;
    /** Embed multiple texts, returning one vector per text. */
    embedBatch(texts: string[]): Promise<number[][]>;
    /** Serialize a float64 JS array into a compact Float32Array Buffer for SQLite BLOB storage. */
    serializeVector(vec: number[]): Buffer;
    /** Deserialize a SQLite BLOB Buffer back into a JS number array. */
    deserializeVector(blob: Buffer): number[];
    /** Binarize a float vector: bit[i] = vector[i] > 0 ? 1 : 0, packed into bytes. */
    binarize(vector: number[]): Buffer;
    /** Hamming distance between two binary vectors (number of differing bits). */
    hammingDistance(a: Buffer, b: Buffer): number;
    /** Get the current embed mode */
    getEmbedMode(): string;
    private tokenize;
    private normalize;
    private hashCode;
    private initVocabularyTables;
    private upsertPersistentVocabularyStats;
    private clearPersistentVocabulary;
    private currentPersistentVocabularyStatus;
    private handlePersistentVocabularyFailure;
}
export declare const createEmbedder: () => Embedder;
