fix: address dense index review findings - #230
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (20)
🚧 Files skipped from review as they are similar to previous changes (20)
Summary by CodeRabbit
WalkthroughDense index construction now buffers records and flushes them incrementally. It validates embedding dimensions and persists provider identity. Dense queries validate model and identity compatibility. CLI configuration validates embedding settings and generates identities. Archive migration and rewrites handle legacy Sequence Diagram(s)sequenceDiagram
participant CLIConfig
participant EmbeddingProvider
participant SearchIndexBuilder
participant SearchIndexDatabase
CLIConfig->>EmbeddingProvider: Create embedding configuration and identity
SearchIndexBuilder->>EmbeddingProvider: Generate embedding vectors
EmbeddingProvider-->>SearchIndexBuilder: Return vectors
SearchIndexBuilder->>SearchIndexBuilder: Validate dimensions and buffer records
SearchIndexBuilder->>SearchIndexDatabase: Persist dense segments and metadata
Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches✨ Simplify code
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/core/src/retrieval/search-index/search/build.ts (2)
553-572: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winPreserve chapter groups across dense-record flushes.
writePendingDenseRecordsclearsdenseRecordsafter 2,000 records, socreateTextEmbeddingSegmentsForGroupprocesses partial chapter groups independently. For 2,001 uniform 20-word sentences, this creates segments1991–1999(180 words) and2000(20 words), instead of one1991–2000segment (200 words). Retain unfinished groups across flushes or flush only at group boundaries.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/core/src/retrieval/search-index/search/build.ts` around lines 553 - 572, Update the dense-record batching flow around writePendingDenseRecords and createTextEmbeddingSegmentsForGroup so chapter groups spanning a 2,000-record flush remain combined. Retain incomplete groups across flushes, or only flush at chapter-group boundaries, ensuring uniform records produce one continuous segment rather than separate partial segments.
68-119: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy liftMove dense-embedding calls out of
ensureSearchIndex’s transaction.
Database.transactionstartsBEGIN IMMEDIATEand holds the SQLite write reservation until the callback resolves.writePendingDenseRecordscallsembeddingProvider.embedTexts, so each flush holds this reservation during network calls and blocks other writers. A provider failure also rolls back the inserted sentence and FTS rows. Keep incremental flushes outside the transaction, preserve the dirty state until all dense segments are written, and finalize the index state in a short transaction.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/core/src/retrieval/search-index/search/build.ts` around lines 68 - 119, Refactor ensureSearchIndex so its database.transaction callback never invokes writePendingDenseRecords or embeddingProvider.embedTexts: commit clearing and sentence/FTS record writes in a short transaction, then perform incremental and final dense flushes outside any transaction. Keep the index marked dirty until all dense segments succeed, and use a final short transaction to finalize search_index_state only after embedding completes; provider failures must leave the dirty state and committed records intact.
🧹 Nitpick comments (2)
packages/cli/src/runtime/config.test.ts (1)
43-55: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winCover each validation rule independently.
This test omits both
modelandbaseURL, so it cannot detect removal of either check. Add separate cases for missingmodel, missingbaseURL, and an OpenAI configuration with a custombaseURL.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/cli/src/runtime/config.test.ts` around lines 43 - 55, Expand the loadCLIConfig validation tests around “ignores incomplete embedding config in general CLI config” to cover each rule independently: add cases missing only model, missing only baseURL, and using an OpenAI provider with a custom baseURL. Keep the existing expectation that invalid configurations omit embedding, and verify the custom-baseURL OpenAI configuration follows the intended validation behavior.packages/core/src/retrieval/search-index/search/build.ts (1)
336-365: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsolidate the duplicate
denseDone/doneOffsetfields.
writePendingDenseRecordsaccepts bothdenseDoneanddoneOffsetas aliases for the same starting-offset value (input.doneOffset ?? input.denseDone ?? 0). Callers use one or the other inconsistently (ensureSearchIndexandwriteSearchIndexBatchpassdenseDone,writeSearchIndexDenseSegmentspassesdoneOffset). A single field name would remove the ambiguity and the fallback chain.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/core/src/retrieval/search-index/search/build.ts` around lines 336 - 365, Consolidate the starting-offset input for writePendingDenseRecords into one field, preferably doneOffset, and remove denseDone plus the nullish fallback chain. Update all callers, including ensureSearchIndex, writeSearchIndexBatch, and writeSearchIndexDenseSegments, to pass the unified field while preserving the existing default offset behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/en/wikg-standard.md`:
- Line 39: Update the index.db description in docs/en/wikg-standard.md (lines
39-39) and docs/zh-CN/wikg-standard.md (lines 31-31) to state that supported
indexes may contain FTS records, Dense embedding segments, or both, including
Dense-only indexes.
In `@packages/cli/src/commands/archive-command/search-index.ts`:
- Line 156: Update the dense and hybrid index capability checks around
capabilities.dense.model to persist and compare a non-secret embedding identity
that includes the provider and baseURL alongside model and dimensions. Ensure
queryDenseTextRows validates the same complete identity, rebuilding or rejecting
indexes when any identity component differs, and add regression tests covering
changed providers and baseURL values.
In `@packages/core/data/help/topics/readiness.jinja`:
- Line 104: Update the openai-compatible embeddings instruction in the readiness
topic to use the configuration key baseURL instead of baseUrl, matching the key
consumed by the embeddings configuration and allowing Dense configuration to
load.
In `@packages/core/src/storage/wikg/archive/write.ts`:
- Around line 92-94: Update flushArchiveOverlays so a database.db change also
adds the fts.db deletion overlay, even when no index.db overlay exists; preserve
the existing archive-path validation and entryPaths handling.
---
Outside diff comments:
In `@packages/core/src/retrieval/search-index/search/build.ts`:
- Around line 553-572: Update the dense-record batching flow around
writePendingDenseRecords and createTextEmbeddingSegmentsForGroup so chapter
groups spanning a 2,000-record flush remain combined. Retain incomplete groups
across flushes, or only flush at chapter-group boundaries, ensuring uniform
records produce one continuous segment rather than separate partial segments.
- Around line 68-119: Refactor ensureSearchIndex so its database.transaction
callback never invokes writePendingDenseRecords or embeddingProvider.embedTexts:
commit clearing and sentence/FTS record writes in a short transaction, then
perform incremental and final dense flushes outside any transaction. Keep the
index marked dirty until all dense segments succeed, and use a final short
transaction to finalize search_index_state only after embedding completes;
provider failures must leave the dirty state and committed records intact.
---
Nitpick comments:
In `@packages/cli/src/runtime/config.test.ts`:
- Around line 43-55: Expand the loadCLIConfig validation tests around “ignores
incomplete embedding config in general CLI config” to cover each rule
independently: add cases missing only model, missing only baseURL, and using an
OpenAI provider with a custom baseURL. Keep the existing expectation that
invalid configurations omit embedding, and verify the custom-baseURL OpenAI
configuration follows the intended validation behavior.
In `@packages/core/src/retrieval/search-index/search/build.ts`:
- Around line 336-365: Consolidate the starting-offset input for
writePendingDenseRecords into one field, preferably doneOffset, and remove
denseDone plus the nullish fallback chain. Update all callers, including
ensureSearchIndex, writeSearchIndexBatch, and writeSearchIndexDenseSegments, to
pass the unified field while preserving the existing default offset behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 06bc46b5-d430-41ef-be9a-bc124c11f8cb
📒 Files selected for processing (17)
docs/en/wikg-standard.mddocs/schema-upgrade.mddocs/zh-CN/wikg-standard.mdpackages/cli/src/commands/archive-command/search-index.tspackages/cli/src/runtime/config.test.tspackages/cli/src/runtime/config.tspackages/cli/src/runtime/embedding.tspackages/cli/src/runtime/local-config.tspackages/core/data/help/commands/predicate.jinjapackages/core/data/help/topics/readiness.jinjapackages/core/src/retrieval/query/archive-view/index-state.test.tspackages/core/src/retrieval/search-index/search/build.tspackages/core/src/retrieval/search-index/search/helpers.tspackages/core/src/retrieval/search-index/search/query.tspackages/core/src/retrieval/search-index/search/status.tspackages/core/src/storage/wikg/archive/write.tstest/core/storage/wikg/archive.test.ts
💤 Files with no reviewable changes (1)
- packages/cli/src/runtime/embedding.ts
86a1c38 to
8eda84c
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/core/src/retrieval/query/archive-view/index-state.test.ts`:
- Around line 452-475: Update the dense indexing flow around
writeTextEmbeddingSegments so inferred embedding dimensions persist across all
flushes in a single rebuildArchiveSearchIndex operation, rather than being
recalculated per call. Reuse the first inferred dimension and reject subsequent
batches whose vectors differ, while preserving explicit dimensions behavior.
Extend the regression coverage to make embedTexts return one vector length on an
earlier call and another on a later call, asserting the build rejects the
mismatch.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 08e6d6aa-ded4-4ed6-884e-5b1849d50dda
📒 Files selected for processing (20)
docs/en/wikg-standard.mddocs/schema-upgrade.mddocs/zh-CN/wikg-standard.mdpackages/cli/src/commands/archive-command/search-index.tspackages/cli/src/runtime/config.test.tspackages/cli/src/runtime/config.tspackages/cli/src/runtime/embedding.tspackages/cli/src/runtime/local-config.tspackages/core/data/help/commands/predicate.jinjapackages/core/data/help/topics/readiness.jinjapackages/core/src/retrieval/query/archive-view/index-state.test.tspackages/core/src/retrieval/search-index/search/build.tspackages/core/src/retrieval/search-index/search/helpers.tspackages/core/src/retrieval/search-index/search/query.tspackages/core/src/retrieval/search-index/search/status.tspackages/core/src/retrieval/search-index/search/types.tspackages/core/src/storage/wikg/archive/write.tspackages/core/src/storage/wikg/wikg-coordinator/flusher.tstest/core/storage/wikg/archive.test.tstest/core/storage/wikg/wiki-graph-archive-file.test.ts
🚧 Files skipped from review as they are similar to previous changes (13)
- packages/core/data/help/commands/predicate.jinja
- test/core/storage/wikg/archive.test.ts
- packages/cli/src/runtime/config.ts
- packages/core/src/retrieval/search-index/search/helpers.ts
- packages/core/src/retrieval/search-index/search/status.ts
- packages/cli/src/runtime/local-config.ts
- packages/core/src/storage/wikg/archive/write.ts
- docs/en/wikg-standard.md
- docs/zh-CN/wikg-standard.md
- packages/core/src/retrieval/search-index/search/query.ts
- docs/schema-upgrade.md
- packages/cli/src/runtime/config.test.ts
- packages/core/src/retrieval/search-index/search/build.ts
8eda84c to
a4bb1c8
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/core/src/retrieval/search-index/search/build.ts (1)
246-308: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsolidate the two names for the same completion offset.
writePendingDenseRecordsaccepts bothinput.denseDone(Line 251, used fromwriteSearchIndexBatch) andinput.doneOffset(Line 251, used fromwriteSearchIndexDenseSegments) to represent the same "already-written count" value, resolved withinput.doneOffset ?? input.denseDone ?? 0. Both names carry the identical meaning at different call sites. Use one property name for both callers to remove the ambiguity and reduce the risk that a future caller sets the wrong one or sets both with different values.♻️ Proposed consolidation
async function writePendingDenseRecords( database: Database, denseRecords: TextSentenceEmbeddingInput[], input: { readonly denseDimensions?: number; - readonly denseDone?: number; - readonly doneOffset?: number; + readonly doneOffset: number; readonly embeddingProvider?: SearchIndexEmbeddingProvider; readonly force: boolean; readonly progress?: SearchIndexProgressReporter; }, ): Promise<{ readonly denseDimensions?: number; readonly denseDone: number; }> { - const doneOffset = input.doneOffset ?? input.denseDone ?? 0; + const doneOffset = input.doneOffset;Then update both call sites (
writeSearchIndexBatchandwriteSearchIndexDenseSegments) to always passdoneOffset.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/core/src/retrieval/search-index/search/build.ts` around lines 246 - 308, Consolidate the completion-offset input in writePendingDenseRecords by removing denseDone and retaining only doneOffset, using it directly with a zero default. Update both writeSearchIndexBatch and writeSearchIndexDenseSegments to pass their existing completion count through doneOffset, and remove the fallback handling for input.denseDone.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/core/src/retrieval/search-index/search/build.ts`:
- Around line 246-308: Consolidate the completion-offset input in
writePendingDenseRecords by removing denseDone and retaining only doneOffset,
using it directly with a zero default. Update both writeSearchIndexBatch and
writeSearchIndexDenseSegments to pass their existing completion count through
doneOffset, and remove the fallback handling for input.denseDone.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d270b345-f773-45cb-9a27-50668cc2d2d0
📒 Files selected for processing (20)
docs/en/wikg-standard.mddocs/schema-upgrade.mddocs/zh-CN/wikg-standard.mdpackages/cli/src/commands/archive-command/search-index.tspackages/cli/src/runtime/config.test.tspackages/cli/src/runtime/config.tspackages/cli/src/runtime/embedding.tspackages/cli/src/runtime/local-config.tspackages/core/data/help/commands/predicate.jinjapackages/core/data/help/topics/readiness.jinjapackages/core/src/retrieval/query/archive-view/index-state.test.tspackages/core/src/retrieval/search-index/search/build.tspackages/core/src/retrieval/search-index/search/helpers.tspackages/core/src/retrieval/search-index/search/query.tspackages/core/src/retrieval/search-index/search/status.tspackages/core/src/retrieval/search-index/search/types.tspackages/core/src/storage/wikg/archive/write.tspackages/core/src/storage/wikg/wikg-coordinator/flusher.tstest/core/storage/wikg/archive.test.tstest/core/storage/wikg/wiki-graph-archive-file.test.ts
🚧 Files skipped from review as they are similar to previous changes (18)
- packages/core/data/help/topics/readiness.jinja
- packages/core/src/storage/wikg/wikg-coordinator/flusher.ts
- packages/core/data/help/commands/predicate.jinja
- packages/core/src/retrieval/search-index/search/status.ts
- packages/core/src/storage/wikg/archive/write.ts
- packages/cli/src/runtime/config.ts
- docs/en/wikg-standard.md
- packages/cli/src/runtime/local-config.ts
- test/core/storage/wikg/wiki-graph-archive-file.test.ts
- packages/core/src/retrieval/search-index/search/types.ts
- packages/cli/src/runtime/embedding.ts
- packages/cli/src/runtime/config.test.ts
- packages/cli/src/commands/archive-command/search-index.ts
- packages/core/src/retrieval/search-index/search/helpers.ts
- test/core/storage/wikg/archive.test.ts
- docs/zh-CN/wikg-standard.md
- packages/core/src/retrieval/search-index/search/query.ts
- docs/schema-upgrade.md
a4bb1c8 to
5b39749
Compare
5b39749 to
3883ab0
Compare
Summary
Verification
Follow-up to CodeRabbit review on #229.