feat: refocus on drawings — code/ADA gated off, drawing-integrity wave, Brain-directed clarification
- ENABLE_CODE_REVIEW flag (default off): skips code/ADA/jurisdiction review path in both pipelines; nothing deleted, one env flag to restore. - Per-sheet Drawing Integrity QA wave (agent + classic, default on): dangling refs, on-sheet contradictions, dimension sanity, missing sheet essentials, tag hygiene. New DrawingIntegrityAgent + classic stage. - Broadened conflict critic: intra-sheet + same-discipline contradictions, not just cross-discipline. - Wave 6.5 Brain-directed clarification (bounded hub-and-spoke): Brain names uncertain findings, verify_evidence requests route through the wave-5b verifier; refuted findings suppressed. One planning call + capped verifies, single iteration. Shared _build_verify_scopes across 5b and 6.5. - Config knobs, .env.example, frontend copy, tests (182 passing).
This commit is contained in:
+72
-1
@@ -6,7 +6,12 @@ from typing import Dict, List, Tuple
|
||||
|
||||
from backend import config
|
||||
from backend.agents.base import AgentUsage
|
||||
from backend.agents.prompts import BRAIN_SYSTEM_PROMPT, BRAIN_USER_PROMPT
|
||||
from backend.agents.prompts import (
|
||||
BRAIN_CLARIFY_SYSTEM_PROMPT,
|
||||
BRAIN_CLARIFY_USER_PROMPT,
|
||||
BRAIN_SYSTEM_PROMPT,
|
||||
BRAIN_USER_PROMPT,
|
||||
)
|
||||
from backend.llm import call_json
|
||||
from backend.pipeline._stage import collect_list, validate_issue
|
||||
|
||||
@@ -127,3 +132,69 @@ class BrainAgent:
|
||||
issues.sort(key=lambda item: -int(item.get("risk_score") or 0))
|
||||
decisions = parsed.get("decisions") or []
|
||||
return issues, [item for item in decisions if isinstance(item, dict)]
|
||||
|
||||
def plan_clarifications(self, prioritized: List[Dict]) -> List[Dict]:
|
||||
"""Wave 6.5 planning call: name kept findings the Brain wants to
|
||||
double-check before publishing, as typed clarification requests.
|
||||
|
||||
Returns a capped list of {issue_id, request_type, reason}. Only
|
||||
findings that carry an issue_id and do NOT already have a verification
|
||||
result are offered to the model; anything the model names outside that
|
||||
set, or with an unknown request_type, is dropped by the caller/router.
|
||||
Never raises — a failed/empty plan just yields no requests.
|
||||
"""
|
||||
max_requests = config.BRAIN_CLARIFY_MAX_REQUESTS
|
||||
if not prioritized or max_requests <= 0:
|
||||
return []
|
||||
candidates = [
|
||||
{
|
||||
"issue_id": f.get("issue_id"),
|
||||
"severity": f.get("severity"),
|
||||
"confidence": f.get("confidence"),
|
||||
"source_stage": f.get("source_stage"),
|
||||
"description": (f.get("description") or "")[:400],
|
||||
"evidence": f.get("evidence") or [],
|
||||
"already_verified": bool(f.get("verification")),
|
||||
}
|
||||
for f in prioritized
|
||||
if f.get("issue_id") and not f.get("verification")
|
||||
]
|
||||
if not candidates:
|
||||
return []
|
||||
instruction = (
|
||||
BRAIN_CLARIFY_USER_PROMPT
|
||||
.replace("{max_requests}", str(max_requests))
|
||||
.replace("{findings}", json.dumps(candidates, ensure_ascii=True))
|
||||
)
|
||||
try:
|
||||
parsed = call_json(
|
||||
system_prompt=BRAIN_CLARIFY_SYSTEM_PROMPT,
|
||||
user_text=instruction,
|
||||
max_tokens=config.BRAIN_CLARIFY_MAX_TOKENS,
|
||||
model=config.AGENT_BRAIN_MODEL,
|
||||
usage_tracker=self.usage,
|
||||
usage_stage="agent.brain_clarify",
|
||||
)
|
||||
except Exception:
|
||||
return []
|
||||
raw = parsed.get("requests") if isinstance(parsed, dict) else parsed
|
||||
if not isinstance(raw, list):
|
||||
return []
|
||||
valid_ids = {c["issue_id"] for c in candidates}
|
||||
requests: List[Dict] = []
|
||||
seen: set = set()
|
||||
for item in raw:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
issue_id = item.get("issue_id")
|
||||
if issue_id not in valid_ids or issue_id in seen:
|
||||
continue
|
||||
requests.append({
|
||||
"issue_id": issue_id,
|
||||
"request_type": (item.get("request_type") or "verify_evidence").strip(),
|
||||
"reason": (item.get("reason") or "").strip(),
|
||||
})
|
||||
seen.add(issue_id)
|
||||
if len(requests) >= max_requests:
|
||||
break
|
||||
return requests
|
||||
|
||||
Reference in New Issue
Block a user