From 55ee75106c675780c2a7f946ab092d95be9b65e8 Mon Sep 17 00:00:00 2001 From: Simon Diesenreiter Date: Fri, 10 Apr 2026 21:24:39 +0200 Subject: [PATCH] fix: n8n workflow generation, refs NOISSUE --- ai_software_factory/agents/n8n_setup.py | 31 +++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/ai_software_factory/agents/n8n_setup.py b/ai_software_factory/agents/n8n_setup.py index 7c89698..01a0e69 100644 --- a/ai_software_factory/agents/n8n_setup.py +++ b/ai_software_factory/agents/n8n_setup.py @@ -220,11 +220,31 @@ class N8NSetupAgent: async def create_workflow(self, workflow_json: dict) -> dict: """Create or update a workflow.""" - return await self._request("POST", "workflows", json=workflow_json) + return await self._request("POST", "workflows", json=self._workflow_payload(workflow_json)) + + def _workflow_payload(self, workflow_json: dict) -> dict: + """Return a workflow payload without server-managed read-only fields.""" + payload = dict(workflow_json) + payload.pop("active", None) + payload.pop("id", None) + payload.pop("createdAt", None) + payload.pop("updatedAt", None) + payload.pop("versionId", None) + return payload + + async def _update_workflow_via_put(self, workflow_id: str, workflow_json: dict) -> dict: + """Fallback update path for n8n instances that only support PUT.""" + return await self._request("PUT", f"workflows/{workflow_id}", json=self._workflow_payload(workflow_json)) async def update_workflow(self, workflow_id: str, workflow_json: dict) -> dict: """Update an existing workflow.""" - return await self._request("PATCH", f"workflows/{workflow_id}", json=workflow_json) + result = await self._request("PATCH", f"workflows/{workflow_id}", json=self._workflow_payload(workflow_json)) + if result.get("status_code") == 405: + fallback = await self._update_workflow_via_put(workflow_id, workflow_json) + if not fallback.get("error") and isinstance(fallback, dict): + fallback.setdefault("method", "PUT") + return fallback + return result async def enable_workflow(self, workflow_id: str) -> dict: """Enable a workflow.""" @@ -232,6 +252,11 @@ class N8NSetupAgent: if result.get("error"): fallback = await self._request("PATCH", f"workflows/{workflow_id}", json={"active": True}) if fallback.get("error"): + if fallback.get("status_code") == 405: + put_fallback = await self._request("PUT", f"workflows/{workflow_id}", json={"active": True}) + if put_fallback.get("error"): + return put_fallback + return {"success": True, "id": workflow_id, "method": "put"} return fallback return {"success": True, "id": workflow_id, "method": "patch"} return {"success": True, "id": workflow_id, "method": "activate"} @@ -255,7 +280,6 @@ class N8NSetupAgent: normalized_path = webhook_path.strip().strip("/") or "telegram" return { "name": "Telegram to AI Software Factory", - "active": False, "settings": {"executionOrder": "v1"}, "nodes": [ { @@ -324,7 +348,6 @@ class N8NSetupAgent: """Build a production Telegram Trigger based workflow.""" return { "name": "Telegram to AI Software Factory", - "active": False, "settings": {"executionOrder": "v1"}, "nodes": [ {