Metadata-Version: 2.4
Name: anz33
Version: 0.4.0
Summary: anz33 — one local endpoint for every AI engine. Routes OpenAI-compatible requests across Ollama, LM Studio, llama.cpp, and cloud by measured speed and power state.
Project-URL: Homepage, https://anz33.com
Author-email: anz33 <hello@anz33.com>
License: Proprietary
Requires-Python: >=3.11
Requires-Dist: fastapi>=0.115
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.9
Requires-Dist: uvicorn>=0.32
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Description-Content-Type: text/markdown

# anz33

**One local endpoint for every AI engine.** — [anz33.com](https://anz33.com)

anz33 is a small daemon that sits in front of every inference engine on (and around) your machine — Ollama, LM Studio, llama.cpp, and optional cloud endpoints — and exposes a single OpenAI-compatible API. Apps point at `http://127.0.0.1:3300/v1` and anz33 routes each request to the best engine, using **measured** tokens-per-second on your hardware and your current power state.

Why: laptops now ship five incompatible AI stacks and most apps hardcode one. The router is the missing layer — pick the engine per request, not per app.

## Quick start

```bash
uv tool install anz33        # or: pip install anz33
anz33 serve                  # http://127.0.0.1:3300/v1
```

Point any OpenAI-compatible client at it:

```bash
curl http://127.0.0.1:3300/v1/chat/completions \
  -d '{"model": "auto", "messages": [{"role": "user", "content": "hello"}]}'
```

`"model": "auto"` lets anz33 choose. Name a specific model and anz33 finds whichever engine hosts it.

## Commands

| Command | What it does |
|---|---|
| `anz33 serve` | Start the router (default `127.0.0.1:3300`) |
| `anz33 status` | Show live engines, models, battery state, measured speeds |
| `anz33 bench` | Measure real tok/s for every local engine × model; routing uses the results |
| `anz33 models` | JSON list of every reachable model |
| `anz33 install` | Run anz33 at login (launchd on macOS, systemd user unit on Linux) |
| `anz33 uninstall` | Stop and remove the login service |
| `anz33 remote add anthropic` | Add a cloud remote from a preset (also: `openai`, plus `remote list` / `remote remove`) |
| `anz33 activate <key>` | Activate a subscription on this machine (Polar.sh, 14-day offline grace) |
| `anz33 license` | Subscription status (`--remove` to deactivate this machine) |

### Privacy (L1)

| Command | What it does |
|---|---|
| `anz33 policy show` | Current rules, kill switch, airlock state |
| `anz33 policy add clients --keyword acme patient` | Anything mentioning these never leaves the machine |
| `anz33 policy offline` / `online` | Kill switch — no request may leave, whatever it says |
| `anz33 audit` | Egress report + tamper-evident chain verification |

Requests are evaluated before routing: a matching `local_only` rule removes every cloud engine from consideration, `deny` blocks the request outright. When a request *is* allowed out, the **PII airlock** replaces emails, phone numbers, cards, IPs and known names with placeholders and restores them in the response — the cloud sees shapes, not people. Every decision appends to a hash-chained audit log; editing or deleting any record breaks the chain and `anz33 audit` says so.

### Memory vault (L2)

| Command | What it does |
|---|---|
| `anz33 remember "I prefer metric units" --kind preference` | Add a memory |
| `anz33 memories` / `anz33 forget <id>` | List / delete |
| `anz33 import chatgpt conversations.json` | Migrate in from a ChatGPT export (also `claude`) |
| `anz33 export-memory ~/backup` | Migrate out — it's yours |

Memories are plain markdown in `~/.anz33/memory/`. The router retrieves the relevant few and injects them into **any** model, so a local 8B remembers you as well as a frontier cloud model. anz33 also captures durable facts from your own turns automatically, locally.

### Skills, chat, household (L3, L5)

| Command | What it does |
|---|---|
| `anz33 skills` | List skills (`--install` to copy built-ins to `~/.anz33/skills` for editing) |
| `anz33 profile add kid --kid-safe` | Household member with its own key; kid profiles are local-only, size-capped, and refuse companion roleplay |
| `anz33 serve --lan` | Bind `0.0.0.0` so the whole household routes through this hub |
| `anz33 savings` | What local routing saved you vs cloud pricing |

Chat UI at **`/anz33chat`**; dashboard at **`/anz33dashboard`**. Select a skill per request:

```json
{"model": "auto", "skill": "fraud-check", "messages": [...]}
```

Built-ins: `homework` (explains, never writes the essay), `fraud-check`, `translate`, `summarize`, `private-notes`, `explain-simply`. Sensitive skills are local-only by construction.

## Routing policy

1. **Exact match, local first** — the requested model on the fastest engine that has it (by your `anz33 bench` measurements).
2. **Battery-aware** — on battery below 50%, big models (>15B) are swapped for the smallest capable local model. Disable with `"battery_saver": false`.
3. **Cloud is opt-in** — remote endpoints are only used if `"allow_cloud": true` in `~/.anz33/config.json`. API keys are read from environment variables, never stored.
4. **`auto`** — fastest measured local model; falls back to a size heuristic until you run `anz33 bench`.

On Apple silicon, anz33 also probes an [mlx-lm](https://github.com/ml-explore/mlx-lm) server for native-speed inference: `pip install mlx-lm && mlx_lm.server --port 8081`.

Every response carries `anz33-engine` and `anz33-route` headers explaining the decision.

## Configuration

`~/.anz33/config.json` (optional — zero config works):

```json
{
  "port": 3300,
  "allow_cloud": false,
  "battery_saver": true,
  "local_engines": {
    "ollama": "http://127.0.0.1:11434",
    "lmstudio": "http://127.0.0.1:1234",
    "llamacpp": "http://127.0.0.1:8080",
    "mlx": "http://127.0.0.1:8081"
  },
  "remotes": [
    {
      "name": "anthropic",
      "base_url": "https://api.anthropic.com/v1",
      "api_key_env": "ANTHROPIC_API_KEY",
      "models": ["claude-sonnet-5"]
    }
  ]
}
```

## Development

```bash
uv sync --extra dev
uv run pytest
uv run anz33 serve
```

## Pricing

anz33 is subscription software: **$20/month, everything included** — routing, benchmarking, dashboard, remotes, priority support. New installs get a 14-day evaluation trial, after which the daemon requires an active subscription (`anz33 activate <key>`).

Proprietary — © 2026 AZMX. All rights reserved.
