# utils.py import re from typing import Optional def safe_truncate(text: str, max_chars: int = 12000) -> str: if not text: return "" return text if len(text) <= max_chars else text[:max_chars] + "\n\n[[TRUNCATED]]" def sanitize_text(text: Optional[str]) -> str: if not text: return "" t = re.sub(r"<[^>]+>", " ", text) t = re.sub(r"\s+", " ", t).strip() return t def _extract_json_from_text(text: str) -> Optional[str]: if not text: return None start = None depth = 0 for i, ch in enumerate(text): if ch == "{": if start is None: start = i depth += 1 elif ch == "}": if depth > 0: depth -= 1 if depth == 0 and start is not None: return text[start:i+1] return None