refactor(evidence): migrate runtime consumption (#29)
This commit is contained in:
@@ -54,18 +54,16 @@ def search_cmd(
|
||||
from rich.table import Table
|
||||
|
||||
from tht.cli.vector_cmd import make_embedder, open_searcher, require_vector_cfg
|
||||
from tht.evidence import active_searcher, validate_corpus_workspace
|
||||
from tht.lshindex import LshIndexError, load_index, query_index
|
||||
from tht.search import combined_search
|
||||
|
||||
cfg = _load_config_or_exit(config)
|
||||
from tht.search.evidence import validate_corpus_workspace
|
||||
|
||||
workspace_id = workspace_id_for_config(cfg, config)
|
||||
validate_corpus_workspace(cfg, workspace_id)
|
||||
dwh_snapshot = _leased_dwh_snapshot(cfg, ctx)
|
||||
require_vector_cfg(cfg)
|
||||
from tht.search.evidence import active_searcher
|
||||
|
||||
runtime_searcher = active_searcher(
|
||||
cfg, open_searcher(cfg),
|
||||
workspace_id=workspace_id,
|
||||
@@ -255,13 +253,17 @@ def pack_cmd(
|
||||
from sqlalchemy.exc import OperationalError
|
||||
|
||||
from tht.cli.vector_cmd import make_embedder, open_searcher, require_vector_cfg
|
||||
from tht.evidence import (
|
||||
active_searcher,
|
||||
build_retrieval_entries,
|
||||
validate_corpus_workspace,
|
||||
)
|
||||
from tht.ports.vector import VectorReadUnavailable, VectorStoreError
|
||||
from tht.search import combined_search, schema_tables
|
||||
from tht.memory import SOLVED_KIND
|
||||
from tht.vectorstore.embeddings import EmbeddingsError
|
||||
|
||||
cfg = _load_config_or_exit(config)
|
||||
from tht.search.evidence import validate_corpus_workspace
|
||||
|
||||
workspace_id = workspace_id_for_config(cfg, config)
|
||||
validate_corpus_workspace(cfg, workspace_id)
|
||||
@@ -277,8 +279,6 @@ def pack_cmd(
|
||||
vec = None
|
||||
searcher = embedder = None
|
||||
try:
|
||||
from tht.search.evidence import active_searcher
|
||||
|
||||
searcher = active_searcher(
|
||||
cfg, open_searcher(cfg),
|
||||
workspace_id=workspace_id,
|
||||
@@ -314,11 +314,7 @@ def pack_cmd(
|
||||
top=PACK_EVIDENCE_TOP, rrf_k=cfg.search.rrf_k,
|
||||
kinds=KIND_MAP["evidence"], query_vec=vec,
|
||||
)
|
||||
evidence = [
|
||||
{"title": r.label, "status": r.status,
|
||||
"excerpt": r.content[:PACK_EXCERPT_CHARS]}
|
||||
for r in ev
|
||||
]
|
||||
evidence = build_retrieval_entries(ev, excerpt_chars=PACK_EXCERPT_CHARS)
|
||||
except degrade as e:
|
||||
warnings.append(f"ricerca evidence fallita ({e})")
|
||||
try:
|
||||
|
||||
@@ -518,7 +518,7 @@ def finalize_cmd(session_id: str = typer.Argument(...), config: Path = CONFIG_OP
|
||||
from tht.execute import ExecutionError
|
||||
from tht.execute.warnings import plan_warnings, runtime_warnings, static_warnings
|
||||
from tht.report import extract_reviewer_notes, render_validation_report
|
||||
from tht.session.artifacts import build_evidence_entries
|
||||
from tht.evidence import project_session
|
||||
from tht.phase import cte_plan as effective_cte_plan
|
||||
from tht.phase import effective_decisions
|
||||
from tht.session.models import SchemaLinking
|
||||
@@ -614,7 +614,7 @@ def finalize_cmd(session_id: str = typer.Argument(...), config: Path = CONFIG_OP
|
||||
linking = SchemaLinking.model_validate(
|
||||
json.loads(snapshot.artifacts["schema_linking"])
|
||||
)
|
||||
entries = build_evidence_entries(decisions, linking, cfg.paths.artifacts / "evidence")
|
||||
entries = project_session(decisions, linking, cfg.paths.artifacts / "evidence")
|
||||
evidence = json.dumps(entries, ensure_ascii=False, indent=2)
|
||||
|
||||
# --- manifest + riepilogo ---
|
||||
|
||||
@@ -55,6 +55,18 @@ def validate_corpus_workspace(cfg, workspace_id: str) -> None:
|
||||
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,
|
||||
@@ -71,15 +83,48 @@ def resolve_citation(
|
||||
)
|
||||
|
||||
|
||||
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."""
|
||||
from tht.session.artifacts import build_evidence_entries
|
||||
|
||||
return build_evidence_entries(decisions, linking, evidence_root)
|
||||
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__ = [
|
||||
@@ -90,6 +135,7 @@ __all__ = [
|
||||
"SourceObject",
|
||||
"acquire",
|
||||
"active_searcher",
|
||||
"build_retrieval_entries",
|
||||
"discover",
|
||||
"project_session",
|
||||
"resolve_citation",
|
||||
|
||||
@@ -1,49 +1,17 @@
|
||||
"""Legacy session-artifact entrypoints retained during the Evidence migration."""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from tht.decisions import DecisionRecord
|
||||
from tht.session.models import SchemaLinking
|
||||
|
||||
|
||||
def _find_evidence_file(evidence_root: Path, evidence_id: str) -> str:
|
||||
# New deployments resolve only immutable materialized files from ACTIVE. Keep
|
||||
# the legacy curated-tree fallback for sessions created before a corpus exists.
|
||||
corpus_root = evidence_root.parent.parent / "corpus"
|
||||
if corpus_root.exists():
|
||||
from tht.corpus.store import CorpusStore
|
||||
from tht.search.evidence import resolve_evidence_file
|
||||
return resolve_evidence_file(
|
||||
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 build_evidence_entries(
|
||||
decisions: list[DecisionRecord],
|
||||
linking: SchemaLinking,
|
||||
evidence_root: Path,
|
||||
) -> list[dict]:
|
||||
"""Elenco {id, file, esito, decision_seq}: evidence citate nello schema linking
|
||||
(esito 'usata') e decisioni esplicite del reviewer (accettata/scartata, che
|
||||
prevalgono sul linking)."""
|
||||
entries: dict[str, dict] = {}
|
||||
for candidate in linking.candidates:
|
||||
for evidence_id in candidate.evidence:
|
||||
entries.setdefault(evidence_id, {
|
||||
"id": evidence_id,
|
||||
"file": _find_evidence_file(evidence_root, evidence_id),
|
||||
"esito": "usata",
|
||||
"decision_seq": candidate.decision_seq,
|
||||
})
|
||||
for d in decisions:
|
||||
if d.type not in ("evidence_accepted", "evidence_rejected"):
|
||||
continue
|
||||
entries[d.subject] = {
|
||||
"id": d.subject,
|
||||
"file": _find_evidence_file(evidence_root, d.subject),
|
||||
"esito": "accettata" if d.type == "evidence_accepted" else "scartata",
|
||||
"decision_seq": d.seq,
|
||||
}
|
||||
return list(entries.values())
|
||||
"""Compatibility shim for callers not yet migrated to ``tht.evidence``."""
|
||||
from tht.evidence import project_session
|
||||
|
||||
return project_session(decisions, linking, evidence_root)
|
||||
|
||||
Reference in New Issue
Block a user