diff --git a/tools-context/.gitkeep b/tools-context/.gitkeep deleted file mode 100644 index 407250d..0000000 --- a/tools-context/.gitkeep +++ /dev/null @@ -1,3 +0,0 @@ -# Platzhalter — tools-context-Module entstehen in Phase M3. -# Geplant: brick-creation.md, user-scoping.md, atomic-chain.md, -# atomic-finalize.md, trace-viewer.md diff --git a/tools-context/atomic-chain.md b/tools-context/atomic-chain.md new file mode 100644 index 0000000..6053b75 --- /dev/null +++ b/tools-context/atomic-chain.md @@ -0,0 +1,61 @@ +--- +module_id: tools-context/atomic-chain +version: 0.1.0 +description: Strikt-sequenzielles atomic_create_*-Pattern mit ID-Weiterreichung. +max_tokens: 250 +applies_to: [lueckentext-builder, future-atomic-chain-builders] +sources: + - personas/lueckentext-builder.md (a→b→c→d-Workflow mit brickId/layerId-Verkettung) +extracted_at: 2026-06-02 +extracted_by: phase-M3 +--- + +# Atomic-Chain Pattern + +Manche Sub-Agents bauen ihr Layer in einer **strikt-linearen Kette** atomarer +Tool-Calls, wo das Ergebnis eines Tools die Eingabe des naechsten ist. + +## Generisches Pattern (Beispiel: Lueckentext) + +``` +a) atomic_create__brick(...) → liefert brickId_1 +b) atomic_create__brick(...) → liefert brickId_2 +c) atomic_create_layer( + layoutTemplate, + brickZones: { [brickId_1]: "...", [brickId_2]: "..." } + ) → liefert layerId +d) atomic_set__solution(layerId, ...) +``` + +## Drei harte Regeln + +### Regel 1 — Reihenfolge ist Pflicht + +`a → b → c → d` in **GENAU dieser Reihenfolge**. Schritt `d` ohne `c` davor +**scheitert immer** — `set_solution` braucht eine real existierende `layerId`. + +### Regel 2 — IDs aus Vorgaenger-Calls, nicht erfunden + +In Schritt `c` musst du die EXAKTEN `brickId`-Werte aus Schritt `a` und `b` +nutzen. In Schritt `d` musst du die EXAKTE `layerId` aus Schritt `c` nutzen. + +**Niemals** `"default"`, `"layer-1"` oder einen erfundenen Wert. Wenn du die +ID nicht parat hast: lies sie aus dem `functionResponse` des Vorgaenger-Tools +(steht meist als `{ brickId: "...", layerId: "..." }`). + +### Regel 3 — Bei Fehlschlag: zurueck zum Anfang der Kette + +Wenn Schritt `c` scheitert, ist die Kette gebrochen — `a` und `b` haben Bricks +erzeugt die jetzt orphans sind. Der Orchestrator-Wrapper raeumt die beim +naechsten Start ueber Orphan-Cleanup auf. Du selbst musst nichts loeschen — +einfach den Run beenden und ehrlich melden was nicht ging. + +## Wann ist das das richtige Pattern? + +- Wenn das Backend KEIN `atomic_finalize_*`-All-in-One-Tool anbietet + (siehe `tools-context/atomic-finalize.md`). +- Wenn Brick-Erstellung und Layer-Erstellung bewusst getrennt sind, damit + das LLM Zwischen-Validierung sieht. + +Wenn ein `atomic_finalize_*`-Tool existiert (wie beim Kreuzwort), nutze das. +Es ist robuster gegen abgebrochene Runs. diff --git a/tools-context/atomic-finalize.md b/tools-context/atomic-finalize.md new file mode 100644 index 0000000..573fafb --- /dev/null +++ b/tools-context/atomic-finalize.md @@ -0,0 +1,51 @@ +--- +module_id: tools-context/atomic-finalize +version: 0.1.0 +description: All-in-One Layer+Solution-Erzeugung via atomic_finalize_*. +max_tokens: 200 +applies_to: [kreuzwort-builder, future-atomic-finalize-builders] +sources: + - personas/kreuzwort-builder.md (atomic_finalize_kreuzwort_layer als FINALER Schritt) +extracted_at: 2026-06-02 +extracted_by: phase-M3 +--- + +# Atomic-Finalize Pattern + +Manche Sub-Agents nutzen ein All-in-One-Tool `atomic_finalize__layer(...)`, +das **Layer-Erstellung und Solution-Persistenz in EINEM atomaren Call** kombiniert. + +## Wann + +Wenn das Backend ein solches Tool anbietet (heute: Kreuzwort), bevorzuge es +gegenueber der getrennten `atomic_create_layer` + `atomic_set_*_solution`-Kette. +Vorteil: kein orphan-Zustand zwischen Layer-Erstellung und Solution-Set. + +## Aufruf-Schema + +``` +atomic_finalize__layer({ + brickZones: { [brickId_1]: "zone-1", [brickId_2]: "zone-2", ... }, + correctMapping: { ... }, // Loesung in Layer-spezifischem Format + title: "...", +}) + → liefert { layerId } +``` + +## Regeln + +- **`brickZones`** muss die **EXAKTEN** `brickId`-Werte aus den Vorgaenger-Tool-Calls + enthalten. Keine erfundenen IDs, keine `"default"`, `"layer-1"` etc. +- **`correctMapping`** hat ein Layer-Typ-spezifisches Format + (z.B. fuer Kreuzwort: `{ "row,col": "L", ... }` pro Cell). +- **Genau ein Call** — das Tool ist nicht idempotent fuer "korrigieren". + Wenn der Layer falsch ist, muss alles davor neu gebaut werden. + +## Warum getrennte Tools im Sub-Agent-Skill? + +Manchmal sind `atomic_create_layer` + `atomic_set_*_solution` separat in +`required_tools`, manchmal nur das `atomic_finalize_*`. Im **Kreuzwort-Skill** +ist BEWUSST nur das Finalize-Tool exponiert (siehe Kommentar in +`kreuzwort-orchestrator.js`: "`atomic_set_kreuzwort_solution` ausgefiltert"), +damit die Reihenfolge nicht durcheinander geraten kann und keine erfundenen +`layerId`s entstehen. diff --git a/tools-context/brick-creation.md b/tools-context/brick-creation.md new file mode 100644 index 0000000..a0a2a59 --- /dev/null +++ b/tools-context/brick-creation.md @@ -0,0 +1,68 @@ +--- +module_id: tools-context/brick-creation +version: 0.1.0 +description: Pulse / View / Row / Pool-View — was welches Tool tut und welches Delete-Tool dazu gehoert. +max_tokens: 350 +applies_to: [main-voice] +applies_NOT_to: [kreuzwort-builder, lueckentext-builder] +note_on_scope: | + Sub-Agents nutzen atomic_*-Tools (siehe atomic-chain.md / atomic-finalize.md), + nicht das hier dokumentierte Brick-Set. Dieses Modul ist Main-Voice-exklusiv. +sources: + - personas/main-voice.md (BRICK-WORKFLOWS-Block + Brick-Loesch-Regeln) +extracted_at: 2026-06-02 +extracted_by: phase-M3 +--- + +# Brick-Creation Tool-Context + +Die Stream-Box kennt drei Brick-Klassen + ein Layer-Konzept. Welches Tool fuer welche +Aenderung — und vor allem: welches **Delete-Tool** dazu gehoert. + +## (A) Pool-View ("zeige mir alle X-Worte") + +``` +create_pool_view(title, source="wortpool", filter={lang, starts_with?, ...}, sort?, limit?) +``` + +Erzeugt eine **View-Brick** die einen Filter-Snapshot aus einer Source rendert. + +## (B) Zeile mit Woertern bauen (DAS HAEUFIGSTE Pattern) + +1. `list_view_bricks()` → gibt es schon eine aktive/leere Zeile? → wenn ja, deren `rowId` nehmen. + (Wenn KEINE Zeile da ist: `create_row_brick(title)` zuerst.) +2. `list_source_items("wortpool", {lang, ...})` → welche Woerter sind schon da? +3. Fuer jedes **NEUE** Wort: `add_source_item("wortpool", {lang, grundform})` → liefert `wortId`. +4. Fuer **JEDES** Wort: `add_word_to_row(rowId, wortId)` ← **NIEMALS VERGESSEN**. + +> `add_word_to_row` braucht eine `wortId` AUS DEM Wortpool (kein freier Text). +> Schritte 3 + 4 koennen NICHT durch nur Schritt 3 ersetzt werden. + +Detail dazu: die Anti-Halluzinations-Regel zu `add_source_item` in der +Main-Voice-Persona — wenn nur Schritt 3 gemacht wird, ist das Wort nur im +**unsichtbaren** Pool, nicht im **sichtbaren** Brick. + +## (C) Alles zuruecksetzen + +``` +clear_view_bricks() +``` + +Entfernt alle View-Bricks. Pulse-Cycle laeuft wieder. + +## (D) Pulse-Brick aendern (soft/fast/shake/text/color) + +``` +update_brick_text / update_brick_color / update_brick_mode +``` + +## Delete-Mapping — Hartes Wissen + +| Was loeschen? | Tool | +|--------------------------------|-----------------------------------------------| +| **STREAM-Brick (Pulse)** | `delete_brick` oder `toggle_brick` | +| **VIEW-Brick (Row, Pool-View)**| `delete_view_brick` (NICHT `delete_brick`!) | +| **Einzelnes Wort aus Row** | `remove_word_from_row(rowId, wortId)` | + +> Falsches Delete-Tool fuer den falschen Brick-Typ → silent fail ohne sichtbare +> Aenderung. Achte auf das Mapping.