apodex/frontier-agent-demo
14
1"""Unicode math-symbol sanitization for Python code blocks."""2from __future__ import annotations3 4_UNICODE_REPLACEMENTS: dict[str, str] = {5 "\u222B": "integral", # Integral sign6 "\u2211": "sum", # Summation7 "\u221E": "inf", # Infinity8 "\u00B2": "**2", # Superscript 29 "\u00B3": "**3", # Superscript 310 "\u2074": "**4", # Superscript 411 "\u207B": "-", # Superscript minus12 "\u00B9": "**1", # Superscript 113 "\u27E8": "<", # Left angle bracket14 "\u27E9": ">", # Right angle bracket15 "\u2329": "<", # Left-pointing angle bracket16 "\u232A": ">", # Right-pointing angle bracket17 "\u2014": "-", # Em dash18 "\u2013": "-", # En dash19 "\u2018": "'", # Left single quote20 "\u2019": "'", # Right single quote21 "\u201C": '"', # Left double quote22 "\u201D": '"', # Right double quote23 "\u2264": "<=", # Less than or equal24 "\u2265": ">=", # Greater than or equal25 "\u2260": "!=", # Not equal26 "\u00D7": "*", # Multiplication sign27 "\u00F7": "/", # Division sign28 "\u2248": "==", # Almost equal29 "\u2245": "==", # Approximately equal30 "\u2261": "==", # Identical to31 "\u2192": "->", # Right arrow32 "\u2190": "<-", # Left arrow33 "\u221A": "sqrt", # Square root34 "\u03C0": "pi", # Pi35}36 37 38def sanitize_code(code: str) -> str:39 """Replace Unicode math symbols with ASCII equivalents and strip non-ASCII40 bytes from comments.41 42 Also removes lines that start with a shell/jupyter escape (``!pip install…``)43 — those get fed to the Python interpreter, which rejects them with a44 ``SyntaxError``.45 46 Code-line behaviour (non-comment):47 * any char present in the replacement table is mapped to its ASCII form48 * non-ASCII chars that have no replacement are left alone — they may49 be legitimate (e.g. a unicode string literal)50 51 Comment-line behaviour:52 * symbol replacement runs first53 * any remaining non-ASCII bytes are replaced by ``?`` (lossy) — comments54 never affect execution, so we drop noise eagerly55 """56 if not code:57 return code58 59 out_lines: list[str] = []60 for line in code.split("\n"):61 # Strip jupyter/shell escapes.62 if line.lstrip().startswith("!"):63 continue64 65 if any(ord(ch) > 127 for ch in line):66 stripped = line.lstrip()67 if stripped.startswith("#"):68 for sym, repl in _UNICODE_REPLACEMENTS.items():69 line = line.replace(sym, repl)70 # Lossy: comments may be in any locale, we don't need them71 # round-tripped.72 line = line.encode("ascii", "replace").decode("ascii")73 else:74 for sym, repl in _UNICODE_REPLACEMENTS.items():75 line = line.replace(sym, repl)76 out_lines.append(line)77 78 return "\n".join(out_lines)79 