{
  "id": "aDPH18fqfD2OikjK",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI Json Optimiser",
  "tags": [],
  "nodes": [
    {
      "id": "5f23ac9b-98ba-4612-a1ec-c5765aaad242",
      "name": "Receive Workflow JSON",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -96,
        512
      ],
      "parameters": {
        "path": "5efd92ae-c139-483a-814e-fbc888924ddc",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "251e2698-77a5-4f72-813e-56873c405adc",
      "name": "Extract & Validate Workflow Body",
      "type": "n8n-nodes-base.code",
      "position": [
        112,
        512
      ],
      "parameters": {
        "jsCode": "if (!Array.isArray($input.all()) || $input.all().length === 0) {\n  throw new Error(\"No input data received\");\n}\n\nconst firstItem = $input.all()[0].json;\n\nif (!firstItem.body || !firstItem.body.workflow) {\n  throw new Error(\"Workflow not found in body\");\n}\n\nreturn [\n  {\n    json: firstItem.body.workflow\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "2c9de695-4eb8-40e3-b2b8-56f09f856c90",
      "name": "Optimize Workflow via AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        320,
        512
      ],
      "parameters": {
        "text": "=Optimize the following n8n workflow JSON for performance, cost efficiency, and structural cleanliness.\n\nMaintain the exact same functionality and outcome.\n\nImprove:\n- Execution speed\n- Node efficiency\n- API usage\n- Structural clarity\n- Remove redundant logic\n- Merge compatible nodes\n- Add batching if helpful\n\nHere is the workflow JSON:\n\n{{ JSON.stringify($json, null, 2) }}",
        "options": {
          "systemMessage": "=You are a senior n8n performance optimization architect.\n\nYour task is to analyze and optimize an existing n8n workflow JSON.\n\nYou must return a COMPLETE, IMPORT-READY, VALID n8n workflow JSON.\n\nCRITICAL OUTPUT RULES:\n\n- Output ONLY raw JSON.\n- Do NOT wrap in markdown.\n- Do NOT explain anything.\n- Do NOT include comments.\n- Do NOT include backticks.\n- Do NOT include extra text before or after JSON.\n- The response must start with { and end with }.\n- JSON must be valid and parsable.\n- All nodes must be properly connected.\n- No orphan nodes.\n- Workflow must remain functionally equivalent.\n\nOPTIMIZATION GOALS:\n\n1. Remove unnecessary or redundant nodes.\n2. Merge multiple Function/Set nodes when possible.\n3. Reduce API calls if duplicate or unnecessary.\n4. Replace inefficient patterns with best-practice nodes.\n5. Add batching if multiple API calls are done sequentially.\n6. Add error handling IF missing and necessary.\n7. Improve node naming for clarity.\n8. Ensure logical and clean node positioning (200px spacing minimum).\n9. Ensure connections object exactly matches node names.\n10. Preserve all required credentials references.\n\nSTRUCTURE REQUIREMENTS:\n\nReturn a valid n8n workflow object containing:\n\n- name (string)\n- nodes (array)\n- connections (object)\n- active (false)\n- settings (object)\n- versionId\n- meta (object)\n- id (null)\n\nNODE REQUIREMENTS:\n\nEach node must include:\n\n- id (unique string)\n- name\n- type\n- typeVersion\n- position [x, y]\n- parameters (object)\n\nCONNECTION FORMAT MUST FOLLOW:\n\n\"connections\": {\n  \"Node Name\": {\n    \"main\": [\n      [\n        {\n          \"node\": \"Next Node Name\",\n          \"type\": \"main\",\n          \"index\": 0\n        }\n      ]\n    ]\n  }\n}\n\nIMPORTANT:\n\n- Do NOT change the business logic.\n- Do NOT remove required triggers.\n- Do NOT remove required integrations.\n- Only improve efficiency, structure, and performance.\n- Ensure workflow is directly importable into n8n without edits.\n\nIf optimization is not possible, return a cleaned and structurally improved version of the original workflow.\n\nReturn ONLY valid n8n JSON."
        },
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "851875ca-2e10-47c2-abcd-55510d1826b0",
      "name": "Parse, Strip & Validate Optimized JSON",
      "type": "n8n-nodes-base.code",
      "position": [
        672,
        512
      ],
      "parameters": {
        "jsCode": "// Ensure input exists\nconst items = $input.all();\n\nif (!items.length) {\n  throw new Error(\"No input received\");\n}\n\n// Get first item\nconst firstItem = items[0].json;\n\n// Validate output field\nif (!firstItem.output) {\n  throw new Error(\"Missing 'output' field\");\n}\n\nlet rawOutput = firstItem.output;\n\n// Ensure it is a string\nif (typeof rawOutput !== \"string\") {\n  throw new Error(\"Output is not a string\");\n}\n\n// Trim possible whitespace\nrawOutput = rawOutput.trim();\n\n// Remove accidental markdown wrapping if AI added it\nif (rawOutput.startsWith(\"```\")) {\n  rawOutput = rawOutput.replace(/```json|```/g, \"\").trim();\n}\n\n// Parse JSON safely\nlet parsedWorkflow;\n\ntry {\n  parsedWorkflow = JSON.parse(rawOutput);\n} catch (error) {\n  throw new Error(\"Invalid JSON returned by AI: \" + error.message);\n}\n\n// Optional: Basic structural validation\nif (!parsedWorkflow.nodes || !parsedWorkflow.connections) {\n  throw new Error(\"Parsed JSON is not a valid n8n workflow structure\");\n}\n\n// Return normalized workflow object\nreturn [\n  {\n    json: parsedWorkflow\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "6b5043b7-d442-486e-a67b-1ec941e8c3c8",
      "name": "Convert Optimized Workflow to File",
      "type": "n8n-nodes-base.convertToFile",
      "position": [
        880,
        512
      ],
      "parameters": {
        "options": {},
        "operation": "toJson"
      },
      "typeVersion": 1.1
    },
    {
      "id": "e95135fd-5b86-4ab8-9022-7c40e03b15bc",
      "name": "Return Optimized File to Caller",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1088,
        512
      ],
      "parameters": {
        "options": {},
        "respondWith": "binary"
      },
      "typeVersion": 1.5
    },
    {
      "id": "f76804b3-61b0-4d60-ae0b-dea1cacc1cbc",
      "name": "\ud83d\udccb Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -720,
        256
      ],
      "parameters": {
        "color": 3,
        "width": 520,
        "height": 930,
        "content": "## \u26a1 AI JSON Optimiser\n\n### How it works\nThis workflow accepts an existing n8n workflow JSON via a POST webhook and uses an Azure OpenAI-powered AI Agent to analyze and return a fully optimized, import-ready version. The AI removes redundant nodes, merges compatible steps, reduces unnecessary API calls, adds missing error handling, and improves structural clarity \u2014 all while preserving the original business logic.\n\n**Data flow:**\n1. **Receive Workflow JSON** \u2014 Accepts a POST request with a `workflow` field inside the request body containing the raw n8n workflow JSON object.\n2. **Extract & Validate Workflow Body** \u2014 Confirms the payload is well-formed and extracts the workflow object, throwing clear errors on malformed input.\n3. **Optimize Workflow via AI Agent** \u2014 Sends the workflow to Azure OpenAI GPT-4o-mini with strict optimization instructions. Returns only raw, valid JSON.\n4. **Parse, Strip & Validate Optimized JSON** \u2014 Strips any accidental markdown, parses the AI output, and validates that it contains required `nodes` and `connections` fields.\n5. **Convert Optimized Workflow to File** \u2014 Wraps the parsed JSON into a downloadable `.json` binary file.\n6. **Return Optimized File to Caller** \u2014 Sends the binary file back as the HTTP response.\n\n### Setup steps\n1. Add your **Azure OpenAI credentials** (`azureOpenAiApi`) in n8n credentials \u2014 ensure deployment is named `gpt-4o-mini`.\n2. Activate the workflow and copy the generated webhook URL.\n3. Send a POST request with body: `{ \"workflow\": { ...your n8n workflow object... } }`\n4. The response will be a downloadable `.json` file ready to import into n8n.\n\n### Customization\n- Swap `gpt-4o-mini` for a more powerful Azure deployment (e.g. `gpt-4o`) for deeper optimizations.\n- Extend the AI system prompt to enforce specific node types or organizational standards."
      },
      "typeVersion": 1
    },
    {
      "id": "474343c6-94c4-4d26-983e-3912e5949def",
      "name": "\ud83d\udce5 Section: Input & Extraction",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -176,
        336
      ],
      "parameters": {
        "width": 440,
        "height": 200,
        "content": "## \ud83d\udce5 Input & Extraction\nReceives the POST request containing the workflow JSON inside `body.workflow`. Validates the payload structure and extracts the workflow object, rejecting malformed or empty requests immediately."
      },
      "typeVersion": 1
    },
    {
      "id": "846a9c9c-84c3-409f-bc0f-0c63b635f178",
      "name": "\ud83e\udd16 Section: AI Optimization",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        336
      ],
      "parameters": {
        "width": 440,
        "height": 200,
        "content": "## \ud83e\udd16 AI Optimization Engine\nThe AI Agent sends the full workflow JSON to Azure OpenAI GPT-4o-mini with a strict system prompt focused on performance, structural clarity, and efficiency. Output must be raw JSON only \u2014 no markdown, no commentary."
      },
      "typeVersion": 1
    },
    {
      "id": "415a6dab-46c6-49a1-81dc-625e83b77e67",
      "name": "\ud83d\udce4 Section: Output Processing",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        768,
        320
      ],
      "parameters": {
        "width": 580,
        "height": 200,
        "content": "## \ud83d\udce4 Output Processing & Delivery\nStrips any accidental markdown from the AI response, parses the JSON, validates the n8n structure, converts it to a downloadable file, and returns it as a binary HTTP response to the caller."
      },
      "typeVersion": 1
    },
    {
      "id": "5d712314-6e28-4862-86bf-c5472fde6e34",
      "name": "\u26a0\ufe0f Warning: Azure OpenAI Credentials",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        96,
        864
      ],
      "parameters": {
        "color": 2,
        "width": 320,
        "content": "\u26a0\ufe0f **Azure OpenAI Credentials Required**\nThis node requires a valid `azureOpenAiApi` credential linked to an active Azure deployment named `gpt-4o-mini`. An incorrect deployment name or missing API key will cause all optimization requests to fail silently."
      },
      "typeVersion": 1
    },
    {
      "id": "b558c606-faa7-4dc8-938a-d2e699faded8",
      "name": "Azure OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
      "position": [
        176,
        720
      ],
      "parameters": {
        "model": "gpt-4o-mini",
        "options": {}
      },
      "credentials": {
        "azureOpenAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "78b3fb40-907b-452a-9530-629477bf5961",
  "connections": {
    "Receive Workflow JSON": {
      "main": [
        [
          {
            "node": "Extract & Validate Workflow Body",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Azure OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Optimize Workflow via AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Optimize Workflow via AI Agent": {
      "main": [
        [
          {
            "node": "Parse, Strip & Validate Optimized JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract & Validate Workflow Body": {
      "main": [
        [
          {
            "node": "Optimize Workflow via AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert Optimized Workflow to File": {
      "main": [
        [
          {
            "node": "Return Optimized File to Caller",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse, Strip & Validate Optimized JSON": {
      "main": [
        [
          {
            "node": "Convert Optimized Workflow to File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}