typesafe-computer-use

CI MIT license Python 3.12+ macOS, Windows experimental TypeSafe Ruff

**typesafe-computer-use** (jev for short) drives a Mac toward a goal you type in plain English, for about a fiftieth of a cent per step. It reads the screen deterministically, asks a small classifier which action comes next, and only calls a writing model when a text field genuinely needs free text or the classifier has stopped and the screen needs reading. One idea runs through it: the classifier picks, code decides facts, and the writer only writes free text. Anything a model would have to work out (a date, whether a field is focused, whether a URL is clean) is computed in code and handed over as state. [VISION.md](VISION.md) says what it is for in a dozen lines. ``` clicker "go to techcrunch and take me to the checkout page for the cheapest tickets to their next upcoming event" --act ``` > **Beta.** This is under heavy development. Expect rough edges, and expect settings and > behavior to change between 0.x [releases](https://github.com/awlevin/typesafe-computer-use/releases). > It drives your real mouse and keyboard, so start with a dry run. ## Why a classifier Frontier-model computer use is capable and expensive: every step ships a screenshot and waits several seconds for a plan. Most steps do not need a plan. They need one choice from a short list, made quickly and cheaply, with a confidence number you can gate on. [TypeSafe](https://docs.typesafe.ai) sells exactly that: a decision model that answers a `Choice` over up to 255 options with a full probability distribution and a calibrated confidence, in a few hundred milliseconds, with free output tokens. This project is a computer-use loop built around it. Measured on the same screenshot and goal, one decision each: | | typesafe (jev) | Claude Opus 5, bare screenshot | multiplier | |---|---|---|---| | input tokens | 4,882 | 4,785 | same | | cost per decision | $0.0002 | $0.032 | 155x cheaper | | cost per decision, realistic loop with history | $0.0002 | $0.035 to $0.08 | 170x to 390x cheaper | | cost per 12-step task | $0.003 | $0.40 to $0.90 | 130x to 300x cheaper | | model latency | 0.13 to 0.38 s | 5.2 s | 14x to 40x faster | | end-to-end step, with capture and OCR | about 1.5 s | about 5.5 s | 3.7x faster | The honest caveat: the big model read the event dates off the pixels and compared them unaided. The classifier needed the date parsing described in [how a step works](docs/how-a-step-works.md). Every piece of reasoning the frontier model does for free has to be rebuilt here as deterministic state. ## Install macOS 14 or newer, Python 3.12 or newer, [uv](https://docs.astral.sh/uv/). Windows 10 and 11 are experimental; see [Windows](docs/windows.md). ``` git clone https://github.com/awlevin/typesafe-computer-use cd typesafe-computer-use uv sync cp .env.example .env # fill in the keys ``` | variable | required | purpose | |---|---|---| | `TYPESAFE_API_KEY` | yes | every decision | | `ANTHROPIC_API_KEY` | no | `type_text`, writer-proposed URLs, and the final answer | | `CLICKER_EMAIL` | no | enables the `type_email` action | | `CLICKER_BROWSER` | no | defaults to `Google Chrome` | `.env` lives at the repo root and is read by every entry point (`clicker`, `clicker-inspect`). To run the writer on another model or endpoint (LM Studio, Ollama, any OpenAI-compatible server), see [writer endpoints](docs/writer-endpoints.md). Grant your terminal **Screen Recording** and **Accessibility** in System Settings > Privacy & Security. Without the first, captures are wallpaper. Without the second, synthetic clicks are silently dropped, and `--act` refuses to start. ## First run ``` uv run clicker "open the Playground" # dry run: one step, prints what it would do uv run clicker "open the Playground" --act # drives the machine, up to 100 steps uv run clicker "log in" --act --steps 20 --delay 3 # longer and slower uv run clicker "log in" --act --handoffs 0 # the classifier alone: its first stop ends the run uv run clicker-inspect "any goal" # 3-2-1, capture, open the annotated screen + payload ``` Clear the terminal first. It is on screen, so its text is OCR input. To stop a live run, press Ctrl-C in the terminal or slam the mouse into the top-left corner of the screen. The loop also stops itself on `done`, low confidence, a stall, or the step limit, and the writer then reads the screen and prints the answer. Every run writes `runs//`, so a stall can be [replayed offline](docs/run-folder.md). ## How a step works 1. The screen is read deterministically: Vision OCR on a crop of the frontmost window, plus the labelled controls from the accessibility tree, which sees the icons OCR cannot. 2. Code adds the facts: the date on any block and how far off it is, the row of a repeated label, the focused field, the app and URL, and the actions already tried on this screen. 3. One TypeSafe request answers three `Choice`s: which kind of action, which item, which site. 4. The action runs deterministically, the loop waits, and the next capture is the only witness of what it did. 5. When the classifier stops, the writer reads the screen and answers, or hands the run back with a focus (one move) or a question for you. It never picks an action. The full walk, with the OCR cost, the tree walk, the action space, and the stop rules, is in [how a step works](docs/how-a-step-works.md). ## Benchmark jev runs as an agent in [OSWorld](https://github.com/xlang-ai/OSWorld-V2), a benchmark of real desktop tasks, beside OSWorld's own GPT agent on the same task. `scripts/osworld setup` fetches OSWorld and installs jev beside it; `scripts/osworld run-jev chrome/ --ocr rapidocr` runs one task. It needs a Linux host with KVM; see [OSWorld](docs/osworld.md) for that and for a one-command machine in Google Cloud. ## Read more - [How a step works](docs/how-a-step-works.md): perception, the three-part decision, the action space, stalls, and the hand-off to the writer - [Run folder](docs/run-folder.md): what every run writes, the timing line, and offline replay - [Browser backend](docs/browser-backend.md): DOM perception over Chrome DevTools, no OCR, no screen permission - [Writer endpoints](docs/writer-endpoints.md): every writer variable, and other models over the Anthropic or OpenAI API - [Windows](docs/windows.md): the experimental adapter and how it differs from macOS - [OSWorld](docs/osworld.md): setup, the two run commands, results, and the Google Cloud machine - [Layout](docs/layout.md): every module and what it owns - [Known limits](docs/known-limits.md) - [Sandbox](docs/sandbox.md): a Linux computer in a container, for running the agent on a screen that is not yours ## Contributing Bug reports with a run folder attached are the most useful thing you can send. Before a pull request, `uv run ruff check . && uv run ruff format --check .` and `uv run pytest -q` must pass. The ground rules, and how to write a scenario for a task the loop cannot do, are in [CONTRIBUTING.md](CONTRIBUTING.md). ## License [MIT](LICENSE)