refactor(evidence): unify formulas with typed evidence

This commit is contained in:
2026-08-25 01:23:04 +02:00
parent d5d65f3659
commit cc30148b69
11 changed files with 342 additions and 38 deletions
+62 -23
View File
@@ -11,7 +11,7 @@ KIND_MAP = {
"evidence": ["evidence"],
"schema": ["schema_table", "schema_column"],
"values": [], # solo LSH
"formula": [], # solo formula store (D14b), niente LSH/vector
"formula": ["evidence"],
}
_STAGE_PURPOSES = {
@@ -30,6 +30,20 @@ DEFAULT_TOP_FALLBACK = 10
search_app = typer.Typer(help="Ricerca semantica (evidence/schema/values) nel vectorstore")
def search_formula_evidence(keyword: str, *, searcher, embedder, top: int):
"""Search only published Formula Evidence through the shared typed facade."""
from tht.evidence import EvidenceSearchContext, search_evidence
return search_evidence(
keyword,
"sql_generation",
EvidenceSearchContext(required_kinds=("formula",)),
searcher=searcher,
embedder=embedder,
top_n=top,
)
def _leased_dwh_snapshot(cfg, context: typer.Context):
from tht.jobs.dwh_pipeline import lease_dwh_snapshot
@@ -143,12 +157,6 @@ def search_cmd(
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)
runtime_searcher = active_searcher(
cfg, open_searcher(cfg),
workspace_id=workspace_id,
)
if kind is not None and kind not in KIND_MAP:
typer.secho(
f"ERRORE: --kind sconosciuto: {kind} (validi: {', '.join(KIND_MAP)})",
@@ -160,29 +168,60 @@ def search_cmd(
top = cfg.search.top_schema_tables if kind == "schema" else DEFAULT_TOP_FALLBACK
if kind == "formula":
# D14b: recupero formule di concetto dallo store locale (niente LSH/vector).
from tht.cli.evidence_cmd import evidence_root
from tht.evidence.formula_store import search_formulas
formulas = search_formulas(evidence_root(cfg), keyword)[:top]
require_vector_cfg(cfg)
outcome = search_formula_evidence(
keyword,
searcher=active_searcher(cfg, open_searcher(cfg), workspace_id=workspace_id),
embedder=make_embedder(cfg.embeddings),
top=top,
)
if outcome.status == "unavailable":
payload = {"status": outcome.status, "code": outcome.code, "message": outcome.message}
if json_out:
typer.echo(json.dumps(payload, ensure_ascii=False))
else:
typer.secho(f"ERRORE: {outcome.message}", fg=typer.colors.RED, err=True)
raise typer.Exit(1)
if json_out:
typer.echo(json.dumps(
[f.model_dump(mode="json") for f in formulas], ensure_ascii=False, indent=2))
typer.echo(json.dumps([
{
"evidence_id": result.evidence_id,
"title": result.title,
"kind": result.kind,
"excerpts": list(result.excerpts),
"provenance": result.provenance,
"citation": result.citation,
"document_id": result.document_id,
}
for result in outcome.results
], ensure_ascii=False, indent=2))
return
if not formulas:
typer.secho(
"ATTENZIONE: lo store formule legacy non viene più consultato; "
"sono disponibili solo Formula Evidence pubblicate.",
fg=typer.colors.YELLOW,
err=True,
)
if not outcome.results:
typer.secho(f"Nessuna formula per '{keyword}'.", fg=typer.colors.YELLOW)
return
table = Table(title=f"Formule per '{keyword}'")
table.add_column("Concetto")
table.add_column("Status")
table.add_column("Colonne")
table.add_column("SQL")
for f in formulas:
sql_preview = (f.sql[:80] + "…") if len(f.sql) > 80 else f.sql
table.add_row(f.concept, f.status, ", ".join(f.columns), sql_preview)
table = Table(title=f"Formula Evidence per '{keyword}'")
table.add_column("Formula")
table.add_column("Provenienza")
table.add_column("Estratto")
for result in outcome.results:
excerpt = result.excerpts[0] if result.excerpts else ""
table.add_row(result.title, result.citation, excerpt[:120])
Console().print(table)
return
dwh_snapshot = _leased_dwh_snapshot(cfg, ctx)
require_vector_cfg(cfg)
runtime_searcher = active_searcher(
cfg, open_searcher(cfg),
workspace_id=workspace_id,
)
lsh_hits = None
try:
lsh, minhashes, meta = load_index(