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

Commit b6265ca

Browse files
Search code annotations from code store
1 parent bd6c1c4 commit b6265ca

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.base import BaseVectorStore
4242
from src.storage.factory import get_vector_store
4343

@@ -121,6 +121,8 @@ def __init__(
121121
model: Optional[BaseChatModel] = None,
122122
vector_store: Optional[BaseVectorStore] = None,
123123
neo4j_client: Optional[Neo4jClient] = None,
124+
code_vector_store: Optional[BaseVectorStore] = None,
125+
org_id: str = "default",
124126
) -> None:
125127
# ── LLM ───────────────────────────────────────────────────────
126128
if model is None:
@@ -139,6 +141,15 @@ def __init__(
139141
self.vector_store = get_vector_store()
140142
else:
141143
self.vector_store = vector_store
144+
if code_vector_store is not None:
145+
self.code_vector_store = code_vector_store
146+
elif vector_store is None:
147+
self.code_vector_store = get_vector_store(
148+
namespace=annotations_namespace(org_id),
149+
create_if_not_exists=False,
150+
)
151+
else:
152+
self.code_vector_store = self.vector_store
142153

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

582-
results = await self.vector_store.search_by_text(
593+
results = await self.code_vector_store.search_by_text(
583594
query_text=query,
584595
top_k=top_k,
585596
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)