import type { RagChunk } from '../hallucination/rag.js'; import type { VectorSearchResult } from '../hallucination/retrieval.js'; import type { RetrieveOptions, SparseRetriever } from '../rag/retrievers.js'; import type { MigrationResult, SchemaMigration } from '../utils/schema-migrations.js'; import { type PostgresLikeClient } from './client.js'; import type { PostgresMigrateOptions } from './migrations.js'; /** Options for `PostgresKeywordIndex`. */ export interface PostgresKeywordIndexOptions { /** Table name, optionally schema-qualified. Defaults to `nexus_keywords`. */ table?: string; /** * Searches the table of a `PostgresVectorStore` instead of keeping chunks of its own. `migrate()` * adds a generated search column and its index to that table, the store's writes keep it current, * and `add()` and `delete()` leave writing to the store. One copy of every chunk, and keyword and * vector search can never disagree about what exists. */ shared?: boolean; /** The text search configuration: `english`, `simple`, `german`, and so on. Defaults to `english`. */ language?: string; /** * `any` (the default) finds chunks with any of the query's terms, ranked by how many and how close, * as keyword search for retrieval should. `all` needs every term, read as a web search query, with * quoted phrases and `-` for exclusion. */ match?: 'any' | 'all'; } /** * The versioned schema, which `migrate()` applies. Version 1 creates the table with a generated * `tsvector` column and a GIN index, or, `shared`, adds the column and the index to a vector table. */ export declare function keywordIndexMigrations(options?: PostgresKeywordIndexOptions): SchemaMigration[]; /** * Keyword search in Postgres, with its full-text search: stemmed terms, a GIN index, and * `ts_rank_cd` ranking, so only the best matches leave the database however large the table. * * A `SparseRetriever`, so `hybridRetriever()` fuses it with `PostgresVectorStore`. With `shared`, it * searches the vector store's own table, and the hybrid search runs over one copy of the data. A * metadata filter runs in SQL, with the same meaning as the vector store's. * * ```ts * const vectors = new PostgresVectorStore(client, { dimensions: 1536, embed }); * const keywords = new PostgresKeywordIndex(client, { table: 'nexus_vectors', shared: true }); * await vectors.migrate(); * await keywords.migrate(); * const retriever = hybridRetriever([vectorRetriever(vectors), keywords]); * ``` */ export declare class PostgresKeywordIndex implements SparseRetriever { private readonly client; private readonly options; private readonly table; private readonly language; constructor(client: PostgresLikeClient, options?: PostgresKeywordIndexOptions); /** * Applies this index's pending migrations, recorded in `nexus_schema_migrations`, under a lock. * Never runs implicitly. With `shared`, run the vector store's `migrate()` first. */ migrate(options?: PostgresMigrateOptions): Promise; /** Adds chunks, or replaces those whose id exists. With `shared`, does nothing: the vector store writes. */ add(chunks: readonly RagChunk[]): Promise; /** Removes chunks by id. With `shared`, does nothing: the vector store deletes. */ delete(ids: readonly string[]): Promise; /** The chunks that best match a query's terms, best first, scored from 0 to 1. */ retrieve(query: string, options?: RetrieveOptions): Promise; /** Chunks held. */ size(): Promise; }