KI-Konzil/_bmad-output/implementation-artifacts/stories/4-1-dynamischer-graph-builder-aus-blueprint-json.md
copilot-swe-agent[bot] 3be3cb73b6 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>
2026-03-12 14:26:40 +00:00

3.6 KiB
Raw Blame History

Story 4.1: Dynamischer Graph-Builder aus Blueprint-JSON

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

  • Task 1: Blueprint-JSON-Schema validieren (AC: 3, 4, 5)
    • Subtask 1.1: Prüfen ob nodes nicht leer
    • Subtask 1.2: Alle Edge source/target IDs auf Existenz in nodes prüfen
    • Subtask 1.3: Sicherstellen ≥1 Edge vorhanden
  • Task 2: Node-Funktionen dynamisch erzeugen (AC: 1, 7, 8)
    • Subtask 2.1: Agent-Node-Fabrik mit konfigurierbarem System-Prompt und Modell
    • Subtask 2.2: Tool-Binding für web_search/pdf_reader
  • Task 3: Graph-Topologie aufbauen (AC: 1, 2, 6)
    • Subtask 3.1: Entry-Point = erster Node ohne eingehende Edges
    • Subtask 3.2: Lineare Edges als add_edge
    • Subtask 3.3: Bedingte Edges als add_conditional_edges mit Routing-Funktion
  • Task 4: God-Mode-Unterstützung via interrupt_before (AC für Story 5.3)
    • Subtask 4.1: interrupt_before=node_ids beim Kompilieren setzen
  • Task 5: Unit-Tests (AC: 16)
    • Subtask 5.1: Test valides Blueprint
    • Subtask 5.2: Test Blueprint mit Zyklus
    • Subtask 5.3: Test Blueprint mit ungültiger Edge (ValueError)
    • 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