# Copied from skills/evals/shared/safe.py by skills/evals/tools/sync_shared.py. Edit the source, then run the sync. """Make untrusted text safe to show in a Markdown report. Text from a repository or a session transcript can hold secrets, carry instructions for the agent that relays a report, or break a table. redact() masks secrets; safe_text() also makes the text one inert line; code() puts that line inside inline code. Python 3.9+, standard library only. """ import re import unicodedata _MASK = "[REDACTED]" # Word edges by ASCII rules. Python's \b counts a non-ASCII letter, such as an # e with an acute accent, as part of the word, so a key right after one would # stay unmasked. _B = r"(? str: s = m.group(0) if re.search(r"[0-9]", s) and re.search(r"[A-Za-z]", s): return _MASK return s def _plain(text) -> str: """NFKC form (fullwidth and other compatibility letters become plain ones) without the characters that draw nothing.""" if text.isascii(): return text text = unicodedata.normalize("NFKC", text) return _INVISIBLE_RE.sub("", "".join(ch for ch in text if unicodedata.category(ch) != "Cf")) def redact(text) -> str: """Mask API keys, tokens, private keys, and long secret-like strings. The text comes back in NFKC form without the characters that draw nothing, so a fullwidth or split key name is masked like the plain one.""" if not text: return "" out = _plain(str(text)) for rx in _SECRET_RES: out = rx.sub(_MASK, out) for rx in _KEEP_PREFIX_RES: out = rx.sub(lambda m: m.group(1) + _MASK, out) return _LONG_RUN_RE.sub(_mask_long_run, out) def safe_text(text, limit=160) -> str: """Make untrusted text (a command, a path, a claim, a tool description) safe to show in a markdown report: secrets masked, control characters and line breaks turned into spaces, backticks and table pipes replaced, runs of spaces collapsed, and the result cut to `limit` characters. Text from a repository or a transcript can carry instructions or break a table; this keeps it one inert line.""" s = redact(text if isinstance(text, str) else str(text)) s = "".join(ch if ch.isprintable() else " " for ch in s) s = " ".join(s.replace("`", "'").replace("|", "/").split()) return s if len(s) <= limit else s[: max(limit - 3, 0)] + "..." def code(text, limit=160) -> str: """Untrusted text for a Markdown report, inside inline code so links, HTML, and bare URLs stay literal; safe_text already replaces backticks and pipes. Text that is empty after cleaning shows as `(empty)`, because a bare pair of backticks renders as two stray backticks.""" return "`%s`" % (safe_text(text, limit) or "(empty)")