Cross-discipline design-contradiction checker for construction drawing sets. Standalone tool broken out from Iron_Bid; a pipeline stage may later fold back into Iron_Bid. Pipeline: PDF->images -> per-sheet assertion extraction -> deterministic clustering by location -> per-cluster reasoning -> report. Includes CLI (cli/run_check.py) and web UI (backend/main.py). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
47 lines
1.6 KiB
Python
47 lines
1.6 KiB
Python
"""
|
|
rfi.py - Stage 11: RFI / QAQC comment generation (LLM, text-only).
|
|
|
|
Drafts professional, evidence-based RFI / QAQC comments from the prioritized
|
|
issue list. Uses TEXT_MODEL (defaults to MODEL). Returns [] on failure.
|
|
"""
|
|
|
|
from typing import Dict, List
|
|
|
|
from backend import config
|
|
from backend.pipeline._serialize import dumps
|
|
from backend.pipeline._stage import call_stage, collect_list
|
|
from backend.prompts import RFI_SYSTEM_PROMPT, RFI_USER_INSTRUCTION
|
|
|
|
|
|
def _valid_rfi(r: Dict) -> Dict:
|
|
"""Keep an RFI only if it has a question or title; coerce list fields."""
|
|
if not isinstance(r, dict):
|
|
return None
|
|
if not (r.get("question") or r.get("title")):
|
|
return None
|
|
return {
|
|
"rfi_id": r.get("rfi_id") or "",
|
|
"issue_id": r.get("issue_id") or "",
|
|
"title": (r.get("title") or "").strip(),
|
|
"question": (r.get("question") or "").strip(),
|
|
"background": (r.get("background") or "").strip(),
|
|
"sheets_referenced": r.get("sheets_referenced") or [],
|
|
"disciplines_to_respond": r.get("disciplines_to_respond") or [],
|
|
"suggested_response_needed": (r.get("suggested_response_needed") or "").strip(),
|
|
"priority": (r.get("priority") or "medium").strip().lower(),
|
|
}
|
|
|
|
|
|
def generate_rfis(prioritized: List[Dict]) -> List[Dict]:
|
|
if not prioritized:
|
|
return []
|
|
parsed = call_stage(
|
|
RFI_SYSTEM_PROMPT,
|
|
RFI_USER_INSTRUCTION,
|
|
subs={"prioritized_issues": dumps(prioritized)},
|
|
max_tokens=config.RFI_MAX_TOKENS,
|
|
)
|
|
rfis = collect_list(parsed, "rfi_comments", _valid_rfi)
|
|
print(f"[RFI] drafted {len(rfis)} RFI/QAQC comment(s)")
|
|
return rfis
|