import { AppError } from '../utils/errors.js'; import { type SourceContext } from '../utils/source-context.js'; /** Multiplier for candidate count in hybrid search (to allow reranking) */ export declare const HYBRID_SEARCH_CANDIDATE_MULTIPLIER = 2; /** Minimum semantic pool for keyword reranking without distance-gap grouping. */ export declare const HYBRID_SEARCH_MIN_CANDIDATES = 200; /** 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}, an object so a new option * 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). The valid range is * `MIN_QUERY_LIMIT`-`MAX_QUERY_LIMIT` (`src/utils/limits.ts`). */ limit?: number; /** * Optional path-prefix scope (exact-or-descendant, prefixes unioned). Omitted * = no prefilter (backward compatible). */ scope?: 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 { /** JSON display context, absent on legacy rows. */ sourceContext?: string; /** 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[]; /** 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; /** * Requested visual-caption profile of the ingestion that wrote this row; * omitted means normal text ingestion. Stored as a raw string: the store does * not interpret the vocabulary, so an unknown value survives a backup. */ visualProfile?: string; /** Ingestion timestamp (ISO 8601 format) */ timestamp: string; } /** * Search result */ export interface SearchResult { sourceContext?: SourceContext; /** 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; /** 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 from {@link VectorStore.getChunksByRange}. Distinct from `SearchResult`: * no score (not ranked). */ export interface ChunkRow { sourceContext?: SourceContext; /** 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 { sourceContext?: string | null; id: string; filePath: string; chunkIndex: number; text: string; /** Document title (optional - existing rows lack this field before migration) */ fileTitle?: string | null; _distance?: number; _score?: number; } /** * 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}, embedding included, so * it round-trips back through `insertChunks` — unlike {@link toChunkRow} and * {@link toSearchResult}, which drop the vector. LanceDB returns a typed array, * normalized here to `number[]`. */ 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; }; /** * The minimal range-read shape: no score (not ranked), so the shape check is narrower than * {@link isLanceDBRawResult}. An empty or missing `fileTitle` reads as `null`. * * @throws DatabaseError when a required field is missing. */ export declare function toChunkRow(raw: unknown): ChunkRow; /** * Database error */ export declare class DatabaseError extends AppError { constructor(message: string, options?: { cause?: Error; }); } //# sourceMappingURL=types.d.ts.map