diff --git a/omos/examples/model-mapping.yaml b/omos/examples/model-mapping.yaml new file mode 100644 index 0000000..65764f7 --- /dev/null +++ b/omos/examples/model-mapping.yaml @@ -0,0 +1,19 @@ +# ~/.config/apm-team/model-mapping.yaml +# +# Lokale Mapping-Tabelle des NUTZERS. +# Ordnet abstrakte Modellklassen aus Team-Profilen konkrete, lokal +# verfügbare Modell-IDs zu. Einmal anlegen, gilt für alle Packages. +# +# Einfache Form: klasse: provider/modell-id +# Erweiterte Form: klasse: { model: ..., variant: ..., temperature: ... } + +model_classes: + strong-generalist: ollama/qwen3.6:35b-a3b-q4_K_M + fast-research: ollama/qwen3.5:9b + strong-writing: + model: ollama/qwen3.6:35b-a3b-q4_K_M + temperature: 0.7 + high-reasoning: + model: ollama/qwen3.6:35b-a3b-q4_K_M + variant: thinking + cheap-reliable: ollama/gemma4:12b diff --git a/omos/examples/package/.apm/skills/job-application/SKILL.md b/omos/examples/package/.apm/skills/job-application/SKILL.md new file mode 100644 index 0000000..9710608 --- /dev/null +++ b/omos/examples/package/.apm/skills/job-application/SKILL.md @@ -0,0 +1,112 @@ +--- +name: job-application +description: Activate when the user wants to find jobs and create tailored applications. Use for Bewerbung, job search, cover letter, application, Stellenuche. +allowed-tools: + - "openviking_search" + - "openviking_recall" + - "openviking_read" + - "websearch" + - "webfetch" + - "sharelatex_*" + - "Read" + - "Write" +--- + +# Job Application Skill + +Find matching positions and create tailored applications (Anschreiben + Lebenslauf) in ShareLaTeX. + +## Reference Project + +Template: ShareLaTeX project `6a873cad300b2c1747bdf4c4` +All files from this project are copied verbatim into each new project. +Only two files are rewritten: `variables.tex` and `cover-letter.tex`. +All other files (resume.tex, sections/*, _header.tex, TLCresume.sty) stay UNCHANGED. + +## Process + +### 1. Profile + +Read user profile from OpenViking: skills, experience, projects, personal data. + +### 2. Search + +Search for jobs via websearch. Use the user's query or infer from profile. +Collect 8-10 candidates with: role, company, location, source URL. + +### 3. Prioritize + +Present top 4 as table: + +| # | Role | Company | Location | Why | +|---|------|---------|----------|-----| + +Wait for user selection before proceeding. + +### 4. Create Projects + +For each selected job: + +1. Create ShareLaTeX project: "Bewerbung – {Company} – {Role}" +2. Copy ALL files from template (resume.tex, sections/*, _header.tex, TLCresume.sty, variables.tex, cover-letter.tex, README.md) +3. Rewrite `variables.tex` with job-specific values +4. Rewrite `cover-letter.tex` with tailored Anschreiben +5. Do NOT modify any other files + +### 5. Cover Letter Rules (DIN 5008) + +#### Format +- Language: German (unless job posting is English) +- Length: exactly one A4 page +- Font: 12pt, matching the template (already set in LaTeX) +- Structure: DIN 5008 business letter format + +#### Variables to set (in variables.tex) +- `\Company`: full company name (e.g. "R+V Allgemeine Versicherung AG") +- `\Position`: exact job title from posting +- `\RefNumber`: job reference number if available +- `\Subject`: "Bewerbung als {Position}" (bold in LaTeX) +- `\Salutation`: "Sehr geehrte/r Frau/Herr {Name}," if known, else "Sehr geehrte Damen und Herren," + +#### Structure of cover-letter.tex +1. Sender block (already in template) +2. Recipient block +3. Date (right-aligned) +4. Subject line (bold, no "Betreff:" prefix) +5. Salutation +6. Opening (3-5 sentences): state position, where found, one compelling reason why +7. Body (2 paragraphs, ~100 words each): + - Paragraph 1: 2-3 matching qualifications with concrete examples from OpenViking profile + - Paragraph 2: Why this company specifically (researched values, projects, mission) +8. Closing: availability for interview, "Mit freundlichen Grüßen" +9. Anlagen list + +#### Do's +- Research company before writing (website, recent news, values) +- Reference specific company projects or values +- Use concrete examples with numbers/metrics +- Match language to job posting (German posting → German letter) +- Use keywords from job posting (ATS optimization) +- Keep sentences short and factual +- End with call to action (interview availability) + +#### Don'ts +- Never start with "Hiermit bewerbe ich mich" (used by 90% of applicants) +- Never use "Mit großem Interesse habe ich Ihre Stellenanzeige gelesen" +- Don't repeat CV content verbatim +- Don't use generic phrases like "innovativ", "teamfähig", "motiviert" +- Don't include personal details (age, marital status) +- Don't exceed one page +- Don't use humor or informal language +- Don't copy-paste between applications (recipients notice) +- Don't make claims you can't back up with examples + +### 6. Compile + +Compile each project. Fix errors. Return project links. + +## Output + +| Role | Project | Status | +|------|---------|--------| +| ... | link | Created | diff --git a/omos/examples/package/.gitignore b/omos/examples/package/.gitignore new file mode 100644 index 0000000..c2ed781 --- /dev/null +++ b/omos/examples/package/.gitignore @@ -0,0 +1,2 @@ +# Generierte Artefakte – Quelle sind team-profile.yaml + model-mapping.yaml +.opencode/ diff --git a/omos/examples/package/apm.yml b/omos/examples/package/apm.yml new file mode 100644 index 0000000..3c38a23 --- /dev/null +++ b/omos/examples/package/apm.yml @@ -0,0 +1,21 @@ +name: job-application +version: 1.0.0 +description: Find matching jobs and create tailored cover letters + CVs in ShareLaTeX +author: Tobias Endres +license: MIT +type: skill +targets: + - generic + - opencode +dependencies: + mcp: + - name: sharelatex + registry: false + transport: sse + url: https://sharelatex-mcp.corentic.eu/sse + - name: openviking + registry: false + transport: sse + url: https://openviking.corentic.eu/mcp + headers: + Authorization: Bearer ${OPENVIKING_API_KEY} diff --git a/omos/examples/package/team-profile.yaml b/omos/examples/package/team-profile.yaml new file mode 100644 index 0000000..c56b8b0 --- /dev/null +++ b/omos/examples/package/team-profile.yaml @@ -0,0 +1,61 @@ +# team-profile.yaml +# Deklaration des empfohlenen Agenten-Teams für das Package job-application. +# +# Diese Datei gehört dem Package-AUTOR. Sie beschreibt: +# - welche Rollen für den fachlichen Workflow sinnvoll sind, +# - welche Modellklasse jede Rolle benötigt (abstrakt, keine konkreten IDs), +# - welche Teilmenge der MCPs und Skills jede Rolle verwenden darf. +# +# Der Nutzer löst die Modellklassen lokal auf (siehe model-mapping.yaml). +# Der Adapter omos generiert daraus ein oh-my-opencode-slim-Preset. + +schema: corentic.team-profile/v1 + +id: acme.job-applications +description: > + Human-in-the-loop-Team zur Recherche, Vorbereitung und Prüfung + individueller Bewerbungsunterlagen. + +roles: + - id: orchestrator + purpose: Zerlegt Aufgaben, delegiert an Spezialisten, integriert Ergebnisse + model_class: strong-generalist + capabilities: + mcps: [] + skills: [job-application] + + - id: researcher + purpose: Sucht und bewertet Stellenausschreibungen gegen das Kandidatenprofil + omos_agent: librarian # nutzt OMOS-Builtin 'librarian' mit Alias + model_class: fast-research + capabilities: + mcps: [websearch, webfetch, openviking] + skills: [job-application] + + - id: writer + purpose: Erstellt auf Fakten basierende Anschreiben und Lebensläufe in ShareLaTeX. + Nutze nur freigegebene Profilfakten. Erfinde keine Erfahrung. + Reiche niemals selbstständig eine Bewerbung ein. + omos_agent: custom # eigener Custom Agent 'writer' + model_class: strong-writing + capabilities: + mcps: [openviking, sharelatex] + skills: [] + + - id: checker + purpose: Prüft Fakten, Ton und Vollständigkeit gegen das Kandidatenprofil. + Jede Behauptung braucht eine belegbare Quelle. + omos_agent: oracle # nutzt OMOS-Builtin 'oracle' mit Alias + model_class: high-reasoning + capabilities: + mcps: [openviking] + skills: [] + + - id: notifier + purpose: Informiert den Nutzer über fertige Entwürfe. + Versende niemals etwas ohne explizite Nutzerfreigabe. + omos_agent: custom # eigener Custom Agent 'notifier' + model_class: cheap-reliable + capabilities: + mcps: [] + skills: [] diff --git a/omos/skills/omos-setup/SKILL.md b/omos/skills/omos-setup/SKILL.md new file mode 100644 index 0000000..38e768f --- /dev/null +++ b/omos/skills/omos-setup/SKILL.md @@ -0,0 +1,73 @@ +--- +name: omos-setup +description: Activate when the user wants to set up, render, or troubleshoot an omos team from an APM package. Use for omos render, team-profile, model-mapping, oh-my-opencode-slim preset, fehlende Modellklassen. +allowed-tools: + - "Bash(python3 omos/omos.py *)" + - "Read" + - "Write" + - "Edit" + - "Glob" +--- + +# OMOS Setup Skill + +Führt den Nutzer durch: APM-Package mit Team-Profil → lokales Modell-Mapping → gerendertes oh-my-opencode-slim-Preset. + +## Der Ablauf (Resolve–Validate–Render) + +### 1. Team-Profil finden + +Prüfe, ob eine `team-profile.yaml` existiert (Package-Root oder `omos/examples/team-profile.yaml`). Lies sie und fasse dem Nutzer zusammen: + +``` +Profil: acme.job-applications +Rollen: orchestrator → strong-generalist, researcher → fast-research, + writer → strong-writing, checker → high-reasoning, notifier → cheap-reliable +MCPs benötigt: openviking, sharelatex (+ websearch/webfetch als OpenCode-Native) +``` + +### 2. Mapping prüfen + +Prüfe `~/.config/apm-team/model-mapping.yaml`. Für **jede** im Profil verwendete Modellklasse muss ein Eintrag existieren. + +Wenn eine Modellklasse fehlt, biete dem Nutzer konkrete Optionen an (verfügbare Modelle aus `~/.config/opencode/opencode.jsonc` auflisten): + +``` +Für 'high-reasoning' ist kein Modell zugeordnet. +1. Vorhandenes Modell wählen (z. B. ollama/qwen3.6:35b-a3b-q4_K_M) +2. Neues Provider/Modell in opencode.jsonc konfigurieren +3. Abbrechen +``` + +Nach Auswahl schreibe das Mapping und markiere optional `# selected_by: user`. + +### 3. MCPs prüfen + +Vergleiche die im Profil genannten MCPs mit der Sektion `mcp` in `~/.config/opencode/opencode.jsonc`. Fehlende dem Nutzer melden – nicht stillschweigend ignorieren. Native OpenCode-Tools (`websearch`, `webfetch`) sind keine MCPs und brauchen keinen Eintrag. + +### 4. Rendern + +```bash +python3 omos/omos.py render --package +``` + +Zeige die Ausgabe inklusive Warnungen. Die Datei `.opencode/oh-my-opencode-slim.json` ist generiert – nicht manuell editieren. + +### 5. Aktivieren + +Nutzer anleiten: `opencode` starten → `/preset ` → Reload. Preset-Wechsel greifen erst nach einem Reload (by Design). + +## Fehlerbehandlung + +| Fehler | Lösung | +|---|---| +| „Modellklasse X ist nicht gemappt" | Schritt 2: Mapping ergänzen | +| „MCP ... nicht in opencode.json konfiguriert" | Schritt 3: MCP einrichten oder Rolle anpassen | +| „Kein Team-Profil gefunden" | Pfad prüfen, `--team-file` verwenden | +| Ungültiges YAML | Zeile aus Fehlermeldung zeigen | + +## Regeln + +- Niemals selbst Modelle erraten oder zuordnen – immer den Nutzer wählen lassen. +- Niemals die generierte `.opencode/oh-my-opencode-slim.json` direkt editieren; Quelle sind Team-Profil + Mapping. +- Sicherheitsgrenzen des Packages (MCP/Skill-Allowlists) nur verschärfen, nie aufweichen.