fix: close task3 qdrant and config quality gaps

This commit is contained in:
2026-08-11 08:06:18 +02:00
parent 88d1790728
commit b7ea5443b3
8 changed files with 290 additions and 47 deletions
+17 -10
View File
@@ -420,16 +420,23 @@ class QdrantVectorStore:
offset = None
seen_offsets = set()
while True:
response = self._call(
"POST",
f"/collections/{self._collection}/points/scroll",
{
"with_payload": True,
"limit": 10000,
"filter": {"must": must},
"offset": offset,
},
)
try:
response = self._call(
"POST",
f"/collections/{self._collection}/points/scroll",
{
"with_payload": True,
"limit": 10000,
"filter": {"must": must},
"offset": offset,
},
)
except VectorTransportError as exc:
if self._collection_lifecycle == "require_existing" and exc.status_code == 404:
raise SemanticIndexIncompatibleError(
"Qdrant collection disappeared during semantic index reconciliation"
) from exc
raise
result = response.get("result", {})
page = result.get("points")
if not isinstance(page, list):
+36
View File
@@ -537,6 +537,41 @@ def _format_validation_error(error: ValidationError) -> str:
return "\n".join(lines)
def _validate_raw_config_shape(raw: dict[str, Any], path: Path) -> None:
"""Reject unsafe YAML shapes before compatibility translation or sorting keys."""
seen: set[int] = set()
def walk(value: Any, location: str) -> None:
if isinstance(value, dict):
marker = id(value)
if marker in seen:
return
seen.add(marker)
for key, item in value.items():
if not isinstance(key, str):
raise ConfigError(
f"Configurazione non valida in {path}: mapping key at {location} "
"must be a string"
)
walk(item, f"{location}.{key}")
elif isinstance(value, list):
for index, item in enumerate(value):
walk(item, f"{location}[{index}]")
walk(raw, "configuration")
resources = raw.get("resources")
if "resources" in raw and not isinstance(resources, dict):
raise ConfigError(
f"Configurazione non valida in {path}: resources must be a mapping"
)
if isinstance(resources, dict):
for name in ("vector", "embeddings"):
if name in resources and not isinstance(resources[name], dict):
raise ConfigError(
f"Configurazione non valida in {path}: resources.{name} must be a mapping"
)
def load_config(path: Path) -> Config:
if not path.exists():
raise ConfigError(f"File di configurazione non trovato: {path}")
@@ -546,6 +581,7 @@ def load_config(path: Path) -> Config:
raise ConfigError(f"Configurazione YAML non valida: {path}") from exc
if not isinstance(raw, dict):
raise ConfigError(f"Configurazione non valida (atteso un mapping YAML): {path}")
_validate_raw_config_shape(raw, path)
expanded = _resolve_secret_files(_resolve_evidence_secret_files(_expand_env(raw)))
_validate_internal_embedding_contract(expanded, path)
_validate_internal_vector_contract(expanded, path)