Files
PaperClip/README.md
T
Jannik ddf678fb9c feat: Add Hermes setup sub-script and in-container CLI installation
Fixes Hermes CLI not found in PATH by installing hermes-agent inside paperclip_app container. Symlinks hermes executable to PATH, mounts persistent volumes for venv and hermes-data, configures shared API keys, and integrates setup script into deployment.
2026-10-02 05:10:10 +02:00

132 lines
6.0 KiB
Markdown

# PaperClip
PaperClip ist eine Plattform zur Orchestrierung von KI-Agenten, die über Docker und Caddy betrieben wird.
Dieses Repository enthält die Infrastruktur, um PaperClip inklusive Caddy (Reverse-Proxy) und einer Postgres-Datenbank auf einem neuen Server auszurollen.
## Architektur
* **Reverse Proxy:** Caddy
* **Datenbank:** Postgres 17
* **Anwendung:** PaperClip (via `ghcr.io/paperclipai/paperclip:latest`)
* **Agent-Runtime:** Hermes Agent (via `nousresearch/hermes-agent:latest`) — Dashboard: `hermes.paperclip.orfel.de`
Alle Volumes werden als lokale Mounts unter `/opt/PaperClip-Data/` auf dem Host abgelegt.
## Installation & Deployment
Um das System auf einem neuen Server (z. B. Hetzner CX23) aufzusetzen, klone das Repository nach `/opt/PaperClip` und führe das Master-Deployment-Skript als `root` aus.
```bash
# Repository klonen
sudo mkdir -p /opt/PaperClip
sudo git clone https://git.orfel.de/Jannik/PaperClip.git /opt/PaperClip
# Setup & Deploy
sudo bash /opt/PaperClip/deploy_script.sh
```
Das Skript ist idempotent und kümmert sich um:
* Die Installation von Docker, age und fail2ban.
* Das Einrichten des Swaps und der Cronjobs (für automatische Updates).
* Das Entschlüsseln der `.env`-Dateien mit age.
* Das Starten von Caddy, Postgres und PaperClip.
## Umgebungsvariablen hinzufügen oder ändern
Es gibt zwei Arten von `.env`-Dateien:
| Datei | Inhalt | Gilt für |
|---|---|---|
| `services/shared.env(.age)` | **API Keys** (OpenRouter, Mistral, etc.) | **Alle** Services |
| `services/<name>/.env(.age)` | Service-spezifische Secrets (DB-Passwort, Auth-Secret) | Nur dieser Service |
Da `.env`-Dateien per `.gitignore` ausgeschlossen sind, wird stattdessen jeweils die `.age`-Variante ins Repository gepusht. Nach Änderungen neu verschlüsseln:
```bash
# Geteilte API Keys (alle Services)
age -r <AGE_PUBLIC_KEY> -o services/shared.env.age services/shared.env
# Service-spezifisch (z. B. PaperClip)
age -r <AGE_PUBLIC_KEY> -o services/paperclip/.env.age services/paperclip/.env
```
## LLM Konfiguration & Onboarding Workaround
Paperclip ist in seiner Benutzeroberfläche bei der Erstinstallation stark auf offizielle **OpenAI**- oder **Anthropic (Claude)**-Accounts fokussiert. Wenn du stattdessen alternative Provider wie **OpenRouter** oder **Mistral** nutzen möchtest, greift ein Workaround im Deployment-Prozess:
1. **API Keys in der `.env` hinterlegen:**
Trage deine gewünschten API-Keys in die `services/paperclip/.env` ein (z. B. `OPENROUTER_API_KEY=sk-or-v1-...`).
2. **Automatischer Patch durch das Deploy-Skript:**
Das `deploy_script.sh` erkennt automatisch, wenn ein `OPENROUTER_API_KEY` (oder `MISTRAL_API_KEY`) vorhanden ist, aber kein nativer OpenAI/Claude-Key. Es führt dann folgende Schritte aus:
* Setzt `OPENAI_API_KEY` auf deinen OpenRouter/Mistral-Key.
* Setzt `OPENAI_BASE_URL` auf die entsprechende API-URL (z. B. `https://openrouter.ai/api/v1`).
* **WICHTIG:** Das Skript patcht den Paperclip-Container (die Datei `ai-connections.js`) direkt nach dem Start. Dadurch wird sichergestellt, dass die strenge UI-Validierung beim Onboarding deine alternative URL (`OPENAI_BASE_URL`) verwendet und nicht hartcodiert bei OpenAI anfragt.
3. **Das Onboarding in der UI abschließen:**
* Sobald du deinen CEO-Account über den Invite-Link erstellst, landest du im Schritt "Connect a model".
* Klicke hier auf die Schaltfläche **OpenAI (API)**.
* Füge exakt deinen **OpenRouter-** oder **Mistral-Key** in das Textfeld ein und klicke auf "Connect".
* Paperclip testet den Key nun erfolgreich gegen deinen Provider und lässt dich ins Dashboard!
## Hermes Agent
[Hermes Agent](https://github.com/NousResearch/hermes-agent) ist ein Open-Source-KI-Agent von Nous Research, der als eigenständiger Docker-Service läuft und von PaperClip als "Mitarbeiter" eingestellt werden kann.
### Architektur
* **Container:** `hermes` (Image: `nousresearch/hermes-agent:latest`)
* **Netz:** Im selben `paperclip-net`
* **API Gateway:** `https://hermes.paperclip.orfel.de` (Port 8642 via Caddy HTTPS)
* **Web-Dashboard:** `https://hermes-ui.paperclip.orfel.de` (Port 9119 via Caddy HTTPS)
* **Daten:** `/opt/PaperClip-Data/hermes/` auf dem Host
### Hermes in PaperClip einbinden
Das Setup-Unterskript `services/hermes/setup_hermes.sh` wird automatisch beim Deployment ausgeführt und richtet die `hermes` CLI vollständig im PaperClip-Container ein (`pip install hermes-agent`).
In PaperClip kann Hermes auf zwei Arten eingestellt werden:
1. **`hermes_local` (Standard & empfohlen):**
* Im PaperClip-Dashboard → **"Hire Agent"**
* Adapter: **`hermes_local`**
* PaperClip ruft die CLI `hermes` direkt im Container auf. API Keys werden automatisch aus `services/shared.env` bereitgestellt.
2. **`hermes_gateway` (Standalone):**
* Adapter: **`Hermes Gateway`**
* Gateway-URL: `http://hermes:8642` (intern) oder `https://hermes.paperclip.orfel.de`
### Manuelles Setup
Falls Hermes manuell neu eingerichtet werden soll:
```bash
sudo bash /opt/PaperClip/services/hermes/setup_hermes.sh
```
## Weitere Adapter einbinden
### 1. OpenCode
PaperClip unterstützt OpenCode nativ mit OpenAI-kompatiblen Endpunkten. In `services/paperclip/docker-compose.yml` ist OpenRouter bereits vorkonfiguriert:
1. Im PaperClip-Dashboard → **"Hire Agent"**
2. Adapter wählen: **`OpenCode`**
3. Model eintragen, z. B.:
* `openrouter/anthropic/claude-sonnet-4-5`
* `openrouter/deepseek/deepseek-r1`
* `openrouter/google/gemini-2.5-pro`
* `openrouter/openai/gpt-4o`
### 2. Gemini CLI
Der `GEMINI_API_KEY` ist in `services/shared.env` hinterlegt und wird automatisch in den PaperClip-Container geladen:
1. Im PaperClip-Dashboard → **"Hire Agent"**
2. Adapter wählen: **`Gemini CLI`**
3. Modell / Parameter konfigurieren und Agent starten.
### Umgebungsvariablen ändern & verschlüsseln
Alle geteilten Keys liegen in `services/shared.env`. Nach Änderungen neu verschlüsseln:
```bash
age -r age1sa3q5qxl5dylld7v839m9lkv5h7l457wq4h40pt7kfmcfhcqkfjqspdjpn -o services/shared.env.age services/shared.env
```