10 KiB
Automation (Graphical Editor)
Ueberblick
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).
Architektur-Saeulen:
- AI Service -- Agent mit Toolbox-Registry, Streaming, Neutralisierung, Failover
- Graphical Editor -- n8n-Style Flow-Builder mit AI Chat, UDB, Tracing, Versioning
- Consolidated Scheduler --
WorkflowSchedulermit inkrementellem Sync (v1-Patterns) - Unified Action Library -- Method/Action-Bibliothek mit Toolbox-Zuordnung
Leitentscheide:
- Legacy-Features
automationundautomation2entfernt (Gateway + Frontend) - Greenfield-DB
poweron_graphicaleditor(keine Migration von Altdaten) - v1-Scheduler-Patterns (inkrementell,
eventId,replaceExisting, Stale-Removal) in konsolidierten Scheduler uebernommen app.pyals generischer Entry-Point ohne feature-spezifische Imports
Datenmodell (Greenfield DB poweron_graphicaleditor)
| 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 |
Invarianten:
- Pro Workflow hoechstens eine
PUBLISHEDVersion; 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
Workflow-Vorlagen
| 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) |
Scheduler (WorkflowScheduler)
Datei: workflows/scheduler/mainScheduler.py
Konsolidierter Scheduler mit v1-Patterns:
| 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 |
Lifecycle:
- Start:
mainGraphicalEditor.onStart()->startScheduler(eventUser) - Stop:
mainGraphicalEditor.onStop()->stopScheduler() - Manual Sync:
POST /api/workflows/{instanceId}/schedule-sync->syncNow() - Main Loop:
app.pysetztsetSchedulerMainLoop(main_loop)beim Start
Run-Failure-Handling:
- In-App Notification fuer Workflow-Creator
- Messaging-Subscription (
GraphicalEditorRunFailed) fuer E-Mail-Benachrichtigung - Event-Emission (
graphicalEditor.run.failed)
Execution Engine
Datei: workflows/automation2/executionEngine.py
| 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 |
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
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.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.pyrefreshttoolDefinitionsnach erfolgreichem Aufruf- Nur inaktive Toolboxes werden als Enum-Optionen angeboten
Aktivierung:
_activateToolboxesinmainServiceAgent.pyprueft User-Connections- Toolboxes ohne
requiresConnectionsind 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 | 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) |
| Agent Tools | serviceCenter/services/serviceAgent/ (coreTools, actionToolAdapter, workflowTools) |
| Bootstrap | interfaces/interfaceBootstrap.py (System-Templates, Billing) |
Regeln / Invarianten
- Eine Action Library: Aenderungen an Methods/Actions betreffen Workspace, Graph-Editor und Agent-Tools gleichzeitig --
actionId-Stabilitaet beachten. - RBAC strikt trennen: Mandantenrollen vs Feature-Instanz-Rollen nicht mischen; Permissions ueber AccessRules.
- Scheduler vs Editor: Ausfuehrung und Zeitplanung gehoeren zum Scheduler; der Graph ist Version-gebunden (Draft vs Published).
- Tool-Skalierung: Toolbox-Konzept mit
requestToolboxMeta-Tool; connection-basierte Verfuegbarkeit. app.pygenerisch: Keine feature-spezifischen Imports inapp.py; Feature-Lifecycle inmainGraphicalEditor.onStart/onStop.- Neutralisierung / KI: Plattformweit gelten die zentralen KI-Datenpfade; Automation nutzt dieselben Services.
- Bootstrap idempotent:
initBootstrapmit_bootstrapDoneFlag; System-Templates, Billing, Stripe-Prices.