fix(roadmap+deploy): gründliche Code-Verifikation — 14 Korrekturen (LLM count, Embedding via LiteLLM, F-LOOP 5d, Phase B 2-Dev, WorkflowRun naming, Automation vs Workflow, Search Provider Activation-Time, Notification Field-Mapping, Production Resources in deploy-guide)

This commit is contained in:
Agent Zero
2026-08-13 12:03:32 +02:00
parent fb444d88c6
commit 7c648e41c1
2 changed files with 45 additions and 7 deletions
+15 -7
View File
@@ -259,17 +259,19 @@ Später — Advanced Autonomy/Automation nur bei echtem Bedarf
## Phase B — Kleine System-Konsolidierung
**Dauer:** 5 Wochen
**Dauer:** 6 Wochen (bei 2 Entwicklern; bei 1 Entwickler ~10-12 Wochen)
**Ziel:** Nur wirklich gemeinsame technische Infrastruktur konsolidieren. Keine Universalmodelle.
### B.1 Zentraler LLM Client
Im Code-Audit verbleiben **8 direkte `litellm.acompletion()` Aufrufe außerhalb des zentralen Clients** (automation, ai_assistant, ai_proactive, unified_search). Diese auf den vorhandenen zentralen Client umstellen.
Im Code-Audit verbleiben **9 direkte `litellm.acompletion()` Aufrufe außerhalb des zentralen Clients** (automation/agent_runner, ai_assistant 2x, ai_proactive 3x, unified_search 2x). Diese auf den vorhandenen zentralen Client umstellen.
**Embedding-API:** Der zentrale Client stellt nicht nur `llm_complete()` sondern auch `llm_embed(texts, model)` bereit. LiteLLM unterstützt Embeddings über `litellm.aembedding()` — derselbe Provider-/API-Key-Mechanismus wie Completion. Aktuell nutzt `unified_search/embedding.py` direkte OpenRouter-API-Calls. Diese werden auf `llm_embed()` über den zentralen Client umgestellt. Provider-Auswahl, API-Key-Auflösung, Error-Handling und Cost-Tracking laufen über denselben zentralen Weg wie Completion-Calls.
| Task | Beschreibung | Aufwand |
|------|-------------|---------|
| B-LLM | `llm_client.py` erweitern: `llm_complete(model, messages, tools, ...)`, `llm_embed(texts, model)`. Provider-Auswahl aus DB, API-Key-Auflösung, Error-Handling, Cost-Tracking, Streaming-Helfer, Timeouts, optionale Retries | 2 Tage |
| B-LLM-MIG | Alle 8 verbleibenden direkten `litellm.acompletion()` Aufrufe außerhalb `llm_client.py` umstellen | 2 Tage |
| B-LLM-MIG | Alle 9 verbleibenden direkten `litellm.acompletion()` Aufrufe außerhalb `llm_client.py` umstellen + `unified_search/embedding.py` auf `llm_embed()` umstellen | 2 Tage |
| B-LLM-TEST | Tests für zentralen Client (mock mode, real mode, error scenarios) | 1 Tag |
| B-LLM-DOC | Plugin-Dev-Guide: `from app.ai.llm_client import llm_complete`. Keine direkten LiteLLM-Aufrufe | 0.5 Tage |
@@ -434,7 +436,7 @@ Das bisher separate Notification-System und das Communication-/Message-System we
| B-NOTIF-EVT | **Event → typisierte System-Message** — relevante Domain Events erzeugen bei konfigurierter Delivery typisierte `CommMessage`/Rich-Content-Blöcke mit Severity, Entity-Referenz/Action und System-Participant. Keine normale Chattext-Semantik erzwingen | 1.5 Tage |
| B-NOTIF-UI | **Notification-Dropdown → System-Channel** — Notification-Dropdown in TopBar zeigt den System-Channel an (letzte Nachrichten). Klick öffnet den System-Channel im Chat. Ungelesene System-Nachrichten = Badge in TopBar. `NotificationDropdown.tsx` und `NotificationItem.tsx` werden durch Chat-Komponenten ersetzt | 1.5 Tage |
| B-NOTIF-PREF | **Delivery-/Notification-Preferences**`NotificationPreference` bleibt als Routing-Konfiguration, z. B. In-App/System-Channel, E-Mail oder stumm; kein zweites Nachrichtensystem | 0.5 Tage |
| B-NOTIF-MIG | **Migration** — bestehende Notifications in System-Channel als CommMessages migrieren. Alte Notification-Tabelle als View behalten für Übergang | 1 Tag |
| B-NOTIF-MIG | **Migration** — bestehende Notifications in System-Channel als CommMessages migrieren. Alte Notification-Tabelle als View behalten für Übergang. **Field-Mapping:** `Notification.read_at``CommMessageRead`, `Notification.type` → Block-Metadata `notification_type`, `Notification.entity_type/entity_id` → Block-Metadata `entity_ref`, `Notification.title/body` → Text-Block + `action_card` Block mit Deep-Link | 1.5 Tage |
| B-NOTIF-DEPREC | **Notification-System vollständig zurückbauen** — nach Migration und Verifikation: `Notification` Model, `NotificationType` Model, `/api/v1/notifications` Routes, `NotificationDropdown.tsx`, `NotificationItem.tsx` vollständig entfernen. Kein doppeltes System. `NotificationPreference` bleibt (für E-Mail/Stumm-Einstellungen). `create_notification()` wird zu `post_system_message()` im Comm-System | 1 Tag |
| B-NOTIF-TEST | Tests: System-Events → Chat-Nachrichten, Preferences respektiert, Unread-Badge korrekt, Migration korrekt | 1 Tag |
@@ -583,7 +585,7 @@ Die spezifischen Suchen bleiben für gute Fach-UX erhalten, laufen technisch abe
| Task | Beschreibung | Aufwand |
|------|-------------|---------|
| E-PROV | SearchProvider-Schnittstelle mit `supports_fts/vector/rag/graph` Flags | 1 Tag |
| E-PROV | SearchProvider-Schnittstelle mit `supports_fts/vector/rag/graph` Flags. **Provider-Registration erfolgt zur Plugin-Aktivierungszeit** (`auto_register_providers`), nicht dynamisch zur Laufzeit. Neue Provider benötigen Plugin-Reaktivierung | 1 Tag |
| E-FTS | FTS für alle Provider die es unterstützen | 1 Tag |
| E-VEC | Vector Search für alle Provider die es unterstützen | 1 Tag |
| E-CHUNK | Document-Chunking für DMS (semantische Chunks) | 2 Tage |
@@ -642,7 +644,7 @@ Kein vollständiger interner Chain-of-Thought; der Extended Trace ist ein expliz
| Task | Beschreibung | Aufwand |
|------|-------------|---------|
| F-LOOP | `agent_loop.py` — ReAct-Loop mit LiteLLM `acompletion()` + `tools=` über zentralen LLM Client | 3 Tage |
| F-LOOP | `agent_loop.py` — ReAct-Loop mit LiteLLM `acompletion()` + `tools=` über zentralen LLM Client. Multi-Step-Reasoning, Tool-Call-Parsing, Error-Recovery, Graceful-Stop, Streaming — komplexer als ein einzelner LLM-Call | 5 Tage |
| F-CALL | Tool-Call-Parser — extrahiert function_calls, ruft ToolRegistry auf | 1 Tag |
| F-CTX | Context-Builder — System-Prompt, Agent-Definition, relevanter User-/Tenant-Kontext, relevantes Memory, freigegebene Skills und Tool-Schemas. Zusätzliche API-/Domain-Dokumentation nur gezielt/on-demand; keine pauschale Vollinjektion der CRM-API-Spec | 2 Tage |
| F-MAX | Max-Steps-Limit + Graceful-Stop | 0.5 Tage |
@@ -689,6 +691,12 @@ Kein vollständiger interner Chain-of-Thought; der Extended Trace ist ein expliz
**Runtime-Invariante:** `Workflow`/`WorkflowRun` ist die authoritative langlebige Multi-Step-Engine. `AutomationDefinition` bleibt die leichte Trigger/Condition/Action-/Scheduler-Schicht und darf Workflows starten, wird aber **keine zweite durable Workflow-Engine**.
**Abgrenzung:**
- **AutomationDefinition** = einfache Event-Reaktion: 'Wenn Event X → führe Action Y aus'. Single-Step, nicht-durable, keine Resume-Semantik. Beispiele: 'Mail empfangen → Notification senden', 'Contact erstellt → Proactive Suggestion'.
- **Workflow** = komplexe Multi-Step-Prozesse: 'Warte auf Approval → führe 5 Steps aus → Warte 3 Tage → finalisiere'. Durable, resumable, mit ExecutionContext und Idempotency.
- **Automation kann Workflows starten** (Trigger → `start_workflow`), aber nicht umgekehrt.
- **Beide nutzen denselben Trigger-Kern** (B.11) und denselben ApprovalRequest-Mechanismus (F-APPR/G-APPROVAL).
**Code-Stand:** persistente Workflow-Instanz/Step-History, Conditions und Approval-Pause sowie AutomationDefinition/Run/Version/Cron existieren bereits. Phase G erweitert diese Basis um allgemeines Resume/Wait, Idempotency, neue Business-Steps und Agent-/Workstream-Integration.
| Task | Beschreibung | Aufwand |
@@ -712,7 +720,7 @@ Kein vollständiger interner Chain-of-Thought; der Extended Trace ist ein expliz
| G-APPROVAL | **Generischer Approval-Step auf zentralem `ApprovalRequest`** — den in Phase F angelegten gemeinsamen Kern für Workflows verwenden/erweitern; für beliebige Workflows, Entities und Aktionen nutzbar; Approver/Gruppe, `pending/approved/rejected/expired`, Referenz auf Workflow/Run/Aktion, Kommentar, Zeitstempel, System-Message, Approval-Queue, Audit und optional Timeout. **Keine pauschalen `pending_approval/active/rejected`-Statusfelder auf allen Entities**; fachliche Status nur im jeweiligen Modul, wenn benötigt. Derselbe Mechanismus wird von Agent-Approvals verwendet | 2.5 Tage |
| G-HUMAN-DEC | **Automated-Decision Guard** — für entsprechend konfigurierte AI-Use-Cases dürfen Workflow-/Agent-Ergebnisse keine definierte personen-/risikorelevante Außenwirkung automatisch auslösen, bevor die geforderte Human-Review-/Approval-Policy erfüllt ist. Kein pauschaler Zwang für normale CRM-Automation | 1 Tag |
| G-CTX | **Persistenter Execution-Context** — Daten-Flow zwischen Steps (Variablen, Expressions) wird zusammen mit WorkflowRun dauerhaft gespeichert und kann nach Wait, Restart, Worker-Crash oder Event-Resume fortgesetzt werden | 2 Tage |
| G-RUN | **Durable WorkflowRun / Resume-Semantik** — Run-State, Step-State und Resume-Grund (`resume_at`, Event/Approval/Webhook) persistent halten. Resume lädt denselben Run und setzt exakt am vorgesehenen Step fort; keine zweite Workflow-Runtime | 1.5 Tage |
| G-RUN | **Durable WorkflowRun / Resume-Semantik** bestehendes `WorkflowInstance`-Model wird zu `WorkflowRun` erweitert/umbenannt. Run-State, Step-State und Resume-Grund (`resume_at`, Event/Approval/Webhook) persistent halten. Resume lädt denselben Run und setzt exakt am vorgesehenen Step fort; keine zweite Workflow-Runtime | 1.5 Tage |
| G-IDEMP | **Idempotency-/Deduplizierungsschutz für Side Effects** — Side-Effect-Steps (z. B. Mail, HTTP, CRM-Mutation) erhalten pro Execution einen stabilen Idempotency-/Execution-Key bzw. deduplizierbare Ausführungslogik, damit Retry/Worker-Restart keine unbeabsichtigten Doppelaktionen erzeugt | 1 Tag |
| G-UI-FORM | Form-basierter Step-Editor — Step-Liste mit Up/Down, Formular pro Step-Typ | 2 Tage |
| G-UI-JSON | JSON-Expert-Mode — Toggle zwischen Form und JSON | 0.5 Tage |
+30
View File
@@ -48,3 +48,33 @@ bash /a0/usr/projects/leocrm/scripts/fast-deploy.sh full
- Project UUID: mzu7fvhtad82ujgmbsmyvxzm
- Server UUID: lw80w8scs444gwcw084s00s4
- Private Key UUID: rgcsc0048c04csckk8kogk40
## Production Resource Recommendations
Die docker-compose.yaml hat Development-Defaults (PostgreSQL 512m, Redis 128m). Für Produktion mit 50+ Usern, 100k+ Entities, Agenten, Search und Knowledge müssen die Limits erhöht werden.
| Service | Development | Production (50+ User) | Begründung |
|---|---|---|---|
| **PostgreSQL RAM** | 512m | 1-2GB | pgvector HNSW + FTS + JSONB Snapshots + Outbox + AuditLog |
| **PostgreSQL CPU** | 1.0 | 2.0 | Vector Search + FTS + normale CRM-Queries |
| **PostgreSQL Disk** | Named Volume | 50-100GB | Embeddings (768 dim × 100k = ~300MB), JSONB Snapshots, Outbox |
| **Redis RAM** | 128m | 256-512m | WS Pub/Sub + Caching + Sessions + ARQ + Rate-Limiting |
| **Redis CPU** | 0.5 | 1.0 | Pub/Sub + Cache + Queue |
| **App (FastAPI) RAM** | Nicht limitiert | 512m-1GB | WebSocket Connections + Async Tasks |
| **App CPU** | Nicht limitiert | 1-2 CPUs | API + WS + LLM-Streaming |
| **Worker (ARQ) RAM** | Nicht limitiert | 256-512m | Background Jobs (Indexierung, Agent-Runs, Extraction) |
| **Worker CPU** | Nicht limitiert | 1-2 CPUs | LLM-Calls + Embedding + Text-Extraction |
### Skalierung bei Bedarf
- **Read-Replicas:** Bei hohem Lese-Aufkommen (Search, FTS, Vector) können Read-Replicas für PostgreSQL eingerichtet werden. Schreib-Last (Outbox, EntityHistory, AuditLog) bleibt auf dem Master.
- **Mehr Worker:** Bei hohem Background-Job-Aufkommen können zusätzliche ARQ-Worker-Container gestartet werden. Queue-Prioritäten verhindern dass wichtige Jobs hinter langen Index-Jobs warten.
- **pgvector auslagern:** Bei sehr großen Datasets (>1M Embeddings) kann pgvector auf einen separaten PostgreSQL-Node ausgelagert werden.
- **Redis Cluster:** Bei sehr hohem Cache-/Pub/Sub-Aufkommen kann Redis Cluster eingesetzt werden.
### LLM-Kosten-Management
- **Cost-Tracking:** Der zentrale LLM Client (Phase B.1) trackt Kosten pro Call.
- **Budget-Limits:** Pro Agent (Phase F) und pro Tenant (Phase I).
- **Cost-Dashboard:** Phase I zeigt LLM-Kosten pro Agent/Workflow/User.
- **Alerts:** Budget-Alerts bei Überschreitung konfigurierbarer Schwellwerte.