Initial curated RAGcore source from c16667f0c9397e2bfc8dd0255b114fba23c8d05e

This commit is contained in:
Public Source Publisher committed 2026-10-01 01:34:21 +02:00
commit 7ca726caf2
659 files changed
+98171

No files matched your search

@@ -0,0 +1,445 @@
from __future__ import annotations
import asyncio
from types import SimpleNamespace
from uuid import uuid4
import pytest
from qdrant_client.http import models
from ragcore.application.retrieval import CandidateSearchRequest, CandidateSearchService
from ragcore.application.retrieval.authorization import AuthorizedRetrievalScope
from ragcore.infrastructure.qdrant.filters import compile_retrieval_filter
from ragcore.infrastructure.qdrant.models import CollectionKind, CollectionProfile
from ragcore.retrieval.search import (
BackendSearchRequest,
Candidate,
CandidateBackendError,
CandidateBackendKind,
CandidateBackendState,
CandidateProvenance,
DenseQuery,
EvaluationRetrievalTarget,
QdrantCandidateBackend,
)
from ragcore.retrieval.sparse import SparseEncoder
WORKSPACE_ID = uuid4()
SPACE_ID = uuid4()
PROFILE = CollectionProfile(
kind=CollectionKind.DENSE,
profile="hybrid",
version="v1",
dimensions=2,
model_digest="0" * 64,
)
def candidate(
backend: CandidateBackendKind,
rank: int = 1,
*,
workspace_id: object = WORKSPACE_ID,
space_id: object = SPACE_ID,
) -> Candidate:
return Candidate(
point_id=uuid4(),
score=1.0 / rank,
rank=rank,
backend=backend,
provenance=CandidateProvenance(
workspace_id=workspace_id,
space_id=space_id,
document_id=uuid4(),
document_version_id=uuid4(),
chunk_id=uuid4(),
source_id=uuid4(),
parent_chunk_id=None,
status="published",
content_type="text/plain",
language="en",
trust_level="source",
),
)
class RecordingBackend:
def __init__(self, result: tuple[Candidate, ...] = ()) -> None:
self.result = result
self.requests: list[BackendSearchRequest] = []
async def search(self, request: BackendSearchRequest) -> tuple[Candidate, ...]:
self.requests.append(request)
return self.result
class FailingBackend:
async def search(self, request: BackendSearchRequest) -> tuple[Candidate, ...]:
raise CandidateBackendError("backend_unavailable")
class SlowBackend:
async def search(self, request: BackendSearchRequest) -> tuple[Candidate, ...]:
await asyncio.sleep(1)
return ()
def request(*, timeout_seconds: float = 1.0, dense_limit: int = 50) -> CandidateSearchRequest:
return CandidateSearchRequest(
profile=PROFILE,
dense_query=DenseQuery((0.1, 0.2)),
sparse_query=SparseEncoder().encode_query("HTTP_500"),
filter_plan=compile_retrieval_filter(
AuthorizedRetrievalScope(WORKSPACE_ID, frozenset({SPACE_ID}))
),
dense_limit=dense_limit,
timeout_seconds=timeout_seconds,
)
@pytest.mark.asyncio
async def test_dense_and_sparse_run_in_parallel_and_preserve_provenance() -> None:
dense = RecordingBackend((candidate(CandidateBackendKind.DENSE),))
sparse = RecordingBackend((candidate(CandidateBackendKind.SPARSE),))
result = await CandidateSearchService(dense, sparse).search(request())
assert result.degraded is False
assert result.dense.candidates[0].provenance.document_id.int != 0
assert result.sparse.candidates[0].provenance.source_id.int != 0
assert dense.requests[0].limit == 50
assert sparse.requests[0].backend is CandidateBackendKind.SPARSE
@pytest.mark.asyncio
async def test_partial_backend_failure_is_explicit_degraded_metadata() -> None:
dense = RecordingBackend((candidate(CandidateBackendKind.DENSE),))
result = await CandidateSearchService(dense, FailingBackend()).search(request())
assert result.degraded is True
assert result.dense.timing.state is CandidateBackendState.AVAILABLE
assert result.sparse.timing.state is CandidateBackendState.DEGRADED
assert result.sparse.timing.error_code == "backend_unavailable"
@pytest.mark.asyncio
async def test_out_of_scope_backend_result_is_explicitly_degraded() -> None:
result = await CandidateSearchService(
RecordingBackend((candidate(CandidateBackendKind.DENSE, space_id=uuid4()),)),
RecordingBackend(),
).search(request())
assert result.dense.timing.state is CandidateBackendState.DEGRADED
assert result.dense.timing.error_code == "candidate_contract_violation"
@pytest.mark.asyncio
async def test_backend_timeout_is_explicit_and_bounded() -> None:
result = await CandidateSearchService(SlowBackend(), RecordingBackend()).search(
request(timeout_seconds=0.05)
)
assert result.degraded is True
assert result.dense.timing.state is CandidateBackendState.TIMEOUT
assert result.dense.timing.error_code == "backend_timeout"
def test_candidate_limits_are_enforced_before_backend_execution() -> None:
with pytest.raises(ValueError):
request(dense_limit=51)
@pytest.mark.asyncio
async def test_qdrant_backend_decodes_provenance_and_uses_named_active_alias() -> None:
point_id = uuid4()
workspace_id = uuid4()
space_id = uuid4()
provenance = {
"workspace_id": str(workspace_id),
"space_id": str(space_id),
"document_id": str(uuid4()),
"document_version_id": str(uuid4()),
"chunk_id": str(uuid4()),
"source_id": str(uuid4()),
"parent_chunk_id": None,
"status": "published",
"content_type": "text/plain",
"language": "en",
"trust_level": "source",
"embedding_model_digest": PROFILE.model_digest,
"chunk_profile_version": PROFILE.version,
}
class StaticQdrantClient:
def __init__(self) -> None:
self.calls: list[dict[str, object]] = []
async def get_aliases(self, **kwargs: object) -> SimpleNamespace:
return SimpleNamespace(
aliases=[
SimpleNamespace(
alias_name=PROFILE.alias_name,
collection_name=PROFILE.collection_name,
)
]
)
async def get_collection(self, collection_name: str, **kwargs: object) -> SimpleNamespace:
assert collection_name == PROFILE.collection_name
return SimpleNamespace(
config=SimpleNamespace(
params=SimpleNamespace(
vectors={
"dense": models.VectorParams(
size=PROFILE.dimensions,
distance=models.Distance.COSINE,
)
},
sparse_vectors={"sparse": models.SparseVectorParams()},
)
)
)
async def query_points(self, **kwargs: object) -> models.QueryResponse:
self.calls.append(kwargs)
return models.QueryResponse(
points=[
models.ScoredPoint(id=str(point_id), version=0, score=0.9, payload=provenance)
]
)
client = StaticQdrantClient()
backend = QdrantCandidateBackend(client, CandidateBackendKind.DENSE)
plan = compile_retrieval_filter(AuthorizedRetrievalScope(workspace_id, frozenset({space_id})))
results = await backend.search(
BackendSearchRequest(
backend=CandidateBackendKind.DENSE,
profile=PROFILE,
query=DenseQuery((0.1, 0.2)),
filter_plan=plan,
limit=1,
)
)
assert results[0].point_id == point_id
assert str(results[0].provenance.document_id) == provenance["document_id"]
assert client.calls[0]["collection_name"] == PROFILE.collection_name
assert client.calls[0]["using"] == "dense"
@pytest.mark.asyncio
async def test_internal_shadow_target_reads_named_collection_without_alias_cutover() -> None:
shadow_space = uuid4()
shadow_profile = CollectionProfile(
kind=CollectionKind.DENSE,
profile="modelforge-rag",
version="m6",
dimensions=2,
model_digest="a" * 64,
embedding_space_id=shadow_space,
)
workspace_id, space_id, point_id = uuid4(), uuid4(), uuid4()
class ShadowClient:
async def get_aliases(self) -> SimpleNamespace:
return SimpleNamespace(aliases=[])
async def get_collection(self, collection_name: str) -> SimpleNamespace:
assert collection_name == shadow_profile.collection_name
return SimpleNamespace(
config=SimpleNamespace(
params=SimpleNamespace(
vectors={
"dense": models.VectorParams(size=2, distance=models.Distance.COSINE)
},
sparse_vectors={"sparse": models.SparseVectorParams()},
)
)
)
async def query_points(self, **kwargs: object) -> models.QueryResponse:
return models.QueryResponse(
points=[
models.ScoredPoint(
id=str(point_id),
version=0,
score=0.9,
payload={
"workspace_id": str(workspace_id),
"space_id": str(space_id),
"document_id": str(uuid4()),
"document_version_id": str(uuid4()),
"chunk_id": str(point_id),
"source_id": str(uuid4()),
"parent_chunk_id": None,
"status": "published",
"content_type": "text/plain",
"language": "en",
"trust_level": "source",
"embedding_model_digest": shadow_profile.model_digest,
"chunk_profile_version": shadow_profile.version,
"embedding_space_id": str(shadow_space),
},
)
]
)
backend = QdrantCandidateBackend(
ShadowClient(),
CandidateBackendKind.DENSE,
target=EvaluationRetrievalTarget.SHADOW,
)
results = await backend.search(
BackendSearchRequest(
backend=CandidateBackendKind.DENSE,
profile=shadow_profile,
query=DenseQuery((1.0, 0.0)),
filter_plan=compile_retrieval_filter(
AuthorizedRetrievalScope(workspace_id, frozenset({space_id}))
),
limit=1,
)
)
assert results[0].point_id == point_id
@pytest.mark.asyncio
async def test_current_target_reads_the_explicit_pinned_collection_and_alias() -> None:
pinned_collection = "rag_dense_current_pinned_20260912"
point_id = uuid4()
workspace_id, space_id = uuid4(), uuid4()
class PinnedClient:
def __init__(self) -> None:
self.collection_names: list[str] = []
async def get_aliases(self) -> SimpleNamespace:
return SimpleNamespace(
aliases=[
SimpleNamespace(
alias_name=PROFILE.alias_name,
collection_name=pinned_collection,
)
]
)
async def get_collection(self, collection_name: str) -> SimpleNamespace:
self.collection_names.append(collection_name)
assert collection_name == pinned_collection
return SimpleNamespace(
config=SimpleNamespace(
params=SimpleNamespace(
vectors={
"dense": models.VectorParams(
size=PROFILE.dimensions, distance=models.Distance.COSINE
)
},
sparse_vectors={"sparse": models.SparseVectorParams()},
)
)
)
async def query_points(self, **kwargs: object) -> models.QueryResponse:
assert kwargs["collection_name"] == pinned_collection
return models.QueryResponse(
points=[
models.ScoredPoint(
id=str(point_id),
version=0,
score=0.9,
payload={
"workspace_id": str(workspace_id),
"space_id": str(space_id),
"document_id": str(uuid4()),
"document_version_id": str(uuid4()),
"chunk_id": str(point_id),
"source_id": str(uuid4()),
"parent_chunk_id": None,
"status": "published",
"content_type": "text/plain",
"language": "en",
"trust_level": "source",
"embedding_model_digest": PROFILE.model_digest,
"chunk_profile_version": PROFILE.version,
},
)
]
)
client = PinnedClient()
backend = QdrantCandidateBackend(
client, CandidateBackendKind.DENSE, collection_name=pinned_collection
)
result = await backend.search(
BackendSearchRequest(
backend=CandidateBackendKind.DENSE,
profile=PROFILE,
query=DenseQuery((0.1, 0.2)),
filter_plan=compile_retrieval_filter(
AuthorizedRetrievalScope(workspace_id, frozenset({space_id}))
),
limit=1,
)
)
assert result[0].point_id == point_id
assert client.collection_names == [pinned_collection]
def test_qdrant_backend_rejects_unsafe_pinned_collection_name() -> None:
with pytest.raises(ValueError, match="safe Qdrant collection"):
QdrantCandidateBackend(
object(), CandidateBackendKind.DENSE, collection_name="../production"
)
@pytest.mark.asyncio
async def test_dense_and_sparse_tasks_start_before_either_completes() -> None:
started = [0]
both_started = asyncio.Event()
class GatedBackend:
async def search(self, request: BackendSearchRequest) -> tuple[Candidate, ...]:
started[0] += 1
if started[0] == 2:
both_started.set()
await both_started.wait()
return ()
result = await CandidateSearchService(GatedBackend(), GatedBackend()).search(
request(timeout_seconds=0.5)
)
assert started[0] == 2
assert result.degraded is False
@pytest.mark.asyncio
async def test_cancellation_is_propagated_to_both_backends() -> None:
started = asyncio.Event()
cancelled = [0]
blocked = asyncio.Event()
class CancellableBackend:
async def search(self, request: BackendSearchRequest) -> tuple[Candidate, ...]:
started.set()
try:
await blocked.wait()
except asyncio.CancelledError:
cancelled[0] += 1
raise
return ()
task = asyncio.create_task(
CandidateSearchService(CancellableBackend(), CancellableBackend()).search(request())
)
await started.wait()
task.cancel()
with pytest.raises(asyncio.CancelledError):
await task
assert cancelled[0] == 2