M3.10: tools-context/* — drei Tool-Context-Module + drop gitkeep

Drei Module, klar nach Persona-Scope getrennt:

- brick-creation.md: Pulse / View / Row / Pool-View-Tools + die haerteste
  Stolperfalle (delete_brick vs delete_view_brick vs remove_word_from_row).
  Main-Voice-exklusiv.

- atomic-chain.md: Strikt-lineares Pattern fuer Sub-Agents ohne
  All-in-One-Finalize (Lueckentext). Drei Regeln: Reihenfolge, IDs aus
  Vorgaenger, bei Fehlschlag-Run beenden statt aufraeumen.

- atomic-finalize.md: All-in-One-Pattern fuer Sub-Agents MIT Finalize
  (Kreuzwort). Kombiniert Layer-Erstellung + Solution-Set atomar —
  vermeidet orphan-Zustaende.

atomic-chain und atomic-finalize zeigen explizit zueinander: wenn ein
Finalize-Tool existiert, bevorzuge es. atomic-chain ist Fallback wenn
das Backend nur die getrennten Tools anbietet.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
tim
2026-06-02 15:32:58 +02:00
parent eb89be6a3f
commit ee18a1f591
4 changed files with 180 additions and 3 deletions
-3
View File
@@ -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
+61
View File
@@ -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_<TYP_1>_brick(...) → liefert brickId_1
b) atomic_create_<TYP_2>_brick(...) → liefert brickId_2
c) atomic_create_layer(
layoutTemplate,
brickZones: { [brickId_1]: "...", [brickId_2]: "..." }
) → liefert layerId
d) atomic_set_<TYP>_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.
+51
View File
@@ -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_<TYP>_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_<TYP>_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.
+68
View File
@@ -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.