Files
agent/app/modules/chat/evidence_gate.py

63 lines
2.6 KiB
Python

from __future__ import annotations
from dataclasses import dataclass, field
from app.modules.rag.explain.models import ExplainPack
@dataclass(slots=True)
class EvidenceGateDecision:
passed: bool
answer: str = ""
diagnostics: dict[str, list[str]] = field(default_factory=dict)
class CodeExplainEvidenceGate:
def __init__(self, min_excerpts: int = 2) -> None:
self._min_excerpts = min_excerpts
def evaluate(self, pack: ExplainPack) -> EvidenceGateDecision:
diagnostics = self._diagnostics(pack)
if len(pack.code_excerpts) >= self._min_excerpts:
return EvidenceGateDecision(passed=True, diagnostics=diagnostics)
return EvidenceGateDecision(
passed=False,
answer=self._build_answer(pack, diagnostics),
diagnostics=diagnostics,
)
def _diagnostics(self, pack: ExplainPack) -> dict[str, list[str]]:
return {
"entrypoints": [item.title for item in pack.selected_entrypoints[:3] if item.title],
"symbols": [item.title for item in pack.seed_symbols[:5] if item.title],
"paths": self._paths(pack),
"missing": list(pack.missing),
}
def _paths(self, pack: ExplainPack) -> list[str]:
values: list[str] = []
for item in pack.selected_entrypoints + pack.seed_symbols:
path = item.source or (item.location.path if item.location else "")
if path and path not in values:
values.append(path)
for excerpt in pack.code_excerpts:
if excerpt.path and excerpt.path not in values:
values.append(excerpt.path)
return values[:6]
def _build_answer(self, pack: ExplainPack, diagnostics: dict[str, list[str]]) -> str:
lines = [
"Недостаточно опоры в коде, чтобы дать объяснение без догадок.",
"",
f"Найдено фрагментов кода: {len(pack.code_excerpts)} из {self._min_excerpts} минимально необходимых.",
]
if diagnostics["paths"]:
lines.append(f"Пути: {', '.join(diagnostics['paths'])}")
if diagnostics["entrypoints"]:
lines.append(f"Entrypoints: {', '.join(diagnostics['entrypoints'])}")
if diagnostics["symbols"]:
lines.append(f"Символы: {', '.join(diagnostics['symbols'])}")
if diagnostics["missing"]:
lines.append(f"Диагностика: {', '.join(diagnostics['missing'])}")
return "\n".join(lines).strip()