Files
ARIA-AGENT/host-agent
duffyduckandClaude Opus 5 443b36bb9d fix(android-agent): Sprachausgabe meldet erst Erfolg, wenn wirklich Ton laeuft
Der Agent meldete "gesprochen", sobald die TTS-Anfrage im Socket lag. Ob sie
ueberhaupt rausging, ob der Server antwortete oder ob ein einziger Ton kam,
hat nie jemand geprueft. Auf dem Fire TV blieb es damit still, waehrend ARIA
"erledigt" sagte — ein Fehler, der sich nicht melden kann.

Drei Ursachen:
- OkHttps send() WIRFT NICHT, sondern gibt false zurueck, wenn die Verbindung
  zu ist. Der Rueckgabewert wurde verworfen: Senden ins Leere sah aus wie
  Erfolg. send() gibt das jetzt durch, requestTts wirft bei abgelehntem Senden.
- Niemand wartete auf Audio. Neu: awaitSpeechStart() wartet, bis fuer diese
  messageId wirklich Ton laeuft, sonst Fehler mit Grund.
- Warten darf NICHT im WS-Lese-Thread passieren: handle() laeuft dort, und das
  erwartete audio_pcm kommt ueber genau diese Verbindung — wir haetten uns
  selbst ausgehungert. speak/notify laufen jetzt in einem eigenen Thread und
  schicken ihr host_result von dort.

Brain-seitig haben speak/notify 40s statt 20s Zeit, damit die ehrliche Antwort
(TTS-Render + Uebertragung) nicht in den Timeout laeuft.

APK baut durch (Gradle, nur die zwei bekannten Deprecation-Warnungen).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-03 10:17:48 +02:00
..
2026-10-03 10:16:20 +02:00

ARIA Host-Agent

Ein schlanker Agent, der direkt auf einem Rechner läuft und ARIA erlaubt, diesen Rechner zu steuern — auch wenn er sonst aus dem Netz nicht erreichbar ist (hinter NAT/Firewall, kein offener Port). Der Agent verbindet sich ausgehend zum RVS (gleicher Token wie der Rest von ARIA).

Unterschied zum Satelliten: der Satellit entdeckt und steuert andere Geräte in einem LAN; der Host-Agent steuert den Rechner, auf dem er läuft.

Fähigkeiten

Aktion Was
exec Shell-Kommando ausführen (optional sudo), stdout/stderr/exit
read Datei lesen (Base64, mit Offset/Limit)
write Datei schreiben/anhängen (Base64 oder Text)
info OS, CPU/RAM/Disk-Auslastung, Uptime, IP, gui-Methode
screenshot Bildschirmfoto (X11: scrot/maim · Wayland: grim)
ui_tap Mausklick auf x,y (button/double optional) (nur mit GUI)
ui_text Text ins fokussierte Feld tippen (nur mit GUI)
ui_key Taste/Kombi (Return, Escape, ctrl+c …) (nur mit GUI)
ui_swipe Maus ziehen x1,y1 → x2,y2 (nur mit GUI)
app_launch App/Programm starten (app/query oder command) (nur mit GUI)

ARIA nutzt diese über die Brain-Tools host_list/host_exec/host_read/ host_write/host_info/host_screenshot sowie host_ui_tap/host_ui_text/ host_ui_key/host_ui_swipe/host_app_launch (dieselben Tools wie beim Android-Agenten — ein Werkzeugset für Handy und Rechner).

GUI-Steuerung ist capability-gated. Der Agent meldet die ui_*/app_launch- Fähigkeiten in seinen caps nur, wenn eine grafische Session da ist — ein reiner Terminal-/Server-Linux (kein DISPLAY/WAYLAND_DISPLAY) bekommt sie nicht (dort bleibt es bei exec & Co.). ARIA arbeitet mit dem Screenshot als Augen (voller Auflösung = echte Pixel; auf dem Desktop gibt es kein ui_dump).

Nötige Helfer je System: Linux/X11 → xdotool; Linux/Wayland → ydotool (Daemon, meist root); macOS → Text/Tasten via Bordmittel (osascript), Maus via cliclick (brew install cliclick); Windows → Bordmittel (PowerShell). HiDPI/Retina-Hinweis: Screenshot-Pixel können 2× der Klick-Koordinaten sein — bei Fehlklicks Koordinaten halbieren.

Plattformen

Eine Codebasis, läuft auf Linux, macOS und Windows (der Agent wählt Shell, Screenshot-Methode und Root/Admin-Check je OS automatisch):

exec Root/Admin Screenshot GUI-Steuerung (ui_*)
Linux bash -lc sudo (SUDO_PASSWORD/SUDO_NOPASSWD) / root grim (Wayland) · scrot/maim (X11) xdotool (X11) · ydotool (Wayland)
macOS bash -lc sudo (wie Linux) screencapture (Bordmittel) osascript (Text/Tasten) · cliclick (Maus)
Windows PowerShell Agent als Administrator starten (kein sudo) PowerShell/System.Drawing (Bordmittel) PowerShell (Bordmittel)

PyInstaller kann nicht cross-kompilieren — jede Binary wird auf ihrem OS gebaut.

Bauen

Linux (portabel, empfohlen) — Docker-Container mit altem glibc:

./build.sh          # -> dist/aria-host-agent  (~15 MB, läuft auf vielen Distros)

Linux/macOS ohne Docker — PyInstaller direkt (linkt gegen lokales glibc/OS):

./build-native.sh   # -> dist/aria-host-agent

Windows — nativ (auf einem Windows-Rechner, Python 3 im PATH nötig):

build-native.bat    REM -> dist\aria-host-agent.exe

Windows — aus Docker heraus (auf Linux!), inkl. Installer — Wine baut die .exe, NSIS packt ein setup.exe, das den Agent als Windows-Dienst einrichtet:

./build-win.sh [version]
#  -> dist/aria-host-agent.exe        (Konsolen-Binary)
#  -> dist/aria-host-agent-setup.exe  (Installer: Dienst + .env in ProgramData)

Der erste Lauf zieht das tobix/pywine-Image (~1–2 GB) und richtet die Wine- Python-Umgebung ein — das dauert; Folge-Builds sind schnell. PyInstaller kann nicht cross-compilen, deshalb der Wine-Umweg. macOS geht so NICHT (Apple lässt sich nicht legal aus Docker bauen) — dort ./build-native.sh auf einem Mac.

Docker scheitert? (Live-ISO / overlayfs-Root)

Wenn build.sh mit failed to mount … overlayfs … invalid argument abbricht, läufst du wahrscheinlich auf einem Live-System (Live-ISO). Dessen Root ist selbst ein overlayfs, und Dockers overlay2-Treiber kann kein Overlay-auf- Overlay stapeln. Zwei Auswege:

  • Empfohlen: Binary auf einem normal installierten Linux bauen (./build.sh) und nur die fertige dist/aria-host-agent aufs Live-System kopieren. Die Binary ist portabel — Ziel braucht weder Docker noch Python.
  • Nativ bauen (ohne Docker):
    sudo apt install -y python3-pip python3-venv
    ./build-native.sh
    
    Achtung: nativ gebaut linkt die Binary gegen das glibc dieser Maschine — sie läuft dann nur auf Systemen mit gleichem oder neuerem glibc.

Installieren

  1. dist/aria-host-agent auf den Ziel-Rechner kopieren.
  2. .env.example → .env daneben, RVS-Zugang + CONTROL_ENABLED=true eintragen.
  3. Starten: chmod +x aria-host-agent && ./aria-host-agent

Als systemd-Dienst (empfohlen für Dauerbetrieb)

Der Installer kopiert Binary + .env an ihre Plätze und richtet den Dienst ein:

# .env-Pfad direkt übergeben:
sudo ./install-service.sh /pfad/zur/.env

# ODER ohne Argument -> ncurses-Dateidialog (dialog) zum Auswählen der .env:
sudo ./install-service.sh

Er legt ab:

  • Binary → /usr/local/bin/aria-host-agent
  • .env → /etc/aria-host-agent/.env (Rechte 0600, enthält Token/Passwörter)
  • Unit → /etc/systemd/system/aria-host-agent.service, dann enable --now.

Danach: systemctl status aria-host-agent · journalctl -u aria-host-agent -f. Die Binary sucht er unter dist/aria-host-agent bzw. ./aria-host-agent (oder 2. Argument). Braucht dialog für den Dateibrowser (bietet die Installation an).

Windows-Dienst (setup.exe)

aria-host-agent-setup.exe (aus build-win.sh oder dem Gitea-Release) als Administrator ausführen. Der Installer:

  • kopiert die .exe nach %ProgramFiles%\ARIA Host-Agent,
  • legt %ProgramData%\ARIA-Host-Agent\.env an (nur falls noch keine da ist),
  • richtet über nssm den Dienst ARIA Host-Agent ein (Autostart) und startet ihn.

Danach die .env unter %ProgramData%\ARIA-Host-Agent\ mit RVS-Zugang + CONTROL_ENABLED=true füllen und den Dienst neu starten (services.msc → ARIA Host-Agent, oder nssm restart ARIAHostAgent). Deinstallation über Apps & Features → ARIA Host-Agent (die .env in ProgramData bleibt erhalten).

Release (Binaries als Gitea-Assets)

release_agent.sh <version> baut alles Docker-Baubare und hängt es als Release-Asset an den Tag agent-v<version> — nichts landet im Git-Tree:

./release_agent.sh 0.2.0                 # Linux + Android + Windows (Wine)
SKIP_WINDOWS=1 ./release_agent.sh 0.2.0  # ohne Windows (schneller)

Assets: aria-host-agent-linux-x64, aria-host-agent-android-agent-v<v>.apk, aria-host-agent-windows.exe, aria-host-agent-windows-setup.exe. macOS ist nicht Docker-baubar — auf einem Mac ./build-native.sh laufen lassen und das Ergebnis vor dem Release nach dist/aria-host-agent-macos legen, dann nimmt das Skript es automatisch mit. Gitea-Zugang via .env/Umgebung (GITEA_URL, GITEA_REPO, GITEA_USER), Kennwort wird abgefragt.

TLS / SNI — Agent im selben Netz wie der RVS

Steht der Rechner im selben Netz wie der RVS (z.B. Rechenzentrum) und soll direkt auf dessen interne IP verbinden (kein NAT-Hairpin über den externen Hostnamen), scheitert der TLS-Handshake sonst an tlsv1 alert internal error (Caddy hat kein Zertifikat für die IP). Lösung — in der .env:

RVS_HOST=10.0.0.2            # interne RVS-IP
RVS_SNI=example.com    # Name, für den das Caddy-Zert gilt

Der Agent verbindet dann auf die IP, präsentiert aber den Namen im TLS-SNI. Zuhause / im Normalfall RVS_SNI leer lassen und den Hostnamen als RVS_HOST.

sudo

Vier Fälle, der Agent wählt automatisch:

  1. Agent läuft als root (z.B. systemd User=root) → volle Rechte, kein sudo nötig.
  2. SUDO_PASSWORD=… in der .env → sudo -S mit Passwort.
  3. SUDO_NOPASSWD=true → sudo -n (Live-ISO / passwortloses sudo, z.B. Linux Mint vom Stick).
  4. sonst → sudo-Kommandos scheitern mit klarer Meldung.

Sicherheit

  • Reagiert nur auf den eigenen RVS-Raum (Token) und nur, wenn CONTROL_ENABLED=true.
  • Keine offenen Ports (reiner ausgehender Client).
  • Alle Kommandos werden geloggt.
  • Der Agent gibt vollen Zugriff auf den Rechner — nur auf Maschinen einsetzen, denen du ARIA anvertraust.

Hinweis Screenshot

Als Systemdienst fehlt die grafische Session. Für screenshot den Agent in der Desktop-Session starten (Autostart) oder DISPLAY/XAUTHORITY in der Unit setzen.