interface CrystalConfig { /** Root directory for all crystal data */ dataDir: string; /** Embedding provider: 'openai' | 'ollama' | 'google' */ embeddingProvider: 'openai' | 'ollama' | 'google'; /** OpenAI API key (required if provider is 'openai') */ openaiApiKey?: string; /** OpenAI embedding model (default: text-embedding-3-small) */ openaiModel?: string; /** Ollama host (default: http://localhost:11434) */ ollamaHost?: string; /** Ollama model (default: nomic-embed-text) */ ollamaModel?: string; /** Google API key (required if provider is 'google') */ googleApiKey?: string; /** Google embedding model (default: text-embedding-004) */ googleModel?: string; /** Remote Worker URL for cloud mirror mode */ remoteUrl?: string; /** Remote auth token */ remoteToken?: string; } interface Chunk { id?: number; text: string; embedding?: number[]; role: 'user' | 'assistant' | 'system'; source_type: string; source_id: string; agent_id: string; token_count: number; created_at: string; } /** Pre-embedded chunk for delta sync. Includes embedding vector so Nodes don't re-embed. */ interface ExportedChunk { id: number; text: string; text_hash: string; role: string; source_type: string; source_id: string; agent_id: string; token_count: number; created_at: string; embedding: number[] | null; } interface Memory { id?: number; text: string; embedding?: number[]; category: 'fact' | 'preference' | 'event' | 'opinion' | 'skill'; confidence: number; source_ids: string; status: 'active' | 'deprecated' | 'deleted'; created_at: string; updated_at: string; } interface SearchResult { text: string; role: string; score: number; source_type: string; source_id: string; agent_id: string; created_at: string; freshness?: "fresh" | "recent" | "aging" | "stale"; } interface CrystalStatus { chunks: number; memories: number; sources: number; agents: string[]; oldestChunk: string | null; newestChunk: string | null; embeddingProvider: string; dataDir: string; capturedSessions: number; latestCapture: string | null; } interface SourceCollection { id?: number; name: string; root_path: string; glob_patterns: string; ignore_patterns: string; file_count: number; chunk_count: number; last_sync_at: string | null; created_at: string; } interface SourceFile { id?: number; collection_id: number; file_path: string; file_hash: string; file_size: number; chunk_count: number; last_indexed_at: string; } interface SourcesStatus { collections: Array<{ name: string; root_path: string; file_count: number; chunk_count: number; last_sync_at: string | null; }>; total_files: number; total_chunks: number; } interface SyncResult { collection: string; added: number; updated: number; removed: number; chunks_added: number; duration_ms: number; } declare class Crystal { private config; private lanceDb; private sqliteDb; private chunksTable; private vecDimensions; constructor(config: CrystalConfig); init(): Promise; private initSqliteTables; private initChunksTables; private ensureVecTable; private initLanceTables; embed(texts: string[]): Promise; chunkText(text: string, targetTokens?: number, overlapTokens?: number): string[]; ingest(chunks: Chunk[]): Promise; /** Export interface for delta sync payloads. */ static readonly DELTA_VERSION = 1; /** Export chunks with IDs greater than sinceId. Returns pre-embedded chunks for delta sync. * Core calls this to build delta payloads for Nodes. */ exportChunksSince(sinceId: number): ExportedChunk[]; /** Get the highest chunk ID in the database. Used for watermark tracking. */ getMaxChunkId(): number; /** Import pre-embedded chunks from Core. Node calls this to apply delta payloads. * Skips chunks that already exist (by text_hash). Does NOT re-embed. */ importChunks(exported: ExportedChunk[]): number; private recencyWeight; /** Parse relative time strings ("24h", "7d", "30d") or ISO dates into ISO date strings. */ private parseSince; private freshnessLabel; search(query: string, limit?: number, filter?: { agent_id?: string; source_type?: string; since?: string; }): Promise; /** Deep search: query expansion + LLM re-ranking + position-aware blending. * Falls back to standard search if no LLM provider is available. */ deepSearch(query: string, limit?: number, filter?: { agent_id?: string; source_type?: string; since?: string; }): Promise; /** Vector search via sqlite-vec. Two-step pattern: MATCH first, then JOIN. */ private searchVec; /** Full-text search via FTS5 with BM25 scoring. */ private searchFTS; /** Build a safe FTS5 query from user input. */ private buildFTS5Query; /** * Reciprocal Rank Fusion. Ported from QMD (MIT License, Tobi Lutke, 2024-2026). * Fuses multiple ranked result lists into one using RRF scoring. * Uses text content as dedup key (instead of QMD's file path). */ private reciprocalRankFusion; /** LanceDB fallback for search (used when sqlite-vec tables are empty, pre-migration). */ private searchLanceFallback; remember(text: string, category?: Memory['category']): Promise; forget(memoryId: number): boolean; status(): Promise; getCaptureState(agentId: string, sourceId: string): { lastMessageCount: number; captureCount: number; }; setCaptureState(agentId: string, sourceId: string, messageCount: number, captureCount: number): void; private static readonly DEFAULT_INCLUDE; private static readonly DEFAULT_IGNORE; /** Add a directory as a source collection for indexing. */ sourcesAdd(rootPath: string, name: string, options?: { include?: string[]; ignore?: string[]; }): Promise; /** Remove a source collection and its file records. Chunks remain in LanceDB. */ sourcesRemove(name: string): boolean; /** Sync a collection: scan files, detect changes, re-index what changed. */ sourcesSync(name: string, options?: { dryRun?: boolean; batchSize?: number; }): Promise; /** Get status of all source collections. */ sourcesStatus(): SourcesStatus; /** Scan a directory recursively, matching include/ignore patterns. */ private scanDirectory; /** Clean orphaned entries in chunks_vec and chunks_fts that no longer have * corresponding rows in the chunks table. Returns counts of what was found/cleaned. */ cleanOrphans(options?: { dryRun?: boolean; }): { orphanedVec: number; orphanedFts: number; cleanedVec: number; cleanedFts: number; dryRun: boolean; }; close(): void; } declare function resolveConfig(overrides?: Partial): CrystalConfig; declare class RemoteCrystal { private url; private token; constructor(url: string, token: string); init(): Promise; private request; search(query: string, limit?: number, filter?: { agent_id?: string; }): Promise; ingest(chunks: Chunk[]): Promise; remember(text: string, category?: Memory['category']): Promise; forget(memoryId: number): Promise; status(): Promise; chunkText(text: string): string[]; } /** Create the appropriate Crystal instance based on config. */ declare function createCrystal(config: CrystalConfig): Crystal | RemoteCrystal; export { type Chunk, Crystal, type CrystalConfig, type CrystalStatus, type ExportedChunk, type Memory, RemoteCrystal, type SearchResult, type SourceCollection, type SourceFile, type SourcesStatus, type SyncResult, createCrystal, resolveConfig };