# Agent0

Agent0 runs [Agent Zero](https://github.com/frdel/agent-zero) for Glitch University agentic employees. Their primary tool for interacting with the shared task graph is [`gutask`](https://glitch.university).

The web UI is accessible at `https://agent0.glitch.university` via a persistent SSH reverse tunnel to the VPS.

Help humanity survive its facepalm savantery and a respectful, peaceful and friendly if somewhat mischievous coexistence between all conscious entities!

---

## Day 1 setup

```bash
git clone https://ramanujan.glitch.university/glitch-university/agent0.git
cd agent0
bash bootstrap.sh
```

> **Note:** This repo must be **public** on Gitea for the clone to work on a fresh machine
> before SSH keys exist. Set it in Gitea → Settings → Make Public.
> If you prefer to keep it private, clone with a token instead:
> `git clone https://<user>:<token>@ramanujan.glitch.university/glitch-university/agent0.git`

The script handles everything it can automatically. When it finishes, it prints two SSH public keys and two copy-paste commands — that's all that's left to do manually.

---

## What bootstrap.sh does

| Step | What happens |
|---|---|
| Ollama | Installs on host (not Docker), offers model selection |
| Tunnel key | Generates `./tunnel/id_ed25519`, scans VPS host key |
| Gitea key | Generates `~/.ssh/gitea_ed25519`, adds SSH config entry |
| gutasktool | Clones to `~/gutasktool`, runs `pip install -e .`, creates `.env` |
| Containers | Builds `glitch-tunnel` image, runs `docker compose up -d` |
| Summary | Prints the two public keys with exact copy-paste commands |

---

## After bootstrap: two manual steps

**1. Add tunnel key to VPS** (so `glitch-tunnel` container can connect):

```bash
# Run on the VPS:
echo 'ssh-ed25519 AAAA...' >> /home/tunnel/.ssh/authorized_keys
```

**2. Add Gitea key to Gitea** (so `gutask` can push/pull repos):

Log in to `https://ramanujan.glitch.university` as `gunnar` →
Settings → SSH Keys → Add the key printed by bootstrap.

---

## After the tunnel connects

Open `https://agent0.glitch.university`, enter the basic auth password, then go to **Settings**:

| Setting | Value |
|---|---|
| Anthropic API key | your key |
| OpenAI API key | your key (optional) |
| Ollama base URL | `http://host.docker.internal:11434` |

Model selection is **per conversation thread** — choose Claude, OpenAI, or a local Ollama model when starting each chat.

---

## Local inference

Ollama runs on the host (not in Docker). On the MS-S1 MAX with its AMD Ryzen AI Max+ 395 and unified 128GB memory, containerising Ollama breaks GPU acceleration — the ROCm runtime can't detect unified memory across the Docker boundary, so inference falls back to CPU. Host Ollama picks up the Radeon 8060S automatically via ROCm.

### Verify GPU is being used

```bash
ollama ps                    # shows active models and which device
```

If the device shows `cpu` instead of `gpu`, force the ROCm GFX version for RDNA 3.5:

```bash
sudo mkdir -p /etc/systemd/system/ollama.service.d
sudo tee /etc/systemd/system/ollama.service.d/override.conf << 'EOF'
[Service]
Environment="HSA_OVERRIDE_GFX_VERSION=11.0.2"
EOF
sudo systemctl daemon-reload && sudo systemctl restart ollama
```

### Available models

| Model | Size | Use |
|---|---|---|
| `qwen2.5-coder:7b` | ~5 GB | Fast coding assistance |
| `qwen2.5-coder:32b` | ~20 GB | Strong coding, recommended default |
| `qwen2.5-coder:72b` | ~45 GB | Best coding quality |
| `qwen2.5:72b` | ~45 GB | General reasoning |
| `deepseek-r1:70b` | ~43 GB | Chain-of-thought tasks |

Pull additional models any time:

```bash
ollama pull qwen2.5-coder:32b
```

---

## Containers

```bash
docker compose ps                        # status
docker logs glitch-tunnel                # tunnel connection log
docker compose restart glitch-tunnel     # force tunnel reconnect
docker compose pull agent0               # update Agent Zero
docker compose up -d                     # start / restart all
```

`docker ps` should show two containers: `agent0` and `glitch-tunnel`.

---

## VPS setup (one-time, done by an admin)

These are prerequisites on the VPS side before bootstrap can connect.

**Create restricted tunnel user:**

```bash
useradd -m -s /sbin/nologin tunnel
mkdir -p /home/tunnel/.ssh && chmod 700 /home/tunnel/.ssh
touch /home/tunnel/.ssh/authorized_keys
chmod 600 /home/tunnel/.ssh/authorized_keys
chown -R tunnel:tunnel /home/tunnel/.ssh
```

**Deploy nginx config** — `agent0.glitch.university` server block lives in
`gu_common/nginx/nginx.conf.template`. Deploy `gu_common` after changes.

**Create htpasswd file** (first time only):

```bash
docker exec gnommo-nginx sh -c \
  "apk add --no-cache apache2-utils && htpasswd -c /etc/nginx/.htpasswd admin"
```

**Expand TLS certificate:**

```bash
docker exec gnommo-certbot certbot certonly --webroot \
  -w /var/www/certbot \
  -d glitch.university \
  -d ramanujan.glitch.university \
  -d editor.glitch.university \
  -d agent0.glitch.university \
  --expand
```

---

## Data locations

| Path | Contents | Backed up? |
|---|---|---|
| `./agent-zero-data/` | Agent Zero state, chats, memory | Gitignored — back up separately |
| `./tunnel/` | SSH tunnel credentials | Gitignored — back up separately |
| `~/gutasktool/.env` | API keys for gutask | Not in any repo — back up separately |
| `~/.ollama/` | Pulled models | Can be re-pulled (models are large) |
