Download tiny_computer_agent/safety.py from hkblockchaintechnology/tiny-computer-agent: direct link, hf CLI and curl.
- Browser
- Download file 4.33 kB
-
https://huggingface.co/hkblockchaintechnology/tiny-computer-agent/resolve/main/tiny_computer_agent/safety.py
- Command line
-
hf download hf://hkblockchaintechnology/tiny-computer-agent/tiny_computer_agent/safety.py
-
curl -L -o safety.py https://huggingface.co/hkblockchaintechnology/tiny-computer-agent/resolve/main/tiny_computer_agent/safety.py
4.33 kB
| """The gates between a small model's mistake and your filesystem.""" | |
| from __future__ import annotations | |
| import os | |
| import re | |
| from dataclasses import dataclass, field | |
| from typing import Pattern | |
| from tiny_computer_agent.actions import Action | |
| from tiny_computer_agent.observe import Observation | |
| DEFAULT_DENY_TEXT = ( | |
| r"\bsudo\b", | |
| r"\brm\s+-rf\b", | |
| r"\bmkfs\b", | |
| r"\bdd\s+if=", | |
| r"\bchmod\s+777\b", | |
| r"\bgit\s+push\s+--force\b", | |
| r"password", | |
| r"api[_-]?key", | |
| r"\bseed\s+phrase\b", | |
| ) | |
| DEFAULT_DENY_LABELS = ( | |
| "terminal", | |
| "shell", | |
| "keychain", | |
| "password manager", | |
| "bank", | |
| "wallet", | |
| "credit card", | |
| ) | |
| DEFAULT_DENY_KEYS = ("ctrl+alt+t", "ctrl+alt+delete", "ctrl+shift+escape") | |
| class PolicyViolation(RuntimeError): | |
| """Raised when an action is refused. The loop stops; nothing is executed.""" | |
| class Policy: | |
| """Rules an action must pass before it is executed. | |
| dry_run : when True (the default) the loop uses a DryRunExecutor | |
| step_budget : hard cap on actions per episode | |
| deny_text_patterns : regexes a `type` action may not contain | |
| deny_labels : substrings that block a click on a matching element | |
| deny_keys : key chords that are never pressed | |
| kill_switch_path : if this file exists, the episode aborts before the next | |
| action — create it to stop a live run | |
| allow_grid_clicks : numbered grid cells are *blind* clicks: they carry no | |
| meaning, only coordinates. Allowed while planning (a dry | |
| run touches nothing), refused with real input unless this | |
| is set, because "click cell 47" is a guess about your | |
| desktop, not a decision about it. | |
| """ | |
| dry_run: bool = True | |
| step_budget: int = 20 | |
| deny_text_patterns: tuple[str, ...] = DEFAULT_DENY_TEXT | |
| deny_labels: tuple[str, ...] = DEFAULT_DENY_LABELS | |
| deny_keys: tuple[str, ...] = DEFAULT_DENY_KEYS | |
| kill_switch_path: str | None = None | |
| allow_grid_clicks: bool = False | |
| _compiled: tuple[Pattern[str], ...] = field(default=(), init=False, repr=False) | |
| def __post_init__(self) -> None: | |
| self._compiled = tuple(re.compile(p, re.IGNORECASE) for p in self.deny_text_patterns) | |
| if self.step_budget < 1: | |
| raise ValueError("step_budget must be at least 1") | |
| def should_stop(self) -> bool: | |
| """True when the kill switch exists. Checked before every action.""" | |
| return bool(self.kill_switch_path) and os.path.exists(self.kill_switch_path) | |
| def check(self, action: Action, observation: Observation | None = None) -> None: | |
| """Raise :class:`PolicyViolation` if the action is not allowed.""" | |
| if action.kind == "type" and action.text: | |
| for pattern in self._compiled: | |
| if pattern.search(action.text): | |
| raise PolicyViolation( | |
| f"typing {pattern.pattern!r} is on the deny list" | |
| ) | |
| if action.kind == "key" and action.keys: | |
| chord = "+".join(k.strip().lower() for k in action.keys.split("+") if k.strip()) | |
| if chord in {k.lower() for k in self.deny_keys}: | |
| raise PolicyViolation(f"key chord {action.keys!r} is on the deny list") | |
| if action.kind == "click" and action.label: | |
| element = observation.find(action.label) if observation is not None else None | |
| if not self.dry_run and not self.allow_grid_clicks: | |
| is_grid = (element is not None and element.kind == "grid") or ( | |
| element is None and action.label.strip().lower().startswith("cell ") | |
| ) | |
| if is_grid: | |
| raise PolicyViolation( | |
| "clicking a numbered grid cell is a blind click; install an OCR " | |
| "engine or pass --allow-grid if you really mean it" | |
| ) | |
| haystack = (element.label if element is not None else action.label).lower() | |
| for denied in self.deny_labels: | |
| if denied.lower() in haystack: | |
| raise PolicyViolation( | |
| f"clicking {action.label!r} is on the deny list ({denied!r})" | |
| ) | |