Skip to content

Commit 9ddaa58

Browse files
committed
Fix: Track indexing completion state throughout scan lifecycle
- Add markIndexingIncomplete() to set state at start of indexing - Call markIndexingIncomplete() at start of both full and incremental scans - Call markIndexingComplete() after successful full AND incremental scans - Update hasIndexedData() with backward compatibility fallback for old indexes Indexing lifecycle now properly tracked: - incomplete → complete on successful scan - incomplete state persists if scan interrupted - Old indexes without marker fall back to points_count > 0 check Fixes: - Incremental scans now properly mark completion (was missing before) - Interrupted scans correctly identified as incomplete - Backward compatibility ensures existing indexes work without rebuild
1 parent 54d9abb commit 9ddaa58

File tree

3 files changed

+59
-5
lines changed

3 files changed

+59
-5
lines changed

src/services/code-index/interfaces/vector-store.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,15 @@ export interface IVectorStore {
7171

7272
/**
7373
* Marks the indexing process as complete by storing metadata
74-
* Should be called after a successful full workspace scan
74+
* Should be called after a successful full workspace scan or incremental scan
7575
*/
7676
markIndexingComplete(): Promise<void>
77+
78+
/**
79+
* Marks the indexing process as incomplete by storing metadata
80+
* Should be called at the start of indexing to indicate work in progress
81+
*/
82+
markIndexingIncomplete(): Promise<void>
7783
}
7884

7985
export interface VectorStoreSearchResult {

src/services/code-index/orchestrator.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ export class CodeIndexOrchestrator {
149149
)
150150
this.stateManager.setSystemState("Indexing", "Checking for new or modified files...")
151151

152+
// Mark as incomplete at the start of incremental scan
153+
await this.vectorStore.markIndexingIncomplete()
154+
152155
let cumulativeBlocksIndexed = 0
153156
let cumulativeBlocksFoundSoFar = 0
154157
let batchErrors: Error[] = []
@@ -192,11 +195,17 @@ export class CodeIndexOrchestrator {
192195

193196
await this._startWatcher()
194197

198+
// Mark indexing as complete after successful incremental scan
199+
await this.vectorStore.markIndexingComplete()
200+
195201
this.stateManager.setSystemState("Indexed", t("embeddings:orchestrator.fileWatcherStarted"))
196202
} else {
197203
// No existing data or collection was just created - do a full scan
198204
this.stateManager.setSystemState("Indexing", "Services ready. Starting workspace scan...")
199205

206+
// Mark as incomplete at the start of full scan
207+
await this.vectorStore.markIndexingIncomplete()
208+
200209
let cumulativeBlocksIndexed = 0
201210
let cumulativeBlocksFoundSoFar = 0
202211
let batchErrors: Error[] = []

src/services/code-index/vector-store/qdrant-client.ts

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -567,15 +567,23 @@ export class QdrantVectorStore implements IVectorStore {
567567
}
568568

569569
// Check if the indexing completion marker exists
570-
// This ensures we don't return true for partially indexed collections
571570
// Use a deterministic UUID generated from a constant string
572571
const metadataId = uuidv5("__indexing_metadata__", QDRANT_CODE_BLOCK_NAMESPACE)
573572
const metadataPoints = await this.client.retrieve(this.collectionName, {
574573
ids: [metadataId],
575574
})
576575

577-
// Return true only if the completion marker exists and is marked as complete
578-
return metadataPoints.length > 0 && metadataPoints[0].payload?.indexing_complete === true
576+
// If marker exists, use it to determine completion status
577+
if (metadataPoints.length > 0) {
578+
return metadataPoints[0].payload?.indexing_complete === true
579+
}
580+
581+
// Backward compatibility: No marker exists (old index or pre-marker version)
582+
// Fall back to old logic - assume complete if collection has points
583+
console.log(
584+
"[QdrantVectorStore] No indexing metadata marker found. Using backward compatibility mode (checking points_count > 0).",
585+
)
586+
return pointsCount > 0
579587
} catch (error) {
580588
console.warn("[QdrantVectorStore] Failed to check if collection has data:", error)
581589
return false
@@ -584,7 +592,7 @@ export class QdrantVectorStore implements IVectorStore {
584592

585593
/**
586594
* Marks the indexing process as complete by storing metadata
587-
* Should be called after a successful full workspace scan
595+
* Should be called after a successful full workspace scan or incremental scan
588596
*/
589597
async markIndexingComplete(): Promise<void> {
590598
try {
@@ -612,4 +620,35 @@ export class QdrantVectorStore implements IVectorStore {
612620
throw error
613621
}
614622
}
623+
624+
/**
625+
* Marks the indexing process as incomplete by storing metadata
626+
* Should be called at the start of indexing to indicate work in progress
627+
*/
628+
async markIndexingIncomplete(): Promise<void> {
629+
try {
630+
// Create a metadata point with a deterministic UUID to mark indexing as incomplete
631+
// Use uuidv5 to generate a consistent UUID from a constant string
632+
const metadataId = uuidv5("__indexing_metadata__", QDRANT_CODE_BLOCK_NAMESPACE)
633+
634+
await this.client.upsert(this.collectionName, {
635+
points: [
636+
{
637+
id: metadataId,
638+
vector: new Array(this.vectorSize).fill(0),
639+
payload: {
640+
type: "metadata",
641+
indexing_complete: false,
642+
started_at: Date.now(),
643+
},
644+
},
645+
],
646+
wait: true,
647+
})
648+
console.log("[QdrantVectorStore] Marked indexing as incomplete (in progress)")
649+
} catch (error) {
650+
console.error("[QdrantVectorStore] Failed to mark indexing as incomplete:", error)
651+
throw error
652+
}
653+
}
615654
}

0 commit comments

Comments
 (0)