import { AppError } from '../utils/errors.js'; /** Multiplier for candidate count in hybrid search (to allow reranking) */ export declare const HYBRID_SEARCH_CANDIDATE_MULTIPLIER = 2; /** FTS index name (bump version when changing tokenizer settings) */ export declare const FTS_INDEX_NAME = "fts_index_v2"; /** Threshold for cleaning up old index versions (1 minute) */ export declare const FTS_CLEANUP_THRESHOLD_MS: number; /** Default hybrid-search weight (vector vs FTS blend) when not configured */ export declare const DEFAULT_HYBRID_WEIGHT = 0.6; /** * Grouping mode for quality filtering * - 'similar': Only return the most similar group (stops at first distance jump) * - 'related': Include related groups (stops at second distance jump) */ export type GroupingMode = 'similar' | 'related'; /** * VectorStore configuration */ export interface VectorStoreConfig { /** LanceDB database path */ dbPath: string; /** Table name */ tableName: string; /** Maximum distance threshold for filtering results (optional) */ maxDistance?: number; /** Grouping mode for quality filtering (optional) */ grouping?: GroupingMode; /** Hybrid search weight for BM25 (0.0 = vector only, 1.0 = BM25 only, default 0.6) */ hybridWeight?: number; /** Maximum number of files to keep in results (optional, filters by best score per file) */ maxFiles?: number; } /** * Per-call options for {@link VectorStore.search}. * Grouped into an object (instead of positional params) so the caller can pass * any subset and so adding options (like `scope`) is not a breaking signature * change. */ export interface SearchOptions { /** Optional query text for keyword boost (BM25) */ queryText?: string; /** Number of results to retrieve (default 10, valid range 1-20) */ limit?: number; /** * Optional path-prefix scope (exact-or-descendant, prefixes unioned). Omitted * = no prefilter (backward compatible). */ scope?: string[]; } /** * Document metadata */ export interface DocumentMetadata { /** File name */ fileName: string; /** File size in bytes */ fileSize: number; /** File type (extension) */ fileType: string; } /** * Validated, bounded image stored in a chunk's ordered attachment JSON. */ export interface VisualAttachment { imageIndex: number; mimeType: 'image/png' | 'image/jpeg'; data: string; } /** * Vector chunk */ export interface VectorChunk { /** Chunk ID (UUID) */ id: string; /** File path (absolute) */ filePath: string; /** Chunk index (zero-based) */ chunkIndex: number; /** Chunk text */ text: string; /** Embedding vector (dimension depends on model) */ vector: number[]; /** Metadata */ metadata: DocumentMetadata; /** Document title extracted from file content (display-only, not used for scoring) */ fileTitle: string | null; /** SHA-256 of the source file bytes; absent for chunks not ingested from a file. */ contentHash?: string; /** Ordered `JSON.stringify(VisualAttachment[])`; omitted means no attachments. */ visualAttachments?: string; /** Ingestion timestamp (ISO 8601 format) */ timestamp: string; } /** * Search result */ export interface SearchResult { /** Stable persisted row identity used for attachment hydration. */ id: string; /** File path */ filePath: string; /** Chunk index */ chunkIndex: number; /** Chunk text */ text: string; /** Distance score using dot product (0 = identical, 1 = orthogonal, 2 = opposite) */ score: number; /** Metadata */ metadata: DocumentMetadata; /** Document title extracted from file content (display-only, not used for scoring) */ fileTitle: string | null; } /** Validated attachments for one persisted row, in visual order. */ export interface HydratedChunkAttachments { id: string; attachments: VisualAttachment[]; } /** Result of one final-identity hydration query. */ export interface AttachmentHydrationResult { rows: HydratedChunkAttachments[]; omittedCount: number; } /** * Row returned by VectorStore.getChunksByRange. * Distinct from SearchResult: no score (not a ranked result) and no metadata * (not needed for index-adjacent retrieval). Consumed by * handleReadChunkNeighbors and runReadNeighbors. */ export interface ChunkRow { /** File path (absolute) */ filePath: string; /** Chunk index (zero-based) */ chunkIndex: number; /** Chunk text */ text: string; /** Document title extracted from file content (display-only, not used for scoring) */ fileTitle: string | null; } /** * Raw result from LanceDB query (internal type) */ export interface LanceDBRawResult { id: string; filePath: string; chunkIndex: number; text: string; metadata: DocumentMetadata; /** Document title (optional - existing rows lack this field before migration) */ fileTitle?: string | null; _distance?: number; _score?: number; } /** * Type guard for LanceDB raw search result */ export declare function isLanceDBRawResult(value: unknown): value is LanceDBRawResult; /** * Convert LanceDB raw result to SearchResult with type validation * @throws DatabaseError if the result is invalid */ export declare function toSearchResult(raw: unknown): SearchResult; /** * Map a raw LanceDB row to a full {@link VectorChunk}, including the stored * embedding vector and metadata. Used for backup/restore (ingest rollback), * where the row must round-trip back through `insertChunks` intact — unlike * {@link toChunkRow} / {@link toSearchResult}, which drop the vector. The * embedding is normalized to `number[]` (LanceDB returns a typed array). */ export declare function toVectorChunk(raw: unknown): VectorChunk; /** Normalize only the defined legacy no-image sentinels; keep malformed JSON observable. */ export declare function normalizeVisualAttachments(value: unknown): string; /** Parse one persisted attachment cell while keeping malformed siblings observable. */ export declare function parseHydratedVisualAttachments(value: unknown): { attachments: VisualAttachment[]; omittedCount: number; }; /** * Convert LanceDB raw row to ChunkRow with type validation. * Mirrors toSearchResult but returns the minimal range-read shape: no score * (not ranked) and no metadata (not needed for index-adjacent retrieval). * * Uses a narrower shape check than isLanceDBRawResult: only * filePath/chunkIndex/text are required because getChunksByRange * does not project metadata. The empty-string-or-missing fileTitle * is normalized to null per §Field Propagation Map. * * @throws DatabaseError if the raw row is missing required fields */ export declare function toChunkRow(raw: unknown): ChunkRow; /** * Database error */ export declare class DatabaseError extends AppError { constructor(message: string, cause?: Error); } //# sourceMappingURL=types.d.ts.map