"""LangChain decorated tools for artifact and schema validation.""" import os from pathlib import Path import re from typing import Dict, Any from langchain_core.tools import tool @tool def validate_mermaid_diagram(diagram_content: str) -> Dict[str, Any]: """Validates the syntax and graph structure of a Mermaid diagram. Args: diagram_content: Raw text content of the Mermaid diagram file. Returns: Dict with status, valid boolean, and error details if any. """ if not diagram_content or not diagram_content.strip(): return {"valid": False, "error": "Mermaid diagram is empty."} if not re.search(r"\b(flowchart|graph)\b", diagram_content): return { "valid": False, "error": "Mermaid diagram must start with 'flowchart' or 'graph'.", } # Basic bracket matching check open_brackets = diagram_content.count("[") + diagram_content.count("(") + diagram_content.count("{") close_brackets = diagram_content.count("]") + diagram_content.count(")") + diagram_content.count("}") if open_brackets != close_brackets: return { "valid": False, "error": "Mismatched brackets in Mermaid diagram syntax.", } return {"valid": True, "message": "Mermaid diagram syntax is valid."} @tool def validate_terraform_syntax(terraform_content: str) -> Dict[str, Any]: """Validates Terraform HCL basic structure and required Google Cloud blocks. Args: terraform_content: Raw HCL text content of main.tf. Returns: Dict with valid boolean and diagnostic information. """ if not terraform_content or not terraform_content.strip(): return {"valid": False, "error": "Terraform configuration is empty."} if "resource" not in terraform_content and "module" not in terraform_content: return { "valid": False, "error": "Terraform configuration must contain at least one resource or module block.", } return {"valid": True, "message": "Terraform HCL structural check passed."} @tool def validate_repository_artifacts(target_dir: str) -> Dict[str, Any]: """Executes full offline validation against solution architecture artifacts in a directory. Args: target_dir: Directory path containing the solution architecture repository. Returns: Dict containing validation pass status and missing items list. """ root = Path(target_dir) def find_artifact(filename): search_dirs = [ root / "deliverables" / "as-is", root / "deliverables" / "target", root / "deliverables" / "validation", root / "deliverables" / "guides", root / "deliverables", root / "docs", root, ] for d in search_dirs: candidate = d / filename if candidate.is_file(): return candidate return None required_names = ["requirements.md", "architecture.md", "architecture.mmd", "solution-architecture-guide.md"] missing = [] for fname in required_names: if not find_artifact(fname): missing.append(fname) if not (root / "terraform/main.tf").is_file(): missing.append("terraform/main.tf") if not (root / "terraform/variables.tf").is_file(): missing.append("terraform/variables.tf") guide_path = find_artifact("solution-architecture-guide.md") if guide_path: guide_text = guide_path.read_text(encoding="utf-8") required_sections = ["Functional requirements", "Selected products", "Validation results", "Terraform", "Mermaid"] for section in required_sections: if section not in guide_text: missing.append(f"Guide section missing: {section}") else: missing.append("solution-architecture-guide.md missing") mmd_path = find_artifact("architecture.mmd") if mmd_path: mmd_text = mmd_path.read_text(encoding="utf-8") if not re.search(r"flowchart|graph", mmd_text): missing.append("Invalid Mermaid graph directive in architecture.mmd") passed = len(missing) == 0 return { "valid": passed, "missing_items": missing, "message": "All required architecture artifacts valid." if passed else f"Validation failed for: {', '.join(missing)}", }