From 7c648e41c103fda6cd8334bcee764c0a38089ede Mon Sep 17 00:00:00 2001 From: Agent Zero Date: Thu, 13 Aug 2026 12:03:32 +0200 Subject: [PATCH] =?UTF-8?q?fix(roadmap+deploy):=20gr=C3=BCndliche=20Code-V?= =?UTF-8?q?erifikation=20=E2=80=94=2014=20Korrekturen=20(LLM=20count,=20Em?= =?UTF-8?q?bedding=20via=20LiteLLM,=20F-LOOP=205d,=20Phase=20B=202-Dev,=20?= =?UTF-8?q?WorkflowRun=20naming,=20Automation=20vs=20Workflow,=20Search=20?= =?UTF-8?q?Provider=20Activation-Time,=20Notification=20Field-Mapping,=20P?= =?UTF-8?q?roduction=20Resources=20in=20deploy-guide)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PLATFORM_ROADMAP.md | 22 +++++++++++++++------- docs/deploy-guide.md | 30 ++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/PLATFORM_ROADMAP.md b/PLATFORM_ROADMAP.md index 79959bc..c1eb3a5 100644 --- a/PLATFORM_ROADMAP.md +++ b/PLATFORM_ROADMAP.md @@ -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 | diff --git a/docs/deploy-guide.md b/docs/deploy-guide.md index 831c230..6400e27 100644 --- a/docs/deploy-guide.md +++ b/docs/deploy-guide.md @@ -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.