diff --git a/CHANGELOG.md b/CHANGELOG.md index 9895200..1a30490 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,22 +4,43 @@ Alle Änderungen am Projekt. Format: [Keep a Changelog](https://keepachangelog.c --- -## [0.0.0.4] — 2026-03-11 +## [0.0.0.4] — 2026-03-11 / 2026-03-12 + +### Hinzugefügt + +**Diagnostic Container — Selbstcheck-UI** +- Neuer Container `aria-diagnostic` mit Web-UI auf Port 3001 +- Status-Karten: OpenClaw Gateway, RVS, Claude Proxy — jeweils mit Dot-Indicator +- Claude Proxy Test: Prüft Erreichbarkeit (`/v1/models`) und sendet Test-Prompt an Claude +- Chat-Test: Nachrichten direkt über Gateway oder via RVS senden +- Tabbed Logs: Separate Tabs für Alle, Gateway, RVS, Proxy, Server — mit Zähler pro Tab +- Autoscroll-Pause: Automatisch wenn hochgescrollt, "Nach unten" Button zum Fortsetzen +- TLS Fallback für RVS-Verbindung (wie Bridge und App) ### Geändert **Bridge → aria-core: OpenClaw Gateway Protokoll** - Bridge nutzt jetzt das echte OpenClaw Gateway WebSocket-Protokoll (Port 18789 statt 8080) - Vollständiger Handshake: `connect.challenge` → `connect` Request (mit Auth-Token) → `hello-ok` -- Nachrichten über `chat.send` Method mit `sessionKey` und `idempotencyKey` +- Nachrichten über `chat.send` Method mit `message` und `idempotencyKey` - Antworten über `chat:final` Events (statt custom JSON) - Streaming-Support vorbereitet (`chat:delta` Events werden empfangen) - Fehlerbehandlung für `chat:error` Events — werden an die App weitergeleitet +- Client-ID: `gateway-client` / Mode: `backend` (OpenClaw akzeptiert nur bestimmte Werte) -**Docker-Compose Fixes** -- `OPENCLAW_GATEWAY_BIND=0.0.0.0` — Gateway bindet auf alle Interfaces (sonst nur 127.0.0.1, Bridge kann nicht zugreifen) -- `OPENCLAW_GATEWAY_TOKEN` statt `AUTH_TOKEN` — korrekter Env-Var-Name fuer OpenClaw Gateway Auth -- `ARIA_AUTH_TOKEN` an Bridge-Container durchgereicht — Bridge authentifiziert sich am Gateway +**Docker-Compose Überarbeitung** +- Bridge + Diagnostic nutzen `network_mode: "service:aria"` — teilen Netzwerk mit aria-core, kein separates Netz nötig +- `ANTHROPIC_API_KEY` + `ANTHROPIC_BASE_URL` — OpenClaw nutzt Anthropic-Provider, nicht OpenAI +- `DEFAULT_MODEL=claude-sonnet-4-6` — ohne `openai/` Prefix (Anthropic-Provider) +- `OPENCLAW_GATEWAY_TOKEN` statt `AUTH_TOKEN` — korrekter Env-Var-Name +- `ARIA_AUTH_TOKEN` an Bridge und Diagnostic durchgereicht +- Port 3001 auf aria-Service gemappt (für Diagnostic Web-UI) + +### Behoben + +- Handshake fehlgeschlagen `[object Object]` — Fehlermeldung wurde nicht korrekt stringifiziert +- `client.id` und `client.mode` im Connect-Request — OpenClaw akzeptiert nur vordefinierte Werte (`cli`, `gateway-client`, `webchat` etc.) +- `chat.send` nutzt `message` statt `text` als Parameter — OpenClaw Schema-Validierung --- diff --git a/README.md b/README.md index e4b01a5..a2b518a 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,10 @@ Ab da übernimmt ARIA. 😄 │ │ ↕ WebSocket zu aria-core (lokal) │ │ │ │ ↕ WebSocket zu RVS (öffentlich) │ │ │ │ Brücke: App ⟷ RVS ⟷ Bridge ⟷ ARIA │ │ +│ │ │ │ +│ │ [diagnostic] Selbstcheck Web-UI (Port 3001) │ │ +│ │ Gateway + RVS + Proxy Status │ │ +│ │ Chat-Test, Tabbed Logs │ │ │ └──────────────────┬──────────────────────────────┘ │ │ │ Volume Mount │ │ ▼ │ @@ -213,13 +217,16 @@ services: privileged: true # ARIAs Wohnung — sie hat die Schlüssel depends_on: - proxy + ports: + - "3001:3001" # Diagnostic Web-UI (laeuft im shared network) environment: - CANVAS_HOST=127.0.0.1 - - OPENCLAW_GATEWAY_BIND=0.0.0.0 # Bridge muss von Docker-Netz zugreifen - OPENCLAW_GATEWAY_TOKEN=${ARIA_AUTH_TOKEN} - OPENAI_API_KEY=not-needed - OPENAI_BASE_URL=http://proxy:3456/v1 - - DEFAULT_MODEL=openai/claude-sonnet-4-6 + - ANTHROPIC_API_KEY=not-needed + - ANTHROPIC_BASE_URL=http://proxy:3456 + - DEFAULT_MODEL=claude-sonnet-4-6 - RATE_LIMIT_PER_USER=30 - DISPLAY=:0 volumes: @@ -240,6 +247,7 @@ services: container_name: aria-bridge depends_on: - aria + network_mode: "service:aria" # Teilt Netzwerk mit aria-core → localhost:18789 volumes: - ./aria-data/voices:/voices:ro # TTS Stimmen - ./aria-data/config/aria.env:/config/aria.env @@ -257,8 +265,23 @@ services: - RVS_TLS_FALLBACK=${RVS_TLS_FALLBACK:-true} - RVS_TOKEN=${RVS_TOKEN:-} restart: unless-stopped - networks: - - aria-net + + # ─── Diagnostic (Selbstcheck-UI) ────────────────────── + diagnostic: + build: ./diagnostic + container_name: aria-diagnostic + depends_on: + - aria + network_mode: "service:aria" # Teilt Netzwerk mit aria-core → localhost:18789 + environment: + - ARIA_AUTH_TOKEN=${ARIA_AUTH_TOKEN:-} + - PROXY_URL=http://proxy:3456 + - RVS_HOST=${RVS_HOST:-} + - RVS_PORT=${RVS_PORT:-443} + - RVS_TLS=${RVS_TLS:-true} + - RVS_TLS_FALLBACK=${RVS_TLS_FALLBACK:-true} + - RVS_TOKEN=${RVS_TOKEN:-} + restart: unless-stopped networks: aria-net: @@ -697,6 +720,30 @@ cat aria-data/brain/memory/$(date +%Y-%m-%d).md --- +## Diagnostic — Selbstcheck-UI + +Web-Dashboard zur Diagnose aller ARIA-Verbindungen. Läuft auf **Port 3001** der ARIA-VM. + +``` +http://:3001 +``` + +**Status-Karten:** +- **OpenClaw Gateway** — Verbindung + Handshake Status, Reconnect-Button +- **RVS (Rendezvous)** — Verbindung mit TLS-Fallback, Reconnect-Button +- **Claude Proxy** — Erreichbarkeit + Test-Prompt an Claude (prüft ob Credentials gültig sind) + +**Chat-Test:** +- "Gateway senden" — Nachricht direkt an OpenClaw, Antwort wird angezeigt +- "Via RVS senden" — Nachricht über den Rendezvous-Server + +**Tabbed Logs:** +Separate Tabs mit Zähler: Alle | Gateway | RVS | Proxy | Server. Autoscroll pausiert automatisch beim Hochscrollen. + +> Der Diagnostic-Container teilt das Netzwerk mit aria-core (`network_mode: "service:aria"`), deshalb erreicht er den Gateway auf `localhost:18789` und den Proxy über das Docker-Netz. + +--- + ## Repo-Struktur ``` @@ -728,6 +775,12 @@ aria/ ← Gitea Repo — hier wird entwickelt │ ├── aria_bridge.py ← Wake-Word + Whisper STT + Piper TTS │ └── modes.py ← Betriebsmodi │ +├── diagnostic/ ← Selbstcheck Web-UI (Port 3001) +│ ├── Dockerfile +│ ├── server.js ← Gateway + RVS + Proxy Tests +│ ├── index.html ← Dashboard mit Tabs +│ └── package.json +│ ├── rvs/ ← Rendezvous-Server (Rechenzentrum) │ ├── docker-compose.yml ← eigenes Compose — separat deployen! │ ├── server.js ← WebSocket Relay — reiner Durchleiter diff --git a/diagnostic/index.html b/diagnostic/index.html index 91b9e1b..fb7234f 100644 --- a/diagnostic/index.html +++ b/diagnostic/index.html @@ -10,20 +10,22 @@ h1 { font-size: 20px; margin-bottom: 16px; color: #0096FF; } h2 { font-size: 14px; margin-bottom: 8px; color: #8888AA; text-transform: uppercase; letter-spacing: 1px; } - .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px; } + .grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; margin-bottom: 16px; } .card { background: #12122A; border: 1px solid #1E1E2E; border-radius: 8px; padding: 12px; } .card.full { grid-column: 1 / -1; } .status-row { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; } .dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; } .dot.connected { background: #34C759; box-shadow: 0 0 6px #34C759; } - .dot.connecting { background: #FFD60A; } + .dot.connecting, .dot.testing { background: #FFD60A; animation: pulse 1s infinite; } .dot.disconnected { background: #FF3B30; } .dot.error { background: #FF3B30; box-shadow: 0 0 6px #FF3B30; } .dot.not_configured { background: #555570; } + .dot.unknown { background: #555570; } + @keyframes pulse { 50% { opacity: 0.5; } } .status-label { font-size: 13px; } - .error-text { color: #FF6B6B; font-size: 11px; margin-top: 4px; } + .error-text { color: #FF6B6B; font-size: 11px; margin-top: 4px; word-break: break-all; } .btn { background: #0096FF; color: #fff; border: none; border-radius: 6px; padding: 8px 16px; font-family: inherit; font-size: 13px; cursor: pointer; margin: 4px 4px 4px 0; } @@ -32,12 +34,23 @@ .btn.secondary { background: #1E1E2E; border: 1px solid #333; } .btn.secondary:hover { background: #2A2A3E; } - .log-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; } - .log-header h2 { margin-bottom: 0; } + /* Tabs */ + .tab-bar { display: flex; gap: 2px; margin-bottom: 0; } + .tab-btn { background: #1E1E2E; color: #8888AA; border: 1px solid #1E1E2E; border-bottom: none; + border-radius: 6px 6px 0 0; padding: 6px 14px; font-family: inherit; font-size: 12px; + cursor: pointer; position: relative; top: 1px; } + .tab-btn.active { background: #080810; color: #E0E0F0; border-color: #1E1E2E; } + .tab-btn .tab-count { background: #333; color: #888; border-radius: 8px; padding: 1px 6px; + font-size: 10px; margin-left: 4px; } + + .log-header { display: flex; align-items: center; justify-content: space-between; padding: 6px 8px 4px; } + .log-header h2 { margin-bottom: 0; font-size: 12px; } .pause-hint { font-size: 11px; color: #FFD60A; display: none; } .pause-hint.visible { display: inline; } - .log-box { background: #080810; border: 1px solid #1E1E2E; border-radius: 6px; - height: 300px; overflow-y: auto; padding: 8px; font-size: 11px; line-height: 1.6; position: relative; } + + .log-panel { background: #080810; border: 1px solid #1E1E2E; border-radius: 0 0 6px 6px; } + .log-box { height: 280px; overflow-y: auto; padding: 8px; font-size: 11px; line-height: 1.6; } + .log-box.hidden { display: none; } .log-entry { white-space: pre-wrap; word-break: break-all; } .log-entry.error { color: #FF6B6B; } .log-entry.warn { color: #FFD60A; } @@ -81,6 +94,16 @@
+ +
+

Claude Proxy

+
+
+ Nicht getestet +
+
+ +
@@ -96,47 +119,108 @@ - -
-
-

Verbindungslog

- - Autoscroll pausiert - - + +
+
+
+ + + + + +
+
+
+
+ + Autoscroll pausiert + + +
+
+ + + +
-