diff --git a/b-reference/frontend-nyla/architecture.md b/b-reference/frontend-nyla/architecture.md index ed9fb93..2e0f45e 100644 --- a/b-reference/frontend-nyla/architecture.md +++ b/b-reference/frontend-nyla/architecture.md @@ -1,6 +1,6 @@ - - + + # Frontend Nyla -- Architektur @@ -14,8 +14,8 @@ Technologie-Stack (Stand UI-Doku): React 19.x, Vite 5.x, TypeScript 5.8.x, React | Ordner | Inhalt | |--------|--------| -| `pages/` | Seiten: `admin/`, `basedata/`, `billing/`, `settings/`, `views/` (workspace, commcoach, chatbot, trustee, automation, automation2, realestate, neutralization, teamsbot) | -| `components/` | Wiederverwendbar: FormGenerator, FolderTree, Navigation, UnifiedDataBar, Automation2FlowEditor, OnboardingAssistant | +| `pages/` | Seiten: `admin/`, `basedata/`, `billing/`, `settings/`, `views/` (workspace, commcoach, chatbot, trustee, graphicalEditor, realestate, neutralization, teamsbot) | +| `components/` | Wiederverwendbar: FormGenerator, FolderTree, Navigation, UnifiedDataBar, FlowEditor (Graphical Editor), OnboardingAssistant | | `hooks/` | useApiRequest (useApi.ts), useFiles, useNavigation, useConfirm, usePrompt, useResizablePanels, etc. | | `contexts/` | FileContext, PekContext, ToastContext, WorkflowSelectionContext | | `api/` | API-Client (`api.ts`) und Feature-spezifische API-Module | @@ -31,11 +31,16 @@ Ergänzend typische Root-Dateien und Bereiche im Repo: `main.tsx`, `App.tsx`, `a | Komponente | Zweck | |------------|-------| -| `UnifiedDataBar (UDB)` | Multi-Tab-Panel: Chats, Files, Sources — wird in Workspace und CommCoach genutzt | +| `UnifiedDataBar (UDB)` | Multi-Tab-Panel: Chats, Files, Sources — wird in Workspace, CommCoach und Graphical Editor genutzt | | `FormGenerator` | Dynamische Formulare/Tabellen aus Backend-Attribut-Definitionen | | `FolderTree` | Rekursiver Ordnerbaum mit Drag&Drop, Multi-Selection, Inline-Editing | | `MandateNavigation` | Feature-Baum-Navigation mit Mandanten-Kontext | -| `Automation2FlowEditor` | n8n-style Flow-Builder für Automation2 | +| `Automation2FlowEditor` | Konsolidierter n8n-style Flow-Builder (Graphical Editor) mit 3-Column-Layout: [UDB + Chat/Tracing] [Canvas + Header] [Nodes] | +| `FlowCanvas` | Custom React Canvas fuer Workflow-Graph-Rendering mit Node-Highlighting (SSE Live-Tracing) | +| `RunTracingPanel` | Live-Tracing von Workflow-Runs via SSE mit Fallback-Polling | +| `EditorChatPanel` | AI Chat im Editor mit Drag&Drop-Dateianhang und Source-Picker | +| `CanvasHeader` | Workflow-Metadaten, Versioning (Draft/Publish/Archive), Save-as-Template, New-from-Template | +| `TemplatePicker` | Modal zur Auswahl von Workflow-Vorlagen beim Erstellen neuer Workflows | | `WorkspacePage` | AI-Workspace mit Chat, UDB, Agent-Streaming | ## Routing @@ -64,6 +69,13 @@ Ergänzend typische Root-Dateien und Bereiche im Repo: `main.tsx`, `App.tsx`, `a | `core/PageManager/` | State Preservation, Lifecycle, Caching | | `auth/authConfig`, `authProvider`, `ProtectedRoute` | MSAL, geschützte Routen | | `contexts/*` | FileContext, PekContext, Toast, Workflow-Auswahl, etc. | +| `components/FlowEditor/editor/Automation2FlowEditor.tsx` | Haupt-Editor-Komponente (3-Column-Layout, State-Management) | +| `components/FlowEditor/editor/FlowCanvas.tsx` | Custom Canvas mit Node-Rendering, Connections, Highlighting | +| `components/FlowEditor/editor/RunTracingPanel.tsx` | SSE Live-Push + Canvas-Highlighting fuer Workflow-Runs | +| `components/FlowEditor/editor/EditorChatPanel.tsx` | AI Chat mit Dateianhang (Drag&Drop) und Source-Picker | +| `components/FlowEditor/editor/CanvasHeader.tsx` | Versioning, Template-Management, Workflow-Aktionen | +| `components/FlowEditor/editor/TemplatePicker.tsx` | Template-Auswahl-Modal | +| `pages/views/graphicalEditor/GraphicalEditorPage.tsx` | Feature-Seite mit KeepAlive, URL-basiertem Workflow-Loading | | `locales/*` | Übersetzungen (z. B. de / en / fr) | ## Regeln / Invarianten diff --git a/b-reference/gateway/ai-agent.md b/b-reference/gateway/ai-agent.md index 5a4106e..c1140e9 100644 --- a/b-reference/gateway/ai-agent.md +++ b/b-reference/gateway/ai-agent.md @@ -1,6 +1,6 @@ - - + + # AI Agent & Knowledge Store @@ -45,6 +45,37 @@ Pro Request propagiert der **ServiceCenterContext** u. a. `userId`, `mandateId`, | `toolSet` | Aktives Tool-Set (Default `"core"`) | | `temperature` | Optional für den Agent-AI-Call | +### Toolbox Registry + +**Datei:** `serviceCenter/services/serviceAgent/toolboxRegistry.py` + +Statt alle Tools flach zu exponieren, gruppiert die **Toolbox Registry** Tools in thematische Toolboxes. Der Agent startet schlank und kann Spezial-Toolboxes zur Laufzeit nachfordern. + +| Toolbox | Anzahl Tools | Default | Requires Connection | +|---------|-------------|---------|-------------------| +| `core` | 20 | Ja | -- | +| `ai` | 9 | Ja | -- | +| `datasources` | 8 | Ja | -- | +| `email` | 5 | Nein | `microsoft` | +| `sharepoint` | 3 | Nein | `microsoft` | +| `clickup` | 3 | Nein | `clickup` | +| `jira` | 3 | Nein | `jira` | +| `workflow` | 9 | Nein | -- (featureCode: graphicalEditor) | +| `trustee` | 1 | Nein | -- (featureCode: trustee) | + +**Aktivierung (`_activateToolboxes` in `mainServiceAgent.py`):** +- Default-Toolboxes sind immer aktiv +- Connection-abhaengige Toolboxes werden aktiviert, wenn der User eine passende Connection hat +- Tools aus inaktiven Toolboxes werden aus der Registry entfernt +- `workflow`-Tools werden explizit via `workflowTools.getWorkflowToolDefinitions` registriert + +**`requestToolbox` Meta-Tool:** +- Erlaubt dem Agent, zur Laufzeit inaktive Toolboxes anzufordern +- Schema: `{ toolboxId: enum[inactive IDs], reason: string }` +- Handler in `mainServiceAgent._registerRequestToolbox()` +- Nach erfolgreichem Aufruf refresht `agentLoop.py` die `toolDefinitions` fuer die naechste Runde +- Nur Toolboxes, die aktuell nicht aktiv sind, erscheinen als Optionen + ### RBAC (Architekturentscheid) Keine separate Tool-Level-RBAC: Zugriff wird über **Datenbank-RBAC** (z. B. File-Queries), **OAuth/Connections** bei externen Quellen und **`serviceAi`** (Billing, Provider-/Modell-RBAC) sowie **`can_access_service`** für `service.agent` durchgesetzt. @@ -59,6 +90,8 @@ Tools sind registrierte Handler mit JSON-Schema für Argumente, **`readOnly`-Fla Zusätzlich zu den unten genannten **Kern-Tools** existieren **dynamische Tools** aus dem Workflow-System: `ActionToolAdapter` liest `methodDiscovery.methods` und registriert jede Action mit `dynamicMode=True` unter einem zusammengesetzten Namen (`{methodShort}_{actionName}`); im Adapter sind diese derzeit **alle als nicht-readOnly** registriert. +**Toolbox-Zuordnung:** Kern-Tools sind den Toolboxes `core`, `ai` und `datasources` zugeordnet (siehe Toolbox Registry oben). Connection-abhaengige Tools (`email`, `sharepoint`, `clickup`, `jira`) werden nur aktiviert, wenn der User eine passende Connection hat. Workflow-Editing-Tools (`workflow` Toolbox) werden separat via `workflowTools.py` registriert. + ### Kern-Tools (registriert via `registerCoreTools` → `coreTools/`, 40 Stück) **Workspace / Dateien** @@ -125,7 +158,7 @@ Zusätzlich zu den unten genannten **Kern-Tools** existieren **dynamische Tools* | Tool | Kurzbeschreibung | |------|------------------| -| `queryFeatureInstance` | Abfrage anderer Feature-Instanz (setzt bei Bedarf `requireNeutralization` für Sub-Calls) | +| `queryFeatureInstance` | Abfrage anderer Feature-Instanz (setzt bei Bedarf `requireNeutralization` für Sub-Calls). Sub-Agent hat `browseTable`, `queryTable` und `aggregateTable` (SUM/COUNT/AVG/MIN/MAX mit GROUP BY). DB-Connection-Pooling und Result-Caching (5 Min TTL). | | `listWorkflowHistory` | Workflow-Historie | | `readWorkflowMessages` | Nachrichten eines Workflows lesen | @@ -218,6 +251,8 @@ Erweiterte Hilfen (z. B. **`readSection`**, Caching) für selektives Lesen sind | `gateway/modules/serviceCenter/services/serviceAgent/conversationManager.py` | Kontextfenster, Summarization, Systemprompt | | `gateway/modules/serviceCenter/services/serviceAgent/datamodelAgent.py` | `AgentConfig`, Events, Trace-Modelle | | `gateway/modules/serviceCenter/services/serviceAgent/actionToolAdapter.py` | Workflow-Actions → Agent-Tools | +| `gateway/modules/serviceCenter/services/serviceAgent/toolboxRegistry.py` | Toolbox-Definitionen, `requestToolbox` Meta-Tool-Schema | +| `gateway/modules/serviceCenter/services/serviceAgent/workflowTools.py` | Workflow-Editing-Tools (readWorkflowGraph, addNode, ...) | | `gateway/modules/serviceCenter/services/serviceAgent/sandboxExecutor.py` | `executeCode`-Sandbox | | `gateway/modules/serviceCenter/services/serviceKnowledge/mainServiceKnowledge.py` | Index, `buildAgentContext`, Workflow-/Round-Memory-Helfer | | `gateway/modules/interfaces/interfaceDbKnowledge.py` | DB-Zugriff Knowledge / RAG | diff --git a/b-reference/gateway/architecture.md b/b-reference/gateway/architecture.md index 8ce518a..3524f67 100644 --- a/b-reference/gateway/architecture.md +++ b/b-reference/gateway/architecture.md @@ -1,6 +1,6 @@ - - + + # Gateway -- Architektur @@ -18,7 +18,7 @@ Unter `gateway/modules/` (Kontext-Audit): | `auth/` | Authentifizierung, CSRF, Token-Refresh-Middleware, JWT | | `connectors/` | DB-Connector (PostgreSQL), Provider-Subpakete (Microsoft, Google, ClickUp, FTP), Ticket/Messaging/Geo-Konnektoren | | `datamodels/` | Pydantic-Datenmodelle (u. a. Ai, Billing, Chat, Content, Files, Knowledge, Rbac, Subscription, Workflow) | -| `features/` | Feature-Module (autonome Domänen): workspace, automation, automation2, chatbot, commcoach, neutralization, realEstate, trustee, teamsbot | +| `features/` | Feature-Module (autonome Domänen): workspace, graphicalEditor, chatbot, commcoach, neutralization, realEstate, trustee, teamsbot | | `interfaces/` | DB-Interfaces (App, Billing, Chat, Knowledge, Management, Subscription), AI-Objects, RBAC, Features, Messaging | | `migration/` | Daten-Migrationen | | `routes/` | REST-API-Routen (u. a. Admin, Billing, DataFiles, DataSources, Security, Store, System) | @@ -27,7 +27,7 @@ Unter `gateway/modules/` (Kontext-Audit): | `serviceHub/` | Service-Registry und Dependency Injection (u. a. `PublicService`-Wrapper) | | `shared/` | Gemeinsame Utilities (attributeUtils, Konfiguration, Logging, …) | | `system/` | System-Konfiguration, Feature-Discovery (`registry.py`: `loadFeatureMainModules`, `loadFeatureRouters`) | -| `workflows/` | Workflow-Engine mit Methoden und Aktionen | +| `workflows/` | Workflow-Engine mit Methoden, Aktionen, Execution Engine und konsolidiertem Scheduler | ## ServiceCenter (Kern-Orchestrierung) @@ -82,7 +82,7 @@ Weitere Interface-Dateien im Ordner (z. B. Voice, Tickets, Messaging, Bootstrap) | Datei / Pfad | Rolle | |--------------|-------| -| `gateway/app.py` | FastAPI-Anwendung, Einbindung von Routen und Middleware | +| `gateway/app.py` | FastAPI-Anwendung (generischer Entry-Point), Routen, Middleware, EventManager, Scheduler-MainLoop | | `gateway/modules/serviceCenter/__init__.py` | Service Center: `getService`, `preWarm`, RBAC-Registrierung für Service-Objekte | | `gateway/modules/serviceCenter/context.py` | `ServiceCenterContext` pro Request | | `gateway/modules/serviceCenter/registry.py` | Service-Registry (CORE / IMPORTABLE) | @@ -95,7 +95,10 @@ Weitere Interface-Dateien im Ordner (z. B. Voice, Tickets, Messaging, Bootstrap) | `gateway/modules/auth/*` | CSRF, Token-Refresh-Middleware, JWT, OAuth | | `gateway/modules/shared/*` | Querschnitt: Konfiguration, Audit-Logging, Events, Utilities | | `gateway/modules/system/registry.py` | Feature-Discovery, Router-Laden, Katalog-Registrierung beim App-Start | -| `gateway/modules/workflows/workflowManager.py` | Zentrale Workflow-Steuerung | +| `gateway/modules/workflows/workflowManager.py` | Zentrale Workflow-Steuerung (Workspace/Chat Workflows) | +| `gateway/modules/workflows/automation2/executionEngine.py` | Graph-Execution-Engine (Graphical Editor) | +| `gateway/modules/workflows/scheduler/mainScheduler.py` | Konsolidierter Workflow-Scheduler | +| `gateway/modules/interfaces/interfaceBootstrap.py` | System-Bootstrap (Templates, Billing, Stripe) | ## Regeln / Invarianten diff --git a/b-reference/gateway/automation.md b/b-reference/gateway/automation.md index 4e4e4b9..bb53623 100644 --- a/b-reference/gateway/automation.md +++ b/b-reference/gateway/automation.md @@ -1,117 +1,211 @@ - - + + -# Automation +# Automation (Graphical Editor) ## Ueberblick -PowerOn hat **mehrere Automatisierungs-Spuren**, die sich die **gleiche Unified Action Library** (`workflows/methods/` + `ActionExecutor`) teilen, aber unterschiedliche **Persistenz**, **Scheduler** und **Execution Engines** nutzen. Die Business Spec beschreibt eine **Ziel-Architektur**: konsolidierte Plattform mit klarer Trennung Mandant / Feature / Feature-Instanz, skalierbarer **Toolbox**-Schicht fuer Agent-Tools und einem **vereinheitlichten Workflow-Datenmodell** (Draft/Published, Runs, Tracing). +PowerOn hat ein **konsolidiertes Automatisierungssystem** basierend auf dem Feature `graphicalEditor`. Die frueheren separaten Systeme (Automation v1, Automation2) wurden entfernt; der gesamte Workflow-Lebenszyklus laeuft ueber ein einheitliches Datenmodell und eine gemeinsame **Unified Action Library** (`workflows/methods/` + `ActionExecutor`). -**Leitentscheide (Business Spec):** +**Architektur-Saeulen:** -- Keine Migration von Altdaten fuer Automation v1 (nicht produktiv); v1 bleibt bis zur Abloesung. -- **Vier Saeulen:** AI Service (Agent, Streaming, Neutralisierung, Failover), Graphical Editor (Flow + kuenftig Editor-Chat/UDB), Automation Scheduler (Cron/Events/Webhooks), **Unified Action Library** mit Toolboxes. -- **Inkonsistenzen heute:** zwei Workflow-Datenwelten (v1 vs Automation2), zwei DB-Schemas, zwei Scheduler-Patterns, zwei Engines -- Ausrichtung ueber Zielmodell und Uebernahme bewaehrter v1-Scheduler-Patterns in Richtung v2. +1. **AI Service** -- Agent mit Toolbox-Registry, Streaming, Neutralisierung, Failover +2. **Graphical Editor** -- n8n-Style Flow-Builder mit AI Chat, UDB, Tracing, Versioning +3. **Consolidated Scheduler** -- `WorkflowScheduler` mit inkrementellem Sync (v1-Patterns) +4. **Unified Action Library** -- Method/Action-Bibliothek mit Toolbox-Zuordnung + +**Leitentscheide:** + +- Legacy-Features `automation` und `automation2` entfernt (Gateway + Frontend) +- Greenfield-DB `poweron_graphicaleditor` (keine Migration von Altdaten) +- v1-Scheduler-Patterns (inkrementell, `eventId`, `replaceExisting`, Stale-Removal) in konsolidierten Scheduler uebernommen +- `app.py` als generischer Entry-Point ohne feature-spezifische Imports --- -## Ist-Systeme (Gateway, Stand 2026-04-05) +## Datenmodell (Greenfield DB `poweron_graphicaleditor`) -| System | Kurzbeschreibung | -|--------|------------------| -| **Automation v1** | Template + Cron + Placeholders; robuster inkrementeller Scheduler-Sync; keine visuelle Branching-Logik. | -| **Automation2** | n8n-Style Graph; Run/Task; Pause/Resume; Human-in-the-loop; weniger robuster Scheduler-Sync als v1. | -| **AI Workspace** | Chat-Agent mit vielen Tools + RAG; kein persistiertes Workflow-Modell wie im Graph-Editor. | +| Modell | Datei | Beschreibung | +|--------|-------|-------------| +| `AutoWorkflow` | `features/graphicalEditor/datamodelFeatureGraphicalEditor.py` | Workflow mit `graph`, `invocations`, `active`, `eventId`, Template-Felder (`isTemplate`, `templateScope`, `sharedReadOnly`) | +| `AutoVersion` | gleiche Datei | Immutabler Graph-Snapshot: Status `draft`/`published`/`archived` | +| `AutoRun` | gleiche Datei | Ausfuehrung: Status `running`/`paused`/`completed`/`failed`, `nodeOutputs`, `context`, `runEnvelope` | +| `AutoStepLog` | gleiche Datei | Pro-Node-Log: `inputSnapshot`, `output`, `startedAt`, `completedAt`, `durationMs`, `tokensUsed`, `retryCount`, `error` | +| `AutoTask` | gleiche Datei | Human-Task bei Pause: Status `pending`/`completed`/`rejected`/`expired` | -**Gemeinsame technische Basis:** Alle genannten Pfade fuehren ueber **`ActionExecutor.executeAction()`** zur Method/Action Library; der Workspace-Agent mappt `dynamicMode`-Actions via **`ActionToolAdapter`** auf Tools; Automation2-Nodes tragen `_method` / `_action`. +**Invarianten:** +- Pro Workflow hoechstens **eine** `PUBLISHED` Version; Scheduler bindet an die veroeffentlichte Version +- `templateScope`: `user` | `instance` | `mandate` | `system` -- steuert Sichtbarkeit und RBAC +- System-Templates (`templateScope=system`, `mandateId=None`) werden im Bootstrap erstellt -### Automation v1 vs v2 (Ist-Vergleich) +### Workflow-Vorlagen -| Aspekt | Automation v1 | Automation2 (v2) | -|--------|----------------|------------------| -| Modell | Template/Cron/Placeholders | Graph + Node-Typen (`nodeDefinitions/`) | -| DB / Schema | `poweron_automation` | `poweron_automation2` | -| Scheduler | Inkrementell, Callback `automation.changed`, `eventId` auf `AutomationDefinition` | Full re-register, Callback `automation2.workflow.changed` | -| Engine | `WorkflowManager` + `WorkflowProcessor` + `modeAutomation` | `executionEngine.executeGraph` | -| Staerken | Bewaehrtes Scheduling, Execution-Logs | Branching, Loops, Pause/Resume, visuelles Editing | - -**Konsolidierungsrichtung (Spec):** v1-Scheduler-Muster (inkrementell, Job-Handle, Reload+`active`-Check vor Run, capped Logs, `sysCreatedBy` fuer Kontext) in die v2-Welt uebernehmen; einheitliches **Workflow/Version/Run**-Konzept langfristig ueber beide Welten. +| Scope | Sichtbarkeit | Editierbar | Erstellt durch | +|-------|-------------|------------|----------------| +| `user` | Nur Ersteller | Ja | User ("Als Vorlage speichern") | +| `instance` | Alle User der Feature-Instanz | Nein (read-only) | Scope-Erweiterung | +| `mandate` | Alle User des Mandanten | Nein (read-only) | Scope-Erweiterung | +| `system` | Plattformweit | Nein (read-only) | Bootstrap (`_bootstrapSystemTemplates`) | --- -## Datenmodell +## Scheduler (`WorkflowScheduler`) -### Ist: Konkrete Modelle (Gateway, Stand 2026-04-05) +**Datei:** `workflows/scheduler/mainScheduler.py` -| Modell | Datei | DB | Beschreibung | -|--------|-------|-----|-------------| -| `AutomationDefinition` | `features/automation/datamodelFeatureAutomation.py` | `poweron_automation` | v1 Template mit `schedule`, `placeholders`, `eventId` | -| `ChatWorkflow` | `datamodels/datamodelChat.py` | `poweron_chat` | v1 Execution-Artefakt (Status, Tasks, Messages) | -| `Automation2Workflow` | `features/automation2/datamodelFeatureAutomation2.py` | `poweron_automation2` | v2 Graph mit `active`, inline `graph`, `invocations` | -| `Automation2WorkflowRun` | gleiche Datei | `poweron_automation2` | v2 Run: Status `running`/`paused`/`completed`/`failed`, `nodeOutputs`, `context` | -| `Automation2HumanTask` | gleiche Datei | `poweron_automation2` | Human-Task: Status `pending`/`completed`/`rejected` | +Konsolidierter Scheduler mit v1-Patterns: -**Hinweis:** Es gibt **keine** `WorkflowVersion`-Tabelle -- v2 speichert den Graph direkt in `Automation2Workflow`. Tracing ist `nodeOutputs` im Run, nicht ein separates `RunStepLog`-Entity. +| Aspekt | Implementierung | +|--------|----------------| +| Sync-Muster | Inkrementell: nur geaenderte Jobs re-registrieren (`eventId` Tracking) | +| Stale-Removal | Jobs fuer geloeschte/deaktivierte Workflows werden entfernt | +| Re-Registration | `replaceExisting=True` fuer idempotente Updates | +| Active-Check | Vor Execution: Workflow `active` und Entry-Point `enabled` pruefen | +| Cron-Parsing | Einfache Intervalle (*/N) als Sekunden; komplexe Cron via `parse_cron_to_kwargs` | +| Thread-Bridge | `setMainLoop()` fuer async Handler aus Scheduler-Threads | +| Delayed Sync | 5s nach Start fuer spaete DB-Verfuegbarkeit | +| Change-Callback | `callbackRegistry` fuer `graphicalEditor.workflow.changed` | -### Ziel: Vereinheitlichtes Workflow-Modell (Spec -- nicht implementiert) +**Lifecycle:** +- Start: `mainGraphicalEditor.onStart()` -> `startScheduler(eventUser)` +- Stop: `mainGraphicalEditor.onStop()` -> `stopScheduler()` +- Manual Sync: `POST /api/workflows/{instanceId}/schedule-sync` -> `syncNow()` +- Main Loop: `app.py` setzt `setSchedulerMainLoop(main_loop)` beim Start -| Entitaet | Zweck | Heute approximiert durch | -|----------|-------|--------------------------| -| **Workflow** | Metadaten, Mandant/Instanz, `active`, `eventId`, Zeiger auf aktuelle Version | `Automation2Workflow` (ohne Versioning) | -| **WorkflowVersion** | Immutabler Snapshot: `graph`, `invocations`, Status draft/published/archived | *nicht vorhanden* (Graph inline in Workflow) | -| **WorkflowRun** | Ausfuehrung mit Status, Trigger, `nodeOutputs`, Kostenfelder | `Automation2WorkflowRun` (ohne Kostenfelder, Statusmenge abweichend) | -| **RunStepLog** | Pro Node: Input, Output, Dauer, Fehler, Token | *nicht vorhanden* (approximiert durch `nodeOutputs`) | -| **HumanTask** | Menschliche Aufgabe bei Pause; Status pending/completed/cancelled/expired | `Automation2HumanTask` (Status: `pending`/`completed`/`rejected`, kein `expired`) | - -**Invarianten (Zielmodell):** Pro Workflow hoechstens **eine** `PUBLISHED` Version; Scheduler bindet an die veroeffentlichte Version. - -### Toolbox-Datenmodell (Ziel -- nicht im Gateway implementiert) - -`ToolboxDefinition` (id, label i18n, `tools[]`, optional `requiresConnection`), `ToolboxRegistry`, erweiterte `AgentConfig` mit `initialToolboxes` / `availableToolboxes`. - -> Kein Match im Gateway-Code fuer `requestToolbox`, `ToolboxDefinition` oder `availableToolboxes` (Stand 2026-04-05). - -### Gateway-Schichten - -Frontend -> **Features** (instanzgebunden) -> **Services** (request-scoped) -> **Shared Infrastructure** (`workflows/methods`, `workflows/processing`, `workflows/automation2`, `interfaces`, `aicore`, `datamodels`, `security`). - -**Feature-Container-Pattern:** `features//` mit `main*.py` (FEATURE_CODE, UI/RESOURCE/TEMPLATE_ROLES), `routeFeature*.py`, `interfaceFeature*.py`, `datamodelFeature*.py`, optional `nodeDefinitions/`, `service*/`. Discovery ueber `registry.py` / `ServiceHub`. +**Run-Failure-Handling:** +- In-App Notification fuer Workflow-Creator +- Messaging-Subscription (`GraphicalEditorRunFailed`) fuer E-Mail-Benachrichtigung +- Event-Emission (`graphicalEditor.run.failed`) --- -## Ziel-Konzepte (Business Spec, nicht implementiert) +## Execution Engine -**Toolbox-Konzept:** Statt alle Tools flach zu exponieren, **thematische Toolboxes** (`core`, `ai`, `email`, `sharepoint`, `workflow`, ...) mit Meta-Tool **`requestToolbox`** -- Agent startet schlank, fordert Spezial-Toolboxes nach Bedarf; **`availableToolboxes`** ist pro Feature/RBAC/Connections filterbar. +**Datei:** `workflows/automation2/executionEngine.py` -**Sub-Agents:** Datenintensive Features (z. B. Trustee) kapseln Schema-Wissen in einem **Feature Data Agent**; Main-Agent sieht ein aggregiertes Tool (`queryFeatureInstance`), nicht Dutzende Tabellen-Tools. +| Feature | Details | +|---------|---------| +| Graph-Execution | Topologische Sortierung, Branch-Erkennung (ifElse/switch), Loop-Support | +| Pause/Resume | `PauseForHumanTaskError`, `PauseForEmailWaitError` mit Loop-State-Persistenz | +| Retry | Pro-Node Retry-Policy (`retryMaxAttempts`, `retryDelaySeconds`) | +| Step-Logging | `AutoStepLog` mit `inputSnapshot` fuer alle Pfade (inkl. Loops, Skipped) | +| SSE Live-Push | `_emitStepEvent()` sendet Step-Updates an `EventManager`-Queue (`run-trace-{runId}`) | +| Run-Events | `run_complete` / `run_failed` Events am Ende der Execution | -**Agent-Run (State Machine, konzeptionell -- nicht im Code):** `IDLE` -> `THINKING` -> bei Tool-Calls `EXECUTING_TOOLS` -> optional `TOOLBOX_ESCALATION` / `SUB_AGENT_CALL` -> `COMPLETED` / `FAILED` / `CANCELLED` (Limits: `maxRounds`, `maxCostCHF`). +**InputSnapshot-Abdeckung:** +- Regulaere Nodes: Outputs aller Vorgaenger-Nodes +- Loop-Header (`flow.loop`): Vorgaenger-Outputs +- Loop-Body: `_loopItem`, `_loopIndex` + Vorgaenger-Outputs +- Loop-Resume: `_loopItem`, `_loopIndex` + Vorgaenger-Outputs +- Skipped Nodes: `_skipReason: "inactive_branch"` + Vorgaenger-Outputs -**RBAC (Kurz):** Zwei getrennte Template-Systeme -- **System-Template-Rollen** (Mandant: admin/user/viewer) vs **Feature-Template-Rollen** (Instanz: z. B. workspace-admin); keine Vermischung. +--- + +## Node-Types + +Definiert in `features/graphicalEditor/nodeDefinitions/`: + +| Kategorie | Nodes | +|-----------|-------| +| **Trigger** | `trigger.manual`, `trigger.schedule`, `trigger.webhook`, `trigger.form`, `trigger.event` | +| **Flow** | `flow.ifElse`, `flow.switch`, `flow.loop`, `flow.merge`, `flow.delay` | +| **Input** | `input.humanTask`, `input.emailWait` | +| **AI** | `ai.prompt`, `ai.classify`, `ai.extract`, `ai.summarize` | +| **Email** | `email.checkEmail`, `email.sendEmail`, `email.draftEmail` | +| **SharePoint** | `sharepoint.listFiles`, `sharepoint.readFile`, `sharepoint.upload` | +| **ClickUp** | `clickup.searchTasks`, `clickup.createTask`, `clickup.updateTask` | +| **File** | `file.create` | +| **Data** | `data.transform`, `data.filter`, `data.aggregate` | +| **Trustee** | `trustee.refreshAccountingData`, `trustee.extractFromFiles`, `trustee.processDocuments`, `trustee.syncToAccounting` | + +--- + +## Toolbox Registry + +**Datei:** `serviceCenter/services/serviceAgent/toolboxRegistry.py` + +Thematische Tool-Gruppierungen fuer den AI Agent: + +| Toolbox | Tools | Default | Requires Connection | +|---------|-------|---------|-------------------| +| `core` | 20 (readFile, listFiles, webSearch, writeFile, ...) | Ja | -- | +| `ai` | 9 (summarizeContent, generateImage, executeCode, ...) | Ja | -- | +| `datasources` | 8 (browseDataSource, searchDataSource, ...) | Ja | -- | +| `email` | 5 (sendMail, outlook_readEmails, ...) | Nein | `microsoft` | +| `sharepoint` | 3 (sharepoint_findDocuments, ...) | Nein | `microsoft` | +| `clickup` | 3 (clickup_searchTasks, ...) | Nein | `clickup` | +| `jira` | 3 (jira_connect, ...) | Nein | `jira` | +| `workflow` | 9 (readWorkflowGraph, addNode, ...) | Nein | -- (featureCode: graphicalEditor) | +| `trustee` | 1 (trustee_refreshAccountingData) | Nein | -- (featureCode: trustee) | + +**`requestToolbox` Meta-Tool:** +- Agent kann zur Laufzeit inaktive Toolboxes anfordern +- Handler in `mainServiceAgent._registerRequestToolbox()` +- `agentLoop.py` refresht `toolDefinitions` nach erfolgreichem Aufruf +- Nur inaktive Toolboxes werden als Enum-Optionen angeboten + +**Aktivierung:** +- `_activateToolboxes` in `mainServiceAgent.py` prueft User-Connections +- Toolboxes ohne `requiresConnection` sind immer verfuegbar +- Tools aus inaktiven Toolboxes werden aus der Registry entfernt + +--- + +## RBAC + +Feature-Code: `graphicalEditor` + +| Template-Rolle | UI-Zugriff | Daten-Zugriff | +|----------------|-----------|---------------| +| `graphicalEditor-viewer` | Dashboard, Workflows, Tasks, Templates (view) | Read: Mandate | +| `graphicalEditor-user` | + Editor | CRUD: Mandate | +| `graphicalEditor-admin` | Alle UI/Resource | CRUD: Mandate | + +Rollen werden beim Feature-Start via `_syncTemplateRolesToDb()` synchronisiert (inkl. Mandate-Instanz-Rollen). + +--- + +## API-Endpunkte (Auswahl) + +| Methode | Pfad | Beschreibung | +|---------|------|-------------| +| POST | `/{instanceId}/execute` | Workflow ausfuehren | +| GET | `/{instanceId}/runs/{runId}/stream` | SSE Live-Tracing fuer einen Run | +| POST | `/{instanceId}/schedule-sync` | Scheduler manuell synchronisieren | +| POST | `/{instanceId}/{workflowId}/chat/stream` | AI Chat SSE Stream | +| GET | `/{instanceId}/node-types` | Verfuegbare Node-Types | +| GET/POST | `/{instanceId}/workflows` | Workflows CRUD | +| GET/POST | `/{instanceId}/templates` | Templates CRUD | +| POST | `/{instanceId}/workflows/{workflowId}/versions/draft` | Draft-Version erstellen | +| POST | `/{instanceId}/workflows/{workflowId}/versions/{versionId}/publish` | Version veroeffentlichen | --- ## Schluessel-Dateien -| Bereich | Typische Pfade (`gateway/modules/`) | -|---------|-------------------------------------| +| Bereich | Pfade (`gateway/modules/`) | +|---------|--------------------------| +| Feature-Definition | `features/graphicalEditor/mainGraphicalEditor.py` | +| API-Routes | `features/graphicalEditor/routeFeatureGraphicalEditor.py` | +| Interface | `features/graphicalEditor/interfaceFeatureGraphicalEditor.py` | +| Datenmodell | `features/graphicalEditor/datamodelFeatureGraphicalEditor.py` | +| Node-Definitionen | `features/graphicalEditor/nodeDefinitions/` | +| Execution Engine | `workflows/automation2/executionEngine.py` | +| Scheduler | `workflows/scheduler/mainScheduler.py` | +| Toolbox Registry | `serviceCenter/services/serviceAgent/toolboxRegistry.py` | | Action Library | `workflows/methods/`, `workflows/processing/` (`ActionExecutor`, `methodDiscovery`) | -| Automation v1 Feature | `features/automation/` | -| Automation v1 Runtime | `workflows/automation/` (`mainWorkflow.py`, `subAutomationSchedule.py`) | -| Automation2 Feature | `features/automation2/` | -| Automation2 Runtime | `workflows/automation2/` (`executionEngine.py`, `subAutomation2Schedule.py`) | -| Agent <-> Actions | `serviceCenter/services/serviceAgent/` (Tool-Registrierung, `ActionToolAdapter`) | -| Feature-Discovery | `system/registry.py`, `serviceHub/__init__.py` | -| RBAC | `interfaces/interfaceRbac.py`, `security/`, Rollen/AccessRules in Datamodels | +| Agent Tools | `serviceCenter/services/serviceAgent/` (coreTools, actionToolAdapter, workflowTools) | +| Bootstrap | `interfaces/interfaceBootstrap.py` (System-Templates, Billing) | --- ## Regeln / Invarianten -1. **Eine Action Library:** Aenderungen an Methods/Actions betreffen Workspace, Automation v1, Automation2 und Agent-Tools gleichzeitig -- Kompatibilitaet und `actionId`-Stabilitaet beachten. -2. **RBAC strikt trennen:** Mandantenrollen vs Feature-Instanz-Rollen nicht mischen; Permissions ueber AccessRules und Prioritaetsregeln. -3. **Scheduler vs Editor:** Ausfuehrung und Zeitplanung gehoeren zur **Scheduler-Saeule**; der Graph ist **Version**-gebunden (Draft vs Published). -4. **Tool-Skalierung:** Flache Tool-Listen skalieren nicht; Toolbox + `requestToolbox` + connection-basierte Verfuegbarkeit sind das vorgesehene Gegenmittel (Ziel, nicht implementiert). -5. **Zielmodell vs Ist:** `Workflow` / `WorkflowVersion` / `WorkflowRun` in der Spec sind **Zielarchitektur**. Ist-Modelle siehe oben (`Automation2Workflow`, `Automation2WorkflowRun` etc.). Abgleich bei Implementierungsarbeiten erforderlich. -6. **Neutralisierung / KI:** Plattformweit gelten die zentralen KI-Datenpfade (siehe `workflow.md` / Compliance); Automation nutzt dieselben Services wie der Rest des Gateways. +1. **Eine Action Library:** Aenderungen an Methods/Actions betreffen Workspace, Graph-Editor und Agent-Tools gleichzeitig -- `actionId`-Stabilitaet beachten. +2. **RBAC strikt trennen:** Mandantenrollen vs Feature-Instanz-Rollen nicht mischen; Permissions ueber AccessRules. +3. **Scheduler vs Editor:** Ausfuehrung und Zeitplanung gehoeren zum Scheduler; der Graph ist Version-gebunden (Draft vs Published). +4. **Tool-Skalierung:** Toolbox-Konzept mit `requestToolbox` Meta-Tool; connection-basierte Verfuegbarkeit. +5. **`app.py` generisch:** Keine feature-spezifischen Imports in `app.py`; Feature-Lifecycle in `mainGraphicalEditor.onStart/onStop`. +6. **Neutralisierung / KI:** Plattformweit gelten die zentralen KI-Datenpfade; Automation nutzt dieselben Services. +7. **Bootstrap idempotent:** `initBootstrap` mit `_bootstrapDone` Flag; System-Templates, Billing, Stripe-Prices. diff --git a/b-reference/gateway/workflow.md b/b-reference/gateway/workflow.md index 87a2be1..7eaf788 100644 --- a/b-reference/gateway/workflow.md +++ b/b-reference/gateway/workflow.md @@ -1,6 +1,6 @@ - - + + # Workflow-Engine @@ -11,10 +11,11 @@ Die Workflow-Engine im Gateway orchestriert KI-gestützte Aufgabenpläne und die **Einsatzorte (Konsumenten der Action Library):** - **Workspace (Dynamic Mode):** `WorkflowProcessor` / `modeDynamic` → Planung (Stage 1/2) → `ActionExecutor` -- **Automation v1:** `WorkflowProcessor` / `modeAutomation` → `ActionExecutor` -- **Automation2:** Graph-Engine mappt Nodes (`_method` / `_action`) auf dieselbe Library +- **Graphical Editor:** `executionEngine.executeGraph` mappt Nodes (`_method` / `_action`) auf dieselbe Library - **Workspace-Agent:** `ActionToolAdapter` exponiert `dynamicMode=True`-Aktionen als Tools → `ActionExecutor` +*Hinweis:* Die frueheren separaten Systeme Automation v1 und Automation2 wurden im Rahmen der Automation Unification (2026-04) entfernt. Der Graphical Editor ist der einzige Graph-basierte Konsument. + **Ausführungsmodell:** Pro Workflow-Instanz sequentielle Ausführung (kein paralleles Multi-Task-Modell auf einer Instanz). Ausführungszähler (`currentRound`, `currentTask`, `currentAction`) liegen am **`ChatWorkflow`** (Single Source of Truth). --- @@ -54,7 +55,7 @@ Methoden sind Python-Klassen unter `gateway/modules/workflows/methods/`; der **M | `sharepoint` | `findDocumentPath`, `readDocuments`, `uploadDocument`, `listDocuments`, `analyzeFolderUsage`, `findSiteByUrl`, `downloadFileByPath`, `copyFile`, `uploadFile` | | `clickup` | `listTasks`, `searchTasks`, `getTask`, `createTask`, `updateTask`, `uploadAttachment` | | `jira` | `connectJira`, `exportTicketsAsJson`, `importTicketsFromJson`, `mergeTicketData`, `parseCsvContent`, `parseExcelContent`, `createCsvContent`, `createExcelContent` | -| `trustee` | `extractFromFiles`, `processDocuments`, `syncToAccounting` | +| `trustee` | `extractFromFiles`, `processDocuments`, `syncToAccounting`, `refreshAccountingData` (`dynamicMode=True`) | | `chatbot` | `queryDatabase` | | `file` | `create` | @@ -76,12 +77,15 @@ Methoden sind Python-Klassen unter `gateway/modules/workflows/methods/`; der **M | Pfad (unter `gateway/modules/`) | Rolle | |--------------------------------|--------| -| `workflows/workflowManager.py` | Workflow-Orchestrierung, Einstieg | +| `workflows/workflowManager.py` | Workflow-Orchestrierung fuer Workspace/Chat (Einstieg) | | `workflows/processing/` | Processor, Modi (`modeDynamic`, `modeAutomation`), `ActionExecutor` | +| `workflows/automation2/executionEngine.py` | Graph-Execution-Engine (Graphical Editor): Branching, Loops, Pause/Resume, Step-Logging, SSE Live-Push | +| `workflows/scheduler/mainScheduler.py` | Konsolidierter Workflow-Scheduler (inkrementeller Sync) | | `workflows/methods/methodBase.py` | Basis für Methoden, Aktions-Validierung | | `workflows/methods/method*/` | Konkrete Methoden und Aktionen | | `datamodels/datamodelChat.py` | `ChatWorkflow`, `TaskContext`, Task-/Plan-Modelle | | `datamodels/datamodelWorkflowActions.py` | Aktionsdefinitionen | +| `features/graphicalEditor/datamodelFeatureGraphicalEditor.py` | `AutoWorkflow`, `AutoVersion`, `AutoRun`, `AutoStepLog`, `AutoTask` | | `serviceCenter/services/serviceChat/` | Fortschritt, Logs, Nachrichten/Dokumente am Workflow | | `serviceCenter/services/serviceAi/` | Planning- und Content-KI (kein direkter Workflow-Import aus Methods zurück) | | `interfaces/interfaceDbChat*` | Persistenz Workflow/Nachrichten/Dokumente | @@ -95,4 +99,4 @@ Methoden sind Python-Klassen unter `gateway/modules/workflows/methods/`; der **M 3. **Typisierung:** Bevorzugt Pydantic-Modelle für Planungs- und Aktionskontext (`ActionDefinition`, `TaskResult`, …); JSON aus KI-Calls über zentrale Parse-/Repair-Hilfen. 4. **Sequenz:** Ein Workflow läuft in einer Instanz sequentiell ab; parallele Ausführung ist kein Designziel der beschriebenen Engine. 5. **Neutralisierung:** Sensible Daten an **KI-Modelle** laufen über das zentrale Gate in `serviceAi` (`mainServiceAi.py`); die Workflow-Aktion `context.neutralizeData` ist eine **explizite** Neutralisierung extrahierter Inhalte und ersetzt nicht das globale KI-Gate (siehe Compliance-Doku). -6. **Gemeinsame Library:** Dieselben Actions werden von Chat-Workflow, Automation v1/v2 und Agent-Tools genutzt — Änderungen an `actionId` / Parametern wirken quer über alle Konsumenten. +6. **Gemeinsame Library:** Dieselben Actions werden von Chat-Workflow, Graphical Editor und Agent-Tools genutzt — Änderungen an `actionId` / Parametern wirken quer über alle Konsumenten. diff --git a/c-work/1-plan/2026-04-analysis-editor.md b/c-work/1-plan/2026-04-analysis-editor.md new file mode 100644 index 0000000..0a126a7 --- /dev/null +++ b/c-work/1-plan/2026-04-analysis-editor.md @@ -0,0 +1,398 @@ + + + +# Analyse: Typed Node Handover System für den Graphical Editor + +## 1 Problemstellung + +Der Graphical Editor besitzt heute **keine formale Typisierung** der Daten, die zwischen Nodes fließen. Jede Node produziert ein freiformiges Dict; die Folge-Node versucht heuristisch, daraus das Passende zu extrahieren. Das führt zu: + +| Symptom | Wo sichtbar | +|---------|-------------| +| Spezialcode pro Paar (z.B. `_extractEmailContentFromUpstream`, `_getContextFromUpstream`, `_gatherAttachmentDocumentsFromUpstream`) | `actionNodeExecutor.py` (~860 Zeilen, >50 % handover Heuristik) | +| DataPicker zeigt **hartcodierte** Beispiel-Schemas (`outputPreviewRegistry.ts`) — stimmt oft nicht mit echten Laufzeit-Outputs überein | Frontend `outputPreviewRegistry.ts` | +| Kein `data.transform`, `data.filter`, `data.aggregate` implementiert — nur in `automation.md` als Placeholder aufgelistet | `nodeDefinitions/` hat keine Datei dafür | +| Kein „Aggregate" (Gegenstück zu `flow.loop`'s For-Each) | Engine sammelt Loop-Body-Resultate nicht auf | +| Frontend-Parameter haben **eigene** Typdefinitionen (node-level `type: "string"`) statt der in `MethodBase` etablierten `WorkflowActionParameter` mit `FrontendType`-Enum + Validierung | `ai.py`, `email.py` etc. vs. `methodBase.py` | + +**Kern:** Die Method/Action-Schicht hat bereits eine saubere Parameter-Typisierung (`WorkflowActionParameter`, `_validateType`, `_validateParameters`, `FrontendType`). Aber der Graph-Editor nutzt sie weder für Input-Konfiguration noch für die Handover-Logik. + +--- + +## 2 Ist-Zustand (Layer für Layer) + +### 2.1 Node-Definitionen (`nodeDefinitions/*.py`) + +Jede Node ist ein Dict mit: + +```python +{ + "id": "email.draftEmail", + "parameters": [ + {"name": "subject", "type": "string", "required": True, ...}, + ], + "inputs": 1, "outputs": 1, + "_method": "outlook", "_action": "composeAndDraftEmailWithContext", + "_paramMap": {"connectionId": "connectionReference", ...}, +} +``` + +**Was fehlt:** +- Kein `outputSchema` — was liefert die Node zurück? +- Kein `inputSchema` — was erwartet die Node am Eingang? +- `type: "string"` ist Node-Editor-intern, nicht identisch mit `WorkflowActionParameter.type` (`str`, `int`, `List[str]`, …). +- Kein `frontendType` (d.h. Frontend baut eigene Config-Components per Node-Typ statt generisch). + +### 2.2 Execution Engine (`executionEngine.py`) + +- Topologische Sortierung → iteriert Nodes → ruft Executor auf → speichert Output in `nodeOutputs[nodeId]`. +- **Kein Output-Vertrag**: der Executor liefert `Any`, das Dict wird 1:1 in `nodeOutputs` gelegt. +- Folge-Nodes holen via `inputSources[nodeId][0]` den Vorgänger-Output und _hoffen_, dass er das richtige Format hat. + +### 2.3 ActionNodeExecutor (`actionNodeExecutor.py`) + +- ~860 Zeilen, davon ~60 % dedizierte Merge-Logik für Paare: `email→AI`, `AI→email.draftEmail`, `file.create` content-gathering, ClickUp merge, etc. +- Aufruft am Ende `ActionExecutor.executeAction(method, action, params)` — dessen `MethodBase._validateParameters` prüft die **Action**-Parameter, nicht den Graph-Port-Kontrakt. +- Baut ein Output-Dict mit teilweise inkonsistenten Keys (`documents` vs. `documentList` vs. `data` vs. `context`). + +### 2.4 DataPicker + outputPreviewRegistry (Frontend) + +- `outputPreviewRegistry.ts` registriert **statische Beispiele** pro Node-Typ. +- DataPicker zeigt daraus einen Baum und erzeugt `DataRef { type: "ref", nodeId, path }`. +- `resolveParameterReferences` (Backend) löst `DataRef` gegen echte `nodeOutputs`. +- **Problem:** Die Preview-Struktur ist manuell gepflegt und **divergiert** vom echten Output. Der User wählt Pfade, die zur Laufzeit nicht existieren oder anders heißen. + +### 2.5 Method/Action Parameter-System (bereits existent) + +`WorkflowActionParameter` + `MethodBase._validateParameters`: + +```python +class WorkflowActionParameter(BaseModel): + name: str + type: str # 'str', 'int', 'List[str]', 'Dict[str, Any]' + frontendType: FrontendType # TEXT, TEXTAREA, SELECT, USER_CONNECTION, … + frontendOptions: Optional[...] + required: bool + default: Optional[Any] + validation: Optional[Dict] +``` + +`_validateType` konvertiert + prüft: `str→str`, `int→int`, `List[str]→[str,…]`, usw. + +**Dieses System funktioniert bereits** für Workspace-Actions. Es wird aber **nicht** für Node-Ein-/Ausgänge genutzt. + +--- + +## 3 Ziel-Architektur: Typed Port System + +### 3.1 Kern-Konzept: Port-Schema + +Jede Node deklariert **typisierte Ports** für Ein- und Ausgänge — analog zu `WorkflowActionParameter`, aber für den Graphen. + +``` +┌──────────────────────────────────────────────────────────────────────┐ +│ Node Definition (Beispiel: email.draftEmail) │ +│ │ +│ inputPorts: │ +│ [0]: { schema: EmailDraft } ← structured type │ +│ EmailDraft = { subject: str, body: str, to: List[str] } │ +│ │ +│ outputPorts: │ +│ [0]: { schema: ActionResult } │ +│ ActionResult = { success: bool, error: str?, │ +│ documents: List[Document] } │ +│ │ +│ parameters: (config, unabhängig von Ports) │ +│ connectionId: { type: str, frontendType: USER_CONNECTION } │ +└──────────────────────────────────────────────────────────────────────┘ +``` + +### 3.2 Port-Schema Definition + +```python +class PortField(BaseModel): + name: str + type: str # str, int, bool, List[str], List[Document], Dict[str,Any], … + description: Dict[str, str] # {en, de, fr} + required: bool = True + +class PortSchema(BaseModel): + fields: List[PortField] + +class NodePortDefinition(BaseModel): + inputPorts: Dict[int, PortSchema] # port-index → schema + outputPorts: Dict[int, PortSchema] # port-index → schema +``` + +### 3.3 Einheitliche Output-Typen (Port-Typen-Katalog) + +Statt freier Dicts gibt es benannte Schemas, die Node-übergreifend wiederverwendbar sind: + +| Port-Typ | Felder | Produziert von | Konsumiert von | +|----------|--------|----------------|----------------| +| `DocumentList` | `documents: List[{name, data, mimeType, metadata}]` | sharepoint.readFile, sharepoint.downloadFile, ai.*, file.create, input.upload | ai.*, file.create, email.draftEmail, sharepoint.uploadFile | +| `FileList` | `files: List[{url, name, path, size}]` | sharepoint.listFiles, sharepoint.findFile | sharepoint.readFile, sharepoint.downloadFile, flow.loop | +| `EmailDraft` | `subject: str, body: str, to: List[str], cc?: List[str], attachments?: DocumentList` | ai.prompt (mode=email) | email.draftEmail, email.sendEmail | +| `EmailList` | `emails: List[{subject, from, to, body, date, attachments}]` | email.checkEmail, email.searchEmail | ai.prompt, flow.loop, flow.ifElse | +| `TaskList` | `tasks: List[{id, name, status, url, …}]` | clickup.searchTasks, clickup.listTasks | flow.loop, clickup.updateTask | +| `TaskResult` | `success: bool, taskId: str, task: {id, name, status}` | clickup.createTask, clickup.updateTask | flow.ifElse | +| `FormPayload` | `payload: Dict[str, Any]` (dynamisch, Keys = Feldnamen) | trigger.form, input.form | Alle (via Referenz auf Einzelfelder) | +| `AiResult` | `prompt: str, response: str, context: str, documents: List[Document]` | ai.* | email.draftEmail, file.create, sharepoint.uploadFile | +| `BoolResult` | `result: bool, reason?: str` | input.approval, input.confirmation | flow.ifElse | +| `TextResult` | `text: str` | input.comment | ai.*, file.create | +| `LoopItem` | `currentItem: Any, currentIndex: int, items: List[Any], count: int` | flow.loop (pro Iteration) | Loop-Body Nodes | +| `AggregateResult` | `items: List[Any], count: int` | **data.aggregate** (NEU) | Alle | + +### 3.4 Schema auf Node-Definitions + +Erweiterung der bestehenden Node-Definitions um `outputPorts` und `inputPorts`: + +```python +{ + "id": "ai.prompt", + "category": "ai", + "parameters": [...], # Config — bleibt wie bisher + "inputs": 1, + "outputs": 1, + + # NEU ───────────────────────────────────────── + "inputPorts": { + 0: {"accepts": ["DocumentList", "TextResult", "FormPayload", "EmailList", "AiResult", "Any"]}, + }, + "outputPorts": { + 0: {"schema": "AiResult"}, + }, +} +``` + +```python +{ + "id": "email.draftEmail", + "inputPorts": { + 0: {"accepts": ["EmailDraft", "AiResult", "TextResult"]}, + }, + "outputPorts": { + 0: {"schema": "ActionResult"}, + }, +} +``` + +### 3.5 Konsequenzen für bestehende Schichten + +#### A) Node-Definitionen — einmalige Migration + +Jede Node bekommt `inputPorts` + `outputPorts`. Bestehende `inputs`/`outputs` (Zählwerte) bleiben für Rückwärtskompatibilität, aber die Schemas werden die Quelle der Wahrheit. + +#### B) Executors — Output normalisieren + +Jeder Executor erhält eine `_normalizeOutput(rawResult, portSchema) → Dict` Funktion. Sie sorgt dafür, dass die Keys/Typen dem deklarierten Schema entsprechen. Für `AiResult` z.B.: + +```python +def _normalizeAiResult(raw: Any) -> Dict: + return { + "prompt": raw.get("prompt", ""), + "response": raw.get("response", raw.get("context", "")), + "context": raw.get("context", ""), + "documents": _ensureDocumentList(raw.get("documents", [])), + } +``` + +Der Spezialcode in `actionNodeExecutor.py` (~400 Zeilen Paar-Heuristik) fällt dann weg und wird durch generische Normalizer pro Port-Typ ersetzt. + +#### C) ExecutionEngine — Handover-Validierung + +Nach jedem Node-Execute: `nodeOutputs[nodeId]` wird gegen `outputPorts[0].schema` geprüft (Warnung oder Fehler bei Mismatch). Vor jedem Node-Execute: Input-Port-Kompatibilitäts-Check (`accepts` enthält den Schema-Typ des Vorgänger-Outputs). + +#### D) Frontend — DataPicker aus Schema generieren + +`outputPreviewRegistry.ts` wird ersetzt durch eine generische Funktion, die aus dem PortSchema den Preview-Baum baut. Kein manuelles Pflegen mehr: + +```typescript +function buildPreviewFromSchema(schema: PortSchema): Record { + // Iteriert schema.fields → Beispielwert pro Typ +} +``` + +#### E) Frontend — Generisches Parameter-Rendering + +Statt pro Node-Typ eine eigene Config-Component zu schreiben (aktuell 12+ Dateien), können die meisten Parameter-Felder generisch aus dem `WorkflowActionParameter`-Schema gerendert werden. Spezial-UIs (FormBuilder, ClickUp Browse, etc.) bleiben als Override. + +#### F) Verbindungs-Validierung im Editor + +Beim Ziehen einer Kante: prüfe `sourceNode.outputPorts[outputIdx].schema` ∈ `targetNode.inputPorts[inputIdx].accepts`. Falls inkompatibel: Kante rot markieren / verhindern. + +--- + +## 4 Fehlende Nodes / Konzepte + +### 4.1 data.aggregate (Gegenstück zu flow.loop) + +Loop verteilt Items → Body → aber am Ende gibt es keinen Collector. Heute liegt nur das letzte Body-Ergebnis in `nodeOutputs`. + +**Lösung: `data.aggregate`-Node** + +```python +{ + "id": "data.aggregate", + "category": "data", + "label": {"en": "Aggregate", "de": "Sammeln", "fr": "Agréger"}, + "description": {"en": "Collect results from loop body into a list", ...}, + "parameters": [ + {"name": "mode", "type": "string", "options": ["collect", "concat", "sum", "count"], "default": "collect"}, + ], + "inputs": 1, "outputs": 1, + "inputPorts": {0: {"accepts": ["Any"]}}, + "outputPorts": {0: {"schema": "AggregateResult"}}, + "executor": "data", +} +``` + +**Engine-Änderung:** Im Loop-Body erkennt die Engine eine `data.aggregate`-Node und sammelt pro Iteration das Ergebnis in einer Liste. Nach Loop-Ende: `nodeOutputs[aggregateNodeId] = { items: [...], count: N }`. + +### 4.2 data.transform + +Reiner Mapping-Node: Felder umbenennen, extrahieren, umstrukturieren. Konfiguration per Key-Value-Mapping oder einfachem Expression-Sprache. + +```python +{ + "id": "data.transform", + "category": "data", + "parameters": [ + {"name": "mapping", "type": "json", "description": "Key-Value Mapping: {outputField: inputRef}"}, + ], + "inputPorts": {0: {"accepts": ["Any"]}}, + "outputPorts": {0: {"schema": "Dict"}}, +} +``` + +### 4.3 data.filter + +Filtert Items einer Liste nach Bedingung (wie WHERE in SQL). Eingabe: List, Ausgabe: gefilterter List. + +```python +{ + "id": "data.filter", + "category": "data", + "parameters": [ + {"name": "condition", "type": "string", "description": "Filter expression (z.B. item.status == 'open')"}, + ], + "inputPorts": {0: {"accepts": ["AggregateResult", "FileList", "TaskList", "EmailList"]}}, + "outputPorts": {0: {"schema": "AggregateResult"}}, +} +``` + +### 4.4 flow.merge + +Heute in `automation.md` gelistet, aber nicht implementiert. Wartet auf N Eingänge und kombiniert sie. + +--- + +## 5 Migrations-Strategie + +### Phase 1: Port-Schema-Deklaration (Backend, kein Breaking Change) + +1. `PortSchema` als Pydantic-Modell definieren. +2. Katalog der Port-Typen (`DocumentList`, `AiResult`, `EmailDraft`, …) anlegen. +3. Jede Node-Definition in `nodeDefinitions/*.py` um `inputPorts` / `outputPorts` erweitern. +4. API `GET /node-types` liefert die Schemas mit. + +### Phase 2: Output-Normalizer (Backend) + +1. Pro Port-Typ einen Normalizer schreiben (10–15 Funktionen). +2. In `executionEngine.py`: nach jedem Execute `_normalizeOutput(result, schema)` aufrufen. +3. Spezialcode in `actionNodeExecutor.py` schrittweise durch Normalizer ersetzen. +4. Step-Logs mit normalisiertem Output (Debugging/Tracing sofort besser). + +### Phase 3: Frontend — DataPicker aus Schema (Frontend) + +1. `outputPreviewRegistry.ts` durch Schema-basierte Preview-Generierung ersetzen. +2. DataPicker zeigt korrekte Felder + Typen an. +3. Verbindungs-Validierung (rote Kanten bei Typ-Mismatch). + +### Phase 4: Generisches Parameter-Rendering (Frontend) + +1. `NodeConfigPanel` rendert Parameter generisch aus `WorkflowActionParameter`-Schema. +2. Spezial-Components (`FormNodeConfig`, `ClickUpNodeConfig`, …) bleiben als Override für komplexe UIs. +3. Neue Nodes brauchen **keine eigene Config-Component** mehr. + +### Phase 5: Neue Data-Nodes + +1. `data.aggregate` implementieren (Engine + Node-Definition + Frontend). +2. `data.transform` implementieren. +3. `data.filter` implementieren. +4. `flow.merge` implementieren. + +--- + +## 6 Konkretes Beispiel: AI-Mail-Entwurf → Mail-Versand + +### Heute (heuristisch) + +``` +[email.checkEmail] ──→ [ai.prompt] ──→ [email.draftEmail] + ↓ ↓ ↓ + freeform Dict freeform Dict ~100 Zeilen Spezialcode + (data.emails…) (context, docs) in actionNodeExecutor: + _extractEmailContentFromUpstream + _getIncomingEmailFromUpstream + _unpackIncomingEmail + _gatherAttachmentDocumentsFromUpstream +``` + +### Ziel (typisiert) + +``` +[email.checkEmail] [ai.prompt] [email.draftEmail] + outputPort[0]: outputPort[0]: inputPort[0]: + schema: EmailList schema: AiResult accepts: [EmailDraft, AiResult] + + ──────────────────→ ──────────────────→ Normalizer kennt AiResult und + Input: EmailList Input: EmailList mapped response → body, + Engine prüft Kompatibilität Engine prüft kein Spezialcode nötig. +``` + +**Entscheidend:** Der AI-Node kann so konfiguriert werden, dass sein Output-Typ `EmailDraft` statt `AiResult` ist (z.B. via Parameter `outputMode: "emailDraft"` oder via Prompt-Instruktion + structured output). Dann ist der Downstream-Merge trivial. + +--- + +## 7 Offene Fragen / Entscheidungen + +| # | Frage | Optionen | +|---|-------|----------| +| 1 | Soll Typ-Mismatch eine Kante verhindern (hard) oder nur warnen (soft)? | **Empfehlung: soft** (Warnung + gelbe Kante). Hard-Block wäre zu restriktiv bei generischen Nodes. | +| 2 | Port-Typ `Any` erlauben? | Ja, als Fallback. Nodes wie `flow.ifElse` leiten den Input transparent durch. | +| 3 | Dynamische Schemas (z.B. `input.form` Payload hängt von Felddefinition ab)? | Ja. `outputPorts` kann eine Funktion referenzieren, die das Schema aus den `parameters` ableitet (wie heute `outputPreviewRegistry`). | +| 4 | Sollen bestehende Workflows beim Upgrade automatisch migriert werden? | **Nein.** Alte Workflows laufen weiter (Normalizer fängt fehlende Keys ab). Neue Workflows profitieren von Validierung. | +| 5 | Separater `data.aggregate`-Node oder implizit in `flow.loop`? | **Empfehlung: separater Node.** Explizit ist klarer; der Loop-Node bleibt rein für Iteration. | +| 6 | Braucht es einen `data.join`-Node (merge zwei Listen)? | Später. Erst aggregate + filter + transform etablieren. | + +--- + +## 8 Aufwand-Schätzung + +| Phase | Geschätzter Aufwand | Abhängigkeiten | +|-------|-------------------|----------------| +| 1 — Port-Schema-Deklaration | 2–3 Tage | Keine | +| 2 — Output-Normalizer | 3–5 Tage | Phase 1 | +| 3 — Frontend DataPicker aus Schema | 2–3 Tage | Phase 1 | +| 4 — Generisches Parameter-Rendering | 3–4 Tage | Phase 1 | +| 5 — Data Nodes (aggregate, transform, filter) | 3–5 Tage | Phase 2 | +| **Gesamt** | **~13–20 Tage** | Phasen 1–3 sind der kritische Pfad | + +--- + +## 9 Schlüssel-Dateien + +| Bereich | Pfade | +|---------|-------| +| Node-Definitionen | `gateway/modules/features/graphicalEditor/nodeDefinitions/*.py` | +| Execution Engine | `gateway/modules/workflows/automation2/executionEngine.py` | +| ActionNodeExecutor (Handover-Heuristik) | `gateway/modules/workflows/automation2/executors/actionNodeExecutor.py` | +| Graph-Utilities | `gateway/modules/workflows/automation2/graphUtils.py` | +| Method/Action Typsystem | `gateway/modules/workflows/methods/methodBase.py`, `gateway/modules/datamodels/datamodelWorkflowActions.py` | +| FrontendType Enum | `gateway/modules/shared/frontendTypes.py` | +| Output-Preview (Frontend) | `frontend_nyla/src/components/FlowEditor/nodes/shared/outputPreviewRegistry.ts` | +| DataPicker (Frontend) | `frontend_nyla/src/components/FlowEditor/nodes/shared/DataPicker.tsx` | +| DataRef/DynamicValue (Frontend) | `frontend_nyla/src/components/FlowEditor/nodes/shared/dataRef.ts` | +| Node Config Registry (Frontend) | `frontend_nyla/src/components/FlowEditor/nodes/configs/index.ts` | +| DataFlow Context (Frontend) | `frontend_nyla/src/components/FlowEditor/context/Automation2DataFlowContext.tsx` | diff --git a/c-work/1-plan/2026-04-porta-ui-enhancements-team-meeting.md b/c-work/1-plan/2026-04-porta-ui-enhancements-team-meeting.md new file mode 100644 index 0000000..79015c0 --- /dev/null +++ b/c-work/1-plan/2026-04-porta-ui-enhancements-team-meeting.md @@ -0,0 +1,256 @@ + + + + +# PORTA UI-Enhancements (Team-Meeting Inputs, 2026-04-07) + +## Beschreibung und Kontext + +**Quelle:** Transkript POL-Weekly vom 7. April 2026 (`c-work/1-plan/input2026-04-ui-enhancement-inbputs.txt`). Philipp Graf und Dominic Largo haben PORTA als **echte Erstnutzer** (KMU-Perspektive, nicht IT-heavy) getestet; Patrick Motsch und das Team haben Anforderungen präzisiert. + +**Produkt:** PowerOn PORTA — Multi-Tenant SaaS mit AI-Agent-Workspace, siehe [wiki/README.md](../../README.md). + +**Business-Treiber:** Die **Hürde bis zur ersten sinnvollen Interaktion** muss sinken. Ohne klare Userführung und sichtbares Vertrauen springen potenzielle Kunden ab, bevor sie den Mehrwert (ein Abo statt vieler, Datenkontrolle, Schweizer Gegenpartei) erleben. Das UI ist explizit als **Aushängeschild** und Human-Reaction-Hebel genannt. + +**Abhängigkeiten:** Copy und rechtliche Zulässigkeit für Marken-/Partner-Hinweise; Billing-Daten müssen für Transparenz-UI verfügbar sein (Gateway/Billing bereits teilweise vorhanden laut Diskussion). + +**Risiko bei Nicht-Umsetzung:** Weiterhin hohe Abbruchrate nach Login; AI-Workspace wirkt «versteckt» in typischen Fensterbreiten; Vertrauen bleibt abstrakt statt greifbar. + +## Fokus und kritische Details + +### Aus dem Meeting extrahierte UI/UX-Schwerpunkte + +| Thema | Nutzerstimme / Intention | Konsequenz für UI | +|-------|--------------------------|-------------------| +| **Vertrauen & Substanz** | Nicht primär ISO-Badge; wichtig ist z. B. «Daten hosted in der Schweiz» (konkreter Anbieter/Standort sichtbar) | Trust-Badges/Copy: Hosting-Ort, ggf. Anbietername; kurze, scanbare Vertrauenszeile | +| **Marken- & Partneranker** | Swiss Registered (®) am Logo; «Recommended by» mit wenigen, kuratierten Partnern (Valion, PamoCreate, Swiss AI Association, Prescos, Soha Treuhand) | Footer/Landing/Login: Partner-Strip; Markenhinweis konsistent | +| **Erste Datenanbindung** | Sorge: «Baue ich Scheisse?» — Encoding/Sicherheit nicht fühlbar | Onboarding-Microcopy: Read-only/sichere Verbindung, «nichts kaputtmachen», Rollback/Wiederherstellung wo zutreffend | +| **AI-Workspace: Eingabe finden** | «Wo tippe ich die Frage?» — kleines Fenster, Plus, Hover; Vergleich zu Cloud/ChatGPT mit klarem Fragebalken | **Primäre Prompt-Zeile** dominant; sekundäre Aktionen nicht vor Eingabe verstecken | +| **Layout / Viewports** | Schmales Fenster (nicht Mobile, nicht Wide): Chat/Input **verschwindet** praktisch | Breakpoints testen; **Mobile (hoch/schmal)** vs **Desktop (breit)** als zwei klare Modi; mittlere Breiten nicht vernachlässigen | +| **Neuer Chat / Kontext** | Erwartung: schnell «neuer Chat» wie gewohnt; fehlte als klare Handlung | Sichtbarer CTA «Neuer Chat» / Kontext-Reset analog Erwartung aus Chat-Tools | +| **Datei / Prompt** | Drag-in-Prompt erwünscht; Entdeckbarkeit war mühsam | Klare Dropzone oder Hinweis in leerem Zustand | +| **Pricing & Billing Auffindbarkeit** | Erste Session: «Wo steht das Pricing?» Pfad Admin → Benutzer → Billing wirkt versteckt | **Ersteinstieg:** Link oder Teaser zu Kosten/Guthaben; ggf. leere States mit «So siehst du dein Budget» | +| **Informationsdichte** | «Flut der Informationen oder der Logik» — Berufsalltag vs. zu viel parallel | IA: Schichten, progressive Offenlegung; weniger gleichzeitig auf Startscreens | + +### Kritische Details + +- **Int vs. Prod:** Tester war teils auf falscher Instanz — für UX-Tests einheitliche **Test-Links** kommunizieren (Prozess, nicht nur UI). +- **Rollen:** Admin vs. User — Billing nur für Admins sichtbar; Empty States für User müssen trotzdem Orientierung geben («Frag deinen Admin»), ohne frustrierende Sackgassen. +- **Recht/Marken:** Partner-Logos und Formulierungen «Recommended by» mit Partnern abstimmen. + +## Ziel und Nicht-Ziele + +**Ziel:** + +- Nach Login und im **AI-Workspace** ist die **primäre Eingabe** (Frage/Prompt) in typischen Viewports **sofort erkennbar**. +- **Vertrauen** ist ohne Deep-Dive erfassbar: Schweizer Hosting-Hinweis, Marken-/Partner-Elemente wie im Meeting skizziert. +- **Onboarding** zur ersten Connector-/Datenaktion reduziert Angst («sicher verbinden») durch klare Kurztexte. +- **Billing/Usage** ist für berechtigte Rollen **auffindbarer**; erste Orientierung zu Kosten ohne Graben durch Administration. +- **Responsive Verhalten** für schmale Desktop-Fenster und Mobile ist konsistent definiert und getestet. + +**Explizit NICHT:** + +- Neues Produkt-Splitting (z. B. «Teamspot») oder komplette Pricing-/Usage-Modelle neu erfinden — nur **UI/IA/Discoverability** und Anbindung an bestehende Billing-Fakten. +- ISO-Zertifizierung als Projekt; höchstens spätere Verknüpfung zu Compliance-Docs in `e-compliance/`. +- Vollständige Ersetzung der Produktstory zu externen LLM-Abos (Copy kann ergänzt werden, kein Marketing-Whitepaper im Scope). + +## Betroffene Module + +- **Frontend Nyla:** AI-Workspace-Layout, globale Shell (Login/Landing), Navigation/Empty States, ggf. Trust-Strip-Komponente, Breakpoints. +- **Gateway:** nur falls neue/angereicherte Felder für Trust-Copy (Hosting-Text) oder Billing-Summary für Dashboard nötig — zunächst statische/config-gestützte Copy prüfen. +- **DB-Migration:** nein (voraussichtlich). +- **Platform / Wiki:** nach Release `b-reference/frontend-nyla/architecture.md` oder `platform/navigation.md` bei Routing-Änderungen. + +--- + +## Codebase-Audit (Ist-Zustand, `frontend_nyla`) + +Stand: Abgleich mit Repo-Pfaden unter `poweron/frontend_nyla/src/`. Tiefergehende Systemregeln: [b-reference/frontend-nyla/architecture.md](../../b-reference/frontend-nyla/architecture.md), Navigation: [b-reference/platform/navigation.md](../../b-reference/platform/navigation.md). + +### Bereits vorhanden (positiv) + +| Bereich | Was existiert | Wo im Code | +|--------|----------------|------------| +| **3-Spalten-Workspace** | Links `UnifiedDataBar` (Chats / Dateien / Quellen), Mitte `ChatStream` + `WorkspaceInput`, rechts Activity/Preview; resize handles; Collapse links/rechts | `pages/views/workspace/WorkspacePage.tsx` | +| **Mobile (≤1024px)** | Oberleiste «Workspace | Activity | Preview»; linke/rechte Panel als Overlay-Drawer; gleicher Breakpoint wie `MainLayout` Sidebar | `WorkspacePage.tsx`, `layouts/MainLayout.tsx` | +| **Dateien per Drag** | Overlay «Dateien hier ablegen» auf der **gesamten** Center-`main`-Fläche; Upload + `pendingFiles` | `WorkspacePage.tsx` (`onDragEnter`/`Drop` auf `
`) | +| **Prompt-Zeile** | Textarea, `+` Datei, optional Quellen-Picker, Provider-Multi-Select, Voice, Send/Stop; `@file` Autocomplete | `pages/views/workspace/WorkspaceInput.tsx` | +| **Drag auf Prompt-Bereich** | Nur **`application/tree-items`** (Baum) und **`application/chat-id`** (Chat-Referenz) — kein natives File-Drop im Input-Wrapper (Dateien laufen über Parent-`main`) | `WorkspaceInput.tsx` (`_handlePromptDragOver` / `_handlePromptDrop`) | +| **Neuer Chat** | `workspace.resetToNew` an UDB gebunden; in **Chats-Tab** Toolbar Button `+` mit `title="Neuer Chat"` | `WorkspacePage.tsx` → `UnifiedDataBar` → `ChatsTab.tsx` | +| **Billing-Funktionalität** | `BillingDataView`: Tabs Übersicht / Statistik / Transaktionen, Balance Cards, Hinweis auf Admin-Pfad für Aufladung | `pages/billing/BillingDataView.tsx`, `hooks/useBilling.ts`, `api/billingApi.ts` | +| **Guthaben im UI** | User-Menü: Eintrag «Guthaben» → `/billing/transactions` | `components/Navigation/UserSection.tsx` | +| **Quellen / Verbindungen** | Ausführlicher `SourcesTab` (Browse, Active Sources, Neutralize) | `components/UnifiedDataBar/SourcesTab.tsx` | +| **Login** | Logo, Credentials, Microsoft/Google, Registrierung, Kurz-Disclaimer KI/Datenschutz | `pages/Login.tsx`, `Login.module.css` | +| **Rechtstexte** | Modal «Rechtliche Hinweise» + Links zu statischen HTML-Seiten | `UserSection.tsx` | + +### Konkrete Issues (Lücken vs. Meeting-Feedback) + +| # | Problem | Ursache im Code / Verhalten | +|---|---------|------------------------------| +| I1 | **Eingabe wirkt «versteckt»** | Chat-Fläche frisst vertikal Platz; Prompt unten, enges Fenster + zwei Sidebars → Mittelspalte wird sehr schmal (>1024px, beide Sidebars offen). Kein **Empty-State** in `ChatStream`, der die Eingabe einrahmt oder zur Aktion führt. | +| I2 | **«Wo tippe ich?» / kein ChatGPT-Balken** | Textarea ist funktional, aber **Placeholder auf Englisch** (`Type a message...`); visuell keine «Hero»-Eingabe. Sekundäraktionen (`+`, 🔗, Voice, Provider) stehen **in einer Zeile** neben dem Feld — bei wenig Breite wirkt das «nur ein Plus». | +| I3 | **Neuer Chat unsichtbar** | Nur **`+`** in `ChatsTab` Toolbar; wenn linke Spalte eingeklappt oder Mobile-User nicht auf Tab «Chats» wechselt, fehlt ein **zentrale CTA** in der Mitte. | +| I4 | **Schmale Desktop-Breite (ca. 1025–1280px)** | `isMobile` ist **false**, also **beide** Sidebars standardmäßig aktiv (280px + 320px + Handles). Zentrum `flex: 1`, `minWidth: 0` — Eingabe bleibt im DOM, wirkt aber «Wischiwaschi» oder abgeschnitten. Meeting: «A4-Fenster» genau diese Zone. | +| I5 | **Dateien: Entdeckbarkeit** | Vollflächen-Drop existiert, aber ohne **dauerhaften Hinweis** im leeren Chat; Nutzer erwarten oft Drop **direkt auf das Textfeld**. | +| I6 | **Vertrauen / Schweiz / Partner** | Login: **kein** Hosting-Hinweis, kein Partner-Strip, kein ® am Logo in der UI (nur Bildasset — rechtlich/Marken separat klären). Compliance-Texte eher in `e-compliance/` und statischen HTML, nicht **scanbar** auf Login. | +| I7 | **Billing / Pricing Auffindbarkeit** | Funktional stark (`BillingDataView`), aber **Einstieg** primär: Nav-Baum (`GET /api/navigation`, siehe Gateway `NAVIGATION_SECTIONS`) + verstecktes User-Menü «Guthaben». Kein **Dashboard-Teaser** nach erstem Login. | +| I8 | **Connector-Sorge** | `SourcesTab` ist technisch mächtig, aber ohne **kuratierte Erstnutzer-Copy** («Verbindung ist read-only / nichts kaputt») am Einstieg — Meeting-Thema «baue ich Scheisse». | +| I9 | **Informationsdichte** | Workspace + UDB + rechte Spalte parallel; kein **progressives** Onboarding in der Mitte (ausser globalem OnboardingWizard nach Google). | + +--- + +## Umsetzungsplan (integriert) + +Ziele: Issues I1–I9 adressieren, **ohne** Billing-Logik oder Gateway-Tarife neu zu erfinden. Reihenfolge nach **Aufwand × Wirkung** für KMU-Erstnutzung. + +### Phase A — Quick Wins (1–3 Tage) + +| Task | Änderung | Dateien / Hinweise | +|------|-----------|-------------------| +| A1 | Placeholder + primäre Labels **DE** (und i18n Keys, falls `locales` für Workspace genutzt werden soll) | `WorkspaceInput.tsx` — z. B. «Frage stellen oder @Dateiname für Kontext» | +| A2 | **Empty State** in der Mitte: kurzer Titel, Bullet «Hier unten Frage eingeben», «Dateien auf die Fläche ziehen», Button **Neuer Chat** (ruft `onCreateNew`/`resetToNew` — Props von `WorkspacePage` durchreichen) | `ChatStream.tsx` + optionell schmale Props von `WorkspacePage.tsx` | +| A3 | **Neuer Chat** zusätzlich: Button in der **mittleren Kopfzeile** (nur Desktop) oder neben Mobile-«Workspace»-Leiste, sichtbar ohne UDB | `WorkspacePage.tsx` | +| A4 | Billing-Hinweis für **Nicht-Admins**: ein Zeiler im Empty State oder unter Prompt mit Link zu Hilfe («Guthaben: Administrator») — Text mit `BillingDataView` / BalanceCard abgleichen | `ChatStream` oder `WorkspacePage`, Copy-only | + +### Phase B — Layout & Breakpoints (3–5 Tage) + +| Task | Änderung | Dateien / Hinweise | +|------|-----------|-------------------| +| B1 | **Zwischen-Breakpoint** (z. B. `≤1280` oder `≤1360`): **automatisch linke und/oder rechte Sidebar einklappen** oder nur eine Sidebar standardmäßig offen, damit `mindestens ~480px` für die Mittelspalte garantiert sind | `WorkspacePage.tsx` — `useEffect` auf `innerWidth` + lokaler State, dokumentierte Schwellwerte | +| B2 | Optional: **minWidth** auf `
` mit «Seite zu schmal»-Hinweis statt silent squeeze | `WorkspacePage.tsx` | +| B3 | **Visuelle Hierarchie Prompt**: Eingabezeile leicht hervorgehoben (Schatten/Rand), ggf. erste Zeile höher (`minHeight`) | `WorkspaceInput.tsx` oder ausgelagertes CSS Module | +| B4 | E2E/Visuell: Viewports **1100 / 1200 / 1280 / 1440** in Testplan festhalten | Playwright oder manuelle Matrix | + +### Phase C — Vertrauen & Marketing-UI (2–4 Tage, abhängig von Legal) + +| Task | Änderung | Dateien / Hinweise | +|------|-----------|-------------------| +| C1 | Wiederverwendbare **`TrustFooter` / `TrustStrip`**: Zeile Hosting Schweiz (Formulierung mit Legal abgleichen — ggf. Verweis auf [e-compliance/security-overview.md](../../e-compliance/security-overview.md)) | Neue Komponente unter `components/`, einbinden in `Login.tsx`, optional `Register`, optional `MainLayout` Footer | +| C2 | **Recommended by** — statische Logos/Links (max. 5) nur nach **Partner-Freigabe** | Gleiche Komponente; Assets unter `public/` | +| C3 | Swiss **®** am Logo nur nach Markenfreigabe — sonst Textlink «Marke» | `Login.module.css` / Layout-Logo | +| C4 | **SourcesTab** oder erster Besuch «Quellen»: ein **Info-Banner** (1–2 Sätze) zu sicherer Verbindung / keine Zerstörung von Quelldaten — mit Product Owner fact-checken | `SourcesTab.tsx` oben | + +### Phase D — Billing-Discovery (2–3 Tage) + +| Task | Änderung | Dateien / Hinweise | +|------|-----------|-------------------| +| D1 | Nach Login: **einmaliger** Banner oder Home-Teaser «Guthaben & Nutzung» mit Link zu `/billing/transactions` (nur wenn Route erlaubt — Permission prüfen wie andere Nav-Items) | `MainLayout.tsx`, `App.tsx` Home-Route, oder dedizierte `HomePage` — je nachdem wo Landing liegt | +| D2 | Optional: **kleine Balance-Zahl** in UserSection neben Avatar (nur wenn API schon geladen wird und Mandate eindeutig) — Performance/UX mit `useBilling` prüfen | `UserSection.tsx` | +| D3 | Gateway: Navigations-**Label/Reihenfolge** für Billing in «Meine Sicht» nach oben ziehen (wenn gewünscht) — **kein** Frontend-Workaround ohne Backend | `gateway` `NAVIGATION_SECTIONS` / `mainSystem.py` (siehe Wiki navigation.md) | + +### Phase E — Feinschliff (laufend) + +| Task | Änderung | +|------|-----------| +| E1 | `WorkspaceInput`: optional natives **File** im Prompt-`onDragOver`/`Drop` spiegeln (gleiche Logik wie `WorkspacePage._uploadAndAttach`) — dann expliziter Drop auf Eingabe | +| E2 | i18n: alle neuen Strings in `locales/` | +| E3 | Nach Merge: `b-reference/frontend-nyla/architecture.md` um Workspace-UX-Notizen ergänzen | + +### Abhängigkeiten & Risiken + +- **D3** erfordert Gateway-Deploy und gehört fachlich zu «IA», nicht nur CSS. +- **C1–C3** müssen mit **Legal/Marketing** sign-off; keine konkreten Hosting-Anbieter-Namen ohne Vertragslage. +- **D1** braucht klare Regel, wann der Banner **nicht** nervt (localStorage `dismissed`). + +--- + +## Entscheidungen + +| Datum | Entscheidung | Begründung | +|-------|-------------|------------| +| 2026-04-07 | Plan aus Meeting-Transkript abgeleitet; Fokus UI/UX, nicht Pricing-Tarife | Entscheidungen zu Tarifen und Modellen sind separat zu treffen | +| 2026-04-07 | Codebase-Audit gegen `frontend_nyla` — Umsetzung in Phasen A–E | Issues I1–I9 und bestehende Bausteine im Dokument festgehalten | + +*Weitere Einträge nach UX-Review und Abstimmung Partner/Hosting-Formulierung.* + +## Umsetzungs-Checkliste + +Die detaillierte Aufgabenzerlegung steht in **Umsetzungsplan** (Phasen A–E). Hier die Cross-Cutting-Checks: + +**Phase A (Quick Wins)** + +- [ ] A1: `WorkspaceInput.tsx` — DE-Placeholder / Copy +- [ ] A2: `ChatStream.tsx` + Props — Empty State + Kurzhelp +- [ ] A3: `WorkspacePage.tsx` — «Neuer Chat» sichtbar ohne UDB +- [ ] A4: Copy für Nicht-Admins (Guthaben) + +**Phase B (Layout)** + +- [ ] B1–B2: `WorkspacePage.tsx` — Zwischen-Breakpoint / Sidebar-Strategie +- [ ] B3: `WorkspaceInput.tsx` — visuelle Hierarchie Eingabe +- [ ] B4: Viewport-Testmatrix dokumentiert + +**Phase C (Trust)** + +- [ ] C1–C3: Trust-Komponente + Login/Register/Layout — Legal OK +- [ ] C4: `SourcesTab.tsx` — Sicherheits-Banner + +**Phase D (Billing-Discovery)** + +- [ ] D1: Home / nach Login — Teaser-Link Billing +- [ ] D2: optional `UserSection.tsx` — Balance-Snippet +- [ ] D3: optional Gateway — `NAVIGATION_SECTIONS` Billing-Prominenz + +**Phase E / Plattform** + +- [ ] E1: optional File-Drop auf Prompt synchron zu `WorkspacePage` +- [ ] E2: `locales/*` für neue Strings +- [ ] E3: Wiki `b-reference/frontend-nyla/architecture.md` aktualisieren + +**Querschnitt** + +- [ ] API-Endpunkte: nur bei D2/D3 oder neuen Summary-APIs nötig +- [ ] DB-Migration: nein (Planstand) +- [ ] RBAC: Billing-Routen nur anzeigen wenn wie heute erlaubt +- [ ] Neutralisierung: nur Copy in C4, kein Verhalten +- [ ] Navigation / Routing: nur bei D1/D3 +- [ ] Billing-Impact: Darstellung/Auffindbarkeit, keine Tariflogik + +## Akzeptanzkriterien + +| # | Kriterium (Given-When-Then) | Prio | +|---|---------------------------|------| +| 1 | Given ein eingeloggter User ohne verbundene Datenquellen, When er den AI-Workspace öffnet (Desktop ≥1280px und Mobile-Viewport), Then ist die Haupt-Eingabe für Prompt/Frage ohne Hover oder Scrollen in den ersten sichtbaren 50 % des Hauptbereichs erkennbar | must | +| 2 | Given schmales Desktop-Fenster (z. B. 900–1024px Breite), When der AI-Workspace angezeigt wird, Then bleibt die Prompt-Eingabe zugänglich (kein «verschwindendes» Chatfenster ohne Alternativlayout) | must | +| 3 | Given Login- oder Startansicht, When der User die Seite scannt (5–10 Sekunden), Then sind mindestens ein **Schweiz-Hosting**-Hinweis und der **Partner-/Recommended-by**-Block gemäss kuratierter Liste sichtbar oder mit einem klaren «Vertrauen»-Einstieg erreichbar | should | +| 4 | Given User mit Rolle Admin, When er nach dem ersten Login Orientierung zu Kosten sucht, Then führt ein in der UI sichtbarer Einstieg innerhalb ≤2 Klicks zur Billing-/Usage-Übersicht (bestehender Pfad darf erhalten bleiben, muss aber nicht mehr alleinige Entdeckungsquelle sein) | should | +| 5 | Given AI-Workspace, When der User eine neue Unterhaltung beginnen will, Then ist eine explizite «Neuer Chat»- oder gleichwertige Handlung sichtbar und erklärt sich ohne externe Doku | should | +| 6 | Given leerer Chat ohne Nachrichten, When der User eine Datei einbinden will, Then ist erkennbar, ob und wie Drag-and-Drop in den Prompt funktioniert (Text oder Dropzone) | could | + +## Testplan + +| ID | AC | Art | Automatisiert | Repo-Pfad | Status | +|----|----|-----|--------------|-----------|--------| +| T1 | 1,2 | e2e / manuell Viewports | teilweise | `frontend_nyla` — `WorkspacePage.tsx` bei 1100/1200/1280/1440px | pending | +| T2 | 3 | manuell UX-Review | nein | — | pending | +| T3 | 4 | manuell Rolle Admin | nein | — | pending | +| T4 | 5,6 | manuell Explorer/Safari/Edge | nein | — | pending | + +## Links + +- Input: [input2026-04-ui-enhancement-inbputs.txt](./input2026-04-ui-enhancement-inbputs.txt) +- Produkt-Überblick: [README.md](../../README.md) +- Frontend-Referenz: [b-reference/frontend-nyla/architecture.md](../../b-reference/frontend-nyla/architecture.md) +- Navigation API: [b-reference/platform/navigation.md](../../b-reference/platform/navigation.md) +- Billing (Backend-Kontext): [b-reference/gateway/billing.md](../../b-reference/gateway/billing.md) +- Compliance (Copy-Grundlage): [e-compliance/security-overview.md](../../e-compliance/security-overview.md) + +**Code (Haupt-Einstiegspunkte, Repo `frontend_nyla`)** + +- `src/pages/views/workspace/WorkspacePage.tsx` — Layout, Mobile, Drag-Drop, UDB +- `src/pages/views/workspace/WorkspaceInput.tsx` — Prompt, Anhänge, STT +- `src/pages/views/workspace/ChatStream.tsx` — Nachrichtenliste +- `src/components/UnifiedDataBar/ChatsTab.tsx` — Chat-Liste, `+` Neuer Chat +- `src/components/UnifiedDataBar/SourcesTab.tsx` — Verbindungen / Quellen +- `src/pages/Login.tsx` — Login-Shell +- `src/components/Navigation/UserSection.tsx` — Guthaben-Menü +- `src/pages/billing/BillingDataView.tsx` — Nutzer-Billing + +- PR: … +- Issue: … + +## Abschluss + +- [ ] b-reference/ aktualisiert (`frontend-nyla/architecture.md`, ggf. `platform/navigation.md`) +- [ ] TOPICS.md aktualisiert (falls neues Thema «Trust-UI» o. ä.) +- [ ] Dieses Dokument → `z-archive/` verschoben (nach Release) diff --git a/c-work/1-plan/2026-04-trustee-tooling-and-demo-prep.md b/c-work/1-plan/2026-04-trustee-tooling-and-demo-prep.md new file mode 100644 index 0000000..ec6cd04 --- /dev/null +++ b/c-work/1-plan/2026-04-trustee-tooling-and-demo-prep.md @@ -0,0 +1,229 @@ + + + + +# Trustee Tooling Overhaul & PWG Demo Preparation + +## Beschreibung und Kontext + +Für den PWG-Inspirationsworkshop (16. April 2026) werden drei Use Cases in PORTA demonstriert. Use Case 1 (Belegverarbeitung + Budgetkontrolle) und Use Case 3 (Datenneutralisierung) erfordern Code-Anpassungen im Trustee-Feature und im Agent-Tooling. + +**Business-Treiber:** PWG AG (gemeinnützige Wohnungsstiftung Zürich, 200+ Liegenschaften, Abacus als Hauptsystem) evaluiert PORTA. Der Workshop ist die erste Live-Demo — Plattform-Tiefgang und funktionierende Schnittstellen sind entscheidend. + +**Risiko bei Nicht-Umsetzung:** Demo scheitert an fehlenden Tools (Agent kann keine Buchhaltungsdaten lesen), langsamer Performance (jede Query startet neuen Sub-Agent-Loop) oder fehlendem Workflow im Graphical Editor. + +Parallel zur Demo-Vorbereitung wird das Trustee-Tooling grundlegend überarbeitet. Die aktuelle Architektur hat strukturelle Schwächen, die auch im Produktivbetrieb problematisch sind. + +**Hinweis:** Die Automation Unification (v1/v2 → Graphical Editor) ist abgeschlossen (siehe `c-work/3-validate/2026-04-automation-unification.md`, Status: done). Dieses Dokument baut auf dem konsolidierten System auf: Feature `graphicalEditor`, DB `poweron_graphicaleditor`, konsolidierter Scheduler. + +## Fokus und kritische Details + +### Ist-Zustand Trustee-Tooling (Analyse) + +| Fähigkeit | Status | Problem | +|-----------|--------|---------| +| **Daten lesen (Agent)** | `queryFeatureInstance` → Sub-Agent mit `browseTable`/`queryTable` | Jeder Call öffnet neue DB-Connection + startet 5-Runden-Agent-Loop mit AI-Calls. Kein Caching. Langsam (~5-15s pro Query). | +| **Daten aus Buchhaltung importieren** | `AccountingDataSync.importData()` via REST-Endpoint | Full-clear + Full-write bei jedem Import. Kein inkrementeller Sync. Kein Agent-Zugriff (nur REST). | +| **Daten schreiben (Agent)** | Nicht vorhanden | Agent kann keine Trustee-Positionen erstellen oder ändern. | +| **Daten aggregieren** | Nicht vorhanden | Sub-Agent hat nur row-level Tools. Keine SQL-Aggregationen (SUM, GROUP BY). Für Budgetvergleiche muss der Agent alle Rows laden und selbst rechnen. | +| **Chart of Accounts** | `AccountingBridge.getChartOfAccounts()` mit Cache auf `TrusteeAccountingConfig` | Funktioniert, aber nur für Bridge-interne Nutzung. Agent hat keinen direkten Zugriff. | +| **Graph-Editor Nodes (Trustee)** | 3 Nodes in `nodeDefinitions/trustee.py`: `extractFromFiles`, `processDocuments`, `syncToAccounting` | Alle `dynamicMode=False` — nicht als Agent-Tools verfügbar. Für Graph-Editor nutzbar. Kein Node für `refreshAccountingData` / Datenimport. | +| **Graph-Editor Nodes (SharePoint)** | 6 Nodes in `nodeDefinitions/sharepoint.py`: findFile, readFile, uploadFile, listFiles, downloadFile, copyFile | Vorhanden und funktional. `listFiles` + `downloadFile` reichen für den Demo-Flow. | +| **Graph-Editor Nodes (Flow)** | 5 Nodes: ifElse, switch, loop, merge, delay | Loop-Node vorhanden (`flow.loop`). Nötig für "für jede Datei aus SharePoint → Trustee-Pipeline". | +| **Node-Kategorie `trustee`** | Nodes nutzen `category: "trustee"` | **Fehlt in `nodeRegistry.getNodeTypesForApi()` Categories-Liste** (Zeile 63-73) — Trustee-Nodes werden im Editor nicht unter eigener Kategorie angezeigt. | +| **Toolbox `trustee`** | Nicht vorhanden | Die Toolbox Registry (`toolboxRegistry.py`) hat Toolboxes für email, sharepoint, clickup, jira, workflow — aber keine für Trustee. Für den Agent-Zugriff auf Trustee-Actions (`dynamicMode=True`) wäre eine Toolbox sinnvoll. | + +### Performance-Problem `queryFeatureInstance` + +Der Hauptgrund für die langsame Query-Performance: + +1. **Neuer Sub-Agent pro Call** — `runFeatureDataAgent` startet einen eigenen Agent-Loop (max 5 Runden, je ein AI-Call) für jede Frage. Das bedeutet: Main-Agent stellt Frage → Sub-Agent macht 1-3 AI-Calls um SQL zu generieren → Sub-Agent antwortet → Main-Agent verarbeitet. +2. **Neue DB-Connection pro Call** — `DatabaseConnector` wird jedes Mal neu instanziiert und geschlossen. +3. **Kein Result-Cache** — Identische Fragen werden jedes Mal neu beantwortet. + +## Ziel und Nicht-Ziele + +**Ziel:** +- Agent kann Trustee-Buchhaltungsdaten lesen (gecacht oder frisch vom externen System) +- Agent kann Aggregationen auf Trustee-Daten ausführen (SUM, GROUP BY für Budgetvergleiche) +- Graphical-Editor-Workflow für Belegverarbeitung (SharePoint → Trustee Import+Sync) funktioniert +- Performance von Feature-Data-Queries deutlich verbessert +- Demo für PWG-Workshop läuft stabil end-to-end + +**Explizit NICHT:** +- Kein vollständiger Umbau des Sub-Agent-Patterns +- Keine neuen Abacus-API-Endpoints (nutzen bestehenden Connector) +- Keine Frontend-Änderungen am Trustee-UI + +## Betroffene Module + +- Gateway: `features/trustee/`, `serviceCenter/services/serviceAgent/` (inkl. `toolboxRegistry.py`), `workflows/methods/methodTrustee/`, `features/graphicalEditor/nodeDefinitions/`, `features/graphicalEditor/nodeRegistry.py` +- Frontend: keine Änderungen +- DB-Migration: nein (nutzt bestehende `TrusteeData*`-Tabellen in Feature-DB `poweron_trustee`) +- Graphical Editor: Node-Definitionen + Kategorie-Registry + Workflow-Konfiguration für Demo + +## Entscheidungen + +| Datum | Entscheidung | Begründung | +|-------|-------------|------------| +| 2026-04-07 | Neues Tool `refreshTrusteeData` statt Erweiterung von `queryFeatureInstance` | Separation of Concerns: Sync ist eine schreibende Operation, Query ist lesend. Agent entscheidet selbst, ob er zuerst refreshen muss. | +| 2026-04-07 | `aggregateTable`-Tool im Sub-Agent statt SQL in `queryTable` | Saubere Trennung: row-level vs. aggregate. Verhindert SQL-Injection-Risiko bei freien GROUP BY-Ausdrücken. | +| 2026-04-07 | DB-Connection-Pooling für Feature-Data-Agent statt Connection-per-Call | Grösster Performance-Hebel. Connection-Aufbau ist teuer (~200ms), Pool eliminiert das. | +| 2026-04-07 | Result-Cache auf WorkflowMemory-Ebene | Nutzt bestehendes Konzept (WorkflowMemory mit Embedding). Agent kann gecachte Ergebnisse aus früheren Runden wiederverwenden. | + +## Umsetzungs-Checkliste + +### Phase 1: Trustee Agent-Tools (Prio: hoch — Blocker für Demo UC1 Teil B) + +- [x] **`refreshTrusteeData`** — Neue Workflow-Action `trustee.refreshAccountingData` mit `dynamicMode=True` + - Prüft `TrusteeAccountingConfig.lastSyncAt` — wenn älter als Schwellwert (z.B. 1h) oder Daten leer → triggert `AccountingDataSync.importData()` + - Parameter: `featureInstanceId` (required), `forceRefresh` (optional, default false), `dateFrom`/`dateTo` (optional) + - Rückgabe: Summary (Anzahl Records pro Tabelle, Sync-Dauer, ob frisch oder gecacht) + - Registrierung in `MethodTrustee.__init__` analog zu bestehenden Actions + +- [x] **`aggregateTable`** — Neues Tool im Feature-Data-Sub-Agent (`featureDataAgent.py`) + - SQL-Aggregationen: `SUM`, `COUNT`, `AVG`, `MIN`, `MAX` + - `GROUP BY` auf vordefinierte Felder (Whitelist pro Tabelle) + - Scope-Filter wie bei `queryTable` (featureInstanceId + mandateId) + - Beispiel: `aggregateTable(tableName="TrusteeDataJournalLine", aggregate="SUM", field="debitAmount", groupBy="costCenter")` + +### Phase 2: Graphical-Editor Node-Definitionen (Prio: hoch — Blocker für Demo UC1 Teil A) + +**Ist-Zustand Node-Registry (`features/graphicalEditor/nodeDefinitions/`):** + +| Datei | Nodes | Status | +|-------|-------|--------| +| `trustee.py` | `extractFromFiles`, `processDocuments`, `syncToAccounting` | Vorhanden, aber kein Node für Datenimport/Refresh | +| `sharepoint.py` | `findFile`, `readFile`, `uploadFile`, `listFiles`, `downloadFile`, `copyFile` | Vorhanden, ausreichend für Demo | +| `flow.py` | `ifElse`, `switch`, `loop`, `merge`, `delay` | Vorhanden, Loop-Node nötig für Demo | + +**Anpassungen:** + +- [x] **Kategorie `trustee` in `nodeRegistry.py` ergänzen** + - In `getNodeTypesForApi()` → `categories`-Liste (Zeile 63-73) fehlt `{"id": "trustee", "label": {"en": "Trustee", "de": "Treuhand", "fr": "Fiduciaire"}}` + - Ohne diese Kategorie werden die Trustee-Nodes in der Node-Palette des Graphical Editors nicht unter einer eigenen Gruppe angezeigt + +- [x] **Neuer Node `trustee.refreshAccountingData`** in `nodeDefinitions/trustee.py` + - Mapped auf neue Workflow-Action `trustee.refreshAccountingData` (Phase 1) + - Parameter: `featureInstanceId` (required), `forceRefresh` (optional), `dateFrom`/`dateTo` (optional) + - Kategorie: `trustee`, Icon: `mdi-database-refresh`, Color: `#4CAF50` + - Damit kann der Datenimport auch als Flow-Node genutzt werden (z.B. "Jeden Morgen Daten aus Abacus importieren") + +- [~] **Neuer Node `trustee.importAndProcess`** in `nodeDefinitions/trustee.py` (optional, Convenience) — **übersprungen**: bestehende 3 Nodes funktionieren dank Output-Chaining-Fix (s.u.) + - Kombiniert die Pipeline `extractFromFiles` → `processDocuments` → `syncToAccounting` in einem einzigen Node + - Vereinfacht den Demo-Flow auf 2 Nodes statt 4 (SharePoint Download → Trustee Import+Process+Sync) + - Parameter: `connectionId`, `sharepointFolder`, `featureInstanceId`, `prompt` + - Falls zu aufwändig: bestehende 3 Nodes einzeln im Flow verketten (funktioniert, ist aber visuell weniger eindrucksvoll) + +- [x] **Toolbox `trustee` in `toolboxRegistry.py` registrieren** (für Agent-Zugriff) + - Analog zu `sharepoint`, `email`, `clickup` — Toolbox mit `requiresConnection: false` (Trustee hat eigene Config) + - Enthält `refreshTrusteeData` (Phase 1) und ggf. weitere Trustee-Actions wenn `dynamicMode=True` + - Ermöglicht dem Agent, Trustee-Tools via `requestToolbox("trustee")` zu aktivieren + +- [x] **Bestehende Trustee-Nodes prüfen und angepasst** + - `trustee.extractFromFiles`: `_paramMap` korrekt (`connectionId` → `connectionReference`), Output = `ActionDocument`-Liste → wird via `model_dump()` serialisiert + - `trustee.processDocuments`: **Fix implementiert** — neue `_resolveDocumentList()` Funktion erkennt sowohl Graph-Editor-Output (Liste von Dicts mit `documentData`) als auch Chat-Referenzen (Fallback). Kein Chat-Service im Graph-Editor nötig. + - `trustee.syncToAccounting`: **Fix implementiert** — neue `_resolveFirstDocument()` Funktion mit gleicher Dual-Path-Logik + +- [x] **Output-Chaining verifiziert und gefixt:** + - `actionNodeExecutor.py` Zeile 828: `ActionDocument` → `model_dump()` → Dict mit `documentName`, `documentData`, `mimeType` + - `actionNodeExecutor.py` Zeile 836-837: Output enthält `documents` + `documentList` (identisch) + - `_getDocumentsFromUpstream()` (Zeile 237) liest `documents` oder `documentList` aus dem Output-Dict + - Zeile 569: `resolvedParams.setdefault("documentList", docs)` mergt die Dicts in den nächsten Node + - **Problem war:** `processDocuments` und `syncToAccounting` nutzten `DocumentReferenceList.from_string_list()` + `chat.getChatDocumentsFromDocumentList()` — funktioniert nur im Chat-Kontext, nicht im Graph-Editor + - **Lösung:** Beide Actions erkennen jetzt direkt übergebene Dicts (Graph-Editor-Pfad) und nutzen Chat nur als Fallback — **manuell testen** + +### Phase 3: Performance (Prio: hoch — spürbar in jeder Demo) + + +- [x] **DB-Connection-Pooling** für Feature-Data-Agent + - Singleton `DatabaseConnector` pro Feature-DB (z.B. `poweron_trustee`) statt Connection-per-Call + - Pool in `_featureSubAgentTools.py` oder zentral im ServiceCenter + - Connection-Reuse über `featureDbConnPool[featureDbName]` + +- [x] **Sub-Agent Result-Caching** + - Cache-Key: `(featureInstanceId, question_hash, lastSyncAt)` + - Invalidierung bei neuem Sync (`lastSyncAt` ändert sich) + - TTL: 5 Minuten (konfigurierbar) + - Speicherort: In-Memory Dict im Agent-Kontext (pro Workflow-Session) + +### Phase 4: Graphical-Editor Workflow für Demo (Prio: hoch — nötig für UC1 Teil A) + +- [ ] **Workflow im Graphical Editor bauen:** SharePoint Read Files Loop → Trustee Import+Sync + - Trigger: `trigger.manual` (mit Hinweis "könnte automatisch laufen") + - Node 1: `sharepoint.listFiles` → Ordner mit Belegen + - Node 2: `flow.loop` über die Dateiliste + - Node 3 (im Loop): `sharepoint.downloadFile` → PDF herunterladen + - Node 4 (im Loop): `trustee.extractFromFiles` → Belege extrahieren + - Node 5 (im Loop): `trustee.processDocuments` → Buchungen erstellen + - Node 6 (nach Loop): `trustee.syncToAccounting` → Sync mit Abacus + - Alternativ: `trustee.importAndProcess` Convenience-Node (Phase 2) statt Nodes 4-6 + - Testen mit 3-4 Musterbelegen + - Workflow als System-Template speichern (`templateScope: system`) + +- [ ] **Musterbelege erstellen:** Handwerkerrechnung, Nebenkostenabrechnung, Bankbeleg, Versicherungsbeleg (PDFs) + +### Phase 5: Demo-Daten & Testläufe (Prio: mittel) + +- [ ] Budget-Excel erstellen (Soll-Werte 2026 pro Kostenstelle/Liegenschaft) +- [ ] Demo-Prompt für Budgetkontrolle vorbereiten und testen +- [ ] CommCoach-Personas für Immobilien-Kontext erstellen +- [ ] Neutralisierungs-Demo mit fiktivem Mieterdossier testen +- [ ] Demo-Mandant "PWG Demo" sauber aufsetzen +- [ ] Alle 3 Use Cases end-to-end durchspielen + +## Akzeptanzkriterien + +| # | Kriterium (Given-When-Then) | Prio | +|---|---------------------------|------| +| 1 | Given Trustee-Instanz mit Abacus-Config, When Agent `refreshTrusteeData` aufruft, Then werden Daten aus Abacus in `TrusteeData*`-Tabellen importiert und Summary zurückgegeben | must | +| 2 | Given gecachte Daten (lastSyncAt < 1h), When Agent `refreshTrusteeData` ohne `forceRefresh` aufruft, Then wird kein externer Sync ausgelöst und gecachte Counts zurückgegeben | must | +| 3 | Given Trustee-Daten in DB, When Sub-Agent `aggregateTable` mit SUM/GROUP BY aufruft, Then kommen korrekte Aggregationen zurück (verifiziert gegen manuelle Berechnung) | must | +| 4 | Given identische Query innerhalb 5 Min, When `queryFeatureInstance` erneut aufgerufen wird, Then wird gecachtes Ergebnis zurückgegeben (kein neuer Sub-Agent-Loop) | should | +| 5 | Given Graphical Editor geöffnet, When Node-Palette geladen wird, Then erscheint Kategorie "Treuhand" mit allen Trustee-Nodes (inkl. neuem `refreshAccountingData`) | must | +| 6 | Given Workflow im Graphical Editor mit trigger.manual → sharepoint.listFiles → flow.loop → trustee.extractFromFiles → processDocuments → syncToAccounting, When Workflow manuell gestartet wird, Then werden PDFs aus SharePoint geladen, extrahiert und als Positionen mit Sync-Status im Trustee angezeigt | must | +| 7 | Given Trustee-Pipeline im Flow (extract → process → sync), When Node A Output an Node B weitergereicht wird, Then wird `documentList`-Referenz korrekt aufgelöst (Output-Chaining funktioniert) | must | +| 8 | Given Budget-Excel im Workspace + Trustee-Daten, When Budgetkontrolle-Prompt ausgeführt wird, Then erstellt Agent Soll/Ist-Vergleich mit Charts und sendet per Mail | must | + +## Testplan + +| ID | AC | Art | Automatisiert | Repo-Pfad | Status | +|----|----|-----|--------------|-----------|--------| +| T1 | 1 | api | nein (manuell mit Abacus-Sandbox) | — | pending | +| T2 | 2 | api | ja | gateway/tests/features/trustee/test_refresh_tool.py | pending | +| T3 | 3 | api | ja | gateway/tests/features/trustee/test_aggregate_table.py | pending | +| T4 | 4 | api | ja | gateway/tests/serviceAgent/test_feature_data_cache.py | pending | +| T5 | 5 | ui | nein (manuell) | — | pending | +| T6 | 6 | e2e | nein (manuell) | — | pending | +| T7 | 7 | api | ja | gateway/tests/workflows/graphicalEditor/test_node_chaining.py | pending | +| T8 | 8 | e2e | nein (manuell) | — | pending | + +## Links + +- Use Cases: `pamocreate/projects/poweron/customer-pwg/20260407 use-cases-workshop.md` +- Automation Unification (done): `wiki/c-work/3-validate/2026-04-automation-unification.md` +- Trustee Accounting Bridge: `gateway/modules/features/trustee/accounting/accountingBridge.py` +- Accounting Data Sync: `gateway/modules/features/trustee/accounting/accountingDataSync.py` +- Feature Data Agent: `gateway/modules/serviceCenter/services/serviceAgent/featureDataAgent.py` +- Feature Data Provider: `gateway/modules/serviceCenter/services/serviceAgent/featureDataProvider.py` +- Feature Sub-Agent Tool: `gateway/modules/serviceCenter/services/serviceAgent/coreTools/_featureSubAgentTools.py` +- Toolbox Registry: `gateway/modules/serviceCenter/services/serviceAgent/toolboxRegistry.py` +- Abacus Connector: `gateway/modules/features/trustee/accounting/connectors/accountingConnectorAbacus.py` +- Node Registry: `gateway/modules/features/graphicalEditor/nodeRegistry.py` +- Trustee Nodes: `gateway/modules/features/graphicalEditor/nodeDefinitions/trustee.py` +- SharePoint Nodes: `gateway/modules/features/graphicalEditor/nodeDefinitions/sharepoint.py` +- Flow Nodes: `gateway/modules/features/graphicalEditor/nodeDefinitions/flow.py` +- Action Node Executor: `gateway/modules/workflows/automation2/executors/actionNodeExecutor.py` +- Execution Engine: `gateway/modules/workflows/automation2/executionEngine.py` +- Scheduler: `gateway/modules/workflows/scheduler/mainScheduler.py` +- Trustee Workflow Method: `gateway/modules/workflows/methods/methodTrustee/methodTrustee.py` +- Graphical Editor Feature: `gateway/modules/features/graphicalEditor/mainGraphicalEditor.py` +- Graphical Editor Datenmodell: `gateway/modules/features/graphicalEditor/datamodelFeatureGraphicalEditor.py` + +## Abschluss + +- [x] b-reference/gateway/workflow.md aktualisiert (neue Action `trustee.refreshAccountingData`) +- [x] b-reference/gateway/ai-agent.md aktualisiert (`aggregateTable` Tool im Sub-Agent, Trustee-Toolbox) +- [x] b-reference/gateway/automation.md aktualisiert (neue Trustee-Nodes + Kategorie in Node-Palette) +- [ ] TOPICS.md aktualisiert (falls neues Thema) +- [ ] Dieses Dokument → z-archive/ verschoben diff --git a/c-work/2-build/2026-04-automation-unification.md b/c-work/4-done/2026-04-automation-unification.md similarity index 80% rename from c-work/2-build/2026-04-automation-unification.md rename to c-work/4-done/2026-04-automation-unification.md index aa00184..ce68957 100644 --- a/c-work/2-build/2026-04-automation-unification.md +++ b/c-work/4-done/2026-04-automation-unification.md @@ -1,5 +1,6 @@ - + + # Automation Unification -- Konsolidierung v1/v2/Workspace @@ -13,8 +14,8 @@ PowerOn hat drei teilweise ueberlappende Automatisierungssysteme: Automation v1 **Risiko bei Nicht-Umsetzung:** Wachsende Divergenz, doppelter Aufwand bei neuen Aktionen, inkonsistentes Verhalten fuer Endbenutzer. **Leitprinzipien:** -- Keine Migration von Altdaten -- Automation v1 ist nicht produktiv, wird nicht migriert -- Automation v1 bleibt bestehen, bis es durch das neue Feature abgeloest ist +- Keine Migration von Altdaten -- Automation v1 war nicht produktiv, wurde nicht migriert +- Legacy-Features `automation` und `automation2` wurden entfernt (2026-04-07) - Klare Datenmodelle mit definierten State Machines als stabile, erweiterbare Grundlage - Klare Trennung von Mandant/Feature/Feature-Instanz und zugehoeriger RBAC-Logik - Skalierbare AI-Tool-Architektur mit Toolboxes und Sub-Agents fuer 50-100+ Tools @@ -54,16 +55,16 @@ Die `workflows/methods/` Library (methodAi, methodOutlook, methodSharepoint, etc ### Identifizierte Inkonsistenzen -| # | Inkonsistenz | -|---|-------------| -| **I-1** | Zwei Datenmodelle: `AutomationDefinition` (v1) vs `Automation2Workflow` (v2) -- kein gemeinsames Workflow-Konzept | -| **I-2** | Zwei Datenbanken: `poweron_automation` vs `poweron_automation2` | -| **I-3** | Zwei Scheduler: v1 (inkrementell, callback `automation.changed`) vs v2 (full wipe + re-register, callback `automation2.workflow.changed`) | -| **I-4** | Zwei Execution Engines: `WorkflowManager` + `WorkflowProcessor` vs `executionEngine.executeGraph` | -| **I-5** | Kein AI-Chat im Graphical Editor | -| **I-6** | `WorkspaceInput` ist nicht als wiederverwendbare Komponente extrahiert | -| **I-7** | UDB nur in Workspace und CommCoach, nicht im Graphical Editor | -| **I-8** | AI Tools skalieren nicht: 50+ Tools ohne Gruppierungslogik, alle werden dem LLM gleichzeitig exponiert | +| # | Inkonsistenz | Status | +|---|-------------|--------| +| **I-1** | Zwei Datenmodelle: `AutomationDefinition` (v1) vs `Automation2Workflow` (v2) -- kein gemeinsames Workflow-Konzept | **behoben** -- Unified `AutoWorkflow` in Greenfield DB | +| **I-2** | Zwei Datenbanken: `poweron_automation` vs `poweron_automation2` | **behoben** -- Neue DB `poweron_graphicaleditor`, Legacy entfernt | +| **I-3** | Zwei Scheduler: v1 (inkrementell) vs v2 (full wipe + re-register) | offen (Phase 4) | +| **I-4** | Zwei Execution Engines: `WorkflowManager` + `WorkflowProcessor` vs `executionEngine.executeGraph` | offen (bewusst getrennt) | +| **I-5** | Kein AI-Chat im Graphical Editor | **behoben** -- EditorChatPanel mit SSE | +| **I-6** | `WorkspaceInput` ist nicht als wiederverwendbare Komponente extrahiert | offen (Phase 4) | +| **I-7** | UDB nur in Workspace und CommCoach, nicht im Graphical Editor | **behoben** -- UDB im Editor integriert | +| **I-8** | AI Tools skalieren nicht: 50+ Tools ohne Gruppierungslogik | offen (Phase 4: Toolbox Registry) | --- @@ -108,24 +109,26 @@ Die `workflows/methods/` Library (methodAi, methodOutlook, methodSharepoint, etc +------------------------------------------------------------------------+ ``` -### Saeule 1: AI Service (besteht, zu erweitern) +### Saeule 1: AI Service (besteht, zu erweitern in Phase 4) -**Status:** Kern bereit (`serviceAi` + `serviceAgent` + `aicore`). -**Erweiterung:** Toolbox-Architektur fuer 50-100+ Tools (siehe Abschnitt Toolboxes). +**Status:** Kern bereit (`serviceAi` + `serviceAgent` + `aicore`). AI Chat im Editor integriert (EditorChatPanel). +**Offen:** Toolbox-Architektur fuer 50-100+ Tools (siehe Abschnitt Toolboxes, Phase 4). ### Saeule 2: Graphical Editor (Feature "graphicalEditor") -**Status:** Basis vorhanden (Automation2FlowEditor), zu erweitern. +**Status:** Implementiert. Legacy-Features `automation` und `automation2` entfernt. | # | Funktionalitaet | Status | |---|-----------------|--------| -| 1 | **Visual Flow Builder** -- Canvas, Nodes, Connections, Branching, Loops | besteht | -| 2 | **Node Palette** -- abgeleitet aus Toolbox-Registry, jede Action kann als Node exponiert werden | besteht | -| 3 | **AI Chat Sidebar** -- Agent mit Toolbox `"workflow"` fuer Graph-Manipulation | neu | -| 4 | **UDB Integration** -- UnifiedDataBar im Editor | neu | -| 5 | **Tracing/Debug Log** -- AutoStepLog mit Input-Snapshot, Duration, Error pro Node | zu erweitern | +| 1 | **Visual Flow Builder** -- Canvas, Nodes, Connections, Branching, Loops | umgesetzt | +| 2 | **Node Palette** -- Trigger, Flow, AI, Email, SharePoint, ClickUp, File, Trustee | umgesetzt | +| 3 | **AI Chat Sidebar** -- EditorChatPanel mit SSE-Streaming, Graph-Manipulation-Tools | umgesetzt | +| 4 | **UDB Integration** -- UnifiedDataBar mit Files + Sources Tabs, Mandate-gefiltert | umgesetzt | +| 5 | **Tracing/Debug Log** -- RunTracingPanel mit AutoStepLog-Anzeige | umgesetzt (Basis) | | 6 | **Test Runner** -- Visual Highlighting, Step-by-Step, AI-assisted Debugging | zu erweitern | -| 7 | **Version Management** -- Draft/Published Lifecycle | neu | +| 7 | **Version Management** -- Draft/Published/Archived Lifecycle via CanvasHeader | umgesetzt | +| 8 | **Template Management** -- Save as Template, New from Template, Scope-Verwaltung | umgesetzt | +| 9 | **File/Source Attachments** -- Drag&Drop + Source-Picker im AI Chat (wie Workspace) | umgesetzt | ### Saeule 3: Automation Scheduler (zu konsolidieren) @@ -145,7 +148,7 @@ Die `workflows/methods/` Library (methodAi, methodOutlook, methodSharepoint, etc ### Saeule 4: Unified Action Library mit Toolboxes -**Status:** Infrastruktur besteht (`workflows/methods/` + `methodDiscovery` + `ActionExecutor`). Zu erweitern um Toolbox-Konzept (siehe eigener Abschnitt). +**Status:** Infrastruktur besteht (`workflows/methods/` + `methodDiscovery` + `ActionExecutor`). Trustee-Nodes hinzugefuegt. Toolbox-Konzept offen (Phase 4). --- @@ -804,6 +807,9 @@ class AutoWorkflow(PowerOnModel): | `sharepoint.*` | `sharepoint` | entsprechend | `connectionId->connectionReference` | | `clickup.*` | `clickup` | entsprechend | `connectionId->connectionReference` | | `file.create` | `file` | `create` | `template->template` | +| `trustee.extractFromFiles` | `trustee` | `extractFromFiles` | `connectionId->connectionReference` | +| `trustee.processDocuments` | `trustee` | `processDocuments` | `documentList->documentList` | +| `trustee.syncToAccounting` | `trustee` | `syncToAccounting` | `documentList->documentList` | ### Execution-Routing @@ -927,10 +933,9 @@ gateway/modules/ | | +-- interfaceFeatureGraphicalEditor.py (DB: poweron_workflows) | | +-- datamodelFeatureGraphicalEditor.py | | +-- nodeDefinitions/ -| | triggers.py, flow.py, input.py, ai.py, email.py, sharepoint.py, ... +| | triggers.py, flow.py, input.py, ai.py, email.py, sharepoint.py, clickup.py, file.py, trustee.py | | | +-- workspace/ <-- BLEIBT (AI Chat mit UDB) -| +-- automation/ <-- BLEIBT bis Abloesung | +-- commcoach/ <-- BLEIBT | +-- chatbot/ <-- BLEIBT | +-- trustee/ <-- BLEIBT @@ -948,43 +953,45 @@ gateway/modules/ +-- workflows/ | +-- methods/ <-- BLEIBT (Unified Action Library) | +-- processing/ <-- BLEIBT (ActionExecutor, methodDiscovery) -| +-- automation2/ <-- Graph Engine BLEIBT -| +-- scheduler/ <-- NEU (konsolidierter Scheduler) +| +-- automation2/ <-- Graph Engine BLEIBT (executionEngine) +| +-- scheduler/ <-- NEU (konsolidierter Scheduler, Phase 4) | | +-- mainScheduler.py -| +-- automation/ <-- BLEIBT bis Abloesung | +-- workflowManager.py <-- BLEIBT (fuer Workspace Dynamic Mode) ``` --- -## Frontend Code-Struktur (Ziel) +## Frontend Code-Struktur (umgesetzt) ``` frontend_nyla/src/ | +-- components/ <-- SHARED COMPONENTS -| +-- ChatBar/ <-- NEU (extrahiert aus WorkspaceInput) -| | ChatBar.tsx Props: onSend, onStop, onVoice, -| | fileAttachments, showProviderSelector, ... -| +-- ChatStream/ <-- NEU (extrahiert aus workspace/ChatStream) -| | ChatStream.tsx SSE-driven message stream, wiederverwendbar -| +-- UnifiedDataBar/ <-- BLEIBT -| +-- FlowEditor/ <-- RENAMED von Automation2FlowEditor +| +-- UnifiedDataBar/ <-- BLEIBT (Files + Sources Tabs, Mandate-gefiltert) +| +-- FlowEditor/ <-- Umgesetzt (ehemals Automation2FlowEditor) | +-- editor/ -| FlowEditor.tsx + AI Chat Panel -| FlowCanvas.tsx + Visual Run Tracing -| EditorChatPanel.tsx <-- NEU +| Automation2FlowEditor.tsx Hauptkomponente mit 3-Column Layout +| CanvasHeader.tsx Neu/Speichern/Vorlage/Version-Buttons +| EditorChatPanel.tsx AI Chat mit File/Source-Attachments +| RunTracingPanel.tsx Step-Log-Anzeige mit SSE Live-Push + Canvas-Highlighting +| NodeConfigPanel.tsx Node-Konfiguration (inkl. Trustee) +| TemplatePicker.tsx Modal: Vorlage auswaehlen +| +-- nodes/configs/ +| TrusteeNodeConfig.tsx Trustee-Node-Konfiguration +| index.ts NODE_CONFIG_REGISTRY +| +-- index.ts Exports (PendingFile, EditorDataSource, etc.) | +-- pages/views/ | +-- workspace/ | | WorkspacePage.tsx Nutzt ChatBar, ChatStream, UDB -| +-- graphicalEditor/ <-- RENAMED von automation2 -| GraphicalEditorPage.tsx FlowEditor + UDB + ChatPanel -| WorkflowsListPage.tsx -| TasksPage.tsx +| +-- graphicalEditor/ <-- Umgesetzt (ehemals automation2) +| GraphicalEditorPage.tsx FlowEditor + UDB + State-Management +| GraphicalEditorWorkflowsPage.tsx Workflow-Liste mit Umbenennen +| GraphicalEditorTemplatesPage.tsx Vorlagen mit Scope-Verwaltung +| GraphicalEditorTasksPage.tsx | +-- api/ - workflowApi.ts <-- Konsolidiert (ersetzt automation + automation2 API) + workflowApi.ts <-- Konsolidiert (Templates, Versions, Workflows) ``` --- @@ -1028,39 +1035,51 @@ frontend_nyla/src/ ## Phasen-Plan -### Phase 1: Foundation -- Unified Workflow Datenmodell (AutoWorkflow + AutoVersion + AutoRun + AutoStepLog + AutoTask) -- Toolbox-Registry implementieren (Abloesung `_CORE_ONLY_TOOLS`) -- ChatBar-Komponente extrahieren -- Feature Rename: `automation2` -> `graphicalEditor` -- Scheduler konsolidieren (v1 Patterns in v2 Engine) +### Phase 1: Foundation -- ABGESCHLOSSEN (2026-04-05 bis 2026-04-07) +- [x] Unified Workflow Datenmodell (AutoWorkflow + AutoVersion + AutoRun + AutoStepLog + AutoTask) +- [x] Greenfield DB `poweron_graphicaleditor` +- [x] Feature Rename: `automation2` -> `graphicalEditor` +- [x] Legacy-Features `automation` und `automation2` entfernt +- [x] Bootstrap-Prozess konsolidiert und idempotent gemacht +- [x] Boot-Performance optimiert (30s -> 22s) -### Phase 2: Editor Enhancement -- AI Chat Sidebar im Editor (Toolbox `"workflow"` + Graph-Manipulation-Tools) -- UDB Integration im Editor -- AutoVersion Lifecycle (Draft/Published) -- Enhanced AutoStepLog + Visual Tracing +### Phase 2: Editor Enhancement -- ABGESCHLOSSEN (2026-04-07) +- [x] AI Chat Sidebar im Editor (EditorChatPanel mit SSE, Graph-Manipulation) +- [x] UDB Integration im Editor (Files + Sources Tabs, Mandate-gefiltert) +- [x] AutoVersion Lifecycle (Draft/Published/Archived) im CanvasHeader +- [x] Tracing Panel im Editor (RunTracingPanel) +- [x] File/Source-Attachments im AI Chat (Drag&Drop + Source-Picker wie im Workspace) +- [x] 3-Column Layout: [UDB] [Chat/Tracing] [Canvas] [Nodes] -### Phase 3: Productization -- Workflow-Vorlagen: Template-Management (Scope `user` | `instance` | `mandate` | `system`), Bootstrap durch `sysadmin`, Kopie-vs-Freigabe, RBAC laut Abschnitt „Workflow-Vorlagen“ -- Marketplace / Katalog (optional auf Basis derselben Vorlagen-API) -- Monitoring Dashboard -- Retry Policies pro Node -- Notifications bei Scheduler-Fehlern -- Automation v1 Feature entfernen (wird nicht mehr benoetigt) +### Phase 3: Productization -- ABGESCHLOSSEN (2026-04-07) +- [x] Workflow-Vorlagen: Template-Management mit Scope (user/instance/mandate/system) +- [x] System-Template Bootstrap (2 Vorlagen: Personal Assistant, Treuhand) +- [x] Trustee Node-Types (extractFromFiles, processDocuments, syncToAccounting) +- [x] "Als Vorlage speichern" + "Neu aus Vorlage" im Editor +- [x] Scope-Aenderung (erweitern + zuruecknehmen) in Templates-Verwaltung +- [x] Umbenennen von Workflows und Templates +- [x] KeepAlive-Navigation-Fix (Workflow-Laden bei URL-Parameter-Aenderung) +- [ ] Marketplace / Katalog (optional, auf Basis derselben Vorlagen-API) +- [ ] Monitoring Dashboard +- [ ] Retry Policies pro Node +- [ ] Notifications bei Scheduler-Fehlern -### Phase 4: Advanced -- AI Decision Node (`ai.decide`) -- Custom Script Node (Python Sandbox) -- Dynamische Toolbox-Aktivierung basierend auf Connections -- Sub-Agent Pattern fuer weitere Features +### Phase 4: Advanced -- ABGESCHLOSSEN (2026-04-07) +- [x] Toolbox Registry: Tool-Listen fuer alle 8 Toolboxes befuellt, `requestToolbox` Meta-Tool mit Runtime-Refresh in agentLoop +- [x] Scheduler: `subAutomation2Schedule` aus `app.py` entfernt, `/schedule-sync` auf `WorkflowScheduler.syncNow` migriert, Billing-Init in Bootstrap verschoben +- [x] Enhanced AutoStepLog: InputSnapshot fuer Loops/Skipped/alle Pfade, I/O im UI (CollapsibleSection), Live-Push via SSE, Graph-Hervorhebung pro Step, Timestamps + RetryCount +- [x] `app.py` Cleanup: keine feature-spezifischen Imports/Logik mehr (Scheduler, EmailPoller, Billing) +- [ ] AI Decision Node (`ai.decide`) +- [ ] Custom Script Node (Python Sandbox) +- [ ] Sub-Agent Pattern fuer weitere Features --- ## Betroffene Module -- Gateway: `features/automation/`, `features/automation2/`, `workflows/`, `serviceCenter/services/serviceAgent/` -- Frontend: `components/Automation2FlowEditor/`, `pages/views/automation2/` +- Gateway: `features/graphicalEditor/`, `workflows/`, `serviceCenter/services/serviceAgent/`, `interfaces/interfaceBootstrap.py` +- Frontend: `components/FlowEditor/`, `pages/views/graphicalEditor/`, `components/UnifiedDataBar/` +- Entfernt: `features/automation/`, `features/automation2/`, `components/Automation2FlowEditor/`, `pages/views/automation2/` - DB-Migration: nein (Greenfield -- neue DB `poweron_graphicaleditor`, keine Migration von `poweron_automation2`) - Andere: Scheduler (APScheduler/eventManager), RBAC Template-Rollen @@ -1077,18 +1096,45 @@ frontend_nyla/src/ | 2026-04-06 | Workflow-Vorlagen mit Scope + getrenntem RBAC; `my` = nur eigene User-Scope-Vorlagen | Einheitliches Teilen (Kopie vs. read-only Freigabe) ohne Widerspruch zu Mandant/Instanz | | 2026-04-06 | `Auto`-Prefix fuer alle Datenobjekte (AutoWorkflow, AutoVersion, AutoRun, AutoStepLog, AutoTask) | Eindeutige Erkennbarkeit in der Codebase; kein Namenskonflikt mit bestehenden Modellen | | 2026-04-06 | Greenfield-Migration statt DB-Schema-Umbau | Neue DB `poweron_graphicaleditor`; `poweron_automation2` bleibt als Archiv; kein Migrationsrisiko | +| 2026-04-07 | Legacy-Features `automation` und `automation2` entfernt | Konsolidierung abgeschlossen; kein Altcode mehr im Gateway/Frontend | +| 2026-04-07 | Bootstrap idempotent gemacht (`_bootstrapDone` Flag) | Verhindert doppelte Ausfuehrung; `_initRecords` Workaround entfernt | +| 2026-04-07 | Stripe/APScheduler Debug-Logging unterdrueckt | Boot-Performance: 30s -> 22s; AI Pre-Warming dedupliziert | +| 2026-04-07 | UDB Data Sources Mandate-gefiltert | Verhindert Cross-Mandate-Datenlecks bei Active Data Sources | +| 2026-04-07 | Trustee Node-Types im Editor | 3 neue Nodes (extract, process, sync) fuer Treuhand-Workflows | +| 2026-04-07 | System-Templates im Bootstrap | 2 Vorlagen (Personal Assistant, Treuhand) als Startpunkt fuer neue User | +| 2026-04-07 | Template Scope-Aenderung bidirektional | Scope kann erweitert und zurueckgenommen werden; `sharedReadOnly` dynamisch | +| 2026-04-07 | `app.py` als generischer Entry-Point | Keine feature-spezifischen Imports; Scheduler/EmailPoller/Billing in Feature-Lifecycle bzw. Bootstrap | +| 2026-04-07 | SSE Live-Push fuer Run-Tracing | `EventManager`-Queue pro Run; Fallback auf Polling bei SSE-Fehler | +| 2026-04-07 | Canvas Graph-Hervorhebung | `highlightedNodeIds` Prop; farbcodiert nach Step-Status; Glow-Animation bei `running` | +| 2026-04-07 | `requestToolbox` als Meta-Tool | Agent kann zur Laufzeit Toolboxes anfordern; `agentLoop` refresht `toolDefinitions` nach Aufruf | ## Umsetzungs-Checkliste -- [ ] Vereinheitlichtes Schema: AutoWorkflow/AutoVersion/AutoRun/AutoStepLog/AutoTask (Greenfield DB) -- [ ] v1-Scheduler-Pattern in v2 Engine -- [ ] Toolbox Registry + requestToolbox Meta-Tool -- [ ] Feature-Code Rename `automation2` -> `graphicalEditor` -- [ ] Frontend: ChatBar + ChatStream extrahieren -- [ ] Frontend: UDB + Chat im Graph-Editor -- [ ] RBAC Template-Rollen konsolidieren -- [ ] Vorlagen: `templateScope`, Ersteller (Basis-Klasse), Freigabe/Kopie, DATA+RESOURCE-Regeln -- [ ] AutoStepLog + Visual Tracing +- [x] Vereinheitlichtes Schema: AutoWorkflow/AutoVersion/AutoRun/AutoStepLog/AutoTask (Greenfield DB `poweron_graphicaleditor`) +- [x] Feature-Code Rename `automation2` -> `graphicalEditor` (Backend + Frontend) +- [x] Frontend: UDB im Graph-Editor (UnifiedDataBar mit Files + Sources Tabs) +- [x] Frontend: AI Chat Sidebar im Editor (EditorChatPanel mit SSE-Streaming, Graph-Manipulation-Tools) +- [x] Frontend: Tracing Panel im Editor (RunTracingPanel mit Step-Log-Anzeige) +- [x] Frontend: Version Management im Editor (Draft/Published/Archived Lifecycle via CanvasHeader) +- [x] Vorlagen: `templateScope` (user/instance/mandate/system), Freigabe/Kopie, Scope-Aenderung +- [x] Vorlagen: System-Template Bootstrap (`_bootstrapSystemTemplates` in `interfaceBootstrap.py`) +- [x] Vorlagen: 2 System-Templates (Personal Assistant E-Mail-Drafting, Treuhand PDF-Klassifizierung) +- [x] Vorlagen: "Als Vorlage speichern" Button im Editor mit Scope-Auswahl +- [x] Vorlagen: "Neu aus Vorlage" Template-Picker-Modal im Editor +- [x] Vorlagen: Scope-Aenderung (erweitern + zuruecknehmen) in Templates-Seite +- [x] Vorlagen: Umbenennen von Workflows und Templates in den jeweiligen Verwaltungsseiten +- [x] Trustee Node-Types: `trustee.extractFromFiles`, `trustee.processDocuments`, `trustee.syncToAccounting` +- [x] Node-Config Frontend: TrusteeNodeConfig.tsx mit Connection/Folder/Prompt-Feldern +- [x] Legacy-Features `automation` und `automation2` aus Gateway und Frontend entfernt +- [x] Bootstrap: Idempotenter `initBootstrap` mit `_bootstrapDone` Flag +- [x] Bootstrap: Redundanter `_initRecords` Fallback in `interfaceDbApp.py` entfernt +- [x] Boot-Performance: Stripe/APScheduler Debug-Logging unterdrueckt, AI Pre-Warming dedupliziert (30s -> 22s) +- [x] UDB: Mandate-Filter fuer Active Data Sources und Feature Data Sources +- [x] KeepAlive: Workflow-Laden bei Navigation von Workflows-Seite zum Editor (URL-Parameter reaktiv) +- [x] RBAC Template-Rollen fuer graphicalEditor (admin/user/viewer) +- [x] Toolbox Registry: Tool-Listen befuellt (core/ai/datasources/email/sharepoint/clickup/jira/workflow), `requestToolbox` Meta-Tool implementiert, `_activateToolboxes` generisch +- [x] Scheduler-Konsolidierung: `subAutomation2Schedule` entfernt, `/schedule-sync` migriert auf `WorkflowScheduler.syncNow`, `app.py` bereinigt +- [x] AutoStepLog + Enhanced Visual Tracing: InputSnapshot fuer alle Pfade (Loops, Skipped), I/O CollapsibleSections im UI, Live-Push via SSE (`/runs/{runId}/stream`), Graph-Hervorhebung (Canvas Highlighting), Timestamps + RetryCount - [ ] Neutralisierung: keine Aenderung (nutzt gleiche Services) - [ ] Billing-Impact: pruefen (Automation-Runs zaehlen?) @@ -1140,6 +1186,21 @@ frontend_nyla/src/ ## Abschluss +**Vollstaendiger Umbau abgeschlossen am 2026-04-07.** Phasen 1-4 umgesetzt. + +**Phase 4 Umsetzung (2026-04-07):** + +| Punkt | Umgesetzt | +|-------|-----------| +| **Toolbox Registry** | Tool-Listen fuer alle 8 Toolboxes befuellt (core: 20, ai: 9, datasources: 8, email: 5, sharepoint: 3, clickup: 3, jira: 3, workflow: 9). `requestToolbox` Meta-Tool mit Schema, Handler in `mainServiceAgent._registerRequestToolbox()`, Runtime-Refresh in `agentLoop.py`. `_activateToolboxes` generisch (entfernt inaktive Tools). | +| **Scheduler-Konsolidierung** | `subAutomation2Schedule` komplett aus `app.py` entfernt. `/schedule-sync` Endpoint migriert auf `WorkflowScheduler.syncNow()`. `setMainLoop` in `app.py` fuer Thread-Bridge. Billing-Init in `interfaceBootstrap._bootstrapBilling()` verschoben. EmailPoller-Stop in `mainGraphicalEditor.onStop()`. | +| **Enhanced AutoStepLog + Visual Tracing** | `inputSnapshot` fuer alle Pfade: Loop-Header, Loop-Body (`_loopItem`/`_loopIndex`), Resume-Path, Skipped-Nodes (`_skipReason`). RunTracingPanel: CollapsibleSection fuer Input/Output, Timestamps, RetryCount, Loop-Indikator. Live-Push via SSE (`GET /runs/{runId}/stream`) mit Fallback auf 3s-Polling. Canvas Graph-Hervorhebung: `highlightedNodeIds` Prop auf FlowCanvas, farbcodiert nach Status (running=gelb+Glow, completed=gruen, failed=rot, skipped=grau). | + +**Verbleibende optionale Erweiterungen:** +- AI Decision Node (`ai.decide`) +- Custom Script Node (Python Sandbox) +- Sub-Agent Pattern fuer weitere Features + - [ ] b-reference/gateway/automation.md aktualisiert - [ ] TOPICS.md aktualisiert - [ ] Dieses Dokument -> z-archive/ verschoben diff --git a/f-decisions/platzhalter.txt b/f-decisions/platzhalter.txt new file mode 100644 index 0000000..e69de29