feat: wave 5b evidence verification - vision fact-check of cited sheet text

This commit is contained in:
2026-08-10 11:30:28 -05:00
parent 82952df307
commit 3df359500c
4 changed files with 202 additions and 2 deletions
+37 -1
View File
@@ -21,6 +21,9 @@ from backend.agents.linker import LinkerAgent, build_link_scopes, build_object_g
from backend.agents.memory import ProjectMemory
from backend.agents.orchestrator import Orchestrator
from backend.agents.rfi_writer import RFIWriterAgent
from backend.agents.verifier import (
EvidenceVerifierAgent, apply_verdicts, select_findings,
)
from backend.llm import reset_cost
from backend.pipeline.pdf_processor import convert_pdf_to_images
from backend.pipeline.report import build_report, to_markdown
@@ -168,6 +171,38 @@ def run_agent_pipeline(
for result in code_results + construct_results + completeness_results
for artifact in result.artifacts
]
orchestrator.stage("Agent wave 5b: evidence verification")
sheet_to_page = {s.get("sheet_number"): s.get("page_number") for s in sheets}
verify_targets = select_findings(
specialist_findings, clusters,
max_checks=config.AGENT_VERIFY_MAX_CHECKS,
severities=config.AGENT_VERIFY_SEVERITIES,
)
target_indexes = {id(f): i for i, f in enumerate(specialist_findings)}
verify_scopes = [
AgentScope(
scope_id=f"verify:{target_indexes[id(finding)]}",
payload={
"finding_index": target_indexes[id(finding)],
"finding": finding,
"images_b64": [
page_to_b64[sheet_to_page[name]]
for name in (finding.get("sheets") or [])[:config.AGENT_CONFLICT_MAX_IMAGES]
if sheet_to_page.get(name) in page_to_b64
],
},
)
for finding in verify_targets
]
verify_results = orchestrator.run_scopes(
EvidenceVerifierAgent(usage), verify_scopes, config.AGENT_VERIFY_CONCURRENCY)
suppressed = apply_verdicts(specialist_findings, verify_results)
if suppressed:
suppressed_ids = {id(f) for f in suppressed}
specialist_findings = [f for f in specialist_findings if id(f) not in suppressed_ids]
memory.replace("suppressed", suppressed)
memory.extend("findings", specialist_findings)
gap_findings = [
{
@@ -225,7 +260,7 @@ def run_agent_pipeline(
"project_intelligence": object_graph,
"validated_issues": prioritized,
"rfis": [],
"suppressed_issues": [],
"suppressed_issues": memory.snapshot().get("suppressed") or [],
})
progress = store.progress(queue)
# Same usage/stats summary block as the wave-7 path (rfis: 0 — they
@@ -301,6 +336,7 @@ def run_agent_pipeline(
"project_intelligence": object_graph,
"validated_issues": prioritized,
"rfis": rfis,
"suppressed_issues": memory.snapshot().get("suppressed") or [],
})
cost = usage.snapshot()
orchestrator.stats.calls = cost["calls"]