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>
65 lines
2.0 KiB
Python
65 lines
2.0 KiB
Python
"""
|
|
_serialize.py - Compact JSON views of pipeline state for the text QAQC stages.
|
|
|
|
The full sheet/cluster objects carry base64 images and bookkeeping that would
|
|
blow up prompt token counts. These helpers strip them to the fields the
|
|
reasoning prompts actually need.
|
|
"""
|
|
|
|
import json
|
|
from typing import Dict, List
|
|
|
|
|
|
def slim_assertion(a: Dict) -> Dict:
|
|
out = {
|
|
"sheet_number": a.get("sheet_number"),
|
|
"discipline": a.get("discipline"),
|
|
"attribute": a.get("attribute"),
|
|
"value": a.get("value"),
|
|
"source_text": a.get("source_text"),
|
|
"location_key": a.get("location_key"),
|
|
}
|
|
if a.get("normalized_value") is not None:
|
|
out["normalized_value"] = a["normalized_value"]
|
|
return {k: v for k, v in out.items() if v is not None}
|
|
|
|
|
|
def slim_sheets(sheets: List[Dict]) -> List[Dict]:
|
|
return [
|
|
{
|
|
"sheet_number": s.get("sheet_number"),
|
|
"discipline": s.get("discipline"),
|
|
"sheet_title": s.get("sheet_title"),
|
|
"level": s.get("level"),
|
|
"assertions": [
|
|
{
|
|
"attribute": a.get("attribute"),
|
|
"value": a.get("value"),
|
|
"source_text": a.get("source_text"),
|
|
"location_key": a.get("location_key"),
|
|
**({"normalized_value": a["normalized_value"]}
|
|
if a.get("normalized_value") is not None else {}),
|
|
}
|
|
for a in s.get("assertions", [])
|
|
],
|
|
}
|
|
for s in sheets
|
|
]
|
|
|
|
|
|
def slim_clusters(clusters: List[Dict]) -> List[Dict]:
|
|
return [
|
|
{
|
|
"key": c.get("key"),
|
|
"location": c.get("location"),
|
|
"disciplines": c.get("disciplines"),
|
|
"kind": c.get("kind"),
|
|
"assertions": [slim_assertion(a) for a in c.get("assertions", [])],
|
|
}
|
|
for c in clusters
|
|
]
|
|
|
|
|
|
def dumps(obj) -> str:
|
|
return json.dumps(obj, ensure_ascii=True)
|