wiki/b-reference/gateway/workflow.md
ValueOn AG d4095db4f2 fixes
2026-04-25 01:13:24 +02:00

144 lines
12 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- status: canonical -->
<!-- lastReviewed: 2026-04-24 -->
<!-- verifiedAgainst: gateway (codebase audit 2026-04-07, post Automation Unification) + Typed Action Architecture Phasen 1-5 -->
# Workflow-Engine
## Überblick
Die Workflow-Engine im Gateway orchestriert KI-gestützte Aufgabenpläne und die Ausführung einzelner **Aktionen** über eine gemeinsame **Method/Action-Bibliothek**. Sie verbindet die Schichten *Workflow**Methods**Services**Interfaces**Connectors*; Workflows importieren bewusst **nicht** direkt Interfaces, Connectors oder `aicore` (Zugriff über Services).
**Einsatzorte (Konsumenten der Action Library):**
- **Workspace (Dynamic Mode):** `WorkflowProcessor` / `modeDynamic` → Planung (Stage 1/2) → `ActionExecutor`
- **Graphical Editor:** `executionEngine.executeGraph` mappt Nodes (`_method` / `_action`) auf dieselbe Library; vor dem Lauf validiert `validateGraph` u.a. **Port-Kompatibilität** (kein impliziter Wire-Handover mehr). Graph-definierte Outputs (z.B. `input.form` / `trigger.form`) werden über `parse_graph_defined_output_schema` / `{ kind: "fromGraph", parameter: "fields" }` aus den Node-Parametern abgeleitet.
- **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).
---
## WorkflowManager
Zentrale Steuerung in `gateway/modules/workflows/workflowManager.py` (grosse Datei; Einstieg für Start/Stopp und Hauptloop).
**Öffentliche / zentrale Verantwortlichkeiten (Konzept):**
| Bereich | Inhalt |
|--------|--------|
| Lebenszyklus | Start eines Workflow-Laufs, Verarbeitungsschleife, Beendigung |
| Planung | Aufgaben- und Aktionsplanung (modusabhängig; KI-Planning über Services) |
| Ausführung | Abarbeitung von Tasks/Actions in definierter Reihenfolge |
| Zustand | Anbindung an persistierten `ChatWorkflow` / Chat-DB über Service- und Interface-Schicht |
**Workflow-Zustände (konzeptionell):** `running`, `stopped`, `completed`, `failed`.
**Modi (Code-Stand):** `WorkflowProcessor` unterstützt zwei Modi:
- **`WORKFLOW_DYNAMIC`** (`modeDynamic.py`) — zweistufige Aktionsplanung (Stage 1: Aktionswahl + Ressourcen; Stage 2: Parametergenerierung)
- **`WORKFLOW_AUTOMATION`** (`modeAutomation.py`) — sequenzielle Abarbeitung für Automation v1
Zusätzlich definiert `WorkflowModeEnum` den Modus **`WORKFLOW_CHATBOT`** (Chatbot-Feature).
---
## Methoden
Methoden sind Python-Klassen unter `gateway/modules/workflows/methods/`; der **Methodenname** (`self.name`) ist der Registry-Schlüssel (z.B. `ai`, `context`). Aktionen sind über `WorkflowActionDefinition` registriert; viele tragen `actionId` im Muster `<method>.<action>` und `dynamicMode=True` für den Agent/Graph.
| Method (`self.name`) | Actions (Registry-Keys) |
|---------------------|-------------------------|
| `context` | `getDocumentIndex`, `extractContent`, `neutralizeData`, `triggerPreprocessingServer` |
| `ai` | `process`, `webResearch`, `summarizeDocument`, `translateDocument`, `convertDocument`, `generateDocument`, `generateCode`, `consolidate` (KI-Konsolidierung aggregierter Ergebnisse) |
| `outlook` | `readEmails`, `searchEmails`, `composeAndDraftEmailWithContext`, `sendDraftEmail` |
| `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`, `refreshAccountingData` (`dynamicMode=True`) |
| `chatbot` | `queryDatabase` |
| `file` | `create` |
*Hinweis:* Ältere Kontext-Dokumente nennen für `context` u.a. `saveContent` / `transformContent`; der aktuelle Gateway-Stand listet die obigen Aktionen (Stand Abgleich Code / Review 2026-04-05).
### Graphical Editor — UDM, Loop, KI-Badge
- **Unified Document Model (UDM):** Extraktion kann ein hierarchisches JSON (`Document` → `StructuralNode``ContentBlock`) liefern; Port-Typen `UdmDocument`, `UdmNodeList`, `ConsolidateResult` im Typed-Port-System (`portTypes.py`).
- **Nodes:** u. a. `context.extractContent` (ohne KI), `data.consolidate` (deterministisch), `ai.consolidate` (LLM), `flow.loop` mit Parametern `level` (UDM-Ebene) und `concurrency` (parallele Iterationen).
- **Kosten-Transparenz:** Jede Node-Definition trägt `meta.usesAi` (`true` | `false`). Das Frontend (`FlowCanvas`, Node-Palette) zeigt ein **AI-Badge** nur bei `usesAi: true`.
---
## Aktionen
- **Registrierung:** Jede Aktion ist eine `WorkflowActionDefinition` mit Metadaten, Parametern (`WorkflowActionParameter`, u.a. `FrontendType`) und `execute`-Callable.
- **Ausführung:** `ActionExecutor` löst `methodName` + `actionName` auf, validiert Parameter (Action Registry / Pydantic je nach Implementierung) und liefert ein **`ActionResult`** (Erfolg, Dokumente, Fehler).
- **Dokumente:** Ergebnisse werden typischerweise als strukturierte **`ActionDocument`** / Extraktionsartefakte (`ContentExtracted` / `ContentPart`) weitergereicht.
- **Extraktion vs. KI:** Zielarchitektur (siehe `ai_plan_architecture.md`): **reine Extraktion** (`context.extractContent` bzw. dokumentbezogene Pipeline) ist von **KI-Aufrufen** (`serviceAi`) zu trennen; KI-Methoden arbeiten bevorzugt mit bereits extrahierten `ContentPart`-Strukturen.
- **Planung:** Stage 1 liefert u.a. `action` (`method.action`), Zieltext, optional `documentList` / `connectionReference`; Stage 2 ergänzt bei Bedarf das Parameter-JSON ohne die Stage-1-Ressourcen zu überschreiben.
---
## Typed Action Architecture (Phasen 1-5)
Seit April 2026 ist jede Action typisiert; Editor, Adapter und Runtime lesen dieselbe Catalog-Sicht (siehe `wiki/c-work/3-validate/2026-04-typed-action-architecture.md`). Konkrete Bausteine:
### Action-Signaturen + Catalog
- `gateway/modules/workflows/methods/method<Feature>/actions/<action>.py` deklariert pro Action eine **typisierte Pydantic-Eingabe** (Pflicht-Felder, Typen, Default-Werte) und liefert `ActionResult` (`success`, `error`, `documents`).
- `FeatureInstanceRef` (`{$type, id, featureCode}`) ist der **Discriminator-Envelope** fuer feature-instance-Parameter -- ersetzt rohe UUID-Strings, behaelt Backwards-Compat durch Auto-Unwrap im Runtime.
- `/api/automation2/catalog` exportiert die normalisierten Signaturen; Editor + AI-Agent + Adapter konsumieren genau diesen Stream.
### Adapter-Layer (`registerNodeWithMethod`)
- `gateway/modules/features/graphicalEditor/nodeDefinitions/registerNodeWithMethod.py` leitet die Editor-Node-Definitionen automatisch aus den Action-Signaturen ab (Ports, Pflicht-Felder, Typen, Frontend-Hints).
- Snapshot-Test `gateway/tests/unit/graphicalEditor/test_adapter_validator.py::test_staticNodesHaveNoDriftAgainstLiveMethods` haelt das Adapter-Layer hart gegen die Methods (`assert report.errors == []`, `_KNOWN_ADAPTER_DRIFTS = frozenset()`).
- Drift-Backlog wird in `wiki/c-work/4-done/2026-04-adapter-drift-cleanup.md` (abgeschlossen) tracked; neue Drifts MUESSEN entweder behoben oder bewusst ergaenzt werden.
### Runtime (`executeGraph`) -- Pick-not-Push + Materialisierung
- `gateway/modules/workflows/automation2/executionEngine.py::executeGraph` ruft beim Start zwei Migrations-Helper:
- `materializeFeatureInstanceRefs` (`automation2/featureInstanceRefMigration.py`) -- wandelt rohe `featureInstanceId: "<uuid>"` in `FeatureInstanceRef`-Envelope.
- `materializeConnectionRefs` (`automation2/pickNotPushMigration.py`) -- resolviert leere `connectionReference` aus Upstream-DataRefs.
- `resolveParameterReferences` / `_unwrapTypedRef` (`graphUtils`) entpacken Envelopes vor dem Action-Call -- Legacy-Aktionen sehen weiterhin den nackten Wert (`id`).
- DB-Hygiene: `gateway/scripts/script_migrate_feature_instance_refs.py` migriert Stored Graphs persistent (Editor-Reads sehen sofort die Envelopes; Workflows laufen aber auch ohne Skript korrekt).
### Bindings-Resolver mit `*`-Wildcard
- DataRefs unterstuetzen `path = ["documents", "*", "name"]` -- der Resolver iteriert ueber Listen und liefert ein `List[str]` zurueck. Das ist die Basis fuer **Loop-Vorschlaege** im DataPicker (`buildPickablePathsForNode` im Editor-Frontend).
- Generic-object drill-down kennt zwei Stufen: konkretes Item-Schema (wenn bekannt) oder generic `*`-Pfad (wenn der Item-Typ erst zur Laufzeit feststeht).
### Save-with-errors
- Der Editor erlaubt **Save bei Pflicht-Fehlern** (AC-9 / `CanvasHeader.tsx`); Run wird per `executeBlockedReason` blockiert, der Save-Toast meldet die Fehler-Anzahl.
- Backend-Validierung erfolgt in `validateGraph` (Port-Mismatch, fehlende Pflicht-Bindings) -- der eigentliche Run schlaegt mit klarer Fehlermeldung fehl, falls jemand den Editor-Block umgeht.
---
## Schlüssel-Dateien
| Pfad (unter `gateway/modules/`) | Rolle |
|--------------------------------|--------|
| `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 |
---
## Regeln / Invarianten
1. **Schichten-Imports:** Workflows importieren nur `datamodels`, `services`, interne `workflows/*`. Methods importieren `datamodels`, `services`, `workflows.methods.*`**keine** direkten Interface-/Connector-/aicore-Imports in Methods.
2. **Zustand am Workflow:** Rund-/Task-/Action-Indices und Kontext gehören zum **`ChatWorkflow`** / `TaskContext`, nicht als lose Parameter durch alle Ebenen.
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, Graphical Editor und Agent-Tools genutzt — Änderungen an `actionId` / Parametern wirken quer über alle Konsumenten.