Metadata-Version: 2.5
Name: autooptm
Version: 0.6.0
Summary: Client, CLI and MCP server for AutoOptm: measured GPU speedups for your training and inference code
License: MIT
Requires-Python: >=3.9
Provides-Extra: mcp
Requires-Dist: mcp>=1.0; extra == 'mcp'
Description-Content-Type: text/markdown

# autooptm

Measured GPU speedups for your training and inference code, from the
terminal, an agent, or Python. The estimate is free; continuing takes a
2-credit analysis deposit, credited in full against the patch; the patch
is what costs credits.

```bash
pipx install autooptm          # a CLI tool: pipx or `uv tool install autooptm`, not a bare pip
                               # (Homebrew's Python on macOS and recent Debian/Ubuntu refuse it)
autooptm login                 # opens the browser to approve this machine (30-day token)
autooptm run https://github.com/you/repo --entrypoint train.py
autooptm wait <jobId>          # resume waiting after a dropped connection or --no-wait
autooptm unlock <jobId>        # asks before spending credits
git apply autooptm.patch
```

A local directory (`autooptm run .`) is packed on your machine, and you
see the list before it leaves: `.git`, caches and virtualenvs are dropped
without asking; weight files, data files, files over 8 MB and directories
with over 200 files are each shown and asked about (they stay out unless
you say yes, or answer `d` to send a directory up as the private dataset
instead, unpacked at the same path in the sandbox); then the packing list
is printed and `upload? [Y/n]` waits.
`--dry-run` only shows the list, `--include PATH` / `--exclude PATH` answer
from the command line, and `--yes` takes the defaults without asking (off a
terminal, `run` will not upload without it).

`run` first gets the **free estimate** and shows it (expected speedup, the
range, a lossless line, and the reviewer's note if something in the
submission would stop the run); it then asks before taking the analysis
deposit. `--yes` continues without asking, `--no-estimate` skips the
estimate (the deposit is taken at submit). A job left at the estimate can be
answered later:

```bash
autooptm estimate <jobId>            # the numbers again
autooptm decide <jobId> continue     # takes the deposit, credited against the unlock
autooptm decide <jobId> stop         # free
```

`autooptm login --email you@example.com` is the no-browser door (a mailed
code) for servers and CI shells; `--no-browser` prints the approval link
instead of opening it.

Python:

```python
from autooptm import AutoOptm
ao = AutoOptm()
job = ao.submit(".", entrypoint="bench.py", workload="inference")
done = ao.wait(job["jobId"])
print(done["speedup"], done["unlock_credits"])
```

MCP (Claude Code, Cursor, any MCP client), `pipx install 'autooptm[mcp]'`:

```json
{ "mcpServers": { "autooptm": { "command": "autooptm-mcp" } } }
```

Tools: `optimize_submit`, `optimize_status`, `optimize_wait`,
`unlock_patch` (requires explicit user confirmation), `download_patch`,
`account_balance`.

## API keys (CI and scripts)

`autooptm login` saves a 30-day token that slides on use, which is the right
credential for a laptop and the wrong one for a build machine: it expires
while the pipeline is idle, it needs a mailbox to renew, and it can spend
credits. A key fixes all three.

```bash
autooptm login                      # a key is minted from a session
autooptm keys create "CI pipeline"  # printed once, never again
autooptm keys list
autooptm keys revoke aok_1a2b3c4d5e6f
```

Put it in CI as `AUTOOPTM_TOKEN` and it works everywhere a login token does.

Keys carry scopes, and the default is `read,submit`. **`unlock` is opt-in**,
so a build machine can submit work and read the result without being able to
spend a credit, whatever the build does. Add `--scopes read,submit,unlock`
only if you mean it, and `--expires-in-days N` to make it die on its own.
