""" constructability.py - Stage 8: constructability review (LLM). One whole-set reasoning pass flagging things that are drawn but hard, ambiguous, or impossible to build as shown (access/clearance, sequencing, support, routing, tolerance, dimension closure, detail gaps). Emits the canonical issue schema. Returns [] on failure. """ from typing import Dict, List from backend import config from backend.pipeline._serialize import dumps, slim_clusters, slim_sheets from backend.pipeline._stage import call_stage, collect_list, validate_issue from backend.prompts import ( CONSTRUCTABILITY_SYSTEM_PROMPT, CONSTRUCTABILITY_USER_INSTRUCTION, ) def constructability_review(sheets: List[Dict], clusters: List[Dict], conflicts: List[Dict]) -> List[Dict]: parsed = call_stage( CONSTRUCTABILITY_SYSTEM_PROMPT, CONSTRUCTABILITY_USER_INSTRUCTION, subs={ "assertions": dumps(slim_sheets(sheets)), "clusters": dumps(slim_clusters(clusters)), "conflicts": dumps(conflicts), }, max_tokens=config.CONSTRUCT_MAX_TOKENS, ) issues = collect_list(parsed, "issues", lambda c: validate_issue(c, "constructability")) print(f"[Constructability] {len(issues)} constructability issue(s)") return issues