You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Breaking: a keyword-index rebuild no longer stops on a failed batch — it retries in the process until it finishes.
A batch that fails (a statement past the command timeout, a dropped connection) rolls back and is tried again from the
last committed batch after a growing delay (1 s, doubling, at most 5 min). Batches start at 50 chunks (was a fixed
500) and double while they finish within a quarter of the connection's command timeout, halve above half of it, and
halve on each failure, down to one chunk — so a large PostgreSQL index on a cold page cache no longer times out
batch after batch and waits for the next restart. KeywordIndexRebuild gains ConsecutiveFailures, NextAttemptAt and BatchSize; Error now carries the last failure while retrying. KeywordIndexRebuildStatus.Failed is replaced by Retrying = 4 (3 is left unused), and WaitForMaintenanceAsync() no longer throws for a failed batch — it keeps waiting. Migration: read Status == Retrying and Error where you read Failed; bound a readiness wait with a cancellation token.
A keyword-index rebuild writes only the chunks whose postings change. Each batch compares the postings the
configured analyzer and fields produce with the stored ones (body terms with frequency and length; field terms of any
field, so rows of a field no longer configured count as a change) and rewrites only the chunks that differ. Rebuilding
an index that already holds the right terms — its recorded analyzer was lost, or a sampled chunk differed — is now a
read pass plus a few writes instead of rewriting every posting. The completion log line reports how many chunks were
rewritten.
Breaking: EmbeddingGeneratorEmbeddingService reads the generator's identity when it is used, not at
construction. Provider, model id and dimension come from EmbeddingGeneratorMetadata on each GetIdentity(), GetModelName(), GetEmbeddingDimension() and embed call, so a host whose model is picked at run time (a settings
screen, a fallback chain) can register the service — and build a FluxIndexContext — before a model is set. A missing
model id or dimension, or an EmbeddingGeneratorServiceOptions.Dimensions that contradicts the generator, now throws InvalidOperationException at that use instead of ArgumentException from the constructor (a non-positive Dimensions is still refused at construction). Retriever and Indexer bind the vector store to the identity on
each vector operation rather than in their constructors, so the store sees the model that embeds each request: the
Qdrant store refuses a model switched under its index with EmbeddingModelMismatchException, and the sqlite-vec store
names its vector table by the model's fingerprint, so a new model writes and searches its own table. (The PostgreSQL
and plain SQLite stores do not check the identity yet.) Migration: catch InvalidOperationException where you caught the constructor's ArgumentException.