diff --git a/omos/README.md b/omos/README.md new file mode 100644 index 0000000..86e946a --- /dev/null +++ b/omos/README.md @@ -0,0 +1,146 @@ +# omos + +Adapter zwischen APM-Packages mit Team-Profil und [oh-my-opencode-slim](https://github.com/alvinunreal/oh-my-opencode-slim). + +`omos` liest eine `team-profile.yaml` aus einem APM-Package, löst abstrakte Modellklassen gegen deine lokale Mapping-Tabelle auf und generiert ein namespacetes oh-my-opencode-slim-Preset. Deterministisch – `omos` rät nicht. + +``` +APM-Package Nutzer Runtime +team-profile.yaml + model-mapping.yaml → omos render → .opencode/ +(Rollen, Modell- (Modellklasse → oh-my-opencode-slim.json + klassen, MCPs/Skills) konkrete Modell-ID) +``` + +## Voraussetzungen + +- Python 3.10+ mit PyYAML (`pip install pyyaml`) +- OpenCode mit installiertem Plugin [oh-my-opencode-slim](https://ohmyopencodeslim.com/) +- Ein APM-Package mit `team-profile.yaml` + +## Schnellstart + +```bash +# 1. Modell-Mapping einmalig anlegen +mkdir -p ~/.config/apm-team +cp examples/model-mapping.yaml ~/.config/apm-team/model-mapping.yaml +$EDITOR ~/.config/apm-team/model-mapping.yaml # an eigene Modelle anpassen + +# 2. Validieren (Dry-Run) +python3 omos.py check --package examples/package + +# 3. Rendern +cd +python3 /pfad/zu/omos.py render --package /pfad/zum/package + +# 4. Aktivieren +opencode # Projekt-Config wird geladen +/preset acme-job-applications +# Reload OpenCode → Team aktiv (by Design: kein Hot-Swap) +``` + +## Die drei Dateien + +| Datei | Gehört | Zweck | Manuell editieren? | +|---|---|---|---| +| `team-profile.yaml` | Package-Autor | Rollen, Modellklassen, MCP-/Skill-Allowlists pro Rolle | Ja (Autor) | +| `~/.config/apm-team/model-mapping.yaml` | Nutzer | Modellklasse → konkrete Modell-ID (+ optional variant/temperature) | Ja (Nutzer) | +| `.opencode/oh-my-opencode-slim.json` | generiert | OMOS-Preset mit konkreten Modell-IDs | **Nein** – immer neu rendern | + +Dazu eine Provenance-Datei `.opencode/oh-my-opencode-slim.omos-provenance.json`, die dokumentiert, welche Rolle welches Modell erhalten hat. + +## Kommandoreferenz + +```bash +python3 omos.py render --package DIR [--mapping FILE] [--output FILE] [--dry-run] +python3 omos.py check --package DIR [--mapping FILE] +``` + +| Option | Default | Bedeutung | +|---|---|---| +| `--package` | `.` | APM-Package-Verzeichnis mit `team-profile.yaml` | +| `--mapping` | `~/.config/apm-team/model-mapping.yaml` | Lokale Mapping-Tabelle | +| `--output` | `/.opencode/oh-my-opencode-slim.json` | Zieldatei | +| `--team-file` | `team-profile.yaml` (alternativ `team.yaml`) | Alternativer Profilname | + +**Merge-Verhalten:** Existierende Presets in der Zieldatei bleiben unberührt; nur das Preset der Team-ID wird ersetzt. Mehrere Packages koexistieren damit im selben Projekt. Aktiviert wird explizit per `/preset `. + +## Team-Profil-Schema (`corentic.team-profile/v1`) + +```yaml +schema: corentic.team-profile/v1 +id: acme.job-applications # wird zum Preset-Namen (namespaced) +description: ... + +roles: + - id: researcher # fachliche Rolle + purpose: ... # wird zu Prompt/Description für Custom Agents + omos_agent: librarian # optional: OMOS-Builtin oder 'custom' + # (Default: role-id als Custom Agent) + model_class: fast-research # Pflicht, muss im Mapping existieren + capabilities: + mcps: [websearch, openviking] # MCP-Allowlist ([] = keine) + skills: [job-application] # Skill-Allowlist ([] = keine) +``` + +Erkannte OMOS-Builtins: `orchestrator`, `oracle`, `librarian`, `explorer`, `fixer`, `designer`, `council`, `observer`. Alles andere (oder `omos_agent: custom`) erzeugt einen Custom Agent inklusive `prompt` und `orchestratorPrompt` aus dem `purpose`-Feld. + +### Mapping-Formate + +```yaml +model_classes: + fast-research: ollama/qwen3.5:9b # einfach + high-reasoning: # erweitert + model: ollama/qwen3.6:35b-a3b-q4_K_M + variant: thinking + temperature: 0.3 +``` + +Alle Zusatzfelder werden 1:1 in den Agent-Eintrag des Presets übernommen. + +## Was omos prüft + +1. Team-Profil vorhanden, Schema bekannt, `id` und `roles` vorhanden +2. Jede `model_class` hat einen Mapping-Eintrag (sonst Fehler mit Lösungshinweis) +3. MCPs gegen `~/.config/opencode/opencode.json(c)` abgleichen (**Warnung**, kein Abbruch) +4. Rollen ohne MCPs/Skills → Hinweis + +`omos` nimmt keine Verfügbarkeit an und wählt keine Modelle automatisch aus. Fehlt ein Mapping, bricht das Rendern mit konkreter Ursache ab. + +## Walkthrough mit dem Beispiel-Package + +```bash +cd omos/examples + +# Trockenlauf: was würde generiert? +python3 ../omos.py check --package package --mapping model-mapping.yaml + +# Rendern in das Beispiel-Projekt +python3 ../omos.py render --package package \ + --mapping model-mapping.yaml \ + --output package/.opencode/oh-my-opencode-slim.json +``` + +Erwartetes Ergebnis: Preset `acme-job-applications` mit fünf Agenten – `orchestrator`, `librarian` (Alias `researcher`), Custom Agent `writer`, `oracle` (Alias `checker`), Custom Agent `notifier`. Der Researcher erhält keinen LaTeX-Zugang, der Writer keine Job-Suchtools, der Notifier gar keine externen Zugriffe. + +Danach: + +```bash +cd package && opencode +/preset acme-job-applications +``` + +## Troubleshooting + +| Problem | Ursache/Lösung | +|---|---| +| `Modellklasse X ist nicht gemappt` | Mapping ergänzen, erneut rendern | +| `Warnung: MCP ... nicht konfiguriert` | MCP in `opencode.jsonc` einrichten oder aus dem Profil entfernen | +| `/preset` zeigt nichts Neues | OpenCode nach dem Render neu laden; Preset greift nicht mid-session | +| Preset weg nach manuellem Editieren | Datei ist generiert – Änderungen gehören ins Mapping oder Team-Profil | +| YAML-Fehler | Zeilenangabe aus der Fehlermeldung folgen | + +## Grenzen (bewusst) + +- `omos` startet keine Agenten und orchestriert nichts zur Laufzeit – das macht oh-my-opencode-slim. +- MCP-/Skill-Allowlists sind Capability Scoping, keine Sandbox. Irreversible Aktionen brauchen serverseitige Autorisierung + Human Approval. +- Die Modellverfügbarkeit wird gegen die opencode.jsonc-Namen geprüft, nicht per API-Healthcheck.