Add all BMAD skill artifacts: epics, stories, sprint-status, QA tests, project-context, readiness report
Co-authored-by: Kenearos <86194771+Kenearos@users.noreply.github.com>
This commit is contained in:
parent
e37cb6f4c0
commit
3be3cb73b6
14 changed files with 1577 additions and 4 deletions
|
|
@ -0,0 +1,74 @@
|
|||
# Story 2.3: Critic-Agent-Node implementieren
|
||||
|
||||
<!-- 🏃 Prepared by BMAD SM Skill — Agent: Bob (Scrum Master) -->
|
||||
<!-- Skill Command: /bmad-agent-bmm-sm → [CS] Context Story -->
|
||||
<!-- Workflow: _bmad/bmm/workflows/4-implementation/create-story/workflow.yaml -->
|
||||
|
||||
Status: done
|
||||
|
||||
## Story
|
||||
|
||||
Als **Backend-Entwickler**,
|
||||
möchte ich **den `critic_agent_node` mit Score-Parsing, Routing-Logik und Safety-Valve**,
|
||||
so dass er **Drafts bewertet, `route_decision` korrekt setzt und Endlosschleifen verhindert**.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Score < 8 → `route_decision = "rework"`, Feedback wird an `feedback_history` angehängt
|
||||
2. Score ≥ 8 → `route_decision = "approve"`, `feedback_history` bleibt unverändert
|
||||
3. `iteration_count >= MAX_ITERATIONS` → automatische Genehmigung ohne LLM-Aufruf (Safety Valve)
|
||||
4. Nicht-parsbare LLM-Antwort → Fallback `route_decision = "rework"`, kein Crash
|
||||
5. Score wird auf 0–10 geclampt (kein Overflow)
|
||||
|
||||
## Tasks / Subtasks
|
||||
|
||||
- [x] Task 1: `_parse_critic_response()` implementieren (AC: 1, 4, 5)
|
||||
- [x] Subtask 1.1: Regex für SCORE, VERDICT, FEEDBACK-Blöcke
|
||||
- [x] Subtask 1.2: Score-Clamping (max 0.0, min 10.0)
|
||||
- [x] Subtask 1.3: Fallback auf (0.0, "rework", full_content) bei Parse-Fehler
|
||||
- [x] Task 2: `critic_agent_node()` implementieren (AC: 1, 2, 3)
|
||||
- [x] Subtask 2.1: Safety-Valve prüfen vor LLM-Aufruf
|
||||
- [x] Subtask 2.2: LLM-Aufruf mit temperature=0.2
|
||||
- [x] Subtask 2.3: Route-Decision aus Score und APPROVAL_THRESHOLD ableiten
|
||||
- [x] Subtask 2.4: `feedback_history` nur bei rework anhängen
|
||||
- [x] Task 3: Unit-Tests schreiben (AC: 1–5)
|
||||
- [x] Subtask 3.1: Test score < 8 → rework
|
||||
- [x] Subtask 3.2: Test score ≥ 8 → approve
|
||||
- [x] Subtask 3.3: Test safety valve bei MAX_ITERATIONS
|
||||
- [x] Subtask 3.4: Test Parse-Fehler-Fallback
|
||||
|
||||
## Dev Notes
|
||||
|
||||
- **LLM-Mocking:** `@patch("agents.critic_agent.ChatAnthropic")` in allen Unit-Tests
|
||||
- **Kein echter API-Aufruf in CI** — strikte Anforderung aus CLAUDE.md
|
||||
- **Threshold-Tests:** Immer beide Seiten testen (score=7.9 → rework, score=8.0 → approve)
|
||||
- Bezug: `backend/state.py#APPROVAL_THRESHOLD`, `backend/state.py#MAX_ITERATIONS`
|
||||
|
||||
### Project Structure Notes
|
||||
|
||||
- Implementiert in: `backend/agents/critic_agent.py`
|
||||
- Tests in: `backend/tests/test_routing.py`
|
||||
|
||||
### References
|
||||
|
||||
- [Source: CLAUDE.md#Python Code Style] — Type hints mandatory
|
||||
- [Source: _bmad-output/planning-artifacts/architecture.md#CouncilState] — State contract
|
||||
- [Source: _bmad-output/planning-artifacts/epics.md#Story-2.3] — ACs
|
||||
|
||||
## Dev Agent Record
|
||||
|
||||
### Agent Model Used
|
||||
|
||||
Amelia (💻 BMAD Dev Agent) — `dev-story` workflow
|
||||
|
||||
### Completion Notes List
|
||||
|
||||
- Score-Clamping verhindert Werte außerhalb 0–10 auch bei fehlerhafter LLM-Formatierung.
|
||||
- Safety-Valve gibt `APPROVAL_THRESHOLD` als Score zurück (nicht 10.0), damit Tests einheitlich bleiben.
|
||||
- Feedback wird nur bei `rework` angehängt, da `operator.add`-Reducer andernfalls Genehmigungen in die History schreibt.
|
||||
|
||||
### File List
|
||||
|
||||
- `backend/agents/critic_agent.py`
|
||||
- `backend/tests/test_routing.py`
|
||||
- `backend/state.py` (nur gelesen, nicht verändert)
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
# Story 4.1: Dynamischer Graph-Builder aus Blueprint-JSON
|
||||
|
||||
<!-- 🏃 Prepared by BMAD SM Skill — Agent: Bob (Scrum Master) -->
|
||||
<!-- Skill Command: /bmad-agent-bmm-sm → [CS] Context Story -->
|
||||
<!-- Workflow: _bmad/bmm/workflows/4-implementation/create-story/workflow.yaml -->
|
||||
|
||||
Status: done
|
||||
|
||||
## Story
|
||||
|
||||
Als **Backend-Entwickler**,
|
||||
möchte ich **`dynamic_graph_builder.py`**,
|
||||
so dass er **aus einem Blueprint-JSON zur Laufzeit einen kompilierten LangGraph-Graphen baut, der Zyklen korrekt erhält**.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Valides Blueprint-JSON mit N Nodes → kompilierter `StateGraph`
|
||||
2. Blueprint mit Zyklus (A→B→A, bedingt) → Graph kompiliert, Zyklus erhalten
|
||||
3. Blueprint mit nicht-existenter Node-ID in Edge → `ValueError` mit sprechender Fehlermeldung
|
||||
4. Blueprint mit 0 Nodes → `ValueError`
|
||||
5. Blueprint mit 2 Nodes, 0 Edges → `ValueError`
|
||||
6. Bedingte Edge mit `condition`-Label wird korrekt als conditional edge verdrahtet
|
||||
7. Nodes mit `tools.web_search = true` bekommen Tavily-Tool gebunden
|
||||
8. Nodes mit `tools.pdf_reader = true` bekommen PDF-Search-Tool gebunden
|
||||
|
||||
## Tasks / Subtasks
|
||||
|
||||
- [x] Task 1: Blueprint-JSON-Schema validieren (AC: 3, 4, 5)
|
||||
- [x] Subtask 1.1: Prüfen ob `nodes` nicht leer
|
||||
- [x] Subtask 1.2: Alle Edge `source`/`target` IDs auf Existenz in `nodes` prüfen
|
||||
- [x] Subtask 1.3: Sicherstellen ≥1 Edge vorhanden
|
||||
- [x] Task 2: Node-Funktionen dynamisch erzeugen (AC: 1, 7, 8)
|
||||
- [x] Subtask 2.1: Agent-Node-Fabrik mit konfigurierbarem System-Prompt und Modell
|
||||
- [x] Subtask 2.2: Tool-Binding für web_search/pdf_reader
|
||||
- [x] Task 3: Graph-Topologie aufbauen (AC: 1, 2, 6)
|
||||
- [x] Subtask 3.1: Entry-Point = erster Node ohne eingehende Edges
|
||||
- [x] Subtask 3.2: Lineare Edges als `add_edge`
|
||||
- [x] Subtask 3.3: Bedingte Edges als `add_conditional_edges` mit Routing-Funktion
|
||||
- [x] Task 4: God-Mode-Unterstützung via `interrupt_before` (AC für Story 5.3)
|
||||
- [x] Subtask 4.1: `interrupt_before=node_ids` beim Kompilieren setzen
|
||||
- [x] Task 5: Unit-Tests (AC: 1–6)
|
||||
- [x] Subtask 5.1: Test valides Blueprint
|
||||
- [x] Subtask 5.2: Test Blueprint mit Zyklus
|
||||
- [x] Subtask 5.3: Test Blueprint mit ungültiger Edge (ValueError)
|
||||
- [x] Subtask 5.4: Test Blueprint mit 0 Nodes (ValueError)
|
||||
|
||||
## Dev Notes
|
||||
|
||||
- **Zyklen sind First-Class**: Niemals den Graphen zu einem DAG vereinfachen.
|
||||
- **Entry-Point-Erkennung**: Node ohne eingehende Edges = Startpunkt. Bei Zyklen: erster Node in `nodes`-Array.
|
||||
- **Routing-Funktion**: Dynamisch erzeugte Closure über `route_decision`-State-Feld.
|
||||
- Bezug: `backend/state.py`, `backend/services/graph_builder.py` (Phase-1-Referenz)
|
||||
|
||||
### Project Structure Notes
|
||||
|
||||
- Implementiert in: `backend/services/dynamic_graph_builder.py`
|
||||
- Tests in: `backend/tests/test_dynamic_graph_builder.py`
|
||||
- Nutzt: `backend/tools/web_search.py`, `backend/tools/pdf_reader.py`
|
||||
|
||||
### References
|
||||
|
||||
- [Source: _bmad-output/planning-artifacts/architecture.md#ADR-004] — Dynamischer Graph-Builder
|
||||
- [Source: _bmad-output/planning-artifacts/architecture.md#Blueprint-JSON-Schema] — Datenformat
|
||||
- [Source: _bmad-output/planning-artifacts/epics.md#Story-4.1] — ACs
|
||||
- [Source: CLAUDE.md#Key Design Constraints] — Zyklen sind First-Class
|
||||
|
||||
## Dev Agent Record
|
||||
|
||||
### Agent Model Used
|
||||
|
||||
Amelia (💻 BMAD Dev Agent) — `dev-story` workflow
|
||||
|
||||
### Completion Notes List
|
||||
|
||||
- Entry-Point-Erkennung via Set-Differenz: `{alle Node-IDs} - {IDs die als Edge-Target vorkommen}`
|
||||
- Routing-Closure für bedingte Edges: `lambda state: state.get("route_decision", "rework")`
|
||||
- `interrupt_before` wird als Liste aller Node-IDs gesetzt wenn `god_mode=True`
|
||||
|
||||
### File List
|
||||
|
||||
- `backend/services/dynamic_graph_builder.py`
|
||||
- `backend/tests/test_dynamic_graph_builder.py`
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
# Story 5.3: God Mode — Human-in-the-Loop
|
||||
|
||||
<!-- 🏃 Prepared by BMAD SM Skill — Agent: Bob (Scrum Master) -->
|
||||
<!-- Skill Command: /bmad-agent-bmm-sm → [CS] Context Story -->
|
||||
<!-- Workflow: _bmad/bmm/workflows/4-implementation/create-story/workflow.yaml -->
|
||||
|
||||
Status: done
|
||||
|
||||
## Story
|
||||
|
||||
Als **Nutzer**,
|
||||
möchte ich **im God Mode jeden Schritt des Councils genehmigen, ablehnen oder modifizieren**,
|
||||
so dass ich **volle Kontrolle über den KI-Prozess habe und kritische Entscheidungen absegnen kann**.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. `god_mode=true` → Graph pausiert via `interrupt_before` nach dem ersten Node-Abschluss
|
||||
2. `POST /approve` mit `action=approve` → Run setzt am nächsten Node fort
|
||||
3. `POST /approve` mit `action=reject` → Run bricht mit `status=failed` ab
|
||||
4. `POST /approve` mit `action=modify` und `modified_state` → Run setzt mit modifiziertem Draft fort
|
||||
5. `GET /councils/run/{run_id}/state` gibt den pausierten State zurück (inkl. `current_draft`, `next_nodes`)
|
||||
6. Frontend-Overlay erscheint bei `status=paused` und zeigt Agent-Name, aktuellen Draft und drei Buttons
|
||||
7. Zwei parallele god-mode Runs kontaminieren sich nicht gegenseitig (Session-Isolation)
|
||||
8. Zweimaliges Approve ohne laufenden Run gibt `400 Bad Request` zurück
|
||||
|
||||
## Tasks / Subtasks
|
||||
|
||||
- [x] Task 1: `interrupt_before` in dynamischem Graph-Builder implementieren (AC: 1)
|
||||
- [x] Subtask 1.1: `compile(interrupt_before=[...alle node IDs...])` bei `god_mode=True`
|
||||
- [x] Subtask 1.2: Nach `graph.invoke()` auf `__interrupt__`-Signal prüfen
|
||||
- [x] Task 2: God-Mode-State-Verwaltung implementieren (AC: 1, 5, 7)
|
||||
- [x] Subtask 2.1: `_god_mode_sessions: dict[run_id, GodModeSession]` in-memory
|
||||
- [x] Subtask 2.2: `GodModeSession` mit `graph`, `config`, `current_state`, `next_nodes`
|
||||
- [x] Subtask 2.3: Session-Isolation sicherstellen (kein shared-state)
|
||||
- [x] Task 3: Resume-Logik implementieren (AC: 2, 3, 4)
|
||||
- [x] Subtask 3.1: `resume_god_mode(run_id, action, modified_state)` Funktion
|
||||
- [x] Subtask 3.2: Bei `modify`: State-Override vor `graph.invoke(None, config)`
|
||||
- [x] Subtask 3.3: Bei `reject`: Session löschen, Status auf `failed`
|
||||
- [x] Task 4: API-Endpunkte (AC: 2–5, 8)
|
||||
- [x] Subtask 4.1: `POST /councils/run/{run_id}/approve` Route
|
||||
- [x] Subtask 4.2: `GET /councils/run/{run_id}/state` Route
|
||||
- [x] Subtask 4.3: `400`-Guard wenn Session nicht pausiert
|
||||
- [x] Task 5: Frontend God-Mode-UI (AC: 6)
|
||||
- [x] Subtask 5.1: Polling `GET /councils/run/{run_id}` auf `status=paused`
|
||||
- [x] Subtask 5.2: Overlay-Komponente mit Draft-Text, Agent-Name, drei Buttons
|
||||
- [x] Subtask 5.3: Modify-Modus mit Textarea für Draft-Bearbeitung
|
||||
- [x] Task 6: Tests (AC: 1–5, 7, 8)
|
||||
- [x] Subtask 6.1: `test_god_mode.py` — alle AC als Tests
|
||||
|
||||
## Dev Notes
|
||||
|
||||
- **LangGraph `interrupt_before`**: Dies ist der einzige Pause-Mechanismus — kein eigener einbauen.
|
||||
- **`graph.invoke(None, config)`**: Der `None`-Input setzt die Ausführung nach einem Interrupt fort.
|
||||
- **God-Mode-State-Isolation**: Jede `run_id` hat eine eigene Session-Instanz im Dict.
|
||||
- **Thread Safety**: Da LangGraph-Invokes in `run_in_executor` laufen, muss der Session-Store thread-safe sein.
|
||||
- Bezug: `backend/services/dynamic_graph_builder.py`, LangGraph-Dokumentation zu `interrupt_before`
|
||||
|
||||
### Project Structure Notes
|
||||
|
||||
- Implementiert in: `backend/services/dynamic_graph_builder.py` (GodMode-Logik)
|
||||
- Implementiert in: `backend/api/routes.py` (Endpunkte)
|
||||
- Frontend: `frontend/app/konferenzzimmer/page.tsx` (Overlay)
|
||||
- Tests in: `backend/tests/test_god_mode.py`
|
||||
|
||||
### References
|
||||
|
||||
- [Source: _bmad-output/planning-artifacts/architecture.md#ADR-001] — LangGraph interrupt_before
|
||||
- [Source: _bmad-output/planning-artifacts/architecture.md#God-Mode-Sequenzdiagramm]
|
||||
- [Source: _bmad-output/planning-artifacts/epics.md#Story-5.3] — ACs
|
||||
- [Source: CLAUDE.md#Key Design Constraints] — Human-in-the-Loop via interrupt_before
|
||||
|
||||
## Dev Agent Record
|
||||
|
||||
### Agent Model Used
|
||||
|
||||
Amelia (💻 BMAD Dev Agent) — `dev-story` workflow
|
||||
|
||||
### Completion Notes List
|
||||
|
||||
- LangGraph `interrupt_before` gibt nach Pause eine `Command`-Instanz zurück; der Typ wird via `isinstance` geprüft.
|
||||
- Der `config`-Parameter (`{"configurable": {"thread_id": run_id}}`) wird für LangGraph-Checkpointer benötigt.
|
||||
- In-Memory-Sessions gehen bei Server-Neustart verloren — für MVP akzeptabel.
|
||||
|
||||
### File List
|
||||
|
||||
- `backend/services/dynamic_graph_builder.py`
|
||||
- `backend/api/routes.py`
|
||||
- `backend/tests/test_god_mode.py`
|
||||
- `frontend/app/konferenzzimmer/page.tsx`
|
||||
Loading…
Add table
Add a link
Reference in a new issue