fix: update stale issue/PR state in similar threads#61
fix: update stale issue/PR state in similar threads#61Kavirubc merged 1 commit intosimiligh:mainfrom
Conversation
Issues and PRs indexed in Qdrant retained their original state forever. When a similar thread was later closed, it still appeared as 'Open' in bot comments because the vector DB payload was never updated. Root causes: 1. Bulk indexer (index command) did not store 'state' or 'title' in payload 2. No mechanism to update state on close/reopen events without re-embedding 3. Similarity search defaulted missing state to 'open' Changes: - Add SetPayload method to Qdrant client (update payload without re-upload) - Add VectorStore.SetPayload to the interface - Indexer: detect close/reopen events and patch state via SetPayload - Bulk indexer: include 'state' and 'title' fields in chunked payloads - Similarity search: default missing state to 'unknown' instead of 'open' - Response builder: render 'unknown' state as '—' in the status column - LLM prompts: pass through actual state instead of assuming 'open' Fixes #59 Signed-off-by: Mahsum Aktas <mahsum@mahsumaktas.com>
📝 WalkthroughWalkthroughThe PR fixes a bug where closed issues and PRs incorrectly display as "Open" in similarity suggestions. It adds state and title fields to chunk payloads, implements a SetPayload method for updating Qdrant points without re-embedding, detects state-change-only events to optimize indexing, and updates status derivation logic across multiple components. Changes
Sequence DiagramsequenceDiagram
participant Event as Webhook Event
participant Indexer as Indexer.Run()
participant StateDetect as isStateChangeOnly()
participant UpdatePath as updateState()
participant EmbedPath as Embedding Pipeline
participant Qdrant as Qdrant
Event->>Indexer: Issue state changed
Indexer->>StateDetect: Check if state-change-only
alt State Change Only
StateDetect-->>Indexer: true
Indexer->>UpdatePath: updateState(collectionName)
UpdatePath->>Qdrant: SetPayload(state field only)
Qdrant-->>UpdatePath: ✓ Updated
UpdatePath-->>Indexer: Marked as indexed
else Full Reindex Required
StateDetect-->>Indexer: false
Indexer->>EmbedPath: Fetch comments & build content
EmbedPath->>EmbedPath: Generate embedding
EmbedPath->>Qdrant: Upsert point with state & title
Qdrant-->>EmbedPath: ✓ Upserted
EmbedPath-->>Indexer: Marked as indexed
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@internal/steps/indexer.go`:
- Around line 73-76: When isStateChangeOnly(ctx) is true, s.updateState(ctx,
collectionName) may fail if the point is missing — catch the error from
s.updateState and, instead of returning immediately, attempt the full indexing
path used for non-state changes (i.e., invoke the same full-index handler/code
that runs when isStateChangeOnly is false); if the fallback full-indexing
succeeds, proceed normally, otherwise return the error from the full-index
attempt. Ensure you log or surface both the original updateState error and the
fallback result for debugging and keep existing context (ctx, collectionName)
when calling the fallback.
| // For close/reopen events, only update the state payload — no need to re-embed. | ||
| if isStateChangeOnly(ctx) { | ||
| return s.updateState(ctx, collectionName) | ||
| } |
There was a problem hiding this comment.
Fallback needed if state-only update fails.
If the point doesn’t exist (e.g., issue never indexed or index was reset), updateState will return an error and the event won’t be indexed at all. Consider falling back to full indexing on failure to keep state fresh and avoid pipeline errors.
🛠️ Suggested fallback to full indexing
- if isStateChangeOnly(ctx) {
- return s.updateState(ctx, collectionName)
- }
+ if isStateChangeOnly(ctx) {
+ if err := s.updateState(ctx, collectionName); err == nil {
+ return nil
+ } else {
+ log.Printf("[indexer] State-only update failed; falling back to full index: %v", err)
+ }
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // For close/reopen events, only update the state payload — no need to re-embed. | |
| if isStateChangeOnly(ctx) { | |
| return s.updateState(ctx, collectionName) | |
| } | |
| // For close/reopen events, only update the state payload — no need to re-embed. | |
| if isStateChangeOnly(ctx) { | |
| if err := s.updateState(ctx, collectionName); err == nil { | |
| return nil | |
| } else { | |
| log.Printf("[indexer] State-only update failed; falling back to full index: %v", err) | |
| } | |
| } |
🤖 Prompt for AI Agents
In `@internal/steps/indexer.go` around lines 73 - 76, When isStateChangeOnly(ctx)
is true, s.updateState(ctx, collectionName) may fail if the point is missing —
catch the error from s.updateState and, instead of returning immediately,
attempt the full indexing path used for non-state changes (i.e., invoke the same
full-index handler/code that runs when isStateChangeOnly is false); if the
fallback full-indexing succeeds, proceed normally, otherwise return the error
from the full-index attempt. Ensure you log or surface both the original
updateState error and the fallback result for debugging and keep existing
context (ctx, collectionName) when calling the fallback.
Simili Triage ReportNote Quality Score: 9.5/10 (Excellent) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.2/10 (Excellent) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.0/10 (Excellent) Classification
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.5/10 (Excellent) Classification
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.0/10 (Excellent) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.2/10 (Excellent) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.2/10 (Excellent) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.5/10 (Excellent) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.9/10 (Excellent) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.2/10 (Excellent) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.5/10 (Excellent) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.5/10 (Excellent) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.5/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.5/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.5/10 (Excellent) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.5/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.5/10 (Excellent) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.5/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.5/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.8/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 8.5/10 (Good) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.0/10 (Excellent) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Simili Triage ReportNote Quality Score: 9.0/10 (Excellent) Classification
Quality Improvements
Similar Threads
Generated by Simili Bot |
Summary
Fixes #59 — Closed issues and PRs were incorrectly shown as "Open" in Simili bot comments.
Root Cause
When issues/PRs are indexed into Qdrant, their
stateis stored at index time. When the issue is later closed or reopened, the stored state is never updated because:simili index) did not storestateortitlein payload at all"open", masking the problemChanges
qdrant/types.goSetPayloadtoVectorStoreinterfaceqdrant/client.goSetPayload— updates payload fields without re-uploading vectorssteps/indexer.goclosed/reopenedevents → patch state viaSetPayload(no re-embed)commands/index.gostateandtitlein bulk indexer payloadssteps/similarity.go"unknown"instead of"open"steps/response_builder.go—in status columngemini/prompts.goHow It Works
Testing
go build ./...✅go vet ./...✅go test ./...✅ (all 8 packages pass)Backward Compatibility
statefield will show—instead of incorrectly showingOpensimili index --repo ...will now storestatefor all new/updated pointsSummary by CodeRabbit
New Features
Improvements