diff --git a/README.md b/README.md index 600976d..00abc52 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,93 @@ # parsecapere-skills - Multi-Tool-Workflow-Definitionen (.md mit Frontmatter) \ No newline at end of file +> Skill-Manifeste fuer die parsecapere.de Voice-LLM-Plattform. +> Bauplaene — welche Prompt-Module + welche Tools zu welchem Skill zusammenkommen. + +--- + +## Was ein Skill ist + +Ein **Skill** ist ein wiederverwendbares Multi-Tool-Workflow-Paket. Konkret: +eine `.md`-Datei mit Frontmatter die beantwortet: + +- **Wer bin ich?** (`skill_id`, `description`) +- **Wann werde ich aktiviert?** (`trigger_keywords`) +- **Welche Tools brauche ich?** (`required_tools`) +- **Aus welchen Prompt-Modulen wird mein System-Prompt komponiert?** (`required_prompt_modules`) +- **Wieviele Hops darf ich maximal nutzen?** (`hop_budget`) + +Das Skill-Manifest **fuehrt nichts aus**. Es ist ein Bauplan. Der `mcp-gitea`-Service +(kommt in Phase M5) liest das Manifest, holt die Module aus +[`parsecapere-prompts`](../parsecapere-prompts), komponiert sie in der richtigen +Reihenfolge und liefert den fertigen System-Prompt + Tool-Schemas an den Aufrufer. + +--- + +## Ordner-Struktur + +``` +parsecapere-skills/ +├── composite/ # Multi-Tool-Workflow-Skills +│ ├── main-voice.md # User-Facing Default-Skill (kein Trigger noetig) +│ ├── kreuzwort-builder.md +│ ├── lueckentext-builder.md +│ └── (kuenftige: sentence-shuffle-builder, ...) +└── atomic/ # (zukuenftig) Single-Tool-Skills +``` + +--- + +## Compose-Order beim Laden + +Wenn der `mcp-gitea`-Service einen Skill laed, baut er den finalen +System-Prompt in dieser Reihenfolge: + +``` +1. base/identity.md +2. base/style.md +3. base/constraints.md +4. workflows/* (in der im Manifest deklarierten Reihenfolge) +5. tools-context/* (abgeleitet aus required_tools, oder explizit deklariert) +6. personas/.md ← LETZTER, Tie-Breaker +``` + +Persona kommt zuletzt damit sie alles davor ueberschreiben darf (siehe +Stolperstein 3 in `2026-06-02 — Prompt-Modularisierung — Architektur und Composition.md`). + +--- + +## Status-Stand + +### Phase M4 — DONE (2026-06-02) +- Drei initiale Skill-Manifeste angelegt: + - `composite/main-voice.md` + - `composite/kreuzwort-builder.md` + - `composite/lueckentext-builder.md` +- `skill-index.md` im Schwester-Repo `parsecapere-prompts` mit echten Eintraegen befuellt. + +### Phase M5 — NEXT +- `mcp-gitea`-Service auf LLM-VPS implementieren +- Tools: `load_skill(skill_id)`, `list_skills(trigger?)`, `load_prompt_module(path)` +- STDB-Cache `gitea_section_cache` mit Webhook-Invalidation + +--- + +## Cross-Repo + +| Repo | Inhalt | +|-------------------------|---------------------------------------------------------------------| +| [`parsecapere-prompts`](https://gitea.parsecapere.de/tim/parsecapere-prompts) | Prompt-Bausteine (base/, workflows/, tools-context/, personas/) | +| `parsecapere-skills` (hier) | Skill-Manifeste — welche Bausteine wann zusammenkommen | +| [`parsecapere-knowledge`](https://gitea.parsecapere.de/tim/parsecapere-knowledge) | Lang-laufendes Wissen (Vokabel-Listen, Wortpool-Snapshots, ...) | + +--- + +## Architektur-DNA-Bezug + +- **Server denkt, Frontend rendert** — Skill-Composition passiert serverseitig im `mcp-gitea`. +- **Skills sind versioniert** — Frontmatter `version: 0.1.0`, plus `required_prompt_modules` + koennen gepinnte Modul-Versionen referenzieren (z.B. `workflows/error-recovery@v2`), + damit ein Production-Skill bei Modul-Bump nicht ploetzlich anders denkt. +- **Hot-Reload faehig** — wenn jemand ein Modul oder ein Skill editiert und pushed, + invalidiert der `mcp-gitea`-Webhook den Cache pro Pfad — naechster `load_skill`-Call + liefert frisch. diff --git a/composite/kreuzwort-builder.md b/composite/kreuzwort-builder.md new file mode 100644 index 0000000..8dab3ac --- /dev/null +++ b/composite/kreuzwort-builder.md @@ -0,0 +1,85 @@ +--- +skill_id: kreuzwort-builder +version: 0.1.0 +description: Sub-Agent fuer Kreuzwort-Layer-Aufbau mit Self-Correction-Loop. +activation: keyword +trigger_keywords: + - kreuzwort + - kreuzwortraetsel + - crossword + +persona: personas/kreuzwort-builder + +required_prompt_modules: + # base/ — immer dabei + - base/identity + - base/style + - base/constraints + # workflows/ — Sub-Agent-spezifisch + - workflows/sub-agent-discipline # KEIN record_*, keine Voice-Tools + - workflows/tool-scope-lock # nur die 5 unten erlaubt + - workflows/self-correction # Validate-Loop (max 4 Versuche) + # tools-context/ — atomic-finalize statt atomic-chain + - tools-context/atomic-finalize + # persona zuletzt + - personas/kreuzwort-builder + +required_tools: + - atomic_validate_crossword_grid + - atomic_create_crossword_grid_brick + - atomic_create_letter_palette_brick + - atomic_create_questions_block_brick + - atomic_finalize_kreuzwort_layer + +max_tokens_estimate: 1500 +hop_budget: 12 # Self-Correction-Loop kann mehrere Validation-Iterationen brauchen + +source_orchestrator: llm-gateway/orchestrator/kreuzwort-orchestrator.js +spawned_by_tool: create_kreuzwort_task (Main-Voice) +--- + +# Skill: kreuzwort-builder + +Sub-Agent der vom Main-LLM via `create_kreuzwort_task({thema, lang})` gespawned wird. + +## Workflow auf einen Blick + +``` +1. Woerter ausdenken + im Grid positionieren +2. atomic_validate_crossword_grid ← Self-Correction-Loop (max 4 Versuche) +3. atomic_create_crossword_grid_brick +4. atomic_create_letter_palette_brick +5. atomic_create_questions_block_brick +6. atomic_finalize_kreuzwort_layer ← Layer + Solution ATOMAR +``` + +Details: `personas/kreuzwort-builder` + `workflows/self-correction`. + +## Erfolgsmeldung + +``` +"Kreuzwort bereit: Woerter zum Thema ''." +``` + +## Was bewusst NICHT im Tool-Set ist + +- `atomic_set_kreuzwort_solution` — separates Solution-Tool. Wird im + Sub-Agent ausgefiltert damit Reihenfolge nicht kollidiert und keine + erfundenen `layerId`s entstehen (siehe Kommentar in + `kreuzwort-orchestrator.js` Zeile 21-25). Stattdessen ist nur das + All-in-One `atomic_finalize_kreuzwort_layer` exponiert. + +- Alle Voice-Tools (`update_brick_text`, `delete_brick`, `clear_view_bricks`, ...) + — das ist Main-Voice-Sache, nicht Sub-Agent. + +- `record_thought` / `record_reflection` — das ist Main-LLM-Sache. Sub-Agent + wird via `voice_tool_call` automatisch getraced. + +## Was M5+ noch leisten muss + +- Wenn `compose_prompt("kreuzwort-builder")` aufgerufen wird, MUSS der Composer + pruefen ob `self-correction` und `atomic-finalize` mit `applies_to` dieses + Skills kompatibel sind. Heute manuell verifiziert — spaeter via Frontmatter-Check. +- `hop_budget: 12` ist hoeher als die `6` der Main-Voice. Wenn der Composer + einem Sub-Agent ein anderes Hop-Limit als der Main-Voice setzt: das hier + ist der Wert. diff --git a/composite/lueckentext-builder.md b/composite/lueckentext-builder.md new file mode 100644 index 0000000..8084658 --- /dev/null +++ b/composite/lueckentext-builder.md @@ -0,0 +1,84 @@ +--- +skill_id: lueckentext-builder +version: 0.1.0 +description: Sub-Agent fuer Lueckentext-Layer-Aufbau (strikt linear, kein Self-Correction). +activation: keyword +trigger_keywords: + - lueckentext + - lueckentexte + - vokabel-drill + - cloze + +persona: personas/lueckentext-builder + +required_prompt_modules: + # base/ — immer dabei + - base/identity + - base/style + - base/constraints + # workflows/ — Sub-Agent-spezifisch + - workflows/sub-agent-discipline # KEIN record_*, keine Voice-Tools + - workflows/tool-scope-lock # nur die 4 unten erlaubt + - workflows/error-recovery # max 3 Versuche pro Tool (unstrukturierte Fehler) + # tools-context/ — atomic-chain statt atomic-finalize + - tools-context/atomic-chain + # persona zuletzt + - personas/lueckentext-builder + +required_tools: + - atomic_create_sentence_text_brick + - atomic_create_word_palette_brick + - atomic_create_layer + - atomic_set_lueckentext_solution + +max_tokens_estimate: 1300 +hop_budget: 8 + +source_orchestrator: llm-gateway/orchestrator/lueckentext-orchestrator.js +spawned_by_tool: create_lueckentext_task (Main-Voice) +--- + +# Skill: lueckentext-builder + +Sub-Agent der vom Main-LLM via `create_lueckentext_task({thema, lang})` gespawned wird. + +## Workflow auf einen Blick + +``` +a) atomic_create_sentence_text_brick(sentenceTemplate, gapIds) → stbId +b) atomic_create_word_palette_brick(words) → wpbId +c) atomic_create_layer({ layoutTemplate, brickZones }) → layerId +d) atomic_set_lueckentext_solution(layerId, correctMapping) +``` + +Details: `personas/lueckentext-builder` + `tools-context/atomic-chain`. + +## Subtle Diff zum kreuzwort-builder + +| Aspekt | lueckentext-builder | kreuzwort-builder | +|-----------------------|----------------------------|--------------------------------| +| Validation-Schritt | nein — strikt linear | ja — Self-Correction-Loop | +| Atomic-Pattern | `atomic-chain` (a→b→c→d) | `atomic-finalize` (atomar) | +| Recovery-Workflow | `error-recovery` (3 Tries) | `self-correction` (4 Validates)| +| Hop-Budget | 8 | 12 | +| Tool-Count | 4 | 5 | + +## Erfolgsmeldung + +``` +"Lueckentext-Aufgabe bereit: '' mit Loesung gespeichert." +``` + +## Was bewusst NICHT im Tool-Set ist + +- Alle Voice-Tools (Main-Voice-Sache). +- `record_thought` / `record_reflection` (Main-LLM-Sache, Trace-Layer macht den Rest). +- Brick-Loesch-Tools — Orphan-Cleanup macht der Orchestrator-Wrapper + (`cleanupOrphanLueckentextBricks()` vor jedem Run), nicht der Sub-Agent selber. + +## Migrations-Hinweis + +Wenn das Backend kuenftig ein `atomic_finalize_lueckentext_layer`-Tool bekommt +(All-in-One Layer + Solution), kann dieser Skill auf das `atomic-finalize`- +Pattern umgestellt werden — siehe Vergleich in `tools-context/atomic-chain.md`. +Heute (2026-06-02) gibt's das Tool noch nicht. diff --git a/composite/main-voice.md b/composite/main-voice.md new file mode 100644 index 0000000..6f50ea2 --- /dev/null +++ b/composite/main-voice.md @@ -0,0 +1,90 @@ +--- +skill_id: main-voice +version: 0.1.0 +description: User-Facing Voice / Session-Orchestrator — Default-Skill beim Voice-Entry. +activation: default +trigger_keywords: [] +note_on_activation: | + main-voice wird nicht ueber list_skills/load_skill aktiviert sondern direkt + beim Eintritt eines Users in die Voice-Loop. Trigger-Keywords leer. + Der mcp-gitea-Service stellt das Manifest aber trotzdem unter dem + selben Composer-Aufruf bereit fuer Konsistenz. + +persona: personas/main-voice + +required_prompt_modules: + # base/ — immer dabei + - base/identity + - base/style + - base/constraints + # workflows/ — Main-Voice-spezifisch + - workflows/plan-before-action + - workflows/error-recovery + # tools-context/ — Main-Voice braucht das volle Brick-Set + - tools-context/brick-creation + # persona zuletzt (Tie-Breaker) + - personas/main-voice + +required_tools: + # Read-Operations + - list_view_bricks + - list_source_items + # Wortpool-Operations + - add_source_item + - remove_word_from_row + # View-Brick-Operations + - add_word_to_row + - create_row_brick + - create_pool_view + - delete_view_brick + - clear_view_bricks + # Pulse-Brick-Operations + - update_brick_text + - update_brick_color + - update_brick_mode + - delete_brick + - toggle_brick + # Sub-Agent-Dispatchers + - create_sentence_shuffle + - create_lueckentext_task + - create_kreuzwort_task # noch geplant — heute via High-Level-Tool im JS + # Trace-Reducer + - record_thought + - record_reflection + # Escalation + - wishlist_feature + +max_tokens_estimate: 1800 +hop_budget: 6 + +source_orchestrator: llm-gateway/llm/gemini.js (handleVoice) +--- + +# Skill: main-voice + +Default-Persona beim Voice-Entry eines Users in die Stream-Box. + +## Aktivierung + +`main-voice` wird **nicht** ueber Trigger-Keywords entdeckt. Sie wird **direkt** +am Anfang jedes `handleVoice()`-Calls von `llm-gateway/llm/gemini.js` geladen. + +Der Composer-Endpoint `compose_prompt("main-voice")` liefert den fertig +zusammengesetzten System-Prompt + die `functionDeclarations` fuer alle +`required_tools`. Filter `mutates !== "delete" || canDelete` (Rolle-basiert) +passiert im aufrufenden Code (siehe `gemini.js` Zeile 244-245). + +## Spezialfall: Intro-Run + +`generateIntro()` braucht einen kleineren, anderen Prompt — heute in +`personas/main-voice.md` als "Spezialfall: Intro-Run"-Section. Bei +Bedarf in M5+ als eigenes Skill-Manifest `composite/main-voice-intro.md` +auslagern. + +## Sub-Agent-Dispatch + +`create_lueckentext_task` und `create_kreuzwort_task` spawn'en je einen +Sub-Agent-Skill (`lueckentext-builder` / `kreuzwort-builder`). Der +Sub-Agent laeuft mit eigenem System-Prompt (eigenes `load_skill`) und +eigenem Hop-Budget. Sein Ergebnis kommt als Tool-Response zurueck zur +Main-Voice.