120 lines
5 KiB
Markdown
120 lines
5 KiB
Markdown
<!-- status: done -->
|
|
<!-- started: 2026-04-24 -->
|
|
<!-- moved-to-4-done: 2026-04-24 -->
|
|
<!-- component: gateway -->
|
|
|
|
# Adapter Drift Cleanup — abgeschlossen
|
|
|
|
## Beschreibung und Kontext
|
|
|
|
Phase 3 der [Typed Action Architecture](../3-validate/2026-04-typed-action-architecture.md)
|
|
hat den `adapterValidator` (CI-Saftynet) gebaut. Beim ersten scharfen Lauf
|
|
gegen `STATIC_NODE_TYPES` + die live `Method`-Registry hat er **26 reale
|
|
Drifts** zwischen Editor-Node-Adaptern (Schicht 3) und Action-Signaturen
|
|
(Schicht 2) erkannt.
|
|
|
|
Plan #4 hat alle 26 Drifts behoben. `_KNOWN_ADAPTER_DRIFTS` ist jetzt
|
|
`frozenset()` und der Snapshot-Test verlangt strikt
|
|
`assert report.errors == []`.
|
|
|
|
---
|
|
|
|
## Ergebnis
|
|
|
|
| Status | Wert |
|
|
|---|---|
|
|
| Drifts vor Cleanup | 26 |
|
|
| Drifts nach Cleanup | **0** |
|
|
| `_KNOWN_ADAPTER_DRIFTS` | `frozenset()` |
|
|
| `test_staticNodesHaveNoDriftAgainstLiveMethods` | `assert report.errors == []` |
|
|
| Test-Sweep | 428/428 Unit-Tests grün |
|
|
|
|
---
|
|
|
|
## Vorgehen pro Drift-Kategorie
|
|
|
|
### A) Felder umbenennen (UI ↔ Action-Arg-Namen)
|
|
|
|
Die UI hatte die richtige Semantik aber falsche Feldnamen.
|
|
|
|
| Adapter Node | Vorher | Nachher |
|
|
|---|---|---|
|
|
| `ai.prompt` | `outputFormat` | `resultType` (mit Action-Optionen) |
|
|
| `ai.generateCode` | `language` | `resultType` (Datei-Endungen wie `py`, `js`, …) |
|
|
| `ai.summarizeDocument` | `summaryLength` `["short", "medium", "long"]` | `["brief", "medium", "detailed"]` (Action-Vokabular) |
|
|
|
|
### B) UI-Felder ohne Action-Backing entfernt
|
|
|
|
Die UI exponierte Felder, die das Action gar nicht akzeptiert. Statt einen
|
|
neuen Composite-UI-Mechanismus im Adapter-Layer zu bauen (out of scope), wurden
|
|
die UI-Felder entfernt — User füllen das echte Action-Arg direkt aus.
|
|
|
|
| Adapter Node | Entferntes UI-Feld | Wo Funktionalität bleibt |
|
|
|---|---|---|
|
|
| `ai.prompt` | `context` | via Wire (DocumentList → Input) |
|
|
| `email.checkEmail` | `fromAddress`, `subjectContains`, `hasAttachment` | konsolidiert in `filter` |
|
|
| `email.searchEmail` | `filter`, `fromAddress`, `toAddress`, `subjectContains`, `bodyContains`, `hasAttachment` | konsolidiert in `query` (jetzt required) |
|
|
| `email.draftEmail` | `subject`, `body` | via `context` (KI-Komposition) ODER `emailContent` (Direkt-Override) |
|
|
| `email.draftEmail` | `attachments` | umgestellt auf `documentList` |
|
|
| `clickup.createTask` | `teamId` | bereits über `pathQuery`/`listId` identifizierbar |
|
|
| `clickup.updateTask` | `taskUpdateEntries` (keyValueRows) | konsolidiert in `taskUpdate` (JSON) |
|
|
| `context.extractContent` | `outputDetail`, `includeImages`, `includeTables` | konsolidiert in `extractionOptions` (JSON) |
|
|
|
|
### C) Pflicht-Action-Args als hidden DataRef-Felder ergänzt
|
|
|
|
Die Action verlangt einen Pflicht-Parameter, aber der Adapter exponierte ihn
|
|
weder als `userParams.actionArg` noch als `contextParams`. Lösung: das Feld
|
|
als `frontendType: hidden` ergänzt, sodass der DataPicker es bedienen kann
|
|
und der Validator es als gemappt anerkennt.
|
|
|
|
| Adapter Node | Hinzugefügtes Feld |
|
|
|---|---|
|
|
| `ai.summarizeDocument` | `documentList` (hidden, required) |
|
|
| `ai.translateDocument` | `documentList` (hidden, required) |
|
|
| `ai.convertDocument` | `documentList` (hidden, required) |
|
|
| `sharepoint.uploadFile` | `content` (hidden, required) |
|
|
| `clickup.uploadAttachment` | `content` (hidden, required) |
|
|
| `context.extractContent` | `documentList` (hidden, required) |
|
|
|
|
### D) Actions ohne Editor-Adapter (Warnings — bewusst belassen)
|
|
|
|
| Action | Begründung |
|
|
|---|---|
|
|
| `context.neutralizeData` | wird bewusst nicht im Editor angeboten — Backend-only Pre-Processing |
|
|
| `context.triggerPreprocessingServer` | wird bewusst nicht im Editor angeboten — Server-Op, kein Editor-UX |
|
|
|
|
Beide sind Warnings, keine Errors. Wenn später benötigt, einfach auf
|
|
`dynamicMode=True` umstellen oder Editor-Node bauen.
|
|
|
|
---
|
|
|
|
## Akzeptanzkriterien
|
|
|
|
| # | Kriterium | Status |
|
|
|---|---|---|
|
|
| 1 | Jede Zeile in den Drift-Tabellen hat einen abgeschlossenen Fix | DONE |
|
|
| 2 | `_KNOWN_ADAPTER_DRIFTS` ist `frozenset()` | DONE |
|
|
| 3 | `test_staticNodesHaveNoDriftAgainstLiveMethods` auf `assert report.errors == []` umgestellt | DONE |
|
|
| 4 | Dokument nach `c-work/4-done/` verschoben | DONE |
|
|
|
|
---
|
|
|
|
## Berührte Dateien
|
|
|
|
- `gateway/modules/features/graphicalEditor/nodeDefinitions/ai.py`
|
|
- `gateway/modules/features/graphicalEditor/nodeDefinitions/email.py`
|
|
- `gateway/modules/features/graphicalEditor/nodeDefinitions/clickup.py`
|
|
- `gateway/modules/features/graphicalEditor/nodeDefinitions/sharepoint.py`
|
|
- `gateway/modules/features/graphicalEditor/nodeDefinitions/context.py`
|
|
- `gateway/tests/unit/graphicalEditor/test_adapter_validator.py`
|
|
|
|
Keine Action-Implementierungen geändert → kein Runtime-Regressionsrisiko.
|
|
|
|
---
|
|
|
|
## Links
|
|
|
|
- Architektur-Plan: [../3-validate/2026-04-typed-action-architecture.md](../3-validate/2026-04-typed-action-architecture.md)
|
|
- Validator: `gateway/modules/features/graphicalEditor/adapterValidator.py`
|
|
- Snapshot-Test: `gateway/tests/unit/graphicalEditor/test_adapter_validator.py`
|
|
- Konsolidierter Folge-Plan: [../1-plan/2026-04-typed-action-followups.md](../1-plan/2026-04-typed-action-followups.md)
|