# 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.
