APM-Packages/omos-deep-dive.md

257 lines
8.9 KiB
Markdown
Raw Permalink Normal View History

# Was oh-my-opencode-slim wirklich kann und was `omos` daraus machen sollte
*Von Modell-IDs bis Sandboxing: Die OMOS-Konfiguration ist mächtiger, als man denkt.*
Im ersten Teil haben wir beschrieben, wie ein APM-Package sein empfohlenes Team deklarieren kann. Dort haben wir `omos` als Übersetzer zwischen `team-profile.yaml` und OMOS-Presets vorgestellt und dabei nur zwei Konfigurationsflächen genutzt: Modell-IDs und MCP/Skill-Allowlists.
Das war bewusst minimal. Aber OMOS kann deutlich mehr. Und `omos` sollte das nutzen.
## Was OMOS alles kann
Die vollständige Konfiguration von oh-my-opencode-slim geht weit über Presets hinaus. Hier die wichtigsten Features, die für Team-Pakete relevant sind:
### Custom Agents mit eigenen Prompts
OMOS kann unter `agents` eigene Subagenten definieren. Jeder braucht ein `model`, einen `prompt` und optional einen `orchestratorPrompt`, der dem Orchestrator sagt, wann er delegieren soll:
```jsonc
{
"agents": {
"writer": {
"model": "ollama/qwen3.6:35b-a3b-q4_K_M",
"prompt": "Erstelle faktenbasierte Bewerbungsunterlagen. "
+ "Nutze nur freigegebene Profilfakten. "
+ "Erfinde keine Erfahrung. "
+ "Lege Entwürfe in ShareLaTeX ab. "
+ "Reiche niemals eine Bewerbung ein.",
"orchestratorPrompt": "@writer\n"
+ "- Rolle: Anschreiben und CV-Anpassungen erstellen\n"
+ "- Delegiere nach qualifiziertem Stellen-Match\n"
+ "- Liefere einen ShareLaTeX-Entwurf und offene Fragen"
}
}
}
```
Der `orchestratorPrompt` ist der Schlüssel: Er wird direkt in den Orchestrator-Prompt injiziert und bestimmt, **wann** der Orchestrator diesen Agenten aufruft. Ohne ihn weiß der Orchestrator nicht, dass es den Agenten gibt.
### Tool-Permissions: Echte Sandboxing
OMOS bietet pro Agent ein `permission`-Objekt, das auf Tool-Ebene durchgesetzt wird nicht nur MCP-Allowlists, sondern auch OpenCode-Core-Tools:
```jsonc
{
"agents": {
"researcher": {
"model": "ollama/qwen3.5:9b",
"permission": {
"edit": "deny",
"bash": "deny",
"task": "deny",
"webfetch": "allow",
"websearch": "allow"
}
}
}
}
```
Das ist eine **echte Sandbox**. Der Researcher darf suchen und lesen, aber keine Dateien bearbeiten, keine Shell-Befehle ausführen und keine Subagenten spawnen. Das geht über `mcps` und `skills` hinaus und ist das, was wir im ersten Blogpost als „mehrere Schichten der Verteidigung" beschrieben haben.
Verfügbare Permission-Keys:
| Key | Was es kontrolliert |
|-----|-------------------|
| `read` | Dateien lesen |
| `edit` | Dateien bearbeiten |
| `bash` | Shell-Befehle ausführen |
| `task` | Subagenten delegieren |
| `webfetch` | Web-Inhalte abrufen |
| `websearch` | Websuche |
| `glob` | Dateisuche nach Pattern |
| `grep` | Inhaltsuche |
| `skill` | Skill-Ausführung |
Jeder Key akzeptiert `"allow"`, `"deny"` oder `"ask"` (fragt den Nutzer). Für `bash` gibt es zusätzlich Pattern-basierte Regeln:
```jsonc
"bash": {
"*": "deny",
"git status*": "allow",
"git diff*": "allow"
}
```
### Fallback-Ketten
OMOS unterstützt Modell-Failover bei 429-Errors (Rate Limiting). In der Mapping-Tabelle könnte man das so abbilden:
```yaml
# ~/.config/apm-team/model-mapping.yaml
model_classes:
fast-research:
primary: ollama/qwen3.5:9b
fallback:
- openai/gpt-4o-mini
```
`omos` würde daraus ein OMOS-Array generieren:
```jsonc
"librarian": {
"model": ["ollama/qwen3.5:9b", "openai/gpt-4o-mini"]
}
```
OMOS versucht das erste Modell und wechselt bei Fehlern automatisch zum nächsten.
### Prompt-Dateien statt Inline-Prompts
Statt lange Prompts inline in die Config zu schreiben, kann man sie als Markdown-Dateien ablegen:
```
.opencode/oh-my-opencode-slim/
├── acme-job-applications/
│ ├── writer.md # Preset-spezifisch
│ └── researcher.md
└── writer.md # Fallback für alle Presets
```
Die Lookup-Reihenfolge ist:
1. `.opencode/oh-my-opencode-slim/<preset>/<agent>.md` (projektspezifisch, preset-spezifisch)
2. `.opencode/oh-my-opencode-slim/<agent>.md` (projektspezifisch, preset-übergreifend)
3. `~/.config/opencode/oh-my-opencode-slim/<preset>/<agent>.md` (global, preset-spezifisch)
4. `~/.config/opencode/oh-my-opencode-slim/<agent>.md` (global, preset-übergreifend)
`omos` könnte die `purpose`-Felder aus dem Team-Profil in solche Dateien schreiben versionierbar im Package, geteilt über Presets.
### Weitere relevante Features
| Feature | OMOS-Feld | Nutzen für Teams |
|---------|-----------|-----------------|
| **Council** | `council.presets` | Mehrere Modelle parallel für kritische Entscheidungen (z.B. Checker) |
| **ACP Agents** | `acpAgents.<name>` | Externe Agent-CLIs (Claude Code, Gemini) als Subagent einbinden |
| **Multiplexer** | `multiplexer.type` | tmux/zellij-Panes für Live-Beobachtung arbeitender Agenten |
| **displayName** | `displayName` | Alias für den Orchestrator (bereits im ersten Blogpost genutzt) |
| **description** | `description` | Beschreibung, die dem Orchestrator bei der Routing-Entscheidung hilft |
| **disabled_agents** | `disabled_agents[]` | Agenten global deaktivieren (z.B. Observer) |
| **Background Jobs** | `backgroundJobs.*` | Orchestrator-Wake, Wall-Timeout für Hintergrundaufgaben |
## Was `omos` daraus machen sollte
Im ersten Blogpost haben wir `omos` als Übersetzer von Modellklassen und MCP-Allowlists beschrieben. Das war Phase 1. Hier ist, was Phase 2 und 3 aussehen:
### Phase 2: Custom Agents + Permissions
`omos` liest das Team-Profil und generiert für jeden Custom Agent (also jeden, der nicht auf einen eingebauten OMOS-Agenten mapped) einen vollständigen Agent-Block:
**Input** (team-profile.yaml):
```yaml
- id: writer
purpose: Erstellt auf Fakten basierende Anschreiben und Lebensläufe in ShareLaTeX.
Nutze nur freigegebene Profilfakten. Erfinde keine Erfahrung.
omos_agent: custom
model_class: strong-writing
capabilities:
mcps: [openviking, sharelatex]
skills: []
permissions:
edit: deny
bash: deny
task: deny
```
**Output** (OMOS-Preset):
```jsonc
"writer": {
"model": "ollama/qwen3.6:35b-a3b-q4_K_M",
"prompt": "Erstellt auf Fakten basierende Anschreiben und Lebensläufe in ShareLaTeX. Nutze nur freigegebene Profilfakten. Erfinde keine Erfahrung.",
"orchestratorPrompt": "@writer\n- Rolle: Anschreiben und CV erstellen\n- Delegiere nach qualifiziertem Stellen-Match",
"mcps": ["openviking", "sharelatex"],
"skills": [],
"permission": {
"edit": "deny",
"bash": "deny",
"task": "deny"
}
}
```
### Phase 3: Prompt-Dateien + Fallback + Council
`omos` schreibt zusätzlich:
- `.opencode/oh-my-opencode-slim/acme-job-applications/writer.md` mit dem vollständigen Prompt
- Fallback-Ketten aus der Mapping-Tabelle
- Optional: Council-Preset für den Checker (zwei Modelle parallel prüfen lassen)
## Die erweiterte Mapping-Tabelle
Für Phase 2 und 3 wird die Mapping-Tabelle reichhaltiger:
```yaml
# ~/.config/apm-team/model-mapping.yaml
model_classes:
strong-generalist:
primary: ollama/qwen3.6:35b-a3b-q4_K_M
fallback:
- openai/gpt-4o-mini
fast-research:
primary: ollama/qwen3.5:9b
fallback:
- openai/gpt-4o-mini
strong-writing:
primary: ollama/qwen3.6:35b-a3b-q4_K_M
high-reasoning:
primary: ollama/qwen3.6:35b-a3b-q4_K_M
variant: thinking
options:
thinking:
type: enabled
budgetTokens: 10000
cheap-reliable:
primary: ollama/gemma4:12b
```
`omos` übersetzt das deterministisch:
- `primary` → erstes Modell im Array
- `fallback` → weitere Einträge im Array
- `variant` → wird direkt übernommen
- `options` → wird direkt übernommen
## Was das für den Blogpost-Workflow bedeutet
Der erweiterte Flow sieht so aus:
```mermaid
flowchart TD
P[APM Package: team-profile.yaml] --> O[omos liest]
M[~/.config/apm-team/model-mapping.yaml] --> O
O -->|Modellklassen| G[Generiere OMOS-Preset]
O -->|purpose-Felder| PR[Generiere Prompt-Dateien]
O -->|permissions| PE[Generiere Permission-Objekte]
O -->|fallback| FB[Generiere Fallback-Ketten]
G --> C[Schreibe .opencode/oh-my-opencode-slim.json]
PR --> C
PE --> C
FB --> C
C --> D[Fertig]
```
## Fazit
OMOS ist nicht nur ein Preset-Switcher. Es ist ein vollständiges Agent-Konfigurationssystem mit Custom Prompts, Tool-Permissions, Fallback-Ketten und Multi-Model-Synthese. `omos` als Adapter sollte diese Möglichkeiten nutzen nicht nur Modell-IDs übersetzen.
Die drei Phasen:
| Phase | Was omos generiert | OMOS-Features |
|-------|-------------------|---------------|
| **1** | Modell-IDs + MCP/Skill-Allowlists | `presets.<name>.<agent>.model`, `mcps`, `skills` |
| **2** | + Custom Prompts + Permissions | `agents.<name>.prompt`, `orchestratorPrompt`, `permission` |
| **3** | + Fallback-Ketten + Prompt-Dateien + Council | `model[]`, `.md`-Dateien, `council.presets` |
Phase 1 ist der Minimalprototyp. Phase 2 macht die Agenten wirklich arbeitsfähig. Phase 3 macht sie resilient.