From da974190ea1148a4bd47cf921a1a1808e7c66fe6 Mon Sep 17 00:00:00 2001 From: Ida Date: Sun, 3 May 2026 15:01:24 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20alle=20Node=20definitionen=20korrigiert?= =?UTF-8?q?=20und=20im=20backend=20gesetzt=20-=20keine=20mapping=20layer?= =?UTF-8?q?=20sonder=20saubere=20quelldaten,=20fehlende=20dataRef=20parame?= =?UTF-8?q?ter=20hinzugef=C3=BCgt,=20damit=20jede=20node=20kontext=20nutze?= =?UTF-8?q?n=20kann?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../graphicalEditor/nodeDefinitions/ai.py | 48 ++++++++----- .../nodeDefinitions/clickup.py | 70 +++++++++---------- .../nodeDefinitions/context.py | 2 +- .../graphicalEditor/nodeDefinitions/data.py | 10 +-- .../graphicalEditor/nodeDefinitions/email.py | 28 ++++---- .../graphicalEditor/nodeDefinitions/file.py | 12 ++-- .../graphicalEditor/nodeDefinitions/flow.py | 14 ++-- .../graphicalEditor/nodeDefinitions/input.py | 40 +++++++---- .../nodeDefinitions/redmine.py | 60 ++++++++-------- .../nodeDefinitions/sharepoint.py | 32 ++++----- .../nodeDefinitions/triggers.py | 2 +- .../nodeDefinitions/trustee.py | 26 +++---- .../features/graphicalEditor/nodeRegistry.py | 2 + modules/features/graphicalEditor/portTypes.py | 7 +- .../methods/methodAi/actions/generateCode.py | 9 ++- .../methodAi/actions/generateDocument.py | 9 ++- .../methods/methodAi/actions/webResearch.py | 34 ++++++++- 17 files changed, 239 insertions(+), 166 deletions(-) diff --git a/modules/features/graphicalEditor/nodeDefinitions/ai.py b/modules/features/graphicalEditor/nodeDefinitions/ai.py index 65e97654..857b1516 100644 --- a/modules/features/graphicalEditor/nodeDefinitions/ai.py +++ b/modules/features/graphicalEditor/nodeDefinitions/ai.py @@ -4,7 +4,7 @@ from modules.shared.i18nRegistry import t _AI_COMMON_PARAMS = [ - {"name": "requireNeutralization", "type": "boolean", "required": False, + {"name": "requireNeutralization", "type": "bool", "required": False, "frontendType": "checkbox", "default": False, "description": t("Eingaben fuer diesen Call neutralisieren")}, {"name": "allowedModels", "type": "array", "required": False, @@ -19,19 +19,19 @@ AI_NODES = [ "label": t("Prompt"), "description": t("Prompt eingeben und KI führt aus"), "parameters": [ - {"name": "aiPrompt", "type": "string", "required": True, "frontendType": "templateTextarea", + {"name": "aiPrompt", "type": "str", "required": True, "frontendType": "templateTextarea", "description": t("KI-Prompt")}, - {"name": "resultType", "type": "string", "required": False, "frontendType": "select", + {"name": "resultType", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["txt", "json", "md", "csv", "xml", "html", "pdf", "docx", "xlsx", "pptx", "png", "jpg"]}, "description": t("Ausgabeformat"), "default": "txt"}, {"name": "documentList", "type": "DocumentList", "required": False, "frontendType": "dataRef", "description": t("Dokumentenliste (Upstream-Output binden)"), "default": ""}, - {"name": "context", "type": "string", "required": False, "frontendType": "dataRef", + {"name": "context", "type": "str", "required": False, "frontendType": "dataRef", "description": t("Kontextdaten fuer den Prompt (Upstream-Output binden)"), "default": ""}, - {"name": "documentTheme", "type": "string", "required": False, "frontendType": "select", + {"name": "documentTheme", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["general", "finance", "legal", "technical", "hr"]}, "description": t("Dokument-Thema (Style-Hinweis fuer den Renderer)"), "default": "general"}, - {"name": "simpleMode", "type": "boolean", "required": False, "frontendType": "checkbox", + {"name": "simpleMode", "type": "bool", "required": False, "frontendType": "checkbox", "description": t("Einfacher Modus"), "default": True}, ] + _AI_COMMON_PARAMS, "inputs": 1, @@ -50,12 +50,16 @@ AI_NODES = [ "label": t("Web-Recherche"), "description": t("Recherche im Web"), "parameters": [ - {"name": "prompt", "type": "string", "required": True, "frontendType": "textarea", + {"name": "prompt", "type": "str", "required": True, "frontendType": "textarea", "description": t("Recherche-Anfrage")}, + {"name": "context", "type": "str", "required": False, "frontendType": "dataRef", + "description": t("Optionaler Kontext aus Upstream-Node (wird dem Prompt vorangestellt)"), "default": ""}, + {"name": "documentList", "type": "DocumentList", "required": False, "frontendType": "dataRef", + "description": t("Optionale Dokumentenliste aus Upstream-Node (Text wird dem Prompt hinzugefügt)"), "default": ""}, ] + _AI_COMMON_PARAMS, "inputs": 1, "outputs": 1, - "inputPorts": {0: {"accepts": ["Transit"]}}, + "inputPorts": {0: {"accepts": ["Transit", "AiResult", "DocumentList", "ActionResult"]}}, "outputPorts": {0: {"schema": "AiResult"}}, "meta": {"icon": "mdi-magnify", "color": "#9C27B0", "usesAi": True}, "_method": "ai", @@ -69,7 +73,7 @@ AI_NODES = [ "parameters": [ {"name": "documentList", "type": "DocumentList", "required": True, "frontendType": "dataRef", "description": t("Dokumentenliste (Upstream-Output binden)"), "default": ""}, - {"name": "summaryLength", "type": "string", "required": False, "frontendType": "select", + {"name": "summaryLength", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["brief", "medium", "detailed"]}, "description": t("Kurz, mittel oder ausführlich"), "default": "medium"}, ] + _AI_COMMON_PARAMS, @@ -89,7 +93,7 @@ AI_NODES = [ "parameters": [ {"name": "documentList", "type": "DocumentList", "required": True, "frontendType": "dataRef", "description": t("Dokumentenliste (Upstream-Output binden)"), "default": ""}, - {"name": "targetLanguage", "type": "string", "required": True, "frontendType": "text", + {"name": "targetLanguage", "type": "str", "required": True, "frontendType": "text", "description": t("Zielsprache (z.B. de, en, French)")}, ] + _AI_COMMON_PARAMS, "inputs": 1, @@ -108,7 +112,7 @@ AI_NODES = [ "parameters": [ {"name": "documentList", "type": "DocumentList", "required": True, "frontendType": "dataRef", "description": t("Dokumentenliste (Upstream-Output binden)"), "default": ""}, - {"name": "targetFormat", "type": "string", "required": True, "frontendType": "select", + {"name": "targetFormat", "type": "str", "required": True, "frontendType": "select", "frontendOptions": {"options": ["docx", "pdf", "xlsx", "csv", "txt", "html", "json", "md"]}, "description": t("Zielformat")}, ] + _AI_COMMON_PARAMS, @@ -126,12 +130,16 @@ AI_NODES = [ "label": t("Dokument generieren"), "description": t("Dokument aus Prompt generieren"), "parameters": [ - {"name": "prompt", "type": "string", "required": True, "frontendType": "textarea", + {"name": "prompt", "type": "str", "required": True, "frontendType": "textarea", "description": t("Generierungs-Prompt")}, + {"name": "context", "type": "str", "required": False, "frontendType": "dataRef", + "description": t("Optionaler Kontext aus Upstream-Node (wird dem Prompt vorangestellt)"), "default": ""}, + {"name": "documentList", "type": "DocumentList", "required": False, "frontendType": "dataRef", + "description": t("Optionale Dokumentenliste als Vorlage/Referenz"), "default": ""}, ] + _AI_COMMON_PARAMS, "inputs": 1, "outputs": 1, - "inputPorts": {0: {"accepts": ["Transit"]}}, + "inputPorts": {0: {"accepts": ["Transit", "AiResult", "DocumentList", "ActionResult"]}}, "outputPorts": {0: {"schema": "DocumentList"}}, "meta": {"icon": "mdi-file-plus", "color": "#9C27B0", "usesAi": True}, "_method": "ai", @@ -143,15 +151,19 @@ AI_NODES = [ "label": t("Code generieren"), "description": t("Code aus Beschreibung generieren"), "parameters": [ - {"name": "prompt", "type": "string", "required": True, "frontendType": "textarea", + {"name": "prompt", "type": "str", "required": True, "frontendType": "textarea", "description": t("Code-Generierungs-Prompt")}, - {"name": "resultType", "type": "string", "required": False, "frontendType": "select", + {"name": "resultType", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["py", "js", "ts", "html", "java", "cpp", "txt", "json", "csv", "xml"]}, "description": t("Datei-Endung der erzeugten Code-Datei"), "default": "py"}, + {"name": "context", "type": "str", "required": False, "frontendType": "dataRef", + "description": t("Optionaler Kontext aus Upstream-Node (wird dem Prompt vorangestellt)"), "default": ""}, + {"name": "documentList", "type": "DocumentList", "required": False, "frontendType": "dataRef", + "description": t("Optionale Dokumentenliste als Referenz"), "default": ""}, ] + _AI_COMMON_PARAMS, "inputs": 1, "outputs": 1, - "inputPorts": {0: {"accepts": ["Transit"]}}, + "inputPorts": {0: {"accepts": ["Transit", "AiResult", "DocumentList", "ActionResult"]}}, "outputPorts": {0: {"schema": "AiResult"}}, "meta": {"icon": "mdi-code-tags", "color": "#9C27B0", "usesAi": True}, "_method": "ai", @@ -163,10 +175,10 @@ AI_NODES = [ "label": t("KI-Konsolidierung"), "description": t("Gesammelte Ergebnisse mit KI zusammenfassen, klassifizieren oder semantisch zusammenführen"), "parameters": [ - {"name": "mode", "type": "string", "required": False, "frontendType": "select", + {"name": "mode", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["summarize", "classify", "semanticMerge"]}, "description": t("Konsolidierungsmodus"), "default": "summarize"}, - {"name": "prompt", "type": "string", "required": False, "frontendType": "textarea", + {"name": "prompt", "type": "str", "required": False, "frontendType": "textarea", "description": t("Optionaler Prompt für die Konsolidierung"), "default": ""}, ] + _AI_COMMON_PARAMS, "inputs": 1, diff --git a/modules/features/graphicalEditor/nodeDefinitions/clickup.py b/modules/features/graphicalEditor/nodeDefinitions/clickup.py index 56b27984..53b75d4b 100644 --- a/modules/features/graphicalEditor/nodeDefinitions/clickup.py +++ b/modules/features/graphicalEditor/nodeDefinitions/clickup.py @@ -11,23 +11,23 @@ CLICKUP_NODES = [ "label": t("Aufgaben suchen"), "description": t("Aufgaben in einem Workspace suchen"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "clickup"}, "description": t("ClickUp-Verbindung")}, - {"name": "teamId", "type": "string", "required": True, "frontendType": "text", + {"name": "teamId", "type": "str", "required": True, "frontendType": "text", "description": t("Team-/Workspace-ID")}, - {"name": "query", "type": "string", "required": True, "frontendType": "text", + {"name": "query", "type": "str", "required": True, "frontendType": "text", "description": t("Suchbegriff")}, - {"name": "page", "type": "number", "required": False, "frontendType": "number", + {"name": "page", "type": "int", "required": False, "frontendType": "number", "description": t("Seite"), "default": 0}, - {"name": "listId", "type": "string", "required": False, "frontendType": "clickupList", + {"name": "listId", "type": "str", "required": False, "frontendType": "clickupList", "frontendOptions": {"dependsOn": "connectionReference"}, "description": t("In dieser Liste suchen")}, - {"name": "includeClosed", "type": "boolean", "required": False, "frontendType": "checkbox", + {"name": "includeClosed", "type": "bool", "required": False, "frontendType": "checkbox", "description": t("Erledigte einbeziehen"), "default": False}, - {"name": "fullTaskData", "type": "boolean", "required": False, "frontendType": "checkbox", + {"name": "fullTaskData", "type": "bool", "required": False, "frontendType": "checkbox", "description": t("Vollständige Daten"), "default": False}, - {"name": "matchNameOnly", "type": "boolean", "required": False, "frontendType": "checkbox", + {"name": "matchNameOnly", "type": "bool", "required": False, "frontendType": "checkbox", "description": t("Nur Titel"), "default": True}, ], "inputs": 1, @@ -44,15 +44,15 @@ CLICKUP_NODES = [ "label": t("Aufgaben auflisten"), "description": t("Aufgaben einer Liste auflisten"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "clickup"}, "description": t("ClickUp-Verbindung")}, - {"name": "pathQuery", "type": "string", "required": True, "frontendType": "clickupList", + {"name": "pathQuery", "type": "str", "required": True, "frontendType": "clickupList", "frontendOptions": {"dependsOn": "connectionReference"}, "description": t("Pfad zur Liste")}, - {"name": "page", "type": "number", "required": False, "frontendType": "number", + {"name": "page", "type": "int", "required": False, "frontendType": "number", "description": t("Seite"), "default": 0}, - {"name": "includeClosed", "type": "boolean", "required": False, "frontendType": "checkbox", + {"name": "includeClosed", "type": "bool", "required": False, "frontendType": "checkbox", "description": t("Erledigte einbeziehen"), "default": False}, ], "inputs": 1, @@ -69,12 +69,12 @@ CLICKUP_NODES = [ "label": t("Aufgabe abrufen"), "description": t("Eine Aufgabe abrufen"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "clickup"}, "description": t("ClickUp-Verbindung")}, - {"name": "taskId", "type": "string", "required": False, "frontendType": "text", + {"name": "taskId", "type": "str", "required": False, "frontendType": "text", "description": t("Task-ID")}, - {"name": "pathQuery", "type": "string", "required": False, "frontendType": "text", + {"name": "pathQuery", "type": "str", "required": False, "frontendType": "text", "description": t("Oder Pfad")}, ], "inputs": 1, @@ -91,34 +91,34 @@ CLICKUP_NODES = [ "label": t("Aufgabe erstellen"), "description": t("Aufgabe erstellen"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "clickup"}, "description": t("ClickUp-Verbindung")}, - {"name": "pathQuery", "type": "string", "required": False, "frontendType": "clickupList", + {"name": "pathQuery", "type": "str", "required": False, "frontendType": "clickupList", "frontendOptions": {"dependsOn": "connectionReference"}, "description": t("Pfad zur Liste")}, - {"name": "listId", "type": "string", "required": False, "frontendType": "text", + {"name": "listId", "type": "str", "required": False, "frontendType": "text", "description": t("Listen-ID")}, - {"name": "name", "type": "string", "required": True, "frontendType": "text", + {"name": "name", "type": "str", "required": True, "frontendType": "text", "description": t("Name")}, - {"name": "description", "type": "string", "required": False, "frontendType": "textarea", + {"name": "description", "type": "str", "required": False, "frontendType": "textarea", "description": t("Beschreibung")}, - {"name": "taskStatus", "type": "string", "required": False, "frontendType": "text", + {"name": "taskStatus", "type": "str", "required": False, "frontendType": "text", "description": t("Status")}, - {"name": "taskPriority", "type": "string", "required": False, "frontendType": "select", + {"name": "taskPriority", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["1", "2", "3", "4"]}, "description": t("Priorität 1-4")}, - {"name": "taskDueDateMs", "type": "string", "required": False, "frontendType": "text", + {"name": "taskDueDateMs", "type": "str", "required": False, "frontendType": "text", "description": t("Fälligkeit (ms)")}, {"name": "taskAssigneeIds", "type": "object", "required": False, "frontendType": "json", "description": t("Zugewiesene")}, - {"name": "taskTimeEstimateMs", "type": "string", "required": False, "frontendType": "text", + {"name": "taskTimeEstimateMs", "type": "str", "required": False, "frontendType": "text", "description": t("Zeitschätzung (ms)")}, - {"name": "taskTimeEstimateHours", "type": "string", "required": False, "frontendType": "text", + {"name": "taskTimeEstimateHours", "type": "str", "required": False, "frontendType": "text", "description": t("Zeitschätzung (h)")}, {"name": "customFieldValues", "type": "object", "required": False, "frontendType": "json", "description": t("Benutzerdefinierte Felder")}, - {"name": "taskFields", "type": "string", "required": False, "frontendType": "json", + {"name": "taskFields", "type": "str", "required": False, "frontendType": "json", "description": t("Zusätzliches JSON")}, ], "inputs": 1, @@ -135,14 +135,14 @@ CLICKUP_NODES = [ "label": t("Aufgabe aktualisieren"), "description": t("Felder der Aufgabe ändern"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "clickup"}, "description": t("ClickUp-Verbindung")}, - {"name": "taskId", "type": "string", "required": False, "frontendType": "text", + {"name": "taskId", "type": "str", "required": False, "frontendType": "text", "description": t("Task-ID")}, - {"name": "path", "type": "string", "required": False, "frontendType": "text", + {"name": "path", "type": "str", "required": False, "frontendType": "text", "description": t("Oder Pfad")}, - {"name": "taskUpdate", "type": "string", "required": False, "frontendType": "json", + {"name": "taskUpdate", "type": "str", "required": False, "frontendType": "json", "description": t("JSON-Body für PUT /task/{id}, z.B. {\"name\":\"...\",\"status\":\"...\"}")}, ], "inputs": 1, @@ -159,16 +159,16 @@ CLICKUP_NODES = [ "label": t("Anhang hochladen"), "description": t("Datei an Task anhängen"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "clickup"}, "description": t("ClickUp-Verbindung")}, - {"name": "taskId", "type": "string", "required": False, "frontendType": "text", + {"name": "taskId", "type": "str", "required": False, "frontendType": "text", "description": t("Task-ID")}, - {"name": "path", "type": "string", "required": False, "frontendType": "text", + {"name": "path", "type": "str", "required": False, "frontendType": "text", "description": t("Oder Pfad")}, - {"name": "fileName", "type": "string", "required": False, "frontendType": "text", + {"name": "fileName", "type": "str", "required": False, "frontendType": "text", "description": t("Dateiname")}, - {"name": "content", "type": "string", "required": True, "frontendType": "hidden", + {"name": "content", "type": "str", "required": True, "frontendType": "hidden", "description": t("Datei-Inhalt aus Upstream-Node (via Wire oder DataRef)"), "default": ""}, ], "inputs": 1, diff --git a/modules/features/graphicalEditor/nodeDefinitions/context.py b/modules/features/graphicalEditor/nodeDefinitions/context.py index 81d878be..f6757cc8 100644 --- a/modules/features/graphicalEditor/nodeDefinitions/context.py +++ b/modules/features/graphicalEditor/nodeDefinitions/context.py @@ -10,7 +10,7 @@ CONTEXT_NODES = [ "label": t("Inhalt extrahieren"), "description": t("Dokumentstruktur extrahieren ohne KI (Seiten, Abschnitte, Bilder, Tabellen)"), "parameters": [ - {"name": "documentList", "type": "string", "required": True, "frontendType": "hidden", + {"name": "documentList", "type": "str", "required": True, "frontendType": "hidden", "description": t("Dokumentenliste (via Wire oder DataRef)"), "default": ""}, {"name": "extractionOptions", "type": "object", "required": False, "frontendType": "json", "description": t( diff --git a/modules/features/graphicalEditor/nodeDefinitions/data.py b/modules/features/graphicalEditor/nodeDefinitions/data.py index b6208840..ca1f9035 100644 --- a/modules/features/graphicalEditor/nodeDefinitions/data.py +++ b/modules/features/graphicalEditor/nodeDefinitions/data.py @@ -10,7 +10,7 @@ DATA_NODES = [ "label": t("Sammeln"), "description": t("Ergebnisse aus Schleifen-Iterationen sammeln"), "parameters": [ - {"name": "mode", "type": "string", "required": False, "frontendType": "select", + {"name": "mode", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["collect", "concat", "sum", "count"]}, "description": t("Aggregationsmodus"), "default": "collect"}, ], @@ -27,9 +27,9 @@ DATA_NODES = [ "label": t("Filtern"), "description": t("Elemente nach Bedingung filtern"), "parameters": [ - {"name": "condition", "type": "string", "required": True, "frontendType": "filterExpression", + {"name": "condition", "type": "str", "required": True, "frontendType": "filterExpression", "description": t("Filterbedingung")}, - {"name": "udmContentType", "type": "string", "required": False, "frontendType": "select", + {"name": "udmContentType", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["", "text", "image", "table", "code", "media", "link", "formula"]}, "description": t("UDM-ContentType-Filter (optional, leer = kein UDM-Filter)"), "default": ""}, ], @@ -46,10 +46,10 @@ DATA_NODES = [ "label": t("Konsolidieren"), "description": t("Gesammelte Ergebnisse deterministisch zusammenführen (Tabelle, CSV, Merge)"), "parameters": [ - {"name": "mode", "type": "string", "required": False, "frontendType": "select", + {"name": "mode", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["table", "concat", "merge", "csvJoin"]}, "description": t("Konsolidierungsmodus"), "default": "table"}, - {"name": "separator", "type": "string", "required": False, "frontendType": "text", + {"name": "separator", "type": "str", "required": False, "frontendType": "text", "description": t("Trennzeichen (für concat/csvJoin)"), "default": "\n"}, ], "inputs": 1, diff --git a/modules/features/graphicalEditor/nodeDefinitions/email.py b/modules/features/graphicalEditor/nodeDefinitions/email.py index 270b8d63..698efa94 100644 --- a/modules/features/graphicalEditor/nodeDefinitions/email.py +++ b/modules/features/graphicalEditor/nodeDefinitions/email.py @@ -10,14 +10,14 @@ EMAIL_NODES = [ "label": t("E-Mail prüfen"), "description": t("Neue E-Mails prüfen"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "msft"}, "description": t("E-Mail-Konto Verbindung")}, - {"name": "folder", "type": "string", "required": False, "frontendType": "text", + {"name": "folder", "type": "str", "required": False, "frontendType": "text", "description": t("Ordner"), "default": "Inbox"}, - {"name": "limit", "type": "number", "required": False, "frontendType": "number", + {"name": "limit", "type": "int", "required": False, "frontendType": "number", "description": t("Max E-Mails"), "default": 100}, - {"name": "filter", "type": "string", "required": False, "frontendType": "text", + {"name": "filter", "type": "str", "required": False, "frontendType": "text", "description": t("Filter-Ausdruck (z.B. 'from:max@example.com hasAttachment:true betreff')"), "default": ""}, ], "inputs": 1, @@ -34,14 +34,14 @@ EMAIL_NODES = [ "label": t("E-Mail suchen"), "description": t("E-Mails suchen"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "msft"}, "description": t("E-Mail-Konto Verbindung")}, - {"name": "query", "type": "string", "required": True, "frontendType": "text", + {"name": "query", "type": "str", "required": True, "frontendType": "text", "description": t("Suchausdruck (z.B. 'from:max@example.com hasAttachments:true Rechnung')")}, - {"name": "folder", "type": "string", "required": False, "frontendType": "text", + {"name": "folder", "type": "str", "required": False, "frontendType": "text", "description": t("Ordner"), "default": "All"}, - {"name": "limit", "type": "number", "required": False, "frontendType": "number", + {"name": "limit", "type": "int", "required": False, "frontendType": "number", "description": t("Max E-Mails"), "default": 100}, ], "inputs": 1, @@ -59,19 +59,19 @@ EMAIL_NODES = [ "description": t( "AI-gestützt einen E-Mail-Entwurf aus Kontext und optionalen Dokumenten erstellen"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "msft"}, "description": t("E-Mail-Konto")}, - {"name": "context", "type": "string", "required": False, "frontendType": "templateTextarea", + {"name": "context", "type": "str", "required": False, "frontendType": "templateTextarea", "description": t("Kontext / Brief-Beschreibung für die KI-Komposition"), "default": ""}, - {"name": "to", "type": "string", "required": False, "frontendType": "text", + {"name": "to", "type": "str", "required": False, "frontendType": "text", "description": t("Empfänger (komma-separiert, optional für Entwurf)"), "default": ""}, - {"name": "documentList", "type": "string", "required": False, "frontendType": "hidden", + {"name": "documentList", "type": "str", "required": False, "frontendType": "hidden", "description": t("Anhang-Dokumente (via Wire oder DataRef)"), "default": ""}, - {"name": "emailContent", "type": "string", "required": False, "frontendType": "hidden", + {"name": "emailContent", "type": "str", "required": False, "frontendType": "hidden", "description": t("Direkt vorbereiteter Inhalt {subject, body, to} (via Wire — überspringt KI)"), "default": ""}, - {"name": "emailStyle", "type": "string", "required": False, "frontendType": "select", + {"name": "emailStyle", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["formal", "casual", "business"]}, "description": t("Stil"), "default": "business"}, ], diff --git a/modules/features/graphicalEditor/nodeDefinitions/file.py b/modules/features/graphicalEditor/nodeDefinitions/file.py index 8e04f2bc..9fbd261d 100644 --- a/modules/features/graphicalEditor/nodeDefinitions/file.py +++ b/modules/features/graphicalEditor/nodeDefinitions/file.py @@ -12,19 +12,19 @@ FILE_NODES = [ "parameters": [ {"name": "contentSources", "type": "json", "required": False, "frontendType": "json", "description": t("Kontext-Quellen"), "default": []}, - {"name": "outputFormat", "type": "string", "required": True, "frontendType": "select", + {"name": "outputFormat", "type": "str", "required": True, "frontendType": "select", "frontendOptions": {"options": ["docx", "pdf", "txt", "html", "md"]}, "description": t("Ausgabeformat"), "default": "docx"}, - {"name": "title", "type": "string", "required": False, "frontendType": "text", + {"name": "title", "type": "str", "required": False, "frontendType": "text", "description": t("Dokumenttitel")}, - {"name": "templateName", "type": "string", "required": False, "frontendType": "select", + {"name": "templateName", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["default", "corporate", "minimal"]}, "description": t("Stil-Vorlage")}, - {"name": "language", "type": "string", "required": False, "frontendType": "select", + {"name": "language", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["de", "en", "fr"]}, "description": t("Sprache"), "default": "de"}, - {"name": "context", "type": "string", "required": False, "frontendType": "hidden", - "description": t("Inhalt (via Wire oder DataRef)"), "default": ""}, + {"name": "context", "type": "str", "required": False, "frontendType": "dataRef", + "description": t("Inhalt aus Upstream-Node (binden via DataRef oder Wire)"), "default": ""}, ], "inputs": 1, "outputs": 1, diff --git a/modules/features/graphicalEditor/nodeDefinitions/flow.py b/modules/features/graphicalEditor/nodeDefinitions/flow.py index 04a44197..5ebf50bc 100644 --- a/modules/features/graphicalEditor/nodeDefinitions/flow.py +++ b/modules/features/graphicalEditor/nodeDefinitions/flow.py @@ -12,7 +12,7 @@ FLOW_NODES = [ "parameters": [ { "name": "condition", - "type": "string", + "type": "str", "required": True, "frontendType": "condition", "description": t("Bedingung"), @@ -34,7 +34,7 @@ FLOW_NODES = [ "parameters": [ { "name": "value", - "type": "string", + "type": "str", "required": True, "frontendType": "text", "description": t("Zu vergleichender Wert"), @@ -62,14 +62,14 @@ FLOW_NODES = [ "parameters": [ { "name": "items", - "type": "string", + "type": "str", "required": True, "frontendType": "text", "description": t("Pfad zum Array"), }, { "name": "level", - "type": "string", + "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["auto", "documents", "structuralNodes", "contentBlocks"]}, @@ -78,7 +78,7 @@ FLOW_NODES = [ }, { "name": "concurrency", - "type": "number", + "type": "int", "required": False, "frontendType": "number", "frontendOptions": {"min": 1, "max": 20}, @@ -103,7 +103,7 @@ FLOW_NODES = [ "parameters": [ { "name": "mode", - "type": "string", + "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["first", "all", "append"]}, @@ -112,7 +112,7 @@ FLOW_NODES = [ }, { "name": "inputCount", - "type": "number", + "type": "int", "required": False, "frontendType": "number", "frontendOptions": {"min": 2, "max": 5}, diff --git a/modules/features/graphicalEditor/nodeDefinitions/input.py b/modules/features/graphicalEditor/nodeDefinitions/input.py index 647e9ac2..e2d0271a 100644 --- a/modules/features/graphicalEditor/nodeDefinitions/input.py +++ b/modules/features/graphicalEditor/nodeDefinitions/input.py @@ -3,6 +3,18 @@ from modules.shared.i18nRegistry import t +# Canonical form field types — single source of truth. +# portType maps to the PORT_TYPE_CATALOG primitive used by DataPicker / validateGraph. +FORM_FIELD_TYPES = [ + {"id": "text", "label": "Text (einzeilig)", "portType": "str"}, + {"id": "textarea", "label": "Text (mehrzeilig)", "portType": "str"}, + {"id": "number", "label": "Zahl", "portType": "int"}, + {"id": "boolean", "label": "Ja/Nein", "portType": "bool"}, + {"id": "date", "label": "Datum", "portType": "str"}, + {"id": "email", "label": "E-Mail", "portType": "str"}, + {"id": "select", "label": "Auswahl", "portType": "str"}, +] + INPUT_NODES = [ { "id": "input.form", @@ -32,11 +44,11 @@ INPUT_NODES = [ "label": t("Genehmigung"), "description": t("Benutzer genehmigt oder lehnt ab"), "parameters": [ - {"name": "title", "type": "string", "required": True, "frontendType": "text", + {"name": "title", "type": "str", "required": True, "frontendType": "text", "description": t("Genehmigungstitel")}, - {"name": "description", "type": "string", "required": False, "frontendType": "textarea", + {"name": "description", "type": "str", "required": False, "frontendType": "textarea", "description": t("Was genehmigt werden soll")}, - {"name": "approvalType", "type": "string", "required": False, "frontendType": "select", + {"name": "approvalType", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["generic", "document"]}, "description": t("Typ: document oder generic"), "default": "generic"}, ], @@ -53,14 +65,14 @@ INPUT_NODES = [ "label": t("Upload"), "description": t("Benutzer lädt Datei(en) hoch"), "parameters": [ - {"name": "accept", "type": "string", "required": False, "frontendType": "text", + {"name": "accept", "type": "str", "required": False, "frontendType": "text", "description": t("Accept-String"), "default": ""}, {"name": "allowedTypes", "type": "json", "required": False, "frontendType": "multiselect", "frontendOptions": {"options": ["pdf", "docx", "xlsx", "pptx", "txt", "csv", "jpg", "png", "gif"]}, "description": t("Ausgewählte Dateitypen"), "default": []}, - {"name": "maxSize", "type": "number", "required": False, "frontendType": "number", + {"name": "maxSize", "type": "int", "required": False, "frontendType": "number", "description": t("Max. Dateigröße in MB"), "default": 10}, - {"name": "multiple", "type": "boolean", "required": False, "frontendType": "checkbox", + {"name": "multiple", "type": "bool", "required": False, "frontendType": "checkbox", "description": t("Mehrere Dateien erlauben"), "default": False}, ], "inputs": 1, @@ -76,9 +88,9 @@ INPUT_NODES = [ "label": t("Kommentar"), "description": t("Benutzer fügt einen Kommentar hinzu"), "parameters": [ - {"name": "placeholder", "type": "string", "required": False, "frontendType": "text", + {"name": "placeholder", "type": "str", "required": False, "frontendType": "text", "description": t("Platzhalter"), "default": ""}, - {"name": "required", "type": "boolean", "required": False, "frontendType": "checkbox", + {"name": "required", "type": "bool", "required": False, "frontendType": "checkbox", "description": t("Kommentar erforderlich"), "default": True}, ], "inputs": 1, @@ -94,9 +106,9 @@ INPUT_NODES = [ "label": t("Prüfung"), "description": t("Benutzer prüft Inhalt"), "parameters": [ - {"name": "contentRef", "type": "string", "required": True, "frontendType": "text", + {"name": "contentRef", "type": "str", "required": True, "frontendType": "text", "description": t("Referenz auf Inhalt")}, - {"name": "reviewType", "type": "string", "required": False, "frontendType": "select", + {"name": "reviewType", "type": "str", "required": False, "frontendType": "select", "frontendOptions": {"options": ["generic", "document"]}, "description": t("Art der Prüfung"), "default": "generic"}, ], @@ -115,7 +127,7 @@ INPUT_NODES = [ "parameters": [ {"name": "options", "type": "json", "required": True, "frontendType": "keyValueRows", "description": t("Optionen"), "default": []}, - {"name": "multiple", "type": "boolean", "required": False, "frontendType": "checkbox", + {"name": "multiple", "type": "bool", "required": False, "frontendType": "checkbox", "description": t("Mehrfachauswahl erlauben"), "default": False}, ], "inputs": 1, @@ -131,11 +143,11 @@ INPUT_NODES = [ "label": t("Bestätigung"), "description": t("Benutzer bestätigt Ja/Nein"), "parameters": [ - {"name": "question", "type": "string", "required": True, "frontendType": "text", + {"name": "question", "type": "str", "required": True, "frontendType": "text", "description": t("Zu bestätigende Frage")}, - {"name": "confirmLabel", "type": "string", "required": False, "frontendType": "text", + {"name": "confirmLabel", "type": "str", "required": False, "frontendType": "text", "description": t("Label für Bestätigen-Button"), "default": "Confirm"}, - {"name": "rejectLabel", "type": "string", "required": False, "frontendType": "text", + {"name": "rejectLabel", "type": "str", "required": False, "frontendType": "text", "description": t("Label für Ablehnen-Button"), "default": "Reject"}, ], "inputs": 1, diff --git a/modules/features/graphicalEditor/nodeDefinitions/redmine.py b/modules/features/graphicalEditor/nodeDefinitions/redmine.py index d9ea8bab..2d8ebb59 100644 --- a/modules/features/graphicalEditor/nodeDefinitions/redmine.py +++ b/modules/features/graphicalEditor/nodeDefinitions/redmine.py @@ -25,7 +25,7 @@ REDMINE_NODES = [ "description": t("Einzelnes Redmine-Ticket aus dem Mirror laden."), "parameters": [ dict(_REDMINE_INSTANCE_PARAM), - {"name": "ticketId", "type": "number", "required": True, "frontendType": "number", + {"name": "ticketId", "type": "int", "required": True, "frontendType": "number", "description": t("Redmine-Ticket-ID")}, ], "inputs": 1, @@ -43,17 +43,17 @@ REDMINE_NODES = [ "description": t("Tickets aus dem lokalen Mirror mit Filtern (Tracker, Status, Zeitraum, Zuweisung)."), "parameters": [ dict(_REDMINE_INSTANCE_PARAM), - {"name": "trackerIds", "type": "string", "required": False, "frontendType": "text", + {"name": "trackerIds", "type": "str", "required": False, "frontendType": "text", "description": t("Tracker-IDs (Komma-separiert)"), "default": ""}, - {"name": "status", "type": "string", "required": False, "frontendType": "text", + {"name": "status", "type": "str", "required": False, "frontendType": "text", "description": t("Status-Filter: open | closed | *"), "default": "*"}, - {"name": "dateFrom", "type": "string", "required": False, "frontendType": "date", + {"name": "dateFrom", "type": "str", "required": False, "frontendType": "date", "description": t("Zeitraum ab (ISO-Datum)"), "default": ""}, - {"name": "dateTo", "type": "string", "required": False, "frontendType": "date", + {"name": "dateTo", "type": "str", "required": False, "frontendType": "date", "description": t("Zeitraum bis (ISO-Datum)"), "default": ""}, - {"name": "assignedToId", "type": "number", "required": False, "frontendType": "number", + {"name": "assignedToId", "type": "int", "required": False, "frontendType": "number", "description": t("Nur Tickets dieses Benutzers (ID)")}, - {"name": "limit", "type": "number", "required": False, "frontendType": "number", + {"name": "limit", "type": "int", "required": False, "frontendType": "number", "description": t("Max. Anzahl Tickets (1-500)"), "default": 100}, ], "inputs": 1, @@ -71,21 +71,21 @@ REDMINE_NODES = [ "description": t("Neues Ticket in Redmine anlegen. Mirror wird sofort aktualisiert."), "parameters": [ dict(_REDMINE_INSTANCE_PARAM), - {"name": "subject", "type": "string", "required": True, "frontendType": "text", + {"name": "subject", "type": "str", "required": True, "frontendType": "text", "description": t("Ticket-Titel")}, - {"name": "trackerId", "type": "number", "required": True, "frontendType": "number", + {"name": "trackerId", "type": "int", "required": True, "frontendType": "number", "description": t("Tracker-ID (Userstory, Feature, Task, ...)")}, - {"name": "description", "type": "string", "required": False, "frontendType": "textarea", + {"name": "description", "type": "str", "required": False, "frontendType": "textarea", "description": t("Ticket-Beschreibung"), "default": ""}, - {"name": "statusId", "type": "number", "required": False, "frontendType": "number", + {"name": "statusId", "type": "int", "required": False, "frontendType": "number", "description": t("Status-ID (optional)")}, - {"name": "priorityId", "type": "number", "required": False, "frontendType": "number", + {"name": "priorityId", "type": "int", "required": False, "frontendType": "number", "description": t("Prioritaet-ID (optional)")}, - {"name": "assignedToId", "type": "number", "required": False, "frontendType": "number", + {"name": "assignedToId", "type": "int", "required": False, "frontendType": "number", "description": t("Zugewiesene Benutzer-ID (optional)")}, - {"name": "parentIssueId", "type": "number", "required": False, "frontendType": "number", + {"name": "parentIssueId", "type": "int", "required": False, "frontendType": "number", "description": t("Uebergeordnetes Ticket (optional)")}, - {"name": "customFields", "type": "string", "required": False, "frontendType": "textarea", + {"name": "customFields", "type": "str", "required": False, "frontendType": "textarea", "description": t("Custom Fields als JSON {id: value}"), "default": ""}, ], "inputs": 1, @@ -103,25 +103,25 @@ REDMINE_NODES = [ "description": t("Felder eines Redmine-Tickets aktualisieren. Nur gesetzte Felder werden uebertragen."), "parameters": [ dict(_REDMINE_INSTANCE_PARAM), - {"name": "ticketId", "type": "number", "required": True, "frontendType": "number", + {"name": "ticketId", "type": "int", "required": True, "frontendType": "number", "description": t("Ticket-ID")}, - {"name": "subject", "type": "string", "required": False, "frontendType": "text", + {"name": "subject", "type": "str", "required": False, "frontendType": "text", "description": t("Neuer Titel")}, - {"name": "description", "type": "string", "required": False, "frontendType": "textarea", + {"name": "description", "type": "str", "required": False, "frontendType": "textarea", "description": t("Neue Beschreibung")}, - {"name": "trackerId", "type": "number", "required": False, "frontendType": "number", + {"name": "trackerId", "type": "int", "required": False, "frontendType": "number", "description": t("Neuer Tracker")}, - {"name": "statusId", "type": "number", "required": False, "frontendType": "number", + {"name": "statusId", "type": "int", "required": False, "frontendType": "number", "description": t("Neuer Status")}, - {"name": "priorityId", "type": "number", "required": False, "frontendType": "number", + {"name": "priorityId", "type": "int", "required": False, "frontendType": "number", "description": t("Neue Prioritaet")}, - {"name": "assignedToId", "type": "number", "required": False, "frontendType": "number", + {"name": "assignedToId", "type": "int", "required": False, "frontendType": "number", "description": t("Neue Zuweisung")}, - {"name": "parentIssueId", "type": "number", "required": False, "frontendType": "number", + {"name": "parentIssueId", "type": "int", "required": False, "frontendType": "number", "description": t("Neues Parent-Ticket")}, - {"name": "notes", "type": "string", "required": False, "frontendType": "textarea", + {"name": "notes", "type": "str", "required": False, "frontendType": "textarea", "description": t("Kommentar (Journal-Eintrag)"), "default": ""}, - {"name": "customFields", "type": "string", "required": False, "frontendType": "textarea", + {"name": "customFields", "type": "str", "required": False, "frontendType": "textarea", "description": t("Custom Fields als JSON {id: value}"), "default": ""}, ], "inputs": 1, @@ -139,13 +139,13 @@ REDMINE_NODES = [ "description": t("Aggregierte Kennzahlen (KPIs, Durchsatz, Status-Verteilung, Backlog) aus dem Mirror."), "parameters": [ dict(_REDMINE_INSTANCE_PARAM), - {"name": "dateFrom", "type": "string", "required": False, "frontendType": "date", + {"name": "dateFrom", "type": "str", "required": False, "frontendType": "date", "description": t("Zeitraum ab")}, - {"name": "dateTo", "type": "string", "required": False, "frontendType": "date", + {"name": "dateTo", "type": "str", "required": False, "frontendType": "date", "description": t("Zeitraum bis")}, - {"name": "bucket", "type": "string", "required": False, "frontendType": "text", + {"name": "bucket", "type": "str", "required": False, "frontendType": "text", "description": t("Bucket: day | week | month"), "default": "week"}, - {"name": "trackerIds", "type": "string", "required": False, "frontendType": "text", + {"name": "trackerIds", "type": "str", "required": False, "frontendType": "text", "description": t("Tracker-IDs (Komma-separiert)"), "default": ""}, ], "inputs": 1, @@ -163,7 +163,7 @@ REDMINE_NODES = [ "description": t("Tickets und Beziehungen aus Redmine in den lokalen Mirror uebernehmen."), "parameters": [ dict(_REDMINE_INSTANCE_PARAM), - {"name": "force", "type": "boolean", "required": False, "frontendType": "checkbox", + {"name": "force", "type": "bool", "required": False, "frontendType": "checkbox", "description": t("Vollsync erzwingen (ignoriert lastSyncAt)"), "default": False}, ], "inputs": 1, diff --git a/modules/features/graphicalEditor/nodeDefinitions/sharepoint.py b/modules/features/graphicalEditor/nodeDefinitions/sharepoint.py index 7e52ef8d..b47a6b54 100644 --- a/modules/features/graphicalEditor/nodeDefinitions/sharepoint.py +++ b/modules/features/graphicalEditor/nodeDefinitions/sharepoint.py @@ -10,14 +10,14 @@ SHAREPOINT_NODES = [ "label": t("Datei finden"), "description": t("Datei nach Pfad oder Suche finden"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "msft"}, "description": t("SharePoint-Verbindung")}, - {"name": "searchQuery", "type": "string", "required": True, "frontendType": "text", + {"name": "searchQuery", "type": "str", "required": True, "frontendType": "text", "description": t("Suchanfrage oder Pfad")}, - {"name": "site", "type": "string", "required": False, "frontendType": "text", + {"name": "site", "type": "str", "required": False, "frontendType": "text", "description": t("Optionaler Site-Hinweis"), "default": ""}, - {"name": "maxResults", "type": "number", "required": False, "frontendType": "number", + {"name": "maxResults", "type": "int", "required": False, "frontendType": "number", "description": t("Max Ergebnisse"), "default": 1000}, ], "inputs": 1, @@ -34,10 +34,10 @@ SHAREPOINT_NODES = [ "label": t("Datei lesen"), "description": t("Inhalt aus Datei extrahieren"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "msft"}, "description": t("SharePoint-Verbindung")}, - {"name": "pathQuery", "type": "string", "required": True, "frontendType": "sharepointFile", + {"name": "pathQuery", "type": "str", "required": True, "frontendType": "sharepointFile", "frontendOptions": {"dependsOn": "connectionReference"}, "description": t("Dateipfad")}, ], @@ -55,13 +55,13 @@ SHAREPOINT_NODES = [ "label": t("Datei hochladen"), "description": t("Datei zu SharePoint hochladen"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "msft"}, "description": t("SharePoint-Verbindung")}, - {"name": "pathQuery", "type": "string", "required": True, "frontendType": "sharepointFolder", + {"name": "pathQuery", "type": "str", "required": True, "frontendType": "sharepointFolder", "frontendOptions": {"dependsOn": "connectionReference"}, "description": t("Zielordner-Pfad")}, - {"name": "content", "type": "string", "required": True, "frontendType": "hidden", + {"name": "content", "type": "str", "required": True, "frontendType": "hidden", "description": t("Datei-Inhalt aus Upstream-Node (via Wire oder DataRef)"), "default": ""}, ], "inputs": 1, @@ -78,10 +78,10 @@ SHAREPOINT_NODES = [ "label": t("Dateien auflisten"), "description": t("Dateien in Ordner auflisten"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "msft"}, "description": t("SharePoint-Verbindung")}, - {"name": "pathQuery", "type": "string", "required": False, "frontendType": "sharepointFolder", + {"name": "pathQuery", "type": "str", "required": False, "frontendType": "sharepointFolder", "frontendOptions": {"dependsOn": "connectionReference"}, "description": t("Ordnerpfad"), "default": "/"}, ], @@ -99,10 +99,10 @@ SHAREPOINT_NODES = [ "label": t("Datei herunterladen"), "description": t("Datei vom Pfad herunterladen"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "msft"}, "description": t("SharePoint-Verbindung")}, - {"name": "pathQuery", "type": "string", "required": True, "frontendType": "sharepointFile", + {"name": "pathQuery", "type": "str", "required": True, "frontendType": "sharepointFile", "frontendOptions": {"dependsOn": "connectionReference"}, "description": t("Vollständiger Dateipfad")}, ], @@ -120,13 +120,13 @@ SHAREPOINT_NODES = [ "label": t("Datei kopieren"), "description": t("Datei an Ziel kopieren"), "parameters": [ - {"name": "connectionReference", "type": "string", "required": True, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": True, "frontendType": "userConnection", "frontendOptions": {"authority": "msft"}, "description": t("SharePoint-Verbindung")}, - {"name": "sourcePath", "type": "string", "required": True, "frontendType": "sharepointFile", + {"name": "sourcePath", "type": "str", "required": True, "frontendType": "sharepointFile", "frontendOptions": {"dependsOn": "connectionReference"}, "description": t("Quelldatei-Pfad")}, - {"name": "destPath", "type": "string", "required": True, "frontendType": "sharepointFolder", + {"name": "destPath", "type": "str", "required": True, "frontendType": "sharepointFolder", "frontendOptions": {"dependsOn": "connectionReference"}, "description": t("Zielordner")}, ], diff --git a/modules/features/graphicalEditor/nodeDefinitions/triggers.py b/modules/features/graphicalEditor/nodeDefinitions/triggers.py index 7b55d5d7..443f8c02 100644 --- a/modules/features/graphicalEditor/nodeDefinitions/triggers.py +++ b/modules/features/graphicalEditor/nodeDefinitions/triggers.py @@ -46,7 +46,7 @@ TRIGGER_NODES = [ "parameters": [ { "name": "cron", - "type": "string", + "type": "str", "required": False, "frontendType": "cron", "description": t("Cron-Ausdruck"), diff --git a/modules/features/graphicalEditor/nodeDefinitions/trustee.py b/modules/features/graphicalEditor/nodeDefinitions/trustee.py index 0a8e7cd7..7392b4d2 100644 --- a/modules/features/graphicalEditor/nodeDefinitions/trustee.py +++ b/modules/features/graphicalEditor/nodeDefinitions/trustee.py @@ -25,11 +25,11 @@ TRUSTEE_NODES = [ "description": t("Buchhaltungsdaten aus externem System importieren/aktualisieren."), "parameters": [ dict(_TRUSTEE_INSTANCE_PARAM), - {"name": "forceRefresh", "type": "boolean", "required": False, "frontendType": "checkbox", + {"name": "forceRefresh", "type": "bool", "required": False, "frontendType": "checkbox", "description": t("Import erzwingen"), "default": False}, - {"name": "dateFrom", "type": "string", "required": False, "frontendType": "date", + {"name": "dateFrom", "type": "str", "required": False, "frontendType": "date", "description": t("Startdatum"), "default": ""}, - {"name": "dateTo", "type": "string", "required": False, "frontendType": "date", + {"name": "dateTo", "type": "str", "required": False, "frontendType": "date", "description": t("Enddatum"), "default": ""}, ], "inputs": 1, @@ -46,14 +46,14 @@ TRUSTEE_NODES = [ "label": t("Dokumente extrahieren"), "description": t("Dokumenttyp und Daten aus PDF/JPG per AI extrahieren."), "parameters": [ - {"name": "connectionReference", "type": "string", "required": False, "frontendType": "userConnection", + {"name": "connectionReference", "type": "str", "required": False, "frontendType": "userConnection", "frontendOptions": {"authority": "msft"}, "description": t("SharePoint-Verbindung"), "default": ""}, - {"name": "sharepointFolder", "type": "string", "required": False, "frontendType": "sharepointFolder", + {"name": "sharepointFolder", "type": "str", "required": False, "frontendType": "sharepointFolder", "frontendOptions": {"dependsOn": "connectionReference"}, "description": t("SharePoint-Ordnerpfad"), "default": ""}, dict(_TRUSTEE_INSTANCE_PARAM), - {"name": "prompt", "type": "string", "required": False, "frontendType": "textarea", + {"name": "prompt", "type": "str", "required": False, "frontendType": "textarea", "description": t("AI-Prompt für Extraktion"), "default": ""}, ], "inputs": 1, @@ -113,25 +113,25 @@ TRUSTEE_NODES = [ "description": t("Daten aus der Trustee-DB lesen (Lookup, Aggregation, Roh-Export). Pendant zu refreshAccountingData ohne externen Sync."), "parameters": [ dict(_TRUSTEE_INSTANCE_PARAM), - {"name": "mode", "type": "string", "required": True, "frontendType": "select", + {"name": "mode", "type": "str", "required": True, "frontendType": "select", "frontendOptions": {"options": ["lookup", "raw", "aggregate"]}, "description": t("Abfragemodus"), "default": "lookup"}, - {"name": "entity", "type": "string", "required": True, "frontendType": "select", + {"name": "entity", "type": "str", "required": True, "frontendType": "select", "frontendOptions": {"options": ["tenantWithRent", "contact", "journalLines", "accounts", "balances"]}, "description": t("Entität, die gelesen werden soll"), "default": "tenantWithRent"}, - {"name": "tenantNameRef", "type": "string", "required": False, "frontendType": "text", + {"name": "tenantNameRef", "type": "str", "required": False, "frontendType": "text", "frontendOptions": {"dependsOn": "entity", "showWhen": ["tenantWithRent", "contact"]}, "description": t("Mietername (oder {{wire.feld}} aus Upstream)"), "default": ""}, - {"name": "tenantAddressRef", "type": "string", "required": False, "frontendType": "text", + {"name": "tenantAddressRef", "type": "str", "required": False, "frontendType": "text", "frontendOptions": {"dependsOn": "entity", "showWhen": ["tenantWithRent", "contact"]}, "description": t("Mieteradresse (Toleranz für Tippfehler)"), "default": ""}, - {"name": "period", "type": "string", "required": False, "frontendType": "text", + {"name": "period", "type": "str", "required": False, "frontendType": "text", "frontendOptions": {"dependsOn": "entity", "showWhen": ["tenantWithRent", "journalLines", "balances"]}, "description": t("Zeitraum (YYYY oder YYYY-MM-DD/YYYY-MM-DD)"), "default": ""}, - {"name": "rentAccountPattern", "type": "string", "required": False, "frontendType": "text", + {"name": "rentAccountPattern", "type": "str", "required": False, "frontendType": "text", "frontendOptions": {"dependsOn": "entity", "showWhen": ["tenantWithRent"]}, "description": t("Konto-Filter für Mietzins (z.B. '6000-6099' oder '6*')"), "default": ""}, - {"name": "filterJson", "type": "string", "required": False, "frontendType": "textarea", + {"name": "filterJson", "type": "str", "required": False, "frontendType": "textarea", "frontendOptions": {"dependsOn": "mode", "showWhen": ["raw", "aggregate"]}, "description": t("Optionaler JSON-Filter für mode=raw/aggregate"), "default": ""}, ], diff --git a/modules/features/graphicalEditor/nodeRegistry.py b/modules/features/graphicalEditor/nodeRegistry.py index 632e98fc..a3c8bd0b 100644 --- a/modules/features/graphicalEditor/nodeRegistry.py +++ b/modules/features/graphicalEditor/nodeRegistry.py @@ -9,6 +9,7 @@ import logging from typing import Dict, List, Any, Optional from modules.features.graphicalEditor.nodeDefinitions import STATIC_NODE_TYPES +from modules.features.graphicalEditor.nodeDefinitions.input import FORM_FIELD_TYPES from modules.features.graphicalEditor.nodeAdapter import bindsActionFromLegacy from modules.features.graphicalEditor.portTypes import PORT_TYPE_CATALOG, SYSTEM_VARIABLES from modules.shared.i18nRegistry import normalizePrimaryLanguageTag, resolveText @@ -119,6 +120,7 @@ def getNodeTypesForApi( "categories": categories, "portTypeCatalog": catalogSerialized, "systemVariables": SYSTEM_VARIABLES, + "formFieldTypes": FORM_FIELD_TYPES, } diff --git a/modules/features/graphicalEditor/portTypes.py b/modules/features/graphicalEditor/portTypes.py index f1513f9e..246d4791 100644 --- a/modules/features/graphicalEditor/portTypes.py +++ b/modules/features/graphicalEditor/portTypes.py @@ -740,6 +740,9 @@ def _resolveTransitChain( def deriveFormPayloadSchemaFromParam(node: Dict[str, Any], param_key: str) -> Optional[PortSchema]: """Derive output schema from a field-builder JSON list (``fields``, ``formFields``, …).""" + from modules.features.graphicalEditor.nodeDefinitions.input import FORM_FIELD_TYPES + _FORM_TYPE_TO_PORT: Dict[str, str] = {f["id"]: f["portType"] for f in FORM_FIELD_TYPES} + fields_param = (node.get("parameters") or {}).get(param_key) if not fields_param or not isinstance(fields_param, list): return None @@ -749,9 +752,11 @@ def deriveFormPayloadSchemaFromParam(node: Dict[str, Any], param_key: str) -> Op _desc = resolveText(lab) if lab is not None else fname if not str(_desc).strip(): _desc = fname + raw_type = str(ftype) if ftype is not None else "str" + port_type = _FORM_TYPE_TO_PORT.get(raw_type, raw_type) portFields.append(PortField( name=fname, - type=str(ftype) if ftype is not None else "str", + type=port_type, description=_desc, required=required, )) diff --git a/modules/workflows/methods/methodAi/actions/generateCode.py b/modules/workflows/methods/methodAi/actions/generateCode.py index 5ec6b51d..24237289 100644 --- a/modules/workflows/methods/methodAi/actions/generateCode.py +++ b/modules/workflows/methods/methodAi/actions/generateCode.py @@ -14,8 +14,13 @@ from modules.serviceCenter.services.serviceBilling.mainServiceBilling import Bil logger = logging.getLogger(__name__) async def generateCode(self, parameters: Dict[str, Any]) -> ActionResult: - prompt = parameters.get("prompt") - if not prompt: + base_prompt = parameters.get("prompt") or "" + context_val = parameters.get("context") + if context_val and isinstance(context_val, str) and context_val.strip(): + prompt = f"Kontext:\n{context_val.strip()}\n\n{base_prompt.strip()}" + else: + prompt = base_prompt + if not prompt.strip(): return ActionResult.isFailure(error="prompt is required") documentList = parameters.get("documentList", []) diff --git a/modules/workflows/methods/methodAi/actions/generateDocument.py b/modules/workflows/methods/methodAi/actions/generateDocument.py index 18c158c1..1d4a4b66 100644 --- a/modules/workflows/methods/methodAi/actions/generateDocument.py +++ b/modules/workflows/methods/methodAi/actions/generateDocument.py @@ -14,8 +14,13 @@ from modules.serviceCenter.services.serviceBilling.mainServiceBilling import Bil logger = logging.getLogger(__name__) async def generateDocument(self, parameters: Dict[str, Any]) -> ActionResult: - prompt = parameters.get("prompt") - if not prompt: + base_prompt = parameters.get("prompt") or "" + context_val = parameters.get("context") + if context_val and isinstance(context_val, str) and context_val.strip(): + prompt = f"Kontext:\n{context_val.strip()}\n\n{base_prompt.strip()}" + else: + prompt = base_prompt + if not prompt.strip(): return ActionResult.isFailure(error="prompt is required") documentList = parameters.get("documentList", []) diff --git a/modules/workflows/methods/methodAi/actions/webResearch.py b/modules/workflows/methods/methodAi/actions/webResearch.py index 2c873396..2cf388b9 100644 --- a/modules/workflows/methods/methodAi/actions/webResearch.py +++ b/modules/workflows/methods/methodAi/actions/webResearch.py @@ -13,10 +13,42 @@ from modules.serviceCenter.services.serviceBilling.mainServiceBilling import Bil logger = logging.getLogger(__name__) +def _build_research_prompt(parameters: Dict[str, Any]) -> str: + """Assemble the final research prompt from prompt + optional context/documentList.""" + base_prompt = (parameters.get("prompt") or "").strip() + context_val = parameters.get("context") + doc_list = parameters.get("documentList") + + parts: list[str] = [] + + # Prepend context string if provided + if context_val and isinstance(context_val, str) and context_val.strip(): + parts.append(f"Kontext:\n{context_val.strip()}") + + # Extract text from documentList items if provided + if doc_list: + docs: list = [] + if isinstance(doc_list, dict): + docs = doc_list.get("documents", []) or doc_list.get("items", []) + elif isinstance(doc_list, list): + docs = doc_list + doc_texts = [] + for d in docs: + if isinstance(d, dict): + text = d.get("documentData") or d.get("text") or d.get("content") or "" + if text and isinstance(text, str): + doc_texts.append(text.strip()) + if doc_texts: + parts.append("Dokumente:\n" + "\n---\n".join(doc_texts)) + + parts.append(base_prompt) + return "\n\n".join(p for p in parts if p) + + async def webResearch(self, parameters: Dict[str, Any]) -> ActionResult: operationId = None try: - prompt = parameters.get("prompt") + prompt = _build_research_prompt(parameters) if not prompt: return ActionResult.isFailure(error="Research prompt is required")