Files
ThothII/harness/tht/evidence/__init__.py
T

144 lines
4.5 KiB
Python

"""Cohesive public entrypoint for Evidence domain capabilities.
The implementation is introduced beside the legacy module layout so production callers can
migrate one path at a time. These functions deliberately preserve the existing objects, ordering,
and exceptions; they do not define a cross-domain service protocol.
"""
from __future__ import annotations
from collections.abc import Iterable
from pathlib import Path
from typing import TYPE_CHECKING
from tht.ports.evidence import (
AcquiredDocument,
EvidenceSource,
EvidenceSourceError,
EvidenceSourceErrorCategory,
SourceObject,
)
if TYPE_CHECKING:
from tht.corpus.store import CorpusStore
from tht.decisions import DecisionRecord
from tht.search.evidence import ActiveEvidenceSearcher
from tht.session.models import SchemaLinking
def discover(source: EvidenceSource) -> Iterable[SourceObject]:
"""Discover source objects without changing source-defined laziness or ordering."""
return source.discover()
def acquire(source: EvidenceSource, item: SourceObject) -> AcquiredDocument:
"""Acquire one discovered object, preserving the source's classified failures."""
return source.acquire(item)
def active_searcher(
cfg,
delegate,
*,
workspace_id: str | None = None,
) -> ActiveEvidenceSearcher:
"""Bind vector search to the atomically ACTIVE Evidence corpus generation."""
from tht.search.evidence import active_searcher as legacy_active_searcher
return legacy_active_searcher(cfg, delegate, workspace_id=workspace_id)
def validate_corpus_workspace(cfg, workspace_id: str) -> None:
"""Validate persisted Evidence corpus ownership before runtime retrieval setup."""
from tht.search.evidence import validate_corpus_workspace as legacy_validate
legacy_validate(cfg, workspace_id)
def build_retrieval_entries(results, *, excerpt_chars: int) -> list[dict]:
"""Project ordered Evidence search hits into the existing retrieval-pack shape."""
return [
{
"title": result.label,
"status": result.status,
"excerpt": result.content[:excerpt_chars],
}
for result in results
]
def resolve_citation(
store: "CorpusStore",
evidence_id: str,
*,
materialized_root: Path | None = None,
) -> str:
"""Resolve an Evidence identifier to its immutable ACTIVE materialization."""
from tht.search.evidence import resolve_evidence_file
return resolve_evidence_file(
store,
evidence_id,
materialized_root=materialized_root,
)
def _resolve_session_citation(evidence_root: Path, evidence_id: str) -> str:
# New deployments resolve only immutable materialized files from ACTIVE. Keep the
# curated-tree fallback for sessions created before a canonical corpus exists.
corpus_root = evidence_root.parent.parent / "corpus"
if corpus_root.exists():
from tht.corpus.store import CorpusStore
return resolve_citation(
CorpusStore(corpus_root),
evidence_id,
materialized_root=evidence_root.parent / ".materialized-evidence",
)
for match in evidence_root.rglob(f"{evidence_id}.md"):
return str(match)
return ""
def project_session(
decisions: list["DecisionRecord"],
linking: "SchemaLinking",
evidence_root: Path,
) -> list[dict]:
"""Project cited and reviewed Evidence into the existing session artifact shape."""
entries: dict[str, dict] = {}
for candidate in linking.candidates:
for evidence_id in candidate.evidence:
entries.setdefault(evidence_id, {
"id": evidence_id,
"file": _resolve_session_citation(evidence_root, evidence_id),
"esito": "usata",
"decision_seq": candidate.decision_seq,
})
for decision in decisions:
if decision.type not in ("evidence_accepted", "evidence_rejected"):
continue
entries[decision.subject] = {
"id": decision.subject,
"file": _resolve_session_citation(evidence_root, decision.subject),
"esito": "accettata" if decision.type == "evidence_accepted" else "scartata",
"decision_seq": decision.seq,
}
return list(entries.values())
__all__ = [
"AcquiredDocument",
"EvidenceSource",
"EvidenceSourceError",
"EvidenceSourceErrorCategory",
"SourceObject",
"acquire",
"active_searcher",
"build_retrieval_entries",
"discover",
"project_session",
"resolve_citation",
"validate_corpus_workspace",
]