Tools
Fyos Agent
FYOS agent foundation: an OpenClaw mod (image, version-bound patches, behaviour plugins, workspace templates) for FYOS - For Your Own Sake.
README
English: [README.en.md](README.en.md)
# fyos-agent
Die Grundlage der Distribution **FYOS — For Your Own Sake**: das Agentenverhalten als
OpenClaw-Mod, ohne persönliche Inhalte. Kein Quell-Fork: ein Bild auf dem Upstream-Bild von
OpenClaw (per Digest festgenagelt), versionsgebundene Patches, Verhaltens-Plugins,
Workspace-Vorlagen, Verhaltensvertrag und Skills.
## Schichten
```text
fyos.yaml ──► fyos_agent/render.py ──► workspace/{AGENTS,SOUL,IDENTITY,USER}.md (+ BOOTSTRAP.md bei der Ersteinrichtung)
openclaw.json (Gateway-Konfiguration)
openclaw/ Dockerfile, einstieg.sh, patches/ (Hash-geprüfte Eingriffe in das Upstream-Bild)
plugins/ fyos-prioritaet, fyos-freigabe-chat, fyos-meldebudget, fyos-kontext-edit,
fyos-speed-router, fyos-bruecke, fyos-ersteinrichtung (Image: /opt/fyos/<id>)
vertrag/ Verhaltensvertrag (Markdown) + betriebskonzept.yaml + freigabe_vertrag.json
workspace/ *.md.tmpl config/openclaw.json5.tmpl Vorlagen mit {{platzhaltern}}
skills/ betriebskonzept, freigabe (OpenClaw-Skills, SKILL.md; im Bild /opt/fyos/skills, skills.load.extraDirs)
tools/ sauber.py (Sauberkeitsprüfung, siehe .sauber/)
```
Das Verhalten steht in drei Formen, die einander nicht widersprechen dürfen: Prosa
(`vertrag/`), Anweisung an das Modell (`workspace/`) und Durchsetzung unter dem Modell
(`plugins/`). Die Grenze liegt unter dem Modell, nicht in einem Prompt.
## Schnellstart
```sh
# 1. Konfiguration anlegen
cp fyos.example.yaml fyos.yaml # Name, Besitzer, Sprache, Grenzen, Fähigkeiten anpassen
# 2. Bild bauen (aus der Repo-Wurzel)
docker build -f openclaw/Dockerfile -t fyos-agent .
# 3. Starten (Gateway auf 18789; die Shell reicht /agent unverändert durch)
docker run --rm -p 18789:18789 \
-v "$PWD/fyos.yaml:/etc/fyos/fyos.yaml:ro" \
-e FYOS_MODELL_BASIS_URL=http://modell:8080/v1 \
-e FYOS_MODELL_NAME=mein-modell \
-e FYOS_MODELL_SCHLUESSEL=geheim \
-e FYOS_HUB_URL=http://hub:8080/mcp/ \
-e OPENCLAW_GATEWAY_TOKEN="$(openssl rand -hex 24)" \
fyos-agent
```
Startzeile im Bild: `ENTRYPOINT tini -- /opt/fyos/einstieg.sh`, `CMD openclaw gateway --bind lan --port 18789`.
`einstieg.sh` rendert beim Start die Vorlagen nach `~/.openclaw` (Workspace-Dateien und
`openclaw.json`; eine vorhandene Konfiguration wird als `openclaw.json.vorher` gesichert,
`FYOS_KONFIG_BEHALTEN=1` lässt sie unberührt) und reicht dann an den Upstream-Einstieg weiter.
AGENTS.md und SOUL.md schreibt jeder Start neu; USER.md und IDENTITY.md nur, solange sie noch so aussehen,
wie der Start sie zuletzt schrieb (siehe „Ersteinrichtung als Gespräch“).
| Umgebung | Bedeutung |
|---|---|
| `FYOS_CONFIG` | Pfad zu `fyos.yaml` (Vorgabe `/etc/fyos/fyos.yaml`; ohne Datei gelten die Vorgaben) |
| `FYOS_MODELL_BASIS_URL`, `FYOS_MODELL_NAME`, `FYOS_MODELL_SCHLUESSEL` | Modell als OpenAI-kompatibler Anbieter (siehe Abschnitt „Modell“) |
| `FYOS_HUB_URL` | MCP-Endpunkt des Hubs; ohne `/mcp` auch das Ziel der Ereignisse von `fyos-bruecke` |
| `OPENCLAW_GATEWAY_TOKEN` | Anmeldung am Gateway (Token); signiert auch die Ereignisse an den Hub |
| `FYOS_OEFFENTLICH_URL` | Öffentliche Adresse der Installation (wie für Hub und Shell); ohne `gateway.oeffentliche_url` in `fyos.yaml` der erlaubte Ursprung der Control UI |
| `FYOS_VORGAENGE_URL` | optional: Vorgangs-Dienst für `fyos-freigabe-chat` |
| `FYOS_MATRIX_HOMESERVER`, `FYOS_MATRIX_BENUTZER`, `OPENCLAW_MATRIX_TOKEN`, `FYOS_APPROVER_MATRIX_ID` | optional: Matrix-Kanal (`kanaele.matrix: true`; Bild mit `--build-arg FYOS_KANAELE=matrix` bauen) |
| `OPENCLAW_TELEGRAM_TOKEN`, `FYOS_APPROVER_TELEGRAM_ID` | optional: Telegram-Kanal (`kanaele.telegram: true`; Bot-Token und numerische Besitzer-ID, siehe Abschnitt „Telegram“; steckt schon im Basisbild, kein Build-Argument) |
Nur rendern, ohne Docker:
```sh
FYOS_MODELL_BASIS_URL=http://modell:8080/v1 FYOS_MODELL_NAME=m FYOS_HUB_URL=http://hub:8080/mcp/ \
python3 -m fyos_agent.render --config fyos.example.yaml --ziel /tmp/fyos-ziel
```
Gateway hinter der FYOS-Shell: nginx leitet `/agent` und `/agent/*` unverändert (ohne
Präfix-Strip, mit WebSocket-Upgrade) an `http://agent:18789`. Dafür steht in der Konfiguration
`gateway.controlUi.basePath = "/agent"`, Anmeldung per Token (`OPENCLAW_GATEWAY_TOKEN`).
Die Shell streicht dabei alle Herkunftsköpfe (`Forwarded`, `X-Real-IP`, `X-Forwarded-*`): das Gateway
sieht sie als Absender und verlangt die Anmeldung wie bei jedem entfernten Gerät. Weiterleitungs-Köpfe
glaubt es nur einem Vorsatz unter `gateway.vertrauenswuerdige_proxys`, und auch dem nur, wenn er sie
überschreibt statt anhängt; sonst antwortet es mit 403 `proxy_attribution_required`. Die Einbettung
im Fenster der Shell erlaubt deren nginx (OpenClaw selbst verbietet sie). Der Browser-Ursprung muss
erlaubt sein: `gateway.oeffentliche_url`, ohne Angabe `FYOS_OEFFENTLICH_URL`, sonst meldet die
Control UI „origin not allowed“. Von selbst lässt OpenClaw nur `*.local`, `*.ts.net` und private
Adressen mit gleichem Host herein. Der Renderer schreibt die Adresse so in die Allowlist, wie der
Browser den Origin schickt (klein, ohne Pfad und Standardport). Als `gateway.publicOrigin` setzt er sie
nur bei `https` oder `http` auf localhost/Loopback, denn jede andere http-Adresse lehnt OpenClaws
Konfigurationsprüfung ab und das Gateway startet nicht. Eine LAN-Adresse wie `http://fyos.lan:8080`
bleibt also erlaubter Ursprung, aber ohne `publicOrigin`.
## Modell
Das Modell kommt über `FYOS_MODELL_BASIS_URL`, `FYOS_MODELL_NAME` und `FYOS_MODELL_SCHLUESSEL` als
OpenAI-kompatibler Anbieter: ein eigener Server oder ein Cloud-Anbieter. Cloud-Modelle werden nur mit dem
API-Schlüssel des Anbieters angebunden. Die Anmeldung mit einem Abo wie Claude Pro oder Max ist laut Anthropic <!-- sauber: ok -->
für Claude Code und andere eigene Anthropic-Apps gedacht; Anwendungen Dritter sollen per API-Schlüssel
(Claude Console oder unterstützter Cloud-Anbieter) auf Claude zugreifen und weder Abo-Anmeldungen anbieten noch
Anfragen über Abo-Zugangsdaten leiten (Quelle: [Legal and compliance, Abschnitt „Authentication and credential
use“](https://code.claude.com/docs/en/legal-and-compliance#authentication-and-credential-use)).
## Telegram
Telegram ist ein zweiter Kanal neben Matrix und steckt schon im Basisbild von OpenClaw: anders als bei
Matrix braucht das Bild kein Build-Argument. Vorgabe: aus. Mit `kanaele.telegram: true` schreibt der Renderer
einen Kanal, der nur Direktnachrichten des Besitzers annimmt: `dmPolicy: allowlist` mit genau dessen
numerischer ID (kein Pairing, niemand schaltet sich selbst frei), `groupPolicy: disabled` (der Bot reagiert in
keiner Gruppe) und `configWrites: false` (der Kanal darf die Konfiguration nicht ändern). Bot-Token und
Besitzer-ID stehen nie in `fyos.yaml`, nur in der Umgebung; fehlt eine oder ist sie ungültig, bricht das
Rendern mit einer Meldung ab, die den Namen der Variable nennt und nie ihren Wert. Matrix und Telegram lassen
sich einzeln oder zusammen einschalten.
Einrichten:
1. Bei [@BotFather](https://t.me/BotFather) mit `/newbot` einen Bot anlegen und den Token kopieren. Mit
`/setjoingroups` auf „Disable“ lässt sich der Bot außerdem gar nicht erst in Gruppen einladen.
2. Token als `OPENCLAW_TELEGRAM_TOKEN` setzen.
3. Die numerische Telegram-ID des Besitzers herausfinden (der @-Name genügt nicht): dem Bot eine Nachricht
schreiben und, solange das Gateway den Bot noch nicht abfragt (die Bot-API erlaubt nur eine Abfrage
gleichzeitig), `curl "https://api.telegram.org/bot${OPENCLAW_TELEGRAM_TOKEN}/getUpdates"` aufrufen. Die ID
steht in der Antwort unter `message.from.id`.
4. Die ID als `FYOS_APPROVER_TELEGRAM_ID` setzen (nur Ziffern), in `fyos.yaml` `kanaele: {telegram: true}`
eintragen und das Gateway (neu) starten.
5. Dem Bot einmal schreiben: Telegram lässt einen Bot erst dann dem Besitzer schreiben.
Freigaben laufen auch über Telegram. Native Freigaben des Agenten kommen als Nachricht mit Knöpfen in die
Direktnachricht (`approvals.plugin.targets`, Knöpfe nur in Direktnachrichten). Mit `fyos-freigabe-chat` geht eine
Anfrage des Vorgangs-Dienstes zusätzlich als reine Textnachricht an Telegram, und die Antwort des Besitzers
(`genehmigt CHG-42`, `abgelehnt CHG-42`, `kommentar CHG-42: …`) entscheidet wie in Matrix ohne Modellaufruf; es
genügt, wenn ein Kanal zustellt. Die Reaktions-Knöpfe sind eine Matrix-Eigenheit und fehlen in Telegram.
## Ersteinrichtung als Gespräch
Beim ersten Gespräch einer frischen Installation lernt der Agent den Besitzer kennen, statt dass alles vorab in
`fyos.yaml` stehen muss: Er stellt in einer einzigen Nachricht ein paar Fragen (Anrede oder Name, Sprache,
Zeitzone, wofür er da sein soll, zusätzliche Grenzen, Name des Agenten), jede mit einem Vorschlag aus der
Konfiguration, sodass „passt so“ genügt. Aus den Antworten füllt er USER.md und IDENTITY.md; danach endet das
Ritual und wiederholt sich nicht. Beginnt der Besitzer gleich mit einer Aufgabe, kommt sie zuerst; will er die
Fragen nicht beantworten, gelten die Vorschläge. Schalter: `faehigkeiten.ersteinrichtung` (Vorgabe `true`;
`false` lässt USER.md und IDENTITY.md wie bisher aus `fyos.yaml` entstehen).
So läuft es:
- Beim Start entscheidet der Renderer (`fyos_agent/einrichtung.py`), ob die Einrichtung offen ist: nur bei einer
frischen Installation (noch kein Zustand, kein USER.md im Workspace) und eingeschaltetem Schalter. Eine
bestehende Installation bleibt, wie sie ist; dort hat OpenClaw die Einrichtung längst als erledigt vermerkt.
Der Zustand steht in `~/.openclaw/fyos-agent-zustand.json`.
- Offen heißt: `BOOTSTRAP.md` (das Gespräch) liegt im Workspace, `agents.defaults.skipBootstrap` ist an (OpenClaw
legt dann weder eigene Starterdateien an noch vermerkt es die Einrichtung selbst als erledigt und löscht die
Datei) und das Plugin `fyos-ersteinrichtung` ist an. Es liefert das Werkzeug `fyos_ersteinrichtung`, denn der
Agent hat sonst kein Schreibwerkzeug.
... (truncated)
tools
Comments
Sign in to leave a comment