Skip to content
This repository was archived by the owner on Jun 3, 2026. It is now read-only.

Commit 51c4150

Browse files
Search code annotations from code store
1 parent a3f6429 commit 51c4150

2 files changed

Lines changed: 57 additions & 2 deletions

File tree

src/pipelines/retrieval.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
from src.graph.neo4j_client import Neo4jClient
3838
from src.prompts.retrieval import ANSWER_PROMPT, build_system_prompt
3939
from src.schemas.retrieval import RetrievalResult, SourceRecord
40-
from src.schemas.code import snippets_namespace
40+
from src.schemas.code import annotations_namespace, snippets_namespace
4141
from src.storage.pinecone import PineconeVectorStore
4242

4343
load_dotenv()
@@ -120,6 +120,8 @@ def __init__(
120120
model: Optional[BaseChatModel] = None,
121121
vector_store: Optional[PineconeVectorStore] = None,
122122
neo4j_client: Optional[Neo4jClient] = None,
123+
code_vector_store: Optional[PineconeVectorStore] = None,
124+
org_id: str = "default",
123125
) -> None:
124126
# ── LLM ───────────────────────────────────────────────────────
125127
if model is None:
@@ -138,6 +140,15 @@ def __init__(
138140
self.vector_store = PineconeVectorStore()
139141
else:
140142
self.vector_store = vector_store
143+
if code_vector_store is not None:
144+
self.code_vector_store = code_vector_store
145+
elif vector_store is None:
146+
self.code_vector_store = PineconeVectorStore(
147+
namespace=annotations_namespace(org_id),
148+
create_if_not_exists=False,
149+
)
150+
else:
151+
self.code_vector_store = self.vector_store
141152

142153
# ── Graph store (Neo4j) ───────────────────────────────────────
143154
embed_fn = _get_embed_fn()
@@ -578,7 +589,7 @@ async def _search_code(
578589
) -> List[SourceRecord]:
579590
"""Semantic search over stored code annotations."""
580591

581-
results = await self.vector_store.search_by_text(
592+
results = await self.code_vector_store.search_by_text(
582593
query_text=query,
583594
top_k=top_k,
584595
filters={

tests/integration/test_retrieval_pipeline.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,50 @@ async def test_raw_search_returns_ranked_hits_without_tool_selection(
171171
assert not pipeline.model_with_tools.calls
172172

173173

174+
@pytest.mark.asyncio
175+
async def test_raw_code_search_uses_code_annotation_store(vector_store, neo4j_client):
176+
code_vector_store = type(vector_store)()
177+
vector_store.seed(
178+
"default-code-1",
179+
"This stale default-store code record must not be returned.",
180+
{
181+
"user_id": "alice",
182+
"domain": "code",
183+
"target_symbol": "WrongStore",
184+
"target_file": "src/wrong.py",
185+
},
186+
score=0.99,
187+
)
188+
code_vector_store.seed(
189+
"annotation-code-1",
190+
"RetryLoop can spin when the first retrieval attempt times out.",
191+
{
192+
"user_id": "alice",
193+
"domain": "code",
194+
"annotation_type": "bug_report",
195+
"target_symbol": "RetryLoop",
196+
"target_file": "src/retry.py",
197+
"repo": "xmem",
198+
"severity": "high",
199+
},
200+
score=0.8,
201+
)
202+
model = FakeChatModel()
203+
pipeline = RetrievalPipeline(
204+
model=model,
205+
vector_store=vector_store,
206+
code_vector_store=code_vector_store,
207+
neo4j_client=neo4j_client,
208+
)
209+
210+
results = await pipeline.search_raw("retry", "alice", ["code"], top_k=5)
211+
212+
assert [record.metadata["id"] for record in results] == ["annotation-code-1"]
213+
assert "symbol=RetryLoop" in results[0].content
214+
assert "WrongStore" not in results[0].content
215+
assert not pipeline.model_with_tools.calls
216+
217+
174218
@pytest.mark.asyncio
175219
async def test_raw_search_runs_requested_domains_concurrently(
176220
vector_store, neo4j_client

0 commit comments

Comments
 (0)