- apm-omos-agent-teams-v3.md: main blogpost draft (German) - omos-deep-dive.md: second blogpost on oh-my-opencode-slim capabilities - blog-review.md: source-of-truth copy of the Ghost draft + numbered revision proposals from the Perplexity fact-check - image assets referenced by the blogposts (.jpg/.png)
256 lines
8.9 KiB
Markdown
256 lines
8.9 KiB
Markdown
# 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.
|