Spaces:
Sleeping
Sleeping
File size: 2,198 Bytes
6a1cba7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | from __future__ import annotations
import hashlib
import json
from json import JSONDecodeError
from pathlib import Path
from typing import Any
from .advisory_contract import ADVISORY_SCHEMA_VERSION, validate_advisory_output
from .redaction import redact_object, redact_text
def validate_advisory_response_file(result: dict[str, Any], response_path: Path) -> dict[str, Any]:
"""Validate a provider-produced advisory JSON response against the evidence contract."""
raw = response_path.read_bytes()
contract = _response_contract(response_path, raw)
try:
response = json.loads(raw.decode("utf-8-sig"))
except (UnicodeDecodeError, JSONDecodeError) as exc:
return _response_error(result, contract, "response_parse_error", redact_text(str(exc)) or "response_parse_error")
if not isinstance(response, dict):
return _response_error(result, contract, "response_not_object", "Advisory response JSON must be an object.")
advisory = validate_advisory_output(result, redact_object(response))
advisory["response_contract"] = contract
return redact_object(advisory)
def _response_error(
result: dict[str, Any],
contract: dict[str, Any],
error_type: str,
message: str,
) -> dict[str, Any]:
advisory = validate_advisory_output(result, {
"provider": "external_response",
"model": None,
"mode": "response_file_validation",
"reviewer_notes": [],
"inspection_priorities": [],
})
advisory.update({
"schema_version": ADVISORY_SCHEMA_VERSION,
"provider": "external_response",
"model": None,
"mode": "response_file_validation",
"status": "error",
"errors": [error_type],
"response_error": {"type": error_type, "message": message},
"response_contract": contract,
})
return redact_object(advisory)
def _response_contract(path: Path, raw: bytes) -> dict[str, Any]:
return {
"source_file": path.name,
"source_sha256": hashlib.sha256(raw).hexdigest().upper(),
"byte_count": len(raw),
"parser": "json",
"citation_repair_attempted": False,
"network_called": False,
}
|